OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [itcl/] [iwidgets3.0.0/] [generic/] [timefield.itk] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
#
2
# Timefield
3
# ----------------------------------------------------------------------
4
# Implements a time entry field with adjustable built-in intelligence
5
# levels.
6
# ----------------------------------------------------------------------
7
#   AUTHOR:  John A. Tucker          E-mail: jatucker@austin.dsccc.com
8
#
9
#   @(#) $Id: timefield.itk,v 1.1.1.1 2002-01-16 10:24:50 markom Exp $
10
# ----------------------------------------------------------------------
11
#            Copyright (c) 1997 DSC Technologies Corporation
12
# ======================================================================
13
# Permission to use, copy, modify, distribute and license this software
14
# and its documentation for any purpose, and without fee or written
15
# agreement with DSC, is hereby granted, provided that the above copyright
16
# notice appears in all copies and that both the copyright notice and
17
# warranty disclaimer below appear in supporting documentation, and that
18
# the names of DSC Technologies Corporation or DSC Communications
19
# Corporation not be used in advertising or publicity pertaining to the
20
# software without specific, written prior permission.
21
#
22
# DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
23
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
24
# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
25
# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
26
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL
27
# DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
28
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
29
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
30
# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
31
# SOFTWARE.
32
# ======================================================================
33
 
34
#
35
# Use option database to override default resources of base classes.
36
#
37
option add *Timefield.justify center widgetDefault
38
 
39
 
40
#
41
# Usual options.
42
#
43
itk::usual Timefield {
44
    keep -background -borderwidth -cursor -foreground -highlightcolor \
45
       -highlightthickness -labelfont -textbackground -textfont
46
}
47
 
48
# ------------------------------------------------------------------
49
#                               TIMEFIELD
50
# ------------------------------------------------------------------
51
class iwidgets::Timefield {
52
 
53
    inherit iwidgets::Labeledwidget
54
 
55
    constructor {args} {}
56
 
57
    itk_option define -childsitepos childSitePos Position e
58
    itk_option define -command command Command {}
59
    itk_option define -seconds seconds Seconds on
60
    itk_option define -format format Format civilian
61
    itk_option define -iq iq Iq high
62
 
63
    public {
64
      method get {{format "-string"}}
65
      method isvalid {}
66
      method show {{time "now"}}
67
    }
68
 
69
    protected {
70
      method _backwardCivilian {}
71
      method _backwardMilitary {}
72
      method _focusIn {}
73
      method _forwardCivilian {}
74
      method _forwardMilitary {}
75
      method _keyPress {char sym state}
76
      method _moveField {direction}
77
      method _setField {field}
78
      method _whichField {}
79
      method _toggleAmPm {}
80
 
81
      variable _cfield hour
82
      variable _formatString "%r"
83
      variable _fields {}
84
      variable _numFields 4
85
      variable _forward {}
86
      variable _backward {}
87
 
88
      common _militaryFields {hour minute second}
89
      common _civilianFields {hour minute second ampm}
90
 
91
      common _timeVar
92
    }
93
}
94
 
95
#
96
# Provide a lowercased access method for the timefield class.
97
#
98
proc iwidgets::timefield {pathName args} {
99
    uplevel iwidgets::Timefield $pathName $args
100
}
101
 
102
# ------------------------------------------------------------------
103
#                        CONSTRUCTOR
104
# ------------------------------------------------------------------
105
body iwidgets::Timefield::constructor {args} {
106
    component hull configure -borderwidth 0
107
 
108
    set _timeVar($this) ""
109
 
110
    #
111
    # Create an entry field for entering the time.
112
    #
113
    itk_component add time {
114
      entry $itk_interior.time \
115
            -textvariable [scope _timeVar($this)]
116
    } {
117
      keep -borderwidth -cursor -exportselection \
118
          -foreground -highlightcolor -highlightthickness \
119
          -insertbackground -justify -relief
120
 
121
      rename -font -textfont textFont Font
122
      rename -highlightbackground -background background Background
123
      rename -background -textbackground textBackground Background
124
    }
125
 
126
    #
127
    # Create the child site widget.
128
    #
129
    itk_component add -protected dfchildsite {
130
      frame $itk_interior.dfchildsite
131
    }
132
    set itk_interior $itk_component(dfchildsite)
133
 
134
    #
135
    # Add timefield event bindings for focus in and keypress events.
136
    #
137
    bind $itk_component(time)    [code $this _focusIn]
138
    bind $itk_component(time)   [code $this _keyPress %A %K %s]
139
 
140
    #
141
    # Disable some mouse button event bindings:
142
    #   Button Motion
143
    #   Double-Clicks
144
    #   Triple-Clicks
145
    #   Button2
146
    #
147
    bind $itk_component(time)   break
148
    bind $itk_component(time)   break
149
    bind $itk_component(time)   break
150
    bind $itk_component(time)   break
151
    bind $itk_component(time) <2>          break
152
 
153
    #
154
    # Initialize the widget based on the command line options.
155
    #
156
    eval itk_initialize $args
157
 
158
    #
159
    # Initialize the time to the current time.
160
    #
161
    show
162
}
163
 
164
# ------------------------------------------------------------------
165
#                             OPTIONS
166
# ------------------------------------------------------------------
167
 
168
# ------------------------------------------------------------------
169
# OPTION: -childsitepos
170
#
171
# Specifies the position of the child site in the widget.  Valid
172
# locations are n, s, e, and w.
173
# ------------------------------------------------------------------
174
configbody iwidgets::Timefield::childsitepos {
175
    set parent [winfo parent $itk_component(time)]
176
 
177
    switch $itk_option(-childsitepos) {
178
      n {
179
          grid $itk_component(dfchildsite) -row 0 -column 0 -sticky ew
180
          grid $itk_component(time) -row 1 -column 0 -sticky nsew
181
 
182
          grid rowconfigure $parent 0 -weight 0
183
          grid rowconfigure $parent 1 -weight 1
184
          grid columnconfigure $parent 0 -weight 1
185
          grid columnconfigure $parent 1 -weight 0
186
      }
187
 
188
      e {
189
          grid $itk_component(dfchildsite) -row 0 -column 1 -sticky ns
190
          grid $itk_component(time) -row 0 -column 0 -sticky nsew
191
 
192
          grid rowconfigure $parent 0 -weight 1
193
          grid rowconfigure $parent 1 -weight 0
194
          grid columnconfigure $parent 0 -weight 1
195
          grid columnconfigure $parent 1 -weight 0
196
      }
197
 
198
      s {
199
          grid $itk_component(dfchildsite) -row 1 -column 0 -sticky ew
200
          grid $itk_component(time) -row 0 -column 0 -sticky nsew
201
 
202
          grid rowconfigure $parent 0 -weight 1
203
          grid rowconfigure $parent 1 -weight 0
204
          grid columnconfigure $parent 0 -weight 1
205
          grid columnconfigure $parent 1 -weight 0
206
      }
207
 
208
      w {
209
          grid $itk_component(dfchildsite) -row 0 -column 0 -sticky ns
210
          grid $itk_component(time) -row 0 -column 1 -sticky nsew
211
 
212
          grid rowconfigure $parent 0 -weight 1
213
          grid rowconfigure $parent 1 -weight 0
214
          grid columnconfigure $parent 0 -weight 0
215
          grid columnconfigure $parent 1 -weight 1
216
      }
217
 
218
      default {
219
          error "bad childsite option\
220
                \"$itk_option(-childsitepos)\":\
221
                should be n, e, s, or w"
222
      }
223
    }
224
}
225
 
226
# ------------------------------------------------------------------
227
# OPTION: -command
228
#
229
# Command invoked upon detection of return key press event.
230
# ------------------------------------------------------------------
231
configbody iwidgets::Timefield::command {}
232
 
233
# ------------------------------------------------------------------
234
# OPTION: -iq
235
#
236
# Specifies the level of intelligence to be shown in the actions
237
# taken by the time field during the processing of keypress events.
238
# Valid settings include high or low.  With a high iq,
239
# the time prevents the user from typing in an invalid time.  For
240
# example, if the current time is 05/31/1997 and the user changes
241
# the hour to 04, then the minute will be instantly modified for them
242
# to be 30.  In addition, leap seconds are fully taken into account.
243
# A setting of low iq instructs the widget to do no validity checking
244
# at all during time entry.  With a low iq level, it is assumed that
245
# the validity will be determined at a later time using the time's
246
# isvalid command.
247
# ------------------------------------------------------------------
248
configbody iwidgets::Timefield::iq {
249
 
250
  switch $itk_option(-iq) {
251
    high - low {
252
 
253
    }
254
    default {
255
      error "bad iq option \"$itk_option(-iq)\": should be high or low"
256
    }
257
  }
258
}
259
 
260
# ------------------------------------------------------------------
261
# OPTION: -format
262
#
263
# Specifies the time format displayed in the entry widget.
264
# ------------------------------------------------------------------
265
configbody iwidgets::Timefield::format {
266
 
267
  switch $itk_option(-format) {
268
    civilian {
269
      set _backward _backwardCivilian
270
      set _forward _forwardCivilian
271
      set _fields $_civilianFields
272
      set _numFields 4
273
      set _formatString "%r"
274
      $itk_component(time) config -width 11
275
    }
276
    military {
277
      set _backward _backwardMilitary
278
      set _forward _forwardMilitary
279
      set _fields $_militaryFields
280
      set _numFields 3
281
      set _formatString "%T"
282
      $itk_component(time) config -width 8
283
    }
284
    default {
285
      error "bad iq option \"$itk_option(-iq)\":\
286
             should be civilian or military"
287
    }
288
  }
289
 
290
  #
291
  # Update the current contents of the entry field to reflect
292
  # the configured format.
293
  #
294
  show $_timeVar($this)
295
}
296
 
297
# ------------------------------------------------------------------
298
#                            METHODS
299
# ------------------------------------------------------------------
300
 
301
# ------------------------------------------------------------------
302
# PUBLIC METHOD: get ?format?
303
#
304
# Return the current contents of the timefield in one of two formats
305
# string or as an integer clock value using the -string and -clicks
306
# options respectively.  The default is by string.  Reference the
307
# clock command for more information on obtaining times and their
308
# formats.
309
# ------------------------------------------------------------------
310
body iwidgets::Timefield::get {{format "-string"}} {
311
 
312
  switch -- $format {
313
    "-string" {
314
      return $_timeVar($this)
315
    }
316
    "-clicks" {
317
      return [::clock scan $_timeVar($this)]
318
    }
319
    default {
320
      error "bad format option \"$format\":\
321
               should be -string or -clicks"
322
    }
323
  }
324
}
325
 
326
# ------------------------------------------------------------------
327
# PUBLIC METHOD: show time
328
#
329
# Changes the currently displayed time to be that of the time
330
# argument.  The time may be specified either as a string or an
331
# integer clock value.  Reference the clock command for more
332
# information on obtaining times and their formats.
333
# ------------------------------------------------------------------
334
body iwidgets::Timefield::show {{time "now"}} {
335
 
336
  if {$time == {}} {
337
    set time "now"
338
  }
339
 
340
  switch -regexp -- $time {
341
 
342
    {^now$} {
343
      set seconds [::clock seconds]
344
    }
345
 
346
    {^[0-9]+$} {
347
      if { [catch {::clock format $time}] } {
348
        error "bad time: \"$time\", must be a valid time \
349
           string, clock clicks value or the keyword now"
350
      }
351
      set seconds $time
352
    }
353
 
354
    default {
355
      if {[catch {set seconds [::clock scan $time]}]} {
356
        error "bad time: \"$time\", must be a valid time \
357
           string, clock clicks value or the keyword now"
358
      }
359
    }
360
  }
361
 
362
  set _timeVar($this) [::clock format $seconds -format $_formatString]
363
}
364
 
365
# ------------------------------------------------------------------
366
# PUBLIC METHOD: isvalid
367
#
368
# Returns a boolean indication of the validity of the currently
369
# displayed time value.  For example, 09:59::59 is valid whereas
370
# 26:59:59 is invalid.
371
# ------------------------------------------------------------------
372
body iwidgets::Timefield::isvalid {} {
373
 
374
  return [expr ([catch {::clock scan $_timeVar($this)}] == 0)]
375
}
376
 
377
# ------------------------------------------------------------------
378
# PROTECTED METHOD: _focusIn
379
#
380
# This method is bound to the  event.  It resets the
381
# insert cursor and field settings to be back to their last known
382
# positions.
383
# ------------------------------------------------------------------
384
body iwidgets::Timefield::_focusIn {} {
385
  _setField $_cfield
386
}
387
 
