| [32535cc] | 1 | package require Metawidget |
|---|
| 2 | |
|---|
| 3 | # name: Spinentry |
|---|
| 4 | # args: args |
|---|
| 5 | # for the first instance defines the images for the arrow buttons. |
|---|
| 6 | # creates the two arrow "buttons" and inits the option variables. |
|---|
| 7 | metawidget create Spinentry { |
|---|
| 8 | if { ! [ourinfo exists pDown] } { |
|---|
| 9 | our pDown [image create bitmap -data { |
|---|
| 10 | #define _width 8 |
|---|
| 11 | #define _height 3 |
|---|
| 12 | static char _bits[] = { 0x7c, 0x38, 0x10 }; |
|---|
| 13 | }] |
|---|
| 14 | our pUp [image create bitmap -data { |
|---|
| 15 | #define _width 8 |
|---|
| 16 | #define _height 3 |
|---|
| 17 | static char _bits[] = { 0x10, 0x38, 0x7c }; |
|---|
| 18 | }] |
|---|
| 19 | |
|---|
| 20 | foreach sBind [bind Entry] { |
|---|
| 21 | bind Spinentry $sBind [bind Entry $sBind] |
|---|
| 22 | } |
|---|
| 23 | } |
|---|
| 24 | |
|---|
| 25 | entry $this.entr |
|---|
| 26 | label $this.entr.stup -border 2 -relief raised -image [our pUp] -cursor arrow |
|---|
| 27 | label $this.entr.stdn -border 2 -relief raised -image [our pDown] -cursor arrow |
|---|
| 28 | |
|---|
| 29 | pack $this.entr -fill both -expand 1 |
|---|
| 30 | place $this.entr.stup -relx 1 -rely 0 -w 16 -relh .5 -anchor ne |
|---|
| 31 | place $this.entr.stdn -relx 1 -rely 1 -w 16 -relh .5 -anchor se |
|---|
| 32 | |
|---|
| 33 | bind $this.entr <Up> "$this _step +" |
|---|
| 34 | bind $this.entr <Down> "$this _step -" |
|---|
| 35 | bind $this.entr.stup <Button-1> "$this _press %W +" |
|---|
| 36 | bind $this.entr.stdn <Button-1> "$this _press %W -" |
|---|
| 37 | bind $this.entr.stup <ButtonRelease-1> "$this _press %W" |
|---|
| 38 | bind $this.entr.stdn <ButtonRelease-1> "$this _press %W" |
|---|
| 39 | |
|---|
| 40 | my -step 1 |
|---|
| 41 | my -speed 100 |
|---|
| 42 | my -maximum {} |
|---|
| 43 | my -minimum {} |
|---|
| 44 | my -onerror {} |
|---|
| 45 | my -value {} |
|---|
| 46 | } {} -default entr |
|---|
| 47 | |
|---|
| 48 | # name: _spin |
|---|
| 49 | # args: sDir: + or 0 |
|---|
| 50 | # called on button press. a timer will call this function after -speed ms. |
|---|
| 51 | # the timer job is cancelled with button release. |
|---|
| 52 | metawidget proc Spinentry _spin { sDir } { |
|---|
| 53 | $this _step $sDir |
|---|
| 54 | my iJob1 [after [my -speed] $this _spin $sDir] |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | # name: _press |
|---|
| 58 | # args: sWindow: arrow "button" that was pressed |
|---|
| 59 | # sDir: + or - |
|---|
| 60 | # changes the relief of the arrow button. for button press, it calls |
|---|
| 61 | # _spin. for button release, it kills any pending timer jobs. |
|---|
| 62 | metawidget proc Spinentry _press { sWindow {sDir {}} } { |
|---|
| 63 | if { $sDir == {} } { |
|---|
| 64 | $sWindow config -relief raised |
|---|
| 65 | catch { after cancel [my iJob1] } |
|---|
| 66 | } else { |
|---|
| 67 | $sWindow config -relief sunken |
|---|
| 68 | $this _spin $sDir |
|---|
| 69 | } |
|---|
| 70 | } |
|---|
| 71 | |
|---|
| 72 | # name: _step |
|---|
| 73 | # args: sDir: + or - |
|---|
| 74 | # called on cursor up/down. changes the entry's value one time and updates |
|---|
| 75 | # the entry widget. if the expr does not work and -onerror is defined, it |
|---|
| 76 | # evals it, otherwise escalates the error upward. |
|---|
| 77 | metawidget proc Spinentry _step { sDir } { |
|---|
| 78 | set fValue [$this get] |
|---|
| 79 | |
|---|
| 80 | if { [catch {expr $fValue $sDir [my -step]} fValue] } { |
|---|
| 81 | if { [my -onerror] != {} } { |
|---|
| 82 | eval [my -onerror] |
|---|
| 83 | } else { |
|---|
| 84 | error $fValue |
|---|
| 85 | } |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | if { [my -minimum] != {} && $fValue < [my -minimum]} { |
|---|
| 89 | set fValue [my -minimum] |
|---|
| 90 | } |
|---|
| 91 | if { [my -maximum] != {} && $fValue > [my -maximum]} { |
|---|
| 92 | set fValue [my -maximum] |
|---|
| 93 | } |
|---|
| 94 | |
|---|
| 95 | $this.entr delete 0 end |
|---|
| 96 | $this.entr insert 0 $fValue |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | # name: -value |
|---|
| 100 | # args: fValue |
|---|
| 101 | # simply sets a value in the entry widget. also checks if that value |
|---|
| 102 | # can be stepped up and down. if not, it raises an exception. |
|---|
| 103 | metawidget proc Spinentry -value { fValue } { |
|---|
| 104 | if { [catch { expr $fValue + [my -step] }] } { |
|---|
| 105 | throw "Value $fValue is not numeric" |
|---|
| 106 | } |
|---|
| 107 | |
|---|
| 108 | $this.entr delete 0 end |
|---|
| 109 | $this.entr insert 0 $fValue |
|---|
| 110 | |
|---|
| 111 | my -value $fValue |
|---|
| 112 | } |
|---|
| 113 | |
|---|
| 114 | metawidget command Spinentry _step _step |
|---|
| 115 | metawidget command Spinentry _spin _spin |
|---|
| 116 | metawidget command Spinentry _press _press |
|---|
| 117 | |
|---|
| 118 | metawidget option Spinentry -step |
|---|
| 119 | metawidget option Spinentry -speed |
|---|
| 120 | metawidget option Spinentry -maximum |
|---|
| 121 | metawidget option Spinentry -minimum |
|---|
| 122 | metawidget option Spinentry -onerror |
|---|
| 123 | metawidget option Spinentry -value -value |
|---|
| 124 | |
|---|
| 125 | proc test {} { |
|---|
| 126 | pack [spinentry .spin -value 10 -step 2 -minimum 0 -maximum 20 -speed 80 -onerror {puts NoGood!}] -fill x -pady 10 |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | #test |
|---|
| 130 | |
|---|