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 / timeentry.itk < prev    next >
Text File  |  1999-02-24  |  14KB  |  400 lines

  1. #
  2. # Timeentry
  3. # ----------------------------------------------------------------------
  4. # Implements a quicken style time entry field with a popup clock
  5. # by combining the timefield and watch widgets together.  This
  6. # allows a user to enter the time via the keyboard or by using the
  7. # mouse by selecting the watch icon which brings up a popup clock.
  8. # ----------------------------------------------------------------------
  9. #   AUTHOR:  Mark L. Ulferts          E-mail: mulferts@austin.dsccc.com
  10. #
  11. #   @(#) $Id: timeentry.itk,v 1.1 1998/07/27 18:53:20 stanton Exp $
  12. # ----------------------------------------------------------------------
  13. #            Copyright (c) 1997 DSC Technologies Corporation
  14. # ======================================================================
  15. # Permission to use, copy, modify, distribute and license this software 
  16. # and its documentation for any purpose, and without fee or written 
  17. # agreement with DSC, is hereby granted, provided that the above copyright 
  18. # notice appears in all copies and that both the copyright notice and 
  19. # warranty disclaimer below appear in supporting documentation, and that 
  20. # the names of DSC Technologies Corporation or DSC Communications 
  21. # Corporation not be used in advertising or publicity pertaining to the 
  22. # software without specific, written prior permission.
  23. # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
  24. # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
  25. # INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
  26. # AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
  27. # SUPPORT, UPTIMES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
  28. # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
  29. # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
  30. # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
  31. # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
  32. # SOFTWARE.
  33. # ======================================================================
  34.  
  35. #
  36. # Usual options.
  37. #
  38. itk::usual Timeentry {
  39.     keep -background -borderwidth -cursor -foreground -highlightcolor \
  40.     -highlightthickness -labelfont -textbackground -textfont
  41. }
  42.  
  43. # ------------------------------------------------------------------
  44. #                              TIMEENTRY
  45. # ------------------------------------------------------------------
  46. class iwidgets::Timeentry {
  47.     inherit iwidgets::Timefield
  48.     
  49.     constructor {args} {}
  50.  
  51.     itk_option define -grab grab Grab "global"
  52.     itk_option define -icon icon Icon {}
  53.     itk_option define -state state State normal
  54.     itk_option define -closetext closeText Text Close
  55.  
  56.     #
  57.     # The watch widget isn't created until needed, yet we need
  58.     # its options to be available upon creation of a timeentry widget.
  59.     # So, we'll define them in these class now so they can just be
  60.     # propagated onto the watch later.
  61.     #
  62.     itk_option define -hourradius hourRadius Radius .50
  63.     itk_option define -hourcolor hourColor Color red
  64.     
  65.     itk_option define -minuteradius minuteRadius Radius .80
  66.     itk_option define -minutecolor minuteColor Color yellow
  67.     
  68.     itk_option define -pivotradius pivotRadius Radius .10
  69.     itk_option define -pivotcolor pivotColor Color white
  70.     
  71.     itk_option define -secondradius secondRadius Radius .90
  72.     itk_option define -secondcolor secondColor Color black
  73.     
  74.     itk_option define -clockcolor clockColor Color white
  75.     itk_option define -clockstipple clockStipple ClockStipple {}
  76.     
  77.     itk_option define -tickcolor tickColor Color black
  78.  
  79.     itk_option define -watchheight watchHeight Height 175
  80.     itk_option define -watchwidth watchWidth Width 155
  81.  
  82.     protected {
  83.     method _getPopupTime {}
  84.     method _releaseGrab {}
  85.     method _popup {}
  86.     method _getDefaultIcon {}
  87.  
  88.         common _defaultIcon ""
  89.     }
  90. }
  91.  
  92. #
  93. # Provide a lowercased access method for the timeentry class.
  94. proc ::iwidgets::timeentry {pathName args} {
  95.     uplevel ::iwidgets::Timeentry $pathName $args
  96. }
  97.  
  98. #
  99. # Use option database to override default resources of base classes.
  100. #
  101. option add *Timeentry.watchWidth 155 widgetDefault
  102. option add *Timeentry.watchHeight 175 widgetDefault
  103.  
  104. # ------------------------------------------------------------------
  105. #                        CONSTRUCTOR
  106. # ------------------------------------------------------------------
  107. body iwidgets::Timeentry::constructor {args} {
  108.     #
  109.     # Create an icon label to act as a button to bring up the 
  110.     # watch popup.
  111.     #
  112.     itk_component add iconbutton {
  113.     label $itk_interior.iconbutton -relief raised
  114.     } {
  115.     keep -borderwidth -cursor -foreground 
  116.     }
  117.     grid $itk_component(iconbutton) -row 0 -column 0 -sticky ns
  118.  
  119.     #
  120.     # Initialize the widget based on the command line options.
  121.     #
  122.     eval itk_initialize $args
  123. }
  124.  
  125. # ------------------------------------------------------------------
  126. #                             OPTIONS
  127. # ------------------------------------------------------------------
  128.  
  129. # ------------------------------------------------------------------
  130. # OPTION: -icon
  131. #
  132. # Specifies the clock icon image to be used in the time entry.  
  133. # Should one not be provided, then a default pixmap will be used
  134. # if possible, bitmap otherwise.
  135. # ------------------------------------------------------------------
  136. configbody iwidgets::Timeentry::icon {
  137.     if {$itk_option(-icon) == {}} {
  138.     $itk_component(iconbutton) configure -image [_getDefaultIcon]
  139.     } else {
  140.     if {[lsearch [image names] $itk_option(-icon)] == -1} {
  141.         error "bad icon option \"$itk_option(-icon)\":\
  142.                    should be an existing image"
  143.     } else {
  144.         $itk_component(iconbutton) configure -image $itk_option(-icon)
  145.     }
  146.     }
  147. }
  148.  
  149. # ------------------------------------------------------------------
  150. # OPTION: -grab
  151. #
  152. # Specifies the grab level, local or global, to be obtained when 
  153. # bringing up the popup watch.  The default is global.
  154. # ------------------------------------------------------------------
  155. configbody iwidgets::Timeentry::grab {
  156.     switch -- $itk_option(-grab) {
  157.     "local" - "global" {}
  158.     default {
  159.         error "bad grab option \"$itk_option(-grab)\":\
  160.                    should be local or global"
  161.     }
  162.     }
  163. }
  164.  
  165. # ------------------------------------------------------------------
  166. # OPTION: -state
  167. #
  168. # Specifies the state of the widget which may be disabled or
  169. # normal.  A disabled state prevents selection of the time field
  170. # or time icon button.
  171. # ------------------------------------------------------------------
  172. configbody iwidgets::Timeentry::state {
  173.     switch -- $itk_option(-state) {
  174.     normal {
  175.         bind $itk_component(iconbutton) <Button-1> [code $this _popup]
  176.     }
  177.     disabled {
  178.         bind $itk_component(iconbutton) <Button-1> {}
  179.     }
  180.     }
  181. }
  182.  
  183. # ------------------------------------------------------------------
  184. #                            METHODS
  185. # ------------------------------------------------------------------
  186. # ------------------------------------------------------------------
  187. # PROTECTED METHOD: _getDefaultIcon
  188. #
  189. # This method is invoked uto retrieve the name of the default icon
  190. # image displayed in the icon button.
  191. # ------------------------------------------------------------------
  192. body iwidgets::Timeentry::_getDefaultIcon {} {
  193.  
  194.   if {[lsearch [image types] pixmap] != -1} {
  195.     set _defaultIcon [image create pixmap -data {
  196.             /* XPM */
  197.             static char *watch1a[] = {
  198.             /* width height num_colors chars_per_pixel */
  199.             "    20    20        8            1",
  200.             /* colors */
  201.             ". c #000000",
  202.             "# c #000099",
  203.             "a c #009999",
  204.             "b c #999999",
  205.             "c c #cccccc",
  206.             "d c #ffff00",
  207.             "e c #d9d9d9",
  208.             "f c #ffffff",
  209.             /* pixels */
  210.             "eeeeebbbcccccbbbeeee",
  211.             "eeeee...#####..beeee",
  212.             "eeeee#aacccccaabeeee",
  213.             "eeee#accccccccc##eee",
  214.             "eee#ccc#cc#ccdcff#ee",
  215.             "ee#accccccccccfcca#e",
  216.             "eeaccccccc.cccfcccae",
  217.             "eeac#cccfc.cccc##cae",
  218.             "e#cccccffc.cccccccc#",
  219.             "e#ccccfffc.cccccccc#",
  220.             "e#cc#ffcc......c#cc#",
  221.             "e#ccfffccc.cccccccc#",
  222.             "e#cffccfcc.cccccccc#",
  223.             "eeafdccfcccccccd#cae",
  224.             "eeafcffcccccccccccae",
  225.             "eee#fcc#cccccdccc#ee",
  226.             "eee#fcc#cc#cc#ccc#ee",
  227.             "eeee#accccccccc##eee",
  228.             "eeeee#aacccccaabeeee",
  229.             "eeeee...#####..beeee"
  230.             };
  231.         }]
  232.     } else {
  233.     set _defaultIcon [image create bitmap -data {
  234.             #define watch1a_width 20
  235.             #define watch1a_height 20
  236.             static char watch1a_bits[] = {
  237.             0x40,0x40,0xf0,0xe0,0x7f,0xf0,0xe0,0xe0,0xf0,0x30,
  238.             0x80,0xf1,0x88,0x04,0xf2,0x0c,0x00,0xf6,0x04,0x04,
  239.             0xf4,0x94,0x84,0xf5,0x02,0x06,0xf8,0x02,0x0c,0xf8,
  240.             0x12,0x7e,0xf9,0x02,0x04,0xf8,0x02,0x24,0xf8,0x04,
  241.             0x00,0xf5,0x04,0x00,0xf4,0x88,0x02,0xf2,0x88,0x64,
  242.             0xf2,0x30,0x80,0xf1,0xe0,0x60,0xf0,0xe0,0xff,0xf0};
  243.         }]
  244.     }
  245.  
  246.     #
  247.     # Since this image will only need to be created once, we redefine
  248.     # this method to just return the image name for subsequent calls.
  249.     #
  250.     body ::iwidgets::Timeentry::_getDefaultIcon {} {
  251.     return $_defaultIcon
  252.     }
  253.  
  254.     return $_defaultIcon
  255. }
  256.  
  257.  
  258. # ------------------------------------------------------------------
  259. # PROTECTED METHOD: _popup
  260. #
  261. # This method is invoked upon selection of the icon button.  It 
  262. # creates a watch widget within a toplevel popup, calculates 
  263. # the position at which to display the watch, performs a grab
  264. # and displays the watch.
  265. # ------------------------------------------------------------------
  266. body iwidgets::Timeentry::_popup {} {
  267.     #
  268.     # First, let's nullify the icon binding so that any another 
  269.     # selections are ignored until were done with this one.  Next,
  270.     # change the relief of the icon.
  271.     #
  272.     bind $itk_component(iconbutton) <Button-1> {}
  273.     $itk_component(iconbutton) configure -relief sunken
  274.  
  275.     #
  276.     # Create a withdrawn toplevel widget and remove the window 
  277.     # decoration via override redirect.
  278.     #
  279.     itk_component add -private popup {
  280.     toplevel $itk_interior.popup 
  281.     }
  282.     $itk_component(popup) configure -borderwidth 2 -background black
  283.     wm withdraw $itk_component(popup)
  284.     wm overrideredirect $itk_component(popup) 1
  285.  
  286.     #
  287.     # Add a binding to for Escape to always release the grab.
  288.     #
  289.     bind $itk_component(popup) <KeyPress-Escape> [code $this _releaseGrab]
  290.  
  291.     #
  292.     # Create the watch widget.
  293.     #
  294.     itk_component add watch {
  295.     iwidgets::Watch $itk_component(popup).watch
  296.     } {
  297.     usual
  298.  
  299.     rename -width -watchwidth watchWidth Width 
  300.     rename -height -watchheight watchHeight Height 
  301.  
  302.     keep -hourradius -minuteradius -minutecolor -pivotradius -pivotcolor \
  303.         -secondradius -secondcolor -clockcolor -clockstipple -tickcolor 
  304.     }
  305.     grid $itk_component(watch) -row 0 -column 0
  306.     $itk_component(watch) configure -cursor top_left_arrow
  307.  
  308.     #
  309.     # Create a button widget so the user can say they are done.
  310.     #
  311.     itk_component add close {
  312.     button $itk_component(popup).close -command [code $this _getPopupTime]
  313.     } {
  314.     usual
  315.     rename -text -closetext closeText Text
  316.     }
  317.     grid $itk_component(close) -row 1 -column 0 -sticky ew
  318.     $itk_component(close) configure -cursor top_left_arrow
  319.  
  320.     #
  321.     # The icon button will be used as the basis for the position of the
  322.     # popup on the screen.  We'll always attempt to locate the popup
  323.     # off the lower right corner of the button.  If that would put
  324.     # the popup off the screen, then we'll put above the upper left.
  325.     #
  326.     set rootx [winfo rootx $itk_component(iconbutton)]
  327.     set rooty [winfo rooty $itk_component(iconbutton)]
  328.     set popupwidth [cget -watchwidth]
  329.     set popupheight [expr [cget -watchheight] + \
  330.              [winfo reqheight $itk_component(close)]]
  331.  
  332.     set popupx [expr $rootx + 3 + \
  333.             [winfo width $itk_component(iconbutton)]]
  334.     set popupy [expr $rooty + 3 + \
  335.             [winfo height $itk_component(iconbutton)]]
  336.  
  337.     if {([expr $popupx + $popupwidth] > [winfo screenwidth .]) || \
  338.         ([expr $popupy + $popupheight] > [winfo screenheight .])} {
  339.     set popupx [expr $rootx - 3 - $popupwidth]
  340.     set popupy [expr $rooty - 3 - $popupheight]
  341.     }
  342.     
  343.     #
  344.     # Get the current time from the timefield widget and both
  345.     # show and select it on the watch.
  346.     #
  347.     $itk_component(watch) show [get]
  348.  
  349.     #
  350.     # Display the popup at the calculated position.
  351.     #
  352.     wm geometry $itk_component(popup) +$popupx+$popupy
  353.     wm deiconify $itk_component(popup)
  354.     tkwait visibility $itk_component(popup)
  355.  
  356.     #
  357.     # Perform either a local or global grab based on the -grab option.
  358.     #
  359.     if {$itk_option(-grab) == "local"} {
  360.     grab $itk_component(popup)
  361.     } else {
  362.     grab -global $itk_component(popup)
  363.     }
  364.  
  365.     #
  366.     # Make sure the widget is above all others and give it focus.
  367.     #
  368.     raise $itk_component(popup)
  369.     focus $itk_component(watch)
  370. }
  371.  
  372. # ------------------------------------------------------------------
  373. # PROTECTED METHOD: _popupGetTime
  374. #
  375. # This method is the callback for selection of a time on the 
  376. # watch.  It releases the grab and sets the time in the
  377. # timefield widget.
  378. # ------------------------------------------------------------------
  379. body iwidgets::Timeentry::_getPopupTime {} {
  380.     show [$itk_component(watch) get -clicks]
  381.     _releaseGrab 
  382. }
  383.  
  384. # ------------------------------------------------------------------
  385. # PROTECTED METHOD: _releaseGrab
  386. #
  387. # This method releases the grab, destroys the popup, changes the 
  388. # relief of the button back to raised and reapplies the binding
  389. # to the icon button that engages the popup action.
  390. # ------------------------------------------------------------------
  391. body iwidgets::Timeentry::_releaseGrab {} {
  392.     grab release $itk_component(popup)
  393.     $itk_component(iconbutton) configure -relief raised
  394.     destroy $itk_component(popup) 
  395.     unset itk_component(popup)
  396.     bind $itk_component(iconbutton) <Button-1> [code $this _popup]
  397. }
  398.