388
# ------------------------------------------------------------------
389
# PROTECTED METHOD: _keyPress
390
#
391
# This method is the workhorse of the class.  It is bound to the
392
#  event and controls the processing of all key strokes.
393
# ------------------------------------------------------------------
394
body iwidgets::Timefield::_keyPress {char sym state} {
395
 
396
  #
397
  #  Determine which field we are in currently.  This is needed
398
  # since the user may have moved to this position via a mouse
399
  # selection and so it would not be in the position we last
400
  # knew it to be.
401
  #
402
  set _cfield [_whichField ]
403
 
404
  #
405
  # Set up a few basic variables we'll be needing throughout the
406
  # rest of the method such as the position of the insert cursor
407
  # and the currently displayed minute, hour, and second.
408
  #
409
  set inValid 0
410
  set icursor [$itk_component(time) index insert]
411
  set lastField [lindex $_fields end]
412
 
413
  set prevtime $_timeVar($this)
414
  regexp {^([0-9])([0-9]):([0-9])([0-9]):([0-9])([0-9]).*$} \
415
        $_timeVar($this) dummy \
416
        hour1 hour2 minute1 minute2 second1 second2
417
  set hour      "$hour1$hour2"
418
  set minute    "$minute1$minute2"
419
  set second    "$second1$second2"
420
 
421
  #
422
  # Process numeric keystrokes.  This involes a fair amount of
423
  # processing with step one being to check and make sure we
424
  # aren't attempting to insert more that 6 characters.  If
425
  # so ring the bell and break.
426
  #
427
  if {![catch {expr int($char)}]} {
428
 
429
    # If we are currently in the hour field then we process the
430
    # number entered based on the cursor position.  If we are at
431
    # at the first position and our iq is low, then accept any
432
    # input.
433
    #
434
    # if the current format is military, then
435
    # validate the hour field which can be [00 - 23]
436
    #
437
    switch $_cfield {
438
      hour {
439
        if {$itk_option(-iq) == "low"} {
440
          $itk_component(time) delete $icursor
441
          $itk_component(time) insert $icursor $char
442
 
443
        } elseif {$itk_option(-format) == "military"} {
444
          if {$icursor == 0}  {
445
            #
446
            # if the digit is less than 2, then
447
            # the second hour digit is valid for 0-9
448
            #
449
            if {$char < 2} {
450
              $itk_component(time) delete 0 1
451
              $itk_component(time) insert 0 $char
452
 
453
            #
454
            # if the digit is equal to 2, then
455
            # the second hour digit is valid for 0-3
456
            #
457
            } elseif {$char == 2} {
458
              $itk_component(time) delete 0 1
459
              $itk_component(time) insert 0 $char
460
 
461
              if {$hour2 > 3} {
462
                $itk_component(time) delete 1 2
463
                $itk_component(time) insert 1 "0"
464
                $itk_component(time) icursor 1
465
              }
466
 
467
            #
468
            # if the digit is greater than 2, then
469
            # set the first hour digit to 0 and the
470
            # second hour digit to the value.
471
            #
472
            } elseif {$char > 2}  {
473
              $itk_component(time) delete 0 2
474
              $itk_component(time) insert 0 "0$char"
475
              set icursor 1
476
            } else {
477
              set inValid 1
478
            }
479
 
480
          #
481
          # if the insertion cursor is for the second hour digit, then
482
          # format is military, then it can only be valid if the first
483
          # hour digit is less than 2 or the new digit is less than 4
484
          #
485
          } else {
486
            if {$hour1 < 2 || $char < 4} {
487
              $itk_component(time) delete 1 2
488
              $itk_component(time) insert 1 $char
489
            } else {
490
              set inValid 1
491
            }
492
          }
493
 
494
        #
495
        # The format is civilian, so we need to
496
        # validate the hour field which can be [01 - 12]
497
        #
498
        } else {
499
          if {$icursor == 0}  {
500
            #
501
            # if the digit is 0, then
502
            #   the second hour digit is valid for 1-9
503
            #   so just insert it.
504
            #
505
            if {$char == 0 && $hour2 != 0} {
506
              $itk_component(time) delete 0 1
507
              $itk_component(time) insert 0 $char
508
 
509
            #
510
            # if the digit is equal to 1, then
511
            #   the second hour digit is valid for 0-2
512
            #
513
            } elseif {$char == 1} {
514
              $itk_component(time) delete 0 1
515
              $itk_component(time) insert 0 $char
516
 
517
              if {$hour2 > 2} {
518
                $itk_component(time) delete 1 2
519
                $itk_component(time) insert 1 0
520
                set icursor 1
521
              }
522
 
523
            #
524
            # if the digit is greater than 1, then
525
            #   set the first hour digit to 0 and the
526
            #   second hour digit to the value.
527
            #
528
            } elseif {$char > 1}  {
529
              $itk_component(time) delete 0 2
530
              $itk_component(time) insert 0 "0$char"
531
              set icursor 1
532
 
533
            } else {
534
              set inValid 1
535
            }
536
 
537
          #
538
          # The insertion cursor is at the second hour digit, so
539
          # it can only be valid if the firs thour digit is 0
540
          # or the new digit is less than or equal to 2
541
          #
542
          } else {
543
            if {$hour1 == 0 || $char <= 2} {
544
              $itk_component(time) delete 1 2
545
              $itk_component(time) insert 1 $char
546
            } else {
547
              set inValid 1
548
            }
549
          }
550
        }
551
 
552
        if {$inValid} {
553
          bell
554
        } elseif {$icursor == 1} {
555
          _setField minute
556
        }
557
      }
558
 
559
      minute {
560
        if {$itk_option(-iq) == "low" || $char < 6 || $icursor == 4} {
561
          $itk_component(time) delete $icursor
562
          $itk_component(time) insert $icursor $char
563
        } elseif {$itk_option(-iq) == "high"} {
564
          if {$char > 5} {
565
            $itk_component(time) delete 3 5
566
            $itk_component(time) insert 3 "0$char"
567
            set icursor 4
568
          }
569
        }
570
 
571
        if {$icursor == 4} {
572
          _setField second
573
        }
574
      }
575
 
576
      second {
577
        if {$itk_option(-iq) == "low" || $char < 6 || $icursor == 7} {
578
          $itk_component(time) delete $icursor
579
          $itk_component(time) insert $icursor $char
580
 
581
        } elseif {$itk_option(-iq) == "high"} {
582
          if {$char > 5} {
583
            $itk_component(time) delete 6 8
584
            $itk_component(time) insert 6 "0$char"
585
            set icursor 7
586
          }
587
        }
588
 
589
        if {$icursor == 7} {
590
          _moveField forward
591
        }
592
      }
593
    }
594
 
595
    return -code break
596
  }
597
 
598
  #
599
  # Process the plus and the up arrow keys.  They both yield the same
600
  # effect, they increment the minute by one.
601
  #
602
  switch $sym {
603
    p - P {
604
      if {$itk_option(-format) == "civilian"} {
605
        $itk_component(time) delete 9 10
606
        $itk_component(time) insert 9 P
607
        _setField hour
608
      }
609
    }
610
 
611
    a - A {
612
      if {$itk_option(-format) == "civilian"} {
613
        $itk_component(time) delete 9 10
614
        $itk_component(time) insert 9 A
615
        _setField hour
616
      }
617
    }
618
 
619
    plus - Up {
620
      if {$_cfield == "ampm"} {
621
        _toggleAmPm
622
      } else {
623
        set newclicks [::clock scan "$prevtime 1 $_cfield"]
624
        set newtime   [::clock format $newclicks -format $_formatString]
625
        set _timeVar($this) $newtime
626
      }
627
      return -code continue
628
    }
629
 
630
    minus - Down {
631
      #
632
      # Process the minus and the down arrow keys which decrement the value
633
      # of the field in which the cursor is currently positioned.
634
      #
635
      if {$_cfield == "ampm"} {
636
        _toggleAmPm
637
      } else {
638
        set newclicks [::clock scan "$prevtime 1 $_cfield ago"]
639
        set newtime   [::clock format $newclicks -format $_formatString]
640
        set _timeVar($this) $newtime
641
      }
642
      return -code continue
643
    }
644
 
645
    Tab {
646
      #
647
      # A tab key moves the "hour:minute:second" field forward by one unless
648
      # the current field is the second.  In that case we'll let tab
649
      # do what is supposed to and pass the focus onto the next widget.
650
      #
651
      if {$state == 0} {
652
 
653
        if {($itk_option(-format) == "civilian" && $_cfield == $lastField)} {
654
          _setField hour
655
          return -code continue
656
        }
657
        _moveField forward
658
 
659
      #
660
      # A ctrl-tab key moves the hour:minute:second field backwards by one
661
      # unless the current field is the hour.  In that case we'll let
662
      # tab take the focus to a previous widget.
663
      #
664
      } elseif {$state == 4} {
665
        if {$_cfield == "hour"} {
666
          _setField hour
667
          return -code continue
668
        }
669
        _moveField backward
670
      }
671
    }
672
 
673
    Right {
674
      #
675
      # A right arrow key moves the insert cursor to the right one.
676
      #
677
      $_forward
678
    }
679
 
680
    Left - BackSpace - Delete {
681
      #
682
      # A left arrow, backspace, or delete key moves the insert cursor
683
      # to the left one.  This is what you expect for the left arrow
684
      # and since the whole widget always operates in overstrike mode,
685
      # it makes the most sense for backspace and delete to do the same.
686
      #
687
      $_backward
688
    }
689
 
690
    Return {
691
      #
692
      # A Return key invokes the optionally specified command option.
693
      #
694
      uplevel #0 $itk_option(-command)
695
    }
696
 
697
    default {
698
 
699
    }
700
  }
701
 
702
  return -code break
703
}
704
 
