home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 December / PCWorld_2000-12_cd.bin / Komunikace / Comanche / comanche.exe / lib / iwidgets2.2.0 / scripts / spinner.itk < prev    next >
Text File  |  1999-02-24  |  16KB  |  457 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:49:52 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. # Default resources.
  41. #
  42. option add *Spinner.relief sunken widgetDefault
  43. option add *Spinner.labelPos w widgetDefault
  44. option add *Spinner.labelMargin 2 widgetDefault
  45.  
  46. #
  47. # Usual options.
  48. #
  49. itk::usual Spinner {
  50.     keep -background -borderwidth -cursor -foreground -highlightcolor \
  51.      -highlightthickness -insertbackground -insertborderwidth \
  52.      -insertofftime -insertontime -insertwidth -labelfont \
  53.      -selectbackground -selectborderwidth -selectforeground \
  54.      -textbackground -textfont
  55. }
  56.  
  57. # ------------------------------------------------------------------
  58. #                              SPINNER
  59. # ------------------------------------------------------------------
  60. class iwidgets::Spinner {
  61.     inherit iwidgets::Entryfield 
  62.  
  63.     constructor {args} {}
  64.     destructor {}
  65.  
  66.     itk_option define -arroworient arrowOrient Orient vertical
  67.     itk_option define -textfont textFont \
  68.         Font -Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*
  69.     itk_option define -borderwidth borderWidth BorderWidth 2
  70.     itk_option define -highlightthickness highlightThickness \
  71.         HighlightThickness 2
  72.     itk_option define -increment increment Command {}
  73.     itk_option define -decrement decrement Command {}
  74.     itk_option define -repeatdelay repeatDelay RepeatDelay 300 
  75.     itk_option define -repeatinterval repeatInterval RepeatInterval 100
  76.     itk_option define -foreground foreground Foreground black
  77.  
  78.     public method up {}
  79.     public method down {}
  80.  
  81.     protected method _pushup {}
  82.     protected method _pushdown {}
  83.     protected method _relup {}
  84.     protected method _reldown {}
  85.     protected method _doup {rate}
  86.     protected method _dodown {rate}
  87.     protected method _up {}
  88.     protected method _down {}
  89.  
  90.     protected method _positionArrows {{when later}}
  91.  
  92.     protected variable _reposition ""  ;# non-null => _positionArrows pending
  93.     protected variable _uptimer ""     ;# non-null => _uptimer pending
  94.     protected variable _downtimer ""   ;# non-null => _downtimer pending
  95. }
  96.     
  97. #
  98. # Provide a lowercased access method for the Spinner class.
  99. proc ::iwidgets::spinner {pathName args} {
  100.     uplevel ::iwidgets::Spinner $pathName $args
  101. }
  102.  
  103. # ------------------------------------------------------------------
  104. #                        CONSTRUCTOR
  105. # ------------------------------------------------------------------
  106. body iwidgets::Spinner::constructor {args} {
  107.  
  108.     #
  109.     # Create arrow frame.
  110.     # 
  111.     itk_component add arrowFrame {
  112.     frame $itk_interior.arrowFrame
  113.     } {
  114.     }
  115.     pack $itk_component(arrowFrame) -side left -padx 2
  116.     
  117.     #
  118.     # Create up arrow button.
  119.     # 
  120.     itk_component add uparrow {
  121.     canvas $itk_component(arrowFrame).uparrow -height 10 -width 10 \
  122.         -relief raised -highlightthickness 0
  123.     } {
  124.     keep -background -borderwidth
  125.     }
  126.     
  127.     #
  128.     # Create down arrow button.
  129.     # 
  130.     itk_component add downarrow {
  131.     canvas $itk_component(arrowFrame).downarrow -height 10 -width 10 \
  132.         -relief raised -highlightthickness 0
  133.     } {
  134.     keep -background -borderwidth
  135.     }
  136.  
  137.     bind $itk_component(uparrow) <ButtonPress-1> [code $this _pushup]
  138.     bind $itk_component(uparrow) <ButtonRelease-1> [code $this _relup]
  139.  
  140.     bind $itk_component(downarrow)  <ButtonPress-1> [code $this _pushdown]
  141.     bind $itk_component(downarrow) <ButtonRelease-1> [code $this _reldown]
  142.     
  143.     eval itk_initialize $args
  144.  
  145.     # 
  146.     # When idle, position the arrows.
  147.     #
  148.     _positionArrows
  149. }
  150.  
  151. # ------------------------------------------------------------------
  152. #                          DESTRUCTOR
  153. # ------------------------------------------------------------------
  154.  
  155. body iwidgets::Spinner::destructor {} {
  156.     if {$_reposition != ""} {after cancel $_reposition}
  157.     if {$_uptimer != ""} {after cancel $_uptimer}
  158.     if {$_downtimer != ""} {after cancel $_downtimer}
  159. }
  160.  
  161. # ------------------------------------------------------------------
  162. #                             OPTIONS
  163. # ------------------------------------------------------------------
  164.  
  165. # ------------------------------------------------------------------
  166. # OPTION: -arroworient
  167. #
  168. # Place arrows vertically or horizontally .
  169. # ------------------------------------------------------------------
  170. configbody iwidgets::Spinner::arroworient {
  171.     _positionArrows
  172. }
  173.  
  174. # ------------------------------------------------------------------
  175. # OPTION: -textfont
  176. #
  177. # Change font, resize arrow buttons.
  178. # ------------------------------------------------------------------
  179. configbody iwidgets::Spinner::textfont {
  180.     _positionArrows
  181. }
  182.  
  183. # ------------------------------------------------------------------
  184. # OPTION: -highlightthickness
  185. #
  186. # Change highlightthickness, resize arrow buttons.
  187. # ------------------------------------------------------------------
  188. configbody iwidgets::Spinner::highlightthickness {
  189.     _positionArrows
  190. }
  191.  
  192. # ------------------------------------------------------------------
  193. # OPTION: -borderwidth
  194. #
  195. # Change borderwidth, resize arrow buttons.
  196. # ------------------------------------------------------------------
  197. configbody iwidgets::Spinner::borderwidth {
  198.     _positionArrows
  199. }
  200.  
  201. # ------------------------------------------------------------------
  202. # OPTION: -increment
  203. #
  204. # Up arrow callback. 
  205. # ------------------------------------------------------------------
  206. configbody iwidgets::Spinner::increment {
  207.     if {$itk_option(-increment) == {}} {
  208.     set itk_option(-increment) [code $this up]
  209.     }
  210. }
  211.  
  212. # ------------------------------------------------------------------
  213. # OPTION: -decrement
  214. #
  215. # Down arrow callback. 
  216. # ------------------------------------------------------------------
  217. configbody iwidgets::Spinner::decrement {
  218.     if {$itk_option(-decrement) == {}} {
  219.     set itk_option(-decrement) [code $this down]
  220.     }
  221. }
  222.  
  223. # ------------------------------------------------------------------
  224. # OPTION: -repeatinterval
  225. #
  226. # Arrow repeat rate in milliseconds. A repeatinterval of 0 disables 
  227. # button repeat.
  228. # ------------------------------------------------------------------
  229. configbody iwidgets::Spinner::repeatinterval {
  230.     if {$itk_option(-repeatinterval) < 0} {
  231.        set itk_option(-repeatinterval) 0
  232.     } 
  233. }
  234.  
  235. # ------------------------------------------------------------------
  236. # OPTION: -repeatdelay
  237. #
  238. # Arrow repeat delay in milliseconds. 
  239. # ------------------------------------------------------------------
  240. configbody iwidgets::Spinner::repeatdelay {
  241.     if {$itk_option(-repeatdelay) < 0} {
  242.        set itk_option(-repeatdelay) 0
  243.     } 
  244. }
  245.  
  246. # ------------------------------------------------------------------
  247. # OPTION: -foreground
  248. #
  249. # Set the foreground color of the up and down arrows. Remember
  250. # to make sure the "tag" exists before setting them...
  251. # ------------------------------------------------------------------
  252. configbody iwidgets::Spinner::foreground {
  253.  
  254.     if { [$itk_component(uparrow) gettags up] != "" } {
  255.     $itk_component(uparrow) itemconfigure up \
  256.         -fill $itk_option(-foreground)
  257.     }
  258.  
  259.     if { [$itk_component(downarrow) gettags down] != "" } {
  260.     $itk_component(downarrow) itemconfigure down \
  261.         -fill $itk_option(-foreground)
  262.     }
  263. }
  264.  
  265. # ------------------------------------------------------------------
  266. #                            METHODS
  267. # ------------------------------------------------------------------
  268.  
  269. # ------------------------------------------------------------------
  270. # METHOD: up
  271. #
  272. # Up arrow command.  Meant to be overloaded by derived class. 
  273. # ------------------------------------------------------------------
  274. body iwidgets::Spinner::up {} {
  275. }
  276.  
  277. # ------------------------------------------------------------------
  278. # METHOD: down 
  279. #
  280. # Down arrow command.  Meant to be overloaded by derived class.
  281. # ------------------------------------------------------------------
  282. body iwidgets::Spinner::down {} {
  283. }
  284.  
  285. # ------------------------------------------------------------------
  286. # PROTECTED METHOD: _positionArrows ?when?
  287. #
  288. # Draw Arrows for spinner. If "when" is "now", the change is applied
  289. # immediately.  If it is "later" or it is not specified, then the 
  290. # change is applied later, when the application is idle.
  291. # ------------------------------------------------------------------
  292. body iwidgets::Spinner::_positionArrows {{when later}} {
  293.     if {$when == "later"} {
  294.     if {$_reposition == ""} {
  295.         set _reposition [after idle [code $this _positionArrows now]]
  296.     }
  297.     return
  298.     } elseif {$when != "now"} {
  299.     error "bad option \"$when\": should be now or later"
  300.     }
  301.  
  302.     set _reposition ""
  303.  
  304.     set bdw [cget -borderwidth]
  305.  
  306.     #
  307.     # Based on the orientation of the arrows, pack them accordingly and
  308.     # determine the width and height of the spinners.  For vertical 
  309.     # orientation, it is really tight in the y direction, so we'll take 
  310.     # advantage of the highlightthickness.  Horizontal alignment has 
  311.     # plenty of space vertically, thus we'll ignore the thickness.
  312.     # 
  313.     switch $itk_option(-arroworient) {
  314.     vertical {
  315.         pack configure $itk_component(uparrow) \
  316.             $itk_component(downarrow) -side top
  317.  
  318.         set totalHgt [winfo reqheight $itk_component(entry)] 
  319.         set spinHgt [expr $totalHgt / 2]
  320.         set spinWid [expr round ($spinHgt * 1.6)]
  321.     }
  322.     horizontal {
  323.         pack configure $itk_component(uparrow) \
  324.             $itk_component(downarrow) -side left
  325.  
  326.         set spinHgt [expr [winfo reqheight $itk_component(entry)] - \
  327.             (2 * [$itk_component(entry) cget -highlightthickness])]
  328.         set spinWid $spinHgt
  329.     }
  330.     default {
  331.         error "bad orientation option \"$itk_option(-arroworient)\",\
  332.            should be horizontal or vertical"
  333.     }
  334.     }
  335.  
  336.     #
  337.     # Configure the width and height of the spinners minus the borderwidth.
  338.     # Next delete the previous spinner polygons and create new ones.
  339.     #
  340.     $itk_component(uparrow) config \
  341.         -height [expr $spinHgt - (2 * $bdw)] \
  342.         -width [expr $spinWid - (2 * $bdw)]
  343.     $itk_component(uparrow) delete up
  344.     $itk_component(uparrow) create polygon \
  345.         [expr $spinWid / 2] $bdw \
  346.         [expr $spinWid - $bdw - 1] [expr $spinHgt - $bdw -1] \
  347.         [expr $bdw + 1] [expr $spinHgt - $bdw - 1] \
  348.         -fill $itk_option(-foreground) -tags up
  349.         
  350.     $itk_component(downarrow) config \
  351.         -height [expr $spinHgt - (2 * $bdw)] \
  352.         -width [expr $spinWid - (2 * $bdw)]
  353.     $itk_component(downarrow) delete down
  354.     $itk_component(downarrow) create polygon \
  355.         [expr $spinWid / 2] [expr ($spinHgt - $bdw) - 1] \
  356.         [expr $bdw + 2] [expr $bdw + 1] \
  357.         [expr $spinWid - $bdw - 2] [expr $bdw + 1] \
  358.         -fill $itk_option(-foreground) -tags down
  359. }
  360.  
  361. # ------------------------------------------------------------------
  362. # PRIVATE METHOD: _pushup
  363. #
  364. # Up arrow button press event.  Call _doup with repeatdelay. 
  365. # ------------------------------------------------------------------
  366. body iwidgets::Spinner::_pushup {} {
  367.     $itk_component(uparrow) config -relief sunken
  368.     _doup $itk_option(-repeatdelay)
  369. }
  370.  
  371. # ------------------------------------------------------------------
  372. # PRIVATE METHOD: _pushdown
  373. #
  374. # Down arrow button press event.  Call _dodown with repeatdelay. 
  375. # ------------------------------------------------------------------
  376. body iwidgets::Spinner::_pushdown {} {
  377.     $itk_component(downarrow) config -relief sunken
  378.     _dodown $itk_option(-repeatdelay)
  379. }
  380.  
  381. # ------------------------------------------------------------------
  382. # PRIVATE METHOD: _doup
  383. #
  384. # Call _up and post to do another one after "rate" milliseconds if
  385. # repeatinterval > 0.
  386. # ------------------------------------------------------------------
  387. body iwidgets::Spinner::_doup {rate} {
  388.     _up 
  389.  
  390.     if {$itk_option(-repeatinterval) > 0} {
  391.     set _uptimer [after $rate [code $this _doup $itk_option(-repeatinterval)]]
  392.     }
  393. }
  394.  
  395. # ------------------------------------------------------------------
  396. # PRIVATE METHOD: _dodown
  397. #
  398. # Call _down and post to do another one after "rate" milliseconds if 
  399. # repeatinterval > 0.
  400. # ------------------------------------------------------------------
  401. body iwidgets::Spinner::_dodown {rate} {
  402.     _down 
  403.  
  404.     if {$itk_option(-repeatinterval) > 0} {
  405.     set _downtimer \
  406.         [after $rate [code $this _dodown $itk_option(-repeatinterval)]]
  407.     }
  408. }
  409.  
  410. # ------------------------------------------------------------------
  411. # PRIVATE METHOD: _relup
  412. #
  413. # Up arrow button release event.  Cancel pending up timer.
  414. # ------------------------------------------------------------------
  415. body iwidgets::Spinner::_relup {} {
  416.     $itk_component(uparrow) config -relief raised
  417.  
  418.     if {$_uptimer != ""} {
  419.     after cancel $_uptimer 
  420.     set _uptimer ""
  421.     }
  422. }
  423.  
  424. # ------------------------------------------------------------------
  425. # PRIVATE METHOD: _reldown
  426. #
  427. # Up arrow button release event.  Cancel pending down timer.
  428. # ------------------------------------------------------------------
  429. body iwidgets::Spinner::_reldown {} {
  430.     $itk_component(downarrow) config -relief raised
  431.  
  432.     if {$_downtimer != ""} { 
  433.     after cancel $_downtimer
  434.     set _downtimer ""
  435.     }
  436. }
  437.  
  438. # ------------------------------------------------------------------
  439. # PRIVATE METHOD: _up
  440. #
  441. # Up arrow button press event.  Call defined increment command. 
  442. # ------------------------------------------------------------------
  443. body iwidgets::Spinner::_up {} {
  444.     uplevel #0 $itk_option(-increment)
  445. }
  446.  
  447. # ------------------------------------------------------------------
  448. # PRIVATE METHOD: _down 
  449. #
  450. # Down arrow button press event.  Call defined decrement command. 
  451. # ------------------------------------------------------------------
  452. body iwidgets::Spinner::_down {} {
  453.     uplevel #0 $itk_option(-decrement)
  454. }
  455.