📄 timefield.itk
字号:
## Timefield# ----------------------------------------------------------------------# Implements a time entry field with adjustable built-in intelligence# levels.# ----------------------------------------------------------------------# AUTHOR: John A. Tucker E-mail: jatucker@austin.dsccc.com## @(#) $Id: timefield.itk,v 1.1 2003/02/05 10:54:09 mdejong Exp $# ----------------------------------------------------------------------# Copyright (c) 1997 DSC Technologies Corporation# ======================================================================# Permission to use, copy, modify, distribute and license this software # and its documentation for any purpose, and without fee or written # agreement with DSC, is hereby granted, provided that the above copyright # notice appears in all copies and that both the copyright notice and # warranty disclaimer below appear in supporting documentation, and that # the names of DSC Technologies Corporation or DSC Communications # Corporation not be used in advertising or publicity pertaining to the # software without specific, written prior permission.# # DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL # DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE.# ======================================================================## Use option database to override default resources of base classes.#option add *Timefield.justify center widgetDefault## Usual options.#itk::usual Timefield { keep -background -borderwidth -cursor -foreground -highlightcolor \ -highlightthickness -labelfont -textbackground -textfont}# ------------------------------------------------------------------# TIMEFIELD# ------------------------------------------------------------------class iwidgets::Timefield { inherit iwidgets::Labeledwidget constructor {args} {} itk_option define -childsitepos childSitePos Position e itk_option define -command command Command {} itk_option define -seconds seconds Seconds on itk_option define -format format Format civilian itk_option define -iq iq Iq high itk_option define -gmt gmt GMT no itk_option define -state state State normal public { method get {{format "-string"}} method isvalid {} method show {{time "now"}} } protected { method _backwardCivilian {} method _backwardMilitary {} method _focusIn {} method _forwardCivilian {} method _forwardMilitary {} method _keyPress {char sym state} method _moveField {direction} method _setField {field} method _whichField {} method _toggleAmPm {} variable _cfield hour variable _formatString "%r" variable _fields {} variable _numFields 4 variable _forward {} variable _backward {} variable _timeVar "" common _militaryFields {hour minute second} common _civilianFields {hour minute second ampm} }}## Provide a lowercased access method for the timefield class.# proc iwidgets::timefield {pathName args} { uplevel iwidgets::Timefield $pathName $args}# ------------------------------------------------------------------# CONSTRUCTOR# ------------------------------------------------------------------body iwidgets::Timefield::constructor {args} { component hull configure -borderwidth 0 # # Create an entry field for entering the time. # itk_component add time { entry $itk_interior.time } { keep -borderwidth -cursor -exportselection \ -foreground -highlightcolor -highlightthickness \ -insertbackground -justify -relief -textvariable rename -font -textfont textFont Font rename -highlightbackground -background background Background rename -background -textbackground textBackground Background } # # Create the child site widget. # itk_component add -protected dfchildsite { frame $itk_interior.dfchildsite } set itk_interior $itk_component(dfchildsite) # # Add timefield event bindings for focus in and keypress events. # bind $itk_component(time) <FocusIn> [code $this _focusIn] bind $itk_component(time) <KeyPress> [code $this _keyPress %A %K %s] bind $itk_component(time) <1> "focus $itk_component(time); break" # # Disable some mouse button event bindings: # Button Motion # Double-Clicks # Triple-Clicks # Button2 # bind $itk_component(time) <Button1-Motion> break bind $itk_component(time) <Button2-Motion> break bind $itk_component(time) <Double-Button> break bind $itk_component(time) <Triple-Button> break bind $itk_component(time) <2> break # # Initialize the widget based on the command line options. # eval itk_initialize $args # # Initialize the time to the current time. # show}# ------------------------------------------------------------------# OPTIONS# ------------------------------------------------------------------# ------------------------------------------------------------------# OPTION: -childsitepos## Specifies the position of the child site in the widget. Valid# locations are n, s, e, and w.# ------------------------------------------------------------------configbody iwidgets::Timefield::childsitepos { set parent [winfo parent $itk_component(time)] switch $itk_option(-childsitepos) { n { grid $itk_component(dfchildsite) -row 0 -column 0 -sticky ew grid $itk_component(time) -row 1 -column 0 -sticky nsew grid rowconfigure $parent 0 -weight 0 grid rowconfigure $parent 1 -weight 1 grid columnconfigure $parent 0 -weight 1 grid columnconfigure $parent 1 -weight 0 } e { grid $itk_component(dfchildsite) -row 0 -column 1 -sticky ns grid $itk_component(time) -row 0 -column 0 -sticky nsew grid rowconfigure $parent 0 -weight 1 grid rowconfigure $parent 1 -weight 0 grid columnconfigure $parent 0 -weight 1 grid columnconfigure $parent 1 -weight 0 } s { grid $itk_component(dfchildsite) -row 1 -column 0 -sticky ew grid $itk_component(time) -row 0 -column 0 -sticky nsew grid rowconfigure $parent 0 -weight 1 grid rowconfigure $parent 1 -weight 0 grid columnconfigure $parent 0 -weight 1 grid columnconfigure $parent 1 -weight 0 } w { grid $itk_component(dfchildsite) -row 0 -column 0 -sticky ns grid $itk_component(time) -row 0 -column 1 -sticky nsew grid rowconfigure $parent 0 -weight 1 grid rowconfigure $parent 1 -weight 0 grid columnconfigure $parent 0 -weight 0 grid columnconfigure $parent 1 -weight 1 } default { error "bad childsite option\ \"$itk_option(-childsitepos)\":\ should be n, e, s, or w" } }}# ------------------------------------------------------------------# OPTION: -command## Command invoked upon detection of return key press event.# ------------------------------------------------------------------configbody iwidgets::Timefield::command {}# ------------------------------------------------------------------# OPTION: -iq## Specifies the level of intelligence to be shown in the actions# taken by the time field during the processing of keypress events.# Valid settings include high or low. With a high iq,# the time prevents the user from typing in an invalid time. For # example, if the current time is 05/31/1997 and the user changes# the hour to 04, then the minute will be instantly modified for them # to be 30. In addition, leap seconds are fully taken into account.# A setting of low iq instructs the widget to do no validity checking# at all during time entry. With a low iq level, it is assumed that# the validity will be determined at a later time using the time's# isvalid command.# ------------------------------------------------------------------configbody iwidgets::Timefield::iq { switch $itk_option(-iq) { high - low { } default { error "bad iq option \"$itk_option(-iq)\": should be high or low" } }}# ------------------------------------------------------------------# OPTION: -format## Specifies the time format displayed in the entry widget.# ------------------------------------------------------------------configbody iwidgets::Timefield::format { switch $itk_option(-format) { civilian { set _backward _backwardCivilian set _forward _forwardCivilian set _fields $_civilianFields set _numFields 4 set _formatString "%r" $itk_component(time) config -width 11 } military { set _backward _backwardMilitary set _forward _forwardMilitary set _fields $_militaryFields set _numFields 3 set _formatString "%T" $itk_component(time) config -width 8 } default { error "bad iq option \"$itk_option(-iq)\":\ should be civilian or military" } } # # Update the current contents of the entry field to reflect # the configured format. # show $_timeVar}# ------------------------------------------------------------------# OPTION: -gmt## This option is used for GMT time. Must be a boolean value.# ------------------------------------------------------------------configbody iwidgets::Timefield::gmt { switch $itk_option(-gmt) { 0 - no - false - off { } 1 - yes - true - on { } default { error "bad gmt option \"$itk_option(-gmt)\": should be boolean" } }}# ------------------------------------------------------------------# OPTION: -state## Disable the # ------------------------------------------------------------------configbody iwidgets::Timefield::state { switch -- $itk_option(-state) { normal { $itk_component(time) configure -state normal } disabled { focus $itk_component(hull) $itk_component(time) configure -state disabled } default { error "Invalid value for -state: $itk_option(-state). Should be\ \"normal\" or \"disabled\"." } }}# ------------------------------------------------------------------# METHODS# ------------------------------------------------------------------# ------------------------------------------------------------------# PUBLIC METHOD: get ?format?## Return the current contents of the timefield in one of two formats# string or as an integer clock value using the -string and -clicks# options respectively. The default is by string. Reference the # clock command for more information on obtaining times and their # formats.# ------------------------------------------------------------------body iwidgets::Timefield::get {{format "-string"}} { set _timeVar [$itk_component(time) get] switch -- $format { "-string" { return $_timeVar } "-clicks" { return [::clock scan $_timeVar -gmt $itk_option(-gmt)] } default { error "bad format option \"$format\":\ should be -string or -clicks" } }}# ------------------------------------------------------------------# PUBLIC METHOD: show time## Changes the currently displayed time to be that of the time # argument. The time may be specified either as a string or an# integer clock value. Reference the clock command for more # information on obtaining times and their formats.# ------------------------------------------------------------------body iwidgets::Timefield::show {{time "now"}} { set icursor [$itk_component(time) index insert] if {$time == {}} { set time "now" } switch -regexp -- $time { {^now$} { set seconds [::clock seconds] } {^[0-9]+$} { if { [catch {::clock format $time -gmt $itk_option(-gmt)}] } { error "bad time: \"$time\", must be a valid time \ string, clock clicks value or the keyword now" } set seconds $time } default { if {[catch {set seconds [::clock scan $time -gmt $itk_option(-gmt)]}]} { error "bad time: \"$time\", must be a valid time \ string, clock clicks value or the keyword now" } } } set _timeVar [::clock format $seconds -format $_formatString \ -gmt $itk_option(-gmt)] $itk_component(time) delete 0 end $itk_component(time) insert end $_timeVar $itk_component(time) icursor $icursor return $_timeVar}# ------------------------------------------------------------------# PUBLIC METHOD: isvalid## Returns a boolean indication of the validity of the currently# displayed time value. For example, 09:59::59 is valid whereas# 26:59:59 is invalid.# ------------------------------------------------------------------body iwidgets::Timefield::isvalid {} { set _timeVar [$itk_component(time) get] return [expr ([catch {::clock scan $_timeVar -gmt $itk_option(-gmt)}] == 0)]}# ------------------------------------------------------------------# PROTECTED METHOD: _focusIn## This method is bound to the <FocusIn> event. It resets the # insert cursor and field settings to be back to their last known# positions.# ------------------------------------------------------------------body iwidgets::Timefield::_focusIn {} { _setField $_cfield}# ------------------------------------------------------------------# PROTECTED METHOD: _keyPress ## This method is the workhorse of the class. It is bound to the# <KeyPress> event and controls the processing of all key strokes.# ------------------------------------------------------------------body iwidgets::Timefield::_keyPress {char sym state} { # # Determine which field we are in currently. This is needed # since the user may have moved to this position via a mouse # selection and so it would not be in the position we last # knew it to be. # set _cfield [_whichField ] # # Set up a few basic variables we'll be needing throughout the # rest of the method such as the position of the insert cursor # and the currently displayed minute, hour, and second. # set inValid 0 set icursor [$itk_component(time) index insert] set lastField [lindex $_fields end] set prevtime $_timeVar regexp {^([0-9])([0-9]):([0-9])([0-9]):([0-9])([0-9]).*$} \ $_timeVar dummy \ hour1 hour2 minute1 minute2 second1 second2 set hour "$hour1$hour2" set minute "$minute1$minute2" set second "$second1$second2" # # Process numeric keystrokes. This involes a fair amount of # processing with step one being to check and make sure we # aren't attempting to insert more that 6 characters. If # so ring the bell and break. # if {![catch {expr int($char)}]} { # If we are currently in the hour field then we process the # number entered based on the cursor position. If we are at # at the first position and our iq is low, then accept any # input. # # if the current format is military, then # validate the hour field which can be [00 - 23] # switch $_cfield { hour { if {$itk_option(-iq) == "low"} { $itk_component(time) delete $icursor $itk_component(time) insert $icursor $char } elseif {$itk_option(-format) == "military"} { if {$icursor == 0} { # # if the digit is less than 2, then # the second hour digit is valid for 0-9 # if {$char < 2} { $itk_component(time) delete 0 1 $itk_component(time) insert 0 $char # # if the digit is equal to 2, then # the second hour digit is valid for 0-3 # } elseif {$char == 2} { $itk_component(time) delete 0 1 $itk_component(time) insert 0 $char if {$hour2 > 3} { $itk_component(time) delete 1 2 $itk_component(time) insert 1 "0" $itk_component(time) icursor 1 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -