Gnocl Cookbook‎ > ‎

    Date Spinning

    Using a gnocl::spinButton to Change the Value of a gnocl::entry

    David McClamrock

    A gnocl::spinButton will accept only floating-point values (possibly disguised as integers), and will spin through them only in a fixed numerical sequence. What if you want to spin continuously through a sequence of values that don't fit into that format (such as dates), but you also want to spin through a sequence of values that do fit into that format (such as cheque numbers)?

    The answer is simple (once you finally think of it): You use a gnocl::spinButton to change its own value when you press the left mouse button, and to change the value of an adjoining gnocl::entry widget when you press the middle button. This works because the middle button increments the value of the gnocl::spinButton by ten times the left-button increment. When a "10x" increment is recognized, the value of the gnocl::entry is changed, and the value of the gnocl::spinButton reverts to the value retained by way of the -data variable, so it seems to stay the same. When a "1x" (or, at any rate, less than "9x") increment is recognized, the value of the gnocl::spinButton is changed in the normal way, and the value of the -data variable is changed to match that value. This enables the user to spin through a large number of non-floating-point values (such as dates) by continuously pressing the middle mouse button. All you lose is the ability to get actual "10x" increments with the middle button, but the left button gives you such high-speed increments (sometimes up to "5x" or "6x" instead of only "1x," when pressed continuously) that this shouldn't matter much.


    Here's what it looks like:




    And here's the code:

    #!/usr/bin/env tclsh

    # datespin_trick.tcl: Script to use a gnocl::spinButton
    # to change the value of a gnocl::entry

    package require Gnocl
    set spin [gnocl::spinButton -digits 0 -lower 0 -upper 10000]
    $spin configure -value 2000 ; # Arbitrary, for example
    set initval [$spin cget -value]
    $spin configure -data $initval
    set ent [gnocl::entry]
    set today [clock format [clock seconds] -format {%Y/%m/%d}] ; # Today's date
    set datoa $today ; # Presume today may also be date of transaction
    $ent configure -value $datoa

    proc datespin {way} {
        global ent datoa
        set datoa [$ent cget -value]
        set oldsecs [clock scan $datoa -format {%Y/%m/%d}]
        if {$way eq "up"} {
            set newsecs [clock add $oldsecs 1 day]
        } else {
            set newsecs [clock add $oldsecs "-1" day]
        }
        set datoa [clock format $newsecs -format {%Y/%m/%d}]
        $ent configure -value $datoa
    }

    proc spinwhich {val} {
        global spin ent datoa
        set oldval [$spin cget -data]
        if {$val - $oldval > 9} {
            $spin configure -value $oldval
            datespin up
        } elseif {$oldval - $val > 9} {
            $spin configure -value $oldval
            datespin down
        } else {
            $spin configure -data $val
        }
    }

    $spin configure -data [$spin cget -value] -onValueChanged {spinwhich %v} \
        -tooltip "Use middle mouse button for date, left button\
        for check number (blank = 0); check number will reset to last\
        number used if date is changed"
    set box [gnocl::box -orientation horizontal]
    $box add $spin
    $box add $ent
    set win [gnocl::window -child $box]
    Comments

    Sections