source: tol/tolbase/lib/mkWidgets1.3/Calendar.tcl

devel
Last change on this file was 32535cc, checked in by Jorge Pérez <josp.jorge@…>, 18 years ago

adding more types to config, added mkWidget1.3

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@16 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 7.5 KB
Line 
1package require Metawidget
2
3# name: Calendar
4# args: args: option-value pairs
5# defines icons for the left/right arrows. creates the internal widgets and
6# all bindings for scrolling through the Calendar. The Calendar is a text
7# widget without the typical class bindings for Text.
8metawidget create Calendar {
9  if { ! [ourinfo exists pPrev] } {
10    our pPrev [image create bitmap -data {
11      #define _width 5
12      #define _height 9
13      static char _bits[] = { 0x10,0x18,0x1c,0x1e,0x1f,0x1e,0x1c,0x18,0x10 };
14    }]
15    our pNext [image create bitmap -data {
16      #define _width 5
17      #define _height 9
18      static char _bits[] = { 0x01,0x03,0x07,0x0f,0x1f,0x0f,0x07,0x03,0x01 };
19    }]
20  }
21
22  # control panel and the Calendar (a text widget)
23  pack [frame $this.ctrl -border 1 -relief raised] -fill x
24  pack [label $this.ctrl.prev -border 0 -image [our pPrev]] -ipadx 4 -side left -fill y
25  pack [label $this.ctrl.cumo -border 0 ] -ipady 1 -side left -fill x -expand 1
26  pack [label $this.ctrl.next -border 0 -image [our pNext]] -ipadx 4 -side right -fill y
27  pack [text  $this.text -bg white -spacing1 1 -spacing3 1 -border 0 -width 22 -height 7 -wrap none -cursor arrow]
28
29  # bindings to scroll thru Calendar
30  bind $this.ctrl.prev <1>               "$this _scroll -1"
31  bind $this.ctrl.next <1>               "$this _scroll  1"
32  bind $this.ctrl.prev <Control-1>       "$this _scroll -1 year"
33  bind $this.ctrl.next <Control-1>       "$this _scroll  1 year"
34  bind $this.ctrl.prev <ButtonRelease-1> "$this _scroll  0"
35  bind $this.ctrl.next <ButtonRelease-1> "$this _scroll  0"
36  bind $this.ctrl.cumo <Double-1>        "$this set"
37  bind $this.text <1>                    "focus $this.text"
38  bind $this.text <Left>                 "$this scroll -1 day"
39  bind $this.text <Right>                "$this scroll  1 day"
40  bind $this.text <Up>                   "$this scroll -7 days"
41  bind $this.text <Down>                 "$this scroll  7 days"
42
43  # take Text class bindings away
44  bindtags $this.text [mkw.lshrink [bindtags $this.text] Text]
45  focus $this.text
46
47  # set up 1st row
48  $this.text insert end "\tS\tM\tT\tW\tT\tF\tS\t\n"
49  $this.text tag config tDays -background grey
50  $this.text tag add tDays 1.0 1.end
51
52  # init widget options by calling their member functions
53  -font [$this.text cget -font]
54  -controls top
55
56  # set current date
57  set_
58} {} -default text
59
60# name: _focus
61# args: iDay: day to set selection for
62# each day in the Calendar has a unique tag. the special tag "sel" (the
63# selection of the text widget) is simply mapped over it.
64metawidget proc Calendar _focus { iDay } {
65  if { [myinfo exists iDay] } {
66    $this.text tag remove sel 1.0 end
67  }
68
69  eval $this.text tag add sel [$this.text tag ranges t$iDay]
70  my iDay $iDay
71  my iClock [clock scan [my iMonth]/[my iDay]/[my iYear]]
72}
73
74# name: _scroll
75# args: iStep: step width
76#       sUnit: step unit
77# scrolls and asynchronuously calls the function again by means of a timer,
78# as long as the mouse button is pressed. if released, iStep is zero and
79# the last timer job is cancelled.
80metawidget proc Calendar _scroll { iStep {sUnit month} } {
81  if { $iStep == 0 } {
82    catch { after cancel [my iJob] }
83  } else {
84    scroll $iStep $sUnit
85    my iJob [after 150 $this _scroll $iStep $sUnit]
86  }
87}
88
89# name: -controls
90# args: sPos: controls position: top or bottom
91# packs the control frame according to the option
92metawidget proc Calendar -controls { sPos } {
93  my -controls [mkw.complete $sPos {top bottom}]
94  pack $this.ctrl -side [my -controls]
95}
96
97# name: -font
98# args: sFont: font to set
99# sets the font in the Calendar and the control frame.
100metawidget proc Calendar -font { sFont } {
101  set iW0 [font measure $sFont "0"]
102  set iT0 [expr $iW0*2]
103  set iT  [expr $iW0*3]
104  $this.text config -font $sFont -tabs "$iT0 c [expr $iT0+$iT] c"
105  $this.ctrl.cumo config -font $sFont
106
107  my -font $sFont
108}
109
110# name: headerconfig
111# args: args: option-value pairs
112# args is applied to the tag for the weekdays.
113metawidget proc Calendar headerconfig { args } {
114  eval $this.text tag configure tDays $args
115}
116
117# name: headercget
118# args: args: option name
119# retrieves an option value of the header tag.
120metawidget proc Calendar headercget { args } {
121  eval $this.text tag cget tDays $args
122}
123
124# name: get
125# args: -
126# returns the date the Calendar is set to.
127metawidget proc Calendar get { {sFormat %m/%d/%Y} } {
128  return [clock format [my iClock] -format $sFormat]
129}
130
131# name: set
132# args: sDate: date to set Calendar to
133# sets a date. sDate must be accepted by "clock scan". splits up date
134# into month, day, year. calculates first and last day of the month.
135# fills the text widget and updates the control frame.
136metawidget proc Calendar set_ { {sDate {}} } {
137  # get current date, if sDate not given
138  if { $sDate == {} } {
139    set iClock [clock seconds]
140  } else {
141    set iClock [clock scan $sDate]
142  }
143
144  set iY [clock format $iClock -format %Y]
145  regsub {^0} [clock format $iClock -format %m] {} iM
146  regsub {^0+} [clock format $iClock -format %d] {} iD
147
148  # first and last day of month, in seconds
149  set iFirst [clock scan $iM/01/$iY]
150  set iLast  [expr [clock scan [expr $iM%12+1]/01/[expr $iY+($iM+1)/12]]-86400]
151
152  # number of days, and day of the top-left element in the Calendar
153  set iDays [clock format $iLast  -format %d]
154  set iDay [expr -[clock format $iFirst -format %w]]
155
156  $this.text delete 2.0 end
157  $this.text insert end "\n"
158
159  # if day is of different month, fill in tabs, otherwise the day number
160  for { set i 1 } { $i <= 6 } { incr i } {
161    for { set j 1 } { $j <= 7 } { incr j } {
162      incr iDay
163      if { $iDay < 1 || $iDay > $iDays } {
164        # if day is of different month, fill in tabs
165        $this.text insert end "\t"
166      } else {
167        # otherwise put in number and assign unique tag
168        $this.text insert end "\t$iDay"
169        $this.text tag add t$iDay end-1ch-[string length $iDay]ch end-1ch
170        $this.text tag bind t$iDay <1> "$this _focus $iDay"
171      }
172    }
173    $this.text insert end "\n"
174  }
175
176  # update control frame and set sel tag to current day.
177  $this.ctrl.cumo config -text [clock format $iClock -format "%B %Y"]
178  eval $this.text tag add sel [$this.text tag ranges t$iD]
179
180  my iClock $iClock
181  my iYear  $iY
182  my iMonth $iM
183  my iDay   $iD
184}
185
186# name: scroll
187# args: iStep: step width to scroll
188#       sUnit: unit to scroll
189# moves forward or backward in time as specified by iStep and sUnit.
190metawidget proc Calendar scroll { iStep {sUnit month} } {
191  set sUnit [mkw.complete $sUnit {days months years}]
192
193  set iY [my iYear]
194  set iM [my iMonth]
195  set iD [my iDay]
196
197  switch $sUnit {
198    days {
199      set_ [clock format [expr [my iClock]+$iStep*86400] -format %m/%d/%Y]
200    }
201    months {
202      incr iM $iStep
203      set iLast [clock format [expr [clock scan [expr $iM%12+1]/01/[expr $iY+($iM+1)/12]]-86400] -format %d]
204      set_ [expr ($iM-1)%12+1]/[expr ($iD<$iLast)?$iD:$iLast]/[expr $iY+($iM-1)/12]
205    }
206    years {
207      set_ $iM/$iD/[expr $iY+$iStep]
208    }
209  }
210}
211
212# name: bind
213# args: args: same as for the bind command
214# applies bindings to the text widget.
215metawidget proc Calendar bind_ { args } {
216  eval bind $this.text $args
217}
218
219metawidget command Calendar _scroll      _scroll
220metawidget command Calendar _focus       _focus
221
222metawidget command Calendar set          set_
223metawidget command Calendar get          get
224metawidget command Calendar headerconfig headerconfig
225metawidget command Calendar headercget   headercget
226metawidget command Calendar scroll       scroll
227metawidget command Calendar bind         bind_
228
229metawidget option  Calendar -font        -font
230metawidget option  Calendar -controls    -controls
231
232proc test {} {
233  pack [calendar .cal]
234}
235
236#test
Note: See TracBrowser for help on using the repository browser.