[Derek Peschel] 2005-04-27 This started as [A little calculator] and got transformed to meet my goals: * learn Tk by writing it * add real scientific notation This is a feature I've wanted for a '''long''' time. With modern software and fonts, I see no reason for displaying '''e''' notation to the user in the final result. (Intermediate results, and communications between programs, are another matter.) * make the onscreen keys match the positions of the keypad on my Mac keyboard Calculator keyboard layouts work well on calculators. But on a computer I'd rather use a computer keyboard. Having a calculator layout, and being forced to use the mouse, is doubly inefficient. But getting rid of the screen layout, or making it unresponsive to the mouse, gets rid of the free online help you already have. And forcing the functions to match the keypad wouldn't work well either. You don't need enter ''and'' =. So this is a compromise: the positions work with the keypad layout, but the help and some of the functions remain. And the main part of the keyboard needs to work too. Later, a way to hide the buttons or put them in a separate window would be good. * split the expression and results Again, why not use hardware like the nice big screen you almost certainly have? The split may make selection and cursor placement more intuitive too (but I need more evidence). And it makes the scientific-notation feature more reliable. The color feature just sort of happened along the way. ---- Mysterious bugs: * The text widget doesn't always accumulate characters. [SMH] 20050427 Fixed. Changed by removing $ from set $::estate notDone * The presence of the insertion cursor doesn't tell the whole story about focus. * Superscripts are being translated back into ASCII. I have tried just an entry widget in wish and not gotten correct results then either. * ''[escargo] 27 Apr 2005'' - Numbers entered through the keyboard are entered twice. (I suspect that perhaps two different bindings are firing.) ''[DHP] 28 Apr'' - It has something to do with focus. I thought the problem might be writing clearboth bind .e clearboth bind .e "hit e" bind .e "hit e" bind .e "hit /" bind .e "hit /" bind .e "hit *" bind .e "hit *" bind .e "hit 7" bind .e "hit 7" bind .e "hit 8" bind .e "hit 8" bind .e "hit 9" bind .e "hit 9" bind .e "hit -" bind .e "hit -" bind .e "hit 4" bind .e "hit 4" bind .e "hit 5" bind .e "hit 5" bind .e "hit 6" bind .e "hit 6" bind .e "hit +" bind .e "hit +" bind .e "hit 1" bind .e "hit 1" bind .e "hit 2" bind .e "hit 2" bind .e "hit 3" bind .e "hit 3" bind .e = bind .e = bind .e "hit 0" bind .e "hit 0" bind .e "hit ." bind .e "hit ." ### Procedures that widgets call. proc clearboth {} { focus .e set ::e "" .e config -foreground $::upToDateForeground set ::estate notDone set ::r "" setr .r config -foreground $::upToDateForeground set ::rstate upToDate } proc = {} { focus .e .e config -foreground $::staleForeground set ::estate done if {![catch [set ::r [expr [string map {* *1.0* / *1.0/} $::e]]]]} { # what value should r show? its previous one? expr's best nuemrical # approximation? text of the error? .r config -foreground $::errorForeground # is this really a good idea? setr set ::rstate error } else { .r config -foreground $::upToDateForeground setr set ::rstate upToDate } } proc hit {key} { focus .e switch -- $::estate { notDone { .e insert end $key .e icursor end } done { if [regexp {[-+*/]} $key] { set ::e $::r } else { set ::e "" } .e insert end $key .e icursor end set ::estate notDone .e config -foreground $::upToDateForeground } default { # ignore for now } } switch -- $::rstate { upToDate { .r config -foreground $::staleForeground set ::rstate stale } stale { # remains stale } error { .r config -foreground $::staleErrorForeground set ::rstate staleError } staleError { # remains staleError } default { # ignore for now } } } ### Subroutines. proc setr {} { # Hopefully end will be rounded, as described in manual .r delete 0 end set ignored "" set mantissa "" set exponent "" set rdisplay "" if {[regexp $::superscriptRE $::r ignored mantissa exponent]} { if {[string length $exponent] > 0} { set unicodeExponent [string map [array get superscripts] $exponent] set rdisplay "$mantissa \u00d710$unicodeExponent" } else { set rdisplay $mantissa } } .r insert end $rdisplay } ### Main loop. encoding system utf-8 focus .e wm resizable . 0 0