705
# ------------------------------------------------------------------
706
# PROTECTED METHOD: _toggleAmPm
707
#
708
# Internal method which toggles the displayed time
709
# between "AM" and "PM" when format is "civilian".
710
# ------------------------------------------------------------------
711
body iwidgets::Timefield::_toggleAmPm {} {
712
  set firstChar  [string index $_timeVar($this) 9]
713
  $itk_component(time) delete 9 10
714
  $itk_component(time) insert 9 [expr {($firstChar == "A") ? "P" : "A"}]
715
  $itk_component(time) icursor 9
716
}
717
 
718
# ------------------------------------------------------------------
719
# PROTECTED METHOD: _setField field
720
#
721
# Adjusts the current field to be that of the argument, setting the
722
# insert cursor appropriately.
723
# ------------------------------------------------------------------
724
body iwidgets::Timefield::_setField {field} {
725
 
726
  # Move the position of the cursor to the first character of the
727
  # field given by the argument:
728
  #
729
  # Field   First Character Index
730
  # -----   ---------------------
731
  # hour    0
732
  # minute  3
733
  # second  6
734
  # ampm    9
735
  #
736
  switch $field {
737
    hour {
738
      $itk_component(time) icursor 0
739
    }
740
    minute {
741
      $itk_component(time) icursor 3
742
    }
743
    second {
744
      $itk_component(time) icursor 6
745
    }
746
    ampm {
747
      if {$itk_option(-format) == "military"} {
748
        error "bad field: \"$field\", must be hour, minute or second"
749
      }
750
      $itk_component(time) icursor 9
751
    }
752
    default {
753
      if {$itk_option(-format) == "military"} {
754
        error "bad field: \"$field\", must be hour, minute or second"
755
      } else {
756
        error "bad field: \"$field\", must be hour, minute, second or ampm"
757
      }
758
    }
759
  }
760
 
761
  set _cfield $field
762
 
763
  return $_cfield
764
}
765
 
766
# ------------------------------------------------------------------
767
# PROTECTED METHOD: _moveField
768
#
769
# Moves the cursor one field forward or backward.
770
# ------------------------------------------------------------------
771
body iwidgets::Timefield::_moveField {direction} {
772
 
773
  # Since the value "_fields" list variable is always either value:
774
  #   military => {hour minute second}
775
  #   civilian => {hour minute second ampm}
776
  #
777
  # the index of the previous or next field index can be determined
778
  # by subtracting or adding 1 to current the index, respectively.
779
  #
780
  set index [lsearch $_fields $_cfield]
781
  expr {($direction == "forward") ? [incr index] : [incr index -1]}
782
 
783
  if {$index == $_numFields} {
784
    set index 0
785
  } elseif {$index < 0} {
786
    set index [expr $_numFields-1]
787
  }
788
 
789
  _setField [lindex $_fields $index]
790
}
791
 
792
# ------------------------------------------------------------------
793
# PROTECTED METHOD: _whichField
794
#
795
# Returns the current field that the cursor is positioned within.
796
# ------------------------------------------------------------------
797
body iwidgets::Timefield::_whichField {} {
798
 
799
  # Return the current field based on the position of the cursor.
800
  #
801
  # Field   Index
802
  # -----   -----
803
  # hour    0,1
804
  # minute  3,4
805
  # second  6,7
806
  # ampm    9,10
807
  #
808
  set icursor [$itk_component(time) index insert]
809
  switch $icursor {
810
 
811
      set _cfield hour
812
    }
813
    3 - 4 {
814
      set _cfield minute
815
    }
816
    6 - 7 {
817
      set _cfield second
818
    }
819
    9 - 10 {
820
      set _cfield ampm
821
    }
822
  }
823
 
824
  return $_cfield
825
}
826
 
827
# ------------------------------------------------------------------
828
# PROTECTED METHOD: _forwardCivilian
829
#
830
# Internal method which moves the cursor forward by one character
831
# jumping over the slashes and wrapping.
832
# ------------------------------------------------------------------
833
body iwidgets::Timefield::_forwardCivilian {} {
834
 
835
  #
836
  # If the insertion cursor is at the second digit
837
  # of either the hour, minute or second field, then
838
  # move the cursor to the first digit of the right-most field.
839
  #
840
  # else move the insertion cursor right one character
841
  #
842
  set icursor [$itk_component(time) index insert]
843
  switch $icursor {
844
    1 {
845
      _setField minute
846
    }
847
    4 {
848
      _setField second
849
    }
850
    7 {
851
      _setField ampm
852
    }
853
    9 - 10 {
854
      _setField hour
855
    }
856
    default {
857
      $itk_component(time) icursor [expr $icursor+1]
858
    }
859
  }
860
}
861
 
862
# ------------------------------------------------------------------
863
# PROTECTED METHOD: _forwardMilitary
864
#
865
# Internal method which moves the cursor forward by one character
866
# jumping over the slashes and wrapping.
867
# ------------------------------------------------------------------
868
body iwidgets::Timefield::_forwardMilitary {} {
869
 
870
  #
871
  # If the insertion cursor is at the second digit of either
872
  # the hour, minute or second field, then move the cursor to
873
  # the first digit of the right-most field.
874
  #
875
  # else move the insertion cursor right one character
876
  #
877
  set icursor [$itk_component(time) index insert]
878
  switch $icursor {
879
    1 {
880
      _setField minute
881
    }
882
    4 {
883
      _setField second
884
    }
885
    7 {
886
      _setField hour
887
    }
888
    default {
889
      $itk_component(time) icursor [expr $icursor+1]
890
    }
891
  }
892
}
893
 
894
# ------------------------------------------------------------------
895
# PROTECTED METHOD: _backwardCivilian
896
#
897
# Internal method which moves the cursor backward by one character
898
# jumping over the ":" and wrapping.
899
# ------------------------------------------------------------------
900
body iwidgets::Timefield::_backwardCivilian {} {
901
 
902
  #
903
  # If the insertion cursor is at the first character
904
  # of either the minute or second field or at the ampm
905
  # field, then move the cursor to the second character
906
  # of the left-most field.
907
  #
908
  # else if the insertion cursor is at the first digit of the
909
  # hour field, then move the cursor to the first character
910
  # of the ampm field.
911
  #
912
  # else move the insertion cursor left one character
913
  #
914
  set icursor [$itk_component(time) index insert]
915
  switch $icursor {
916
    9 {
917
      _setField second
918
      $itk_component(time) icursor 7
919
    }
920
    6 {
921
      _setField minute
922
      $itk_component(time) icursor 4
923
    }
924
    3 {
925
      _setField hour
926
      $itk_component(time) icursor 1
927
    }
928
 
929
      _setField ampm
930
      $itk_component(time) icursor 9
931
    }
932
    default {
933
      $itk_component(time) icursor [expr $icursor-1]
934
    }
935
  }
936
}
937
 
938
# ------------------------------------------------------------------
939
# PROTECTED METHOD: _backwardMilitary
940
#
941
# Internal method which moves the cursor backward by one character
942
# jumping over the slashes and wrapping.
943
# ------------------------------------------------------------------
944
body iwidgets::Timefield::_backwardMilitary {} {
945
 
946
  #
947
  # If the insertion cursor is at the first digit of either
948
  # the minute or second field, then move the cursor to the
949
  # second character of the left-most field.
950
  #
951
  # else if the insertion cursor is at the first digit of the
952
  # hour field, then move the cursor to the second digit
953
  # of the second field.
954
  #
955
  # else move the insertion cursor left one character
956
  #
957
  set icursor [$itk_component(time) index insert]
958
  switch $icursor {
959
    6 {
960
      _setField minute
961
      $itk_component(time) icursor 4
962
    }
963
    3 {
964
      _setField hour
965
      $itk_component(time) icursor 1
966
    }
967
 
968
      _setField second
969
      $itk_component(time) icursor 7
970
    }
971
    default {
972
      $itk_component(time) icursor [expr $icursor-1]
973
    }
974
  }
975
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.