home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / iwidgets3.0.0 / scripts / spinner.itk < prev    next >
Text File  |  1999-02-24  |  16KB  |  449 lines

  1. # Spinner 
  2. # ----------------------------------------------------------------------
  3. # Implements a spinner widget.  The Spinner is comprised of an  
  4. # EntryField plus up and down arrow buttons. 
  5. # Spinner is meant to be used as a base class for creating more
  6. # specific spinners such as SpinInt.itk
  7. # Arrows may be drawn horizontally or vertically.
  8. # User may define arrow behavior or accept the default arrow behavior.
  9. #
  10. # ----------------------------------------------------------------------
  11. #   AUTHOR:  Sue Yockey               Phone: (214) 519-2517
  12. #                                     E-mail: syockey@spd.dsccc.com
  13. #                                             yockey@acm.org
  14. #
  15. #   @(#) $Id: spinner.itk,v 1.1 1998/07/27 18:53:18 stanton Exp $
  16. # ----------------------------------------------------------------------
  17. #            Copyright (c) 1995 DSC Technologies Corporation
  18. # ======================================================================
  19. # Permission to use, copy, modify, distribute and license this software 
  20. # and its documentation for any purpose, and without fee or written 
  21. # agreement with DSC, is hereby granted, provided that the above copyright 
  22. # notice appears in all copies and that both the copyright notice and 
  23. # warranty disclaimer below appear in supporting documentation, and that 
  24. # the names of DSC Technologies Corporation or DSC Communications 
  25. # Corporation not be used in advertising or publicity pertaining to the 
  26. # software without specific, written prior permission.
  27. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  28. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  29. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  30. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
  31. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
  32. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
  33. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  34. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  35. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
  36. # SOFTWARE.
  37. # ======================================================================
  38.  
  39. #
  40. # Usual options.
  41. #
  42. itk::usual Spinner {
  43.     keep -background -borderwidth -cursor -foreground -highlightcolor \
  44.      -highlightthickness -insertbackground -insertborderwidth \
  45.      -insertofftime -insertontime -insertwidth -labelfont \
  46.      -selectbackground -selectborderwidth -selectforeground \
  47.      -textbackground -textfont
  48. }
  49.  
  50. # ------------------------------------------------------------------
  51. #                              SPINNER
  52. # ------------------------------------------------------------------
  53. class iwidgets::Spinner {
  54.     inherit iwidgets::Entryfield 
  55.  
  56.     constructor {args} {}
  57.     destructor {}
  58.  
  59.     itk_option define -arroworient arrowOrient Orient vertical
  60.     itk_option define -textfont textFont \
  61.         Font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
  62.     itk_option define -borderwidth borderWidth BorderWidth 2
  63.     itk_option define -highlightthickness highlightThickness \
  64.         HighlightThickness 2
  65.     itk_option define -increment increment Command {}
  66.     itk_option define -decrement decrement Command {}
  67.     itk_option define -repeatdelay repeatDelay RepeatDelay 300 
  68.     itk_option define -repeatinterval repeatInterval RepeatInterval 100
  69.     itk_option define -foreground foreground Foreground black
  70.  
  71.     public method down {}
  72.     public method up {}
  73.  
  74.     protected method _pushup {}
  75.     protected method _pushdown {}
  76.     protected method _relup {}
  77.     protected method _reldown {}
  78.     protected method _doup {rate}
  79.     protected method _dodown {rate}
  80.     protected method _up {}
  81.     protected method _down {}
  82.  
  83.     protected method _positionArrows {{when later}}
  84.  
  85.     protected variable _interior {}
  86.     protected variable _reposition ""  ;# non-null => _positionArrows pending
  87.     protected variable _uptimer ""     ;# non-null => _uptimer pending
  88.     protected variable _downtimer ""   ;# non-null => _downtimer pending
  89. }
  90.     
  91. #
  92. # Provide a lowercased access method for the Spinner class.
  93. proc ::iwidgets::spinner {pathName args} {
  94.     uplevel ::iwidgets::Spinner $pathName $args
  95. }
  96.  
  97. # ------------------------------------------------------------------
  98. #                        CONSTRUCTOR
  99. # ------------------------------------------------------------------
  100. body iwidgets::Spinner::constructor {args} {
  101.     #
  102.     # Save off the interior for later use.
  103.     #
  104.     set _interior $itk_interior
  105.     
  106.     #
  107.     # Create up arrow button.
  108.     # 
  109.     itk_component add uparrow {
  110.     canvas $itk_interior.uparrow -height 10 -width 10 \
  111.         -relief raised -highlightthickness 0
  112.     } {
  113.     keep -background -borderwidth
  114.     }
  115.     
  116.     #
  117.     # Create down arrow button.
  118.     # 
  119.     itk_component add downarrow {
  120.     canvas $itk_interior.downarrow -height 10 -width 10 \
  121.         -relief raised -highlightthickness 0
  122.     } {
  123.     keep -background -borderwidth
  124.     }
  125.  
  126.     #
  127.     # Add bindings for button press events on the up and down buttons.
  128.     #
  129.     bind $itk_component(uparrow) <ButtonPress-1> [code $this _pushup]
  130.     bind $itk_component(uparrow) <ButtonRelease-1> [code $this _relup]
  131.  
  132.     bind $itk_component(downarrow)  <ButtonPress-1> [code $this _pushdown]
  133.     bind $itk_component(downarrow) <ButtonRelease-1> [code $this _reldown]
  134.     
  135.     eval itk_initialize $args
  136.  
  137.     # 
  138.     # When idle, position the arrows.
  139.     #
  140.     _positionArrows
  141. }
  142.  
  143. # ------------------------------------------------------------------
  144. #                          DESTRUCTOR
  145. # ------------------------------------------------------------------
  146.  
  147. body iwidgets::Spinner::destructor {} {
  148.     if {$_reposition != ""} {after cancel $_reposition}
  149.     if {$_uptimer != ""} {after cancel $_uptimer}
  150.     if {$_downtimer != ""} {after cancel $_downtimer}
  151. }
  152.  
  153. # ------------------------------------------------------------------
  154. #                             OPTIONS
  155. # ------------------------------------------------------------------
  156.  
  157. # ------------------------------------------------------------------
  158. # OPTION: -arroworient
  159. #
  160. # Place arrows vertically or horizontally .
  161. # ------------------------------------------------------------------
  162. configbody iwidgets::Spinner::arroworient {
  163.     _positionArrows
  164. }
  165.  
  166. # ------------------------------------------------------------------
  167. # OPTION: -textfont
  168. #
  169. # Change font, resize arrow buttons.
  170. # ------------------------------------------------------------------
  171. configbody iwidgets::Spinner::textfont {
  172.     _positionArrows
  173. }
  174.  
  175. # ------------------------------------------------------------------
  176. # OPTION: -highlightthickness
  177. #
  178. # Change highlightthickness, resize arrow buttons.
  179. # ------------------------------------------------------------------
  180. configbody iwidgets::Spinner::highlightthickness {
  181.     _positionArrows
  182. }
  183.  
  184. # ------------------------------------------------------------------
  185. # OPTION: -borderwidth
  186. #
  187. # Change borderwidth, resize arrow buttons.
  188. # ------------------------------------------------------------------
  189. configbody iwidgets::Spinner::borderwidth {
  190.     _positionArrows
  191. }
  192.  
  193. # ------------------------------------------------------------------
  194. # OPTION: -increment
  195. #
  196. # Up arrow callback. 
  197. # ------------------------------------------------------------------
  198. configbody iwidgets::Spinner::increment {
  199.     if {$itk_option(-increment) == {}} {
  200.     set itk_option(-increment) [code $this up]
  201.     }
  202. }
  203.  
  204. # ------------------------------------------------------------------
  205. # OPTION: -decrement
  206. #
  207. # Down arrow callback. 
  208. # ------------------------------------------------------------------
  209. configbody iwidgets::Spinner::decrement {
  210.     if {$itk_option(-decrement) == {}} {
  211.     set itk_option(-decrement) [code $this down]
  212.     }
  213. }
  214.  
  215. # ------------------------------------------------------------------
  216. # OPTION: -repeatinterval
  217. #
  218. # Arrow repeat rate in milliseconds. A repeatinterval of 0 disables 
  219. # button repeat.
  220. # ------------------------------------------------------------------
  221. configbody iwidgets::Spinner::repeatinterval {
  222.     if {$itk_option(-repeatinterval) < 0} {
  223.        set itk_option(-repeatinterval) 0
  224.     } 
  225. }
  226.  
  227. # ------------------------------------------------------------------
  228. # OPTION: -repeatdelay
  229. #
  230. # Arrow repeat delay in milliseconds. 
  231. # ------------------------------------------------------------------
  232. configbody iwidgets::Spinner::repeatdelay {
  233.     if {$itk_option(-repeatdelay) < 0} {
  234.        set itk_option(-repeatdelay) 0
  235.     } 
  236. }
  237.  
  238. # ------------------------------------------------------------------
  239. # OPTION: -foreground
  240. #
  241. # Set the foreground color of the up and down arrows. Remember
  242. # to make sure the "tag" exists before setting them...
  243. # ------------------------------------------------------------------
  244. configbody iwidgets::Spinner::foreground {
  245.  
  246.     if { [$itk_component(uparrow) gettags up] != "" } {
  247.     $itk_component(uparrow) itemconfigure up \
  248.         -fill $itk_option(-foreground)
  249.     }
  250.  
  251.     if { [$itk_component(downarrow) gettags down] != "" } {
  252.     $itk_component(downarrow) itemconfigure down \
  253.         -fill $itk_option(-foreground)
  254.     }
  255. }
  256.  
  257. # ------------------------------------------------------------------
  258. #                            METHODS
  259. # ------------------------------------------------------------------
  260.  
  261. # ------------------------------------------------------------------
  262. # METHOD: up
  263. #
  264. # Up arrow command.  Meant to be overloaded by derived class. 
  265. # ------------------------------------------------------------------
  266. body iwidgets::Spinner::up {} {
  267. }
  268.  
  269. # ------------------------------------------------------------------
  270. # METHOD: down 
  271. #
  272. # Down arrow command.  Meant to be overloaded by derived class.
  273. # ------------------------------------------------------------------
  274. body iwidgets::Spinner::down {} {
  275. }
  276.  
  277. # ------------------------------------------------------------------
  278. # PROTECTED METHOD: _positionArrows ?when?
  279. #
  280. # Draw Arrows for spinner. If "when" is "now", the change is applied
  281. # immediately.  If it is "later" or it is not specified, then the 
  282. # change is applied later, when the application is idle.
  283. # ------------------------------------------------------------------
  284. body iwidgets::Spinner::_positionArrows {{when later}} {
  285.     if {$when == "later"} {
  286.     if {$_reposition == ""} {
  287.         set _reposition [after idle [code $this _positionArrows now]]
  288.     }
  289.     return
  290.     } elseif {$when != "now"} {
  291.     error "bad option \"$when\": should be now or later"
  292.     }
  293.  
  294.     set _reposition ""
  295.  
  296.     set bdw [cget -borderwidth]
  297.  
  298.     #
  299.     # Based on the orientation of the arrows, pack them accordingly and
  300.     # determine the width and height of the spinners.  For vertical 
  301.     # orientation, it is really tight in the y direction, so we'll take 
  302.     # advantage of the highlightthickness.  Horizontal alignment has 
  303.     # plenty of space vertically, thus we'll ignore the thickness.
  304.     # 
  305.     switch $itk_option(-arroworient) {
  306.     vertical {
  307.         grid $itk_component(uparrow) -row 0 -column 0
  308.         grid $itk_component(downarrow) -row 1 -column 0
  309.  
  310.         set totalHgt [winfo reqheight $itk_component(entry)] 
  311.         set spinHgt [expr $totalHgt / 2]
  312.         set spinWid [expr round ($spinHgt * 1.6)]
  313.     }
  314.     horizontal {
  315.         grid $itk_component(uparrow) -row 0 -column 0
  316.         grid $itk_component(downarrow) -row 0 -column 1
  317.  
  318.         set spinHgt [expr [winfo reqheight $itk_component(entry)] - \
  319.             (2 * [$itk_component(entry) cget -highlightthickness])]
  320.         set spinWid $spinHgt
  321.     }
  322.     default {
  323.         error "bad orientation option \"$itk_option(-arroworient)\",\
  324.            should be horizontal or vertical"
  325.     }
  326.     }
  327.  
  328.     #
  329.     # Configure the width and height of the spinners minus the borderwidth.
  330.     # Next delete the previous spinner polygons and create new ones.
  331.     #
  332.     $itk_component(uparrow) config \
  333.         -height [expr $spinHgt - (2 * $bdw)] \
  334.         -width [expr $spinWid - (2 * $bdw)]
  335.     $itk_component(uparrow) delete up
  336.     $itk_component(uparrow) create polygon \
  337.         [expr $spinWid / 2] $bdw \
  338.         [expr $spinWid - $bdw - 1] [expr $spinHgt - $bdw -1] \
  339.         [expr $bdw + 1] [expr $spinHgt - $bdw - 1] \
  340.         -fill $itk_option(-foreground) -tags up
  341.         
  342.     $itk_component(downarrow) config \
  343.         -height [expr $spinHgt - (2 * $bdw)] \
  344.         -width [expr $spinWid - (2 * $bdw)]
  345.     $itk_component(downarrow) delete down
  346.     $itk_component(downarrow) create polygon \
  347.         [expr $spinWid / 2] [expr ($spinHgt - $bdw) - 1] \
  348.         [expr $bdw + 2] [expr $bdw + 1] \
  349.         [expr $spinWid - $bdw - 2] [expr $bdw + 1] \
  350.         -fill $itk_option(-foreground) -tags down
  351. }
  352.  
  353. # ------------------------------------------------------------------
  354. # PRIVATE METHOD: _pushup
  355. #
  356. # Up arrow button press event.  Call _doup with repeatdelay. 
  357. # ------------------------------------------------------------------
  358. body iwidgets::Spinner::_pushup {} {
  359.     $itk_component(uparrow) config -relief sunken
  360.     _doup $itk_option(-repeatdelay)
  361. }
  362.  
  363. # ------------------------------------------------------------------
  364. # PRIVATE METHOD: _pushdown
  365. #
  366. # Down arrow button press event.  Call _dodown with repeatdelay. 
  367. # ------------------------------------------------------------------
  368. body iwidgets::Spinner::_pushdown {} {
  369.     $itk_component(downarrow) config -relief sunken
  370.     _dodown $itk_option(-repeatdelay)
  371. }
  372.  
  373. # ------------------------------------------------------------------
  374. # PRIVATE METHOD: _doup
  375. #
  376. # Call _up and post to do another one after "rate" milliseconds if
  377. # repeatinterval > 0.
  378. # ------------------------------------------------------------------
  379. body iwidgets::Spinner::_doup {rate} {
  380.     _up 
  381.  
  382.     if {$itk_option(-repeatinterval) > 0} {
  383.     set _uptimer [after $rate [code $this _doup $itk_option(-repeatinterval)]]
  384.     }
  385. }
  386.  
  387. # ------------------------------------------------------------------
  388. # PRIVATE METHOD: _dodown
  389. #
  390. # Call _down and post to do another one after "rate" milliseconds if 
  391. # repeatinterval > 0.
  392. # ------------------------------------------------------------------
  393. body iwidgets::Spinner::_dodown {rate} {
  394.     _down 
  395.  
  396.     if {$itk_option(-repeatinterval) > 0} {
  397.     set _downtimer \
  398.         [after $rate [code $this _dodown $itk_option(-repeatinterval)]]
  399.     }
  400. }
  401.  
  402. # ------------------------------------------------------------------
  403. # PRIVATE METHOD: _relup
  404. #
  405. # Up arrow button release event.  Cancel pending up timer.
  406. # ------------------------------------------------------------------
  407. body iwidgets::Spinner::_relup {} {
  408.     $itk_component(uparrow) config -relief raised
  409.  
  410.     if {$_uptimer != ""} {
  411.     after cancel $_uptimer 
  412.     set _uptimer ""
  413.     }
  414. }
  415.  
  416. # ------------------------------------------------------------------
  417. # PRIVATE METHOD: _reldown
  418. #
  419. # Up arrow button release event.  Cancel pending down timer.
  420. # ------------------------------------------------------------------
  421. body iwidgets::Spinner::_reldown {} {
  422.     $itk_component(downarrow) config -relief raised
  423.  
  424.     if {$_downtimer != ""} { 
  425.     after cancel $_downtimer
  426.     set _downtimer ""
  427.     }
  428. }
  429.  
  430. # ------------------------------------------------------------------
  431. # PRIVATE METHOD: _up
  432. #
  433. # Up arrow button press event.  Call defined increment command. 
  434. # ------------------------------------------------------------------
  435. body iwidgets::Spinner::_up {} {
  436.     uplevel #0 $itk_option(-increment)
  437. }
  438.  
  439. # ------------------------------------------------------------------
  440. # PRIVATE METHOD: _down 
  441. #
  442. # Down arrow button press event.  Call defined decrement command. 
  443. # ------------------------------------------------------------------
  444. body iwidgets::Spinner::_down {} {
  445.     uplevel #0 $itk_option(-decrement)
  446. }
  447.