Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v8plus / lib / python2.4 / site-packages / Pmw / Pmw_1_2 / lib / PmwTimeCounter.py
CommitLineData
920dae64
AT
1# Authors: Joe VanAndel and Greg McFarlane
2
3import string
4import sys
5import time
6import Tkinter
7import Pmw
8
9class TimeCounter(Pmw.MegaWidget):
10 """Up-down counter
11
12 A TimeCounter is a single-line entry widget with Up and Down arrows
13 which increment and decrement the Time value in the entry.
14 """
15
16 def __init__(self, parent = None, **kw):
17
18 # Define the megawidget options.
19 INITOPT = Pmw.INITOPT
20 optiondefs = (
21 ('autorepeat', 1, None),
22 ('buttonaspect', 1.0, INITOPT),
23 ('command', None, None),
24 ('initwait', 300, None),
25 ('labelmargin', 0, INITOPT),
26 ('labelpos', None, INITOPT),
27 ('max', None, self._max),
28 ('min', None, self._min),
29 ('padx', 0, INITOPT),
30 ('pady', 0, INITOPT),
31 ('repeatrate', 50, None),
32 ('value', None, INITOPT),
33 )
34 self.defineoptions(kw, optiondefs)
35
36 # Initialise the base class (after defining the options).
37 Pmw.MegaWidget.__init__(self, parent)
38
39 self.arrowDirection = {}
40 self._flag = 'stopped'
41 self._timerId = None
42
43 self._createComponents(kw)
44
45 value = self['value']
46 if value is None:
47 now = time.time()
48 value = time.strftime('%H:%M:%S', time.localtime(now))
49 self.setvalue(value)
50
51 # Check keywords and initialise options.
52 self.initialiseoptions()
53
54 def _createComponents(self, kw):
55
56 # Create the components.
57 interior = self.interior()
58
59 # If there is no label, put the arrows and the entry directly
60 # into the interior, otherwise create a frame for them. In
61 # either case the border around the arrows and the entry will
62 # be raised (but not around the label).
63 if self['labelpos'] is None:
64 frame = interior
65 if not kw.has_key('hull_relief'):
66 frame.configure(relief = 'raised')
67 if not kw.has_key('hull_borderwidth'):
68 frame.configure(borderwidth = 1)
69 else:
70 frame = self.createcomponent('frame',
71 (), None,
72 Tkinter.Frame, (interior,),
73 relief = 'raised', borderwidth = 1)
74 frame.grid(column=2, row=2, sticky='nsew')
75 interior.grid_columnconfigure(2, weight=1)
76 interior.grid_rowconfigure(2, weight=1)
77
78 # Create the down arrow buttons.
79
80 # Create the hour down arrow.
81 self._downHourArrowBtn = self.createcomponent('downhourarrow',
82 (), 'Arrow',
83 Tkinter.Canvas, (frame,),
84 width = 16, height = 16, relief = 'raised', borderwidth = 2)
85 self.arrowDirection[self._downHourArrowBtn] = 'down'
86 self._downHourArrowBtn.grid(column = 0, row = 2)
87
88 # Create the minute down arrow.
89 self._downMinuteArrowBtn = self.createcomponent('downminutearrow',
90 (), 'Arrow',
91 Tkinter.Canvas, (frame,),
92 width = 16, height = 16, relief = 'raised', borderwidth = 2)
93 self.arrowDirection[self._downMinuteArrowBtn] = 'down'
94 self._downMinuteArrowBtn.grid(column = 1, row = 2)
95
96 # Create the second down arrow.
97 self._downSecondArrowBtn = self.createcomponent('downsecondarrow',
98 (), 'Arrow',
99 Tkinter.Canvas, (frame,),
100 width = 16, height = 16, relief = 'raised', borderwidth = 2)
101 self.arrowDirection[self._downSecondArrowBtn] = 'down'
102 self._downSecondArrowBtn.grid(column = 2, row = 2)
103
104 # Create the entry fields.
105
106 # Create the hour entry field.
107 self._hourCounterEntry = self.createcomponent('hourentryfield',
108 (('hourentry', 'hourentryfield_entry'),), None,
109 Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
110 self._hourCounterEntry.grid(column = 0, row = 1, sticky = 'news')
111
112 # Create the minute entry field.
113 self._minuteCounterEntry = self.createcomponent('minuteentryfield',
114 (('minuteentry', 'minuteentryfield_entry'),), None,
115 Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
116 self._minuteCounterEntry.grid(column = 1, row = 1, sticky = 'news')
117
118 # Create the second entry field.
119 self._secondCounterEntry = self.createcomponent('secondentryfield',
120 (('secondentry', 'secondentryfield_entry'),), None,
121 Pmw.EntryField, (frame,), validate='integer', entry_width = 2)
122 self._secondCounterEntry.grid(column = 2, row = 1, sticky = 'news')
123
124 # Create the up arrow buttons.
125
126 # Create the hour up arrow.
127 self._upHourArrowBtn = self.createcomponent('uphourarrow',
128 (), 'Arrow',
129 Tkinter.Canvas, (frame,),
130 width = 16, height = 16, relief = 'raised', borderwidth = 2)
131 self.arrowDirection[self._upHourArrowBtn] = 'up'
132 self._upHourArrowBtn.grid(column = 0, row = 0)
133
134 # Create the minute up arrow.
135 self._upMinuteArrowBtn = self.createcomponent('upminutearrow',
136 (), 'Arrow',
137 Tkinter.Canvas, (frame,),
138 width = 16, height = 16, relief = 'raised', borderwidth = 2)
139 self.arrowDirection[self._upMinuteArrowBtn] = 'up'
140 self._upMinuteArrowBtn.grid(column = 1, row = 0)
141
142 # Create the second up arrow.
143 self._upSecondArrowBtn = self.createcomponent('upsecondarrow',
144 (), 'Arrow',
145 Tkinter.Canvas, (frame,),
146 width = 16, height = 16, relief = 'raised', borderwidth = 2)
147 self.arrowDirection[self._upSecondArrowBtn] = 'up'
148 self._upSecondArrowBtn.grid(column = 2, row = 0)
149
150 # Make it resize nicely.
151 padx = self['padx']
152 pady = self['pady']
153 for col in range(3):
154 frame.grid_columnconfigure(col, weight = 1, pad = padx)
155 frame.grid_rowconfigure(0, pad = pady)
156 frame.grid_rowconfigure(2, pad = pady)
157
158 frame.grid_rowconfigure(1, weight = 1)
159
160 # Create the label.
161 self.createlabel(interior)
162
163 # Set bindings.
164
165 # Up hour
166 self._upHourArrowBtn.bind('<Configure>',
167 lambda event, s=self,button=self._upHourArrowBtn:
168 s._drawArrow(button, 'up'))
169
170 self._upHourArrowBtn.bind('<1>',
171 lambda event, s=self,button=self._upHourArrowBtn:
172 s._countUp(button, 3600))
173
174 self._upHourArrowBtn.bind('<Any-ButtonRelease-1>',
175 lambda event, s=self, button=self._upHourArrowBtn:
176 s._stopUpDown(button))
177
178 # Up minute
179 self._upMinuteArrowBtn.bind('<Configure>',
180 lambda event, s=self,button=self._upMinuteArrowBtn:
181 s._drawArrow(button, 'up'))
182
183
184 self._upMinuteArrowBtn.bind('<1>',
185 lambda event, s=self,button=self._upMinuteArrowBtn:
186 s._countUp(button, 60))
187
188 self._upMinuteArrowBtn.bind('<Any-ButtonRelease-1>',
189 lambda event, s=self, button=self._upMinuteArrowBtn:
190 s._stopUpDown(button))
191
192 # Up second
193 self._upSecondArrowBtn.bind('<Configure>',
194 lambda event, s=self,button=self._upSecondArrowBtn:
195 s._drawArrow(button, 'up'))
196
197
198 self._upSecondArrowBtn.bind('<1>',
199 lambda event, s=self,button=self._upSecondArrowBtn:
200 s._countUp(button, 1))
201
202 self._upSecondArrowBtn.bind('<Any-ButtonRelease-1>',
203 lambda event, s=self, button=self._upSecondArrowBtn:
204 s._stopUpDown(button))
205
206 # Down hour
207 self._downHourArrowBtn.bind('<Configure>',
208 lambda event, s=self,button=self._downHourArrowBtn:
209 s._drawArrow(button, 'down'))
210
211 self._downHourArrowBtn.bind('<1>',
212 lambda event, s=self,button=self._downHourArrowBtn:
213 s._countDown(button, 3600))
214 self._downHourArrowBtn.bind('<Any-ButtonRelease-1>',
215 lambda event, s=self, button=self._downHourArrowBtn:
216 s._stopUpDown(button))
217
218
219 # Down minute
220 self._downMinuteArrowBtn.bind('<Configure>',
221 lambda event, s=self,button=self._downMinuteArrowBtn:
222 s._drawArrow(button, 'down'))
223
224 self._downMinuteArrowBtn.bind('<1>',
225 lambda event, s=self,button=self._downMinuteArrowBtn:
226 s._countDown(button, 60))
227 self._downMinuteArrowBtn.bind('<Any-ButtonRelease-1>',
228 lambda event, s=self, button=self._downMinuteArrowBtn:
229 s._stopUpDown(button))
230
231 # Down second
232 self._downSecondArrowBtn.bind('<Configure>',
233 lambda event, s=self,button=self._downSecondArrowBtn:
234 s._drawArrow(button, 'down'))
235
236 self._downSecondArrowBtn.bind('<1>',
237 lambda event, s=self, button=self._downSecondArrowBtn:
238 s._countDown(button,1))
239 self._downSecondArrowBtn.bind('<Any-ButtonRelease-1>',
240 lambda event, s=self, button=self._downSecondArrowBtn:
241 s._stopUpDown(button))
242
243 self._hourCounterEntry.component('entry').bind(
244 '<Return>', self._invoke)
245 self._minuteCounterEntry.component('entry').bind(
246 '<Return>', self._invoke)
247 self._secondCounterEntry.component('entry').bind(
248 '<Return>', self._invoke)
249
250 self._hourCounterEntry.bind('<Configure>', self._resizeArrow)
251 self._minuteCounterEntry.bind('<Configure>', self._resizeArrow)
252 self._secondCounterEntry.bind('<Configure>', self._resizeArrow)
253
254 def _drawArrow(self, arrow, direction):
255 Pmw.drawarrow(arrow, self['hourentry_foreground'], direction, 'arrow')
256
257 def _resizeArrow(self, event = None):
258 for btn in (self._upHourArrowBtn, self._upMinuteArrowBtn,
259 self._upSecondArrowBtn,
260 self._downHourArrowBtn,
261 self._downMinuteArrowBtn, self._downSecondArrowBtn):
262 bw = (string.atoi(btn['borderwidth']) +
263 string.atoi(btn['highlightthickness']))
264 newHeight = self._hourCounterEntry.winfo_reqheight() - 2 * bw
265 newWidth = int(newHeight * self['buttonaspect'])
266 btn.configure(width=newWidth, height=newHeight)
267 self._drawArrow(btn, self.arrowDirection[btn])
268
269 def _min(self):
270 min = self['min']
271 if min is None:
272 self._minVal = 0
273 else:
274 self._minVal = Pmw.timestringtoseconds(min)
275
276 def _max(self):
277 max = self['max']
278 if max is None:
279 self._maxVal = None
280 else:
281 self._maxVal = Pmw.timestringtoseconds(max)
282
283 def getvalue(self):
284 return self.getstring()
285
286 def setvalue(self, text):
287 list = string.split(text, ':')
288 if len(list) != 3:
289 raise ValueError, 'invalid value: ' + text
290
291 self._hour = string.atoi(list[0])
292 self._minute = string.atoi(list[1])
293 self._second = string.atoi(list[2])
294
295 self._setHMS()
296
297 def getstring(self):
298 return '%02d:%02d:%02d' % (self._hour, self._minute, self._second)
299
300 def getint(self):
301 return self._hour * 3600 + self._minute * 60 + self._second
302
303 def _countUp(self, button, increment):
304 self._relief = self._upHourArrowBtn.cget('relief')
305 button.configure(relief='sunken')
306 self._count(1, 'start', increment)
307
308 def _countDown(self, button, increment):
309
310 self._relief = self._downHourArrowBtn.cget('relief')
311 button.configure(relief='sunken')
312 self._count(-1, 'start', increment)
313
314 def increment(self, seconds = 1):
315 self._count(1, 'force', seconds)
316
317 def decrement(self, seconds = 1):
318 self._count(-1, 'force', seconds)
319
320 def _count(self, factor, newFlag = None, increment = 1):
321 if newFlag != 'force':
322 if newFlag is not None:
323 self._flag = newFlag
324
325 if self._flag == 'stopped':
326 return
327
328 value = (string.atoi(self._hourCounterEntry.get()) *3600) + \
329 (string.atoi(self._minuteCounterEntry.get()) *60) + \
330 string.atoi(self._secondCounterEntry.get()) + \
331 factor * increment
332 min = self._minVal
333 max = self._maxVal
334 if value < min:
335 value = min
336 if max is not None and value > max:
337 value = max
338
339 self._hour = value /3600
340 self._minute = (value - (self._hour*3600)) / 60
341 self._second = value - (self._hour*3600) - (self._minute*60)
342 self._setHMS()
343
344 if newFlag != 'force':
345 if self['autorepeat']:
346 if self._flag == 'start':
347 delay = self['initwait']
348 self._flag = 'running'
349 else:
350 delay = self['repeatrate']
351 self._timerId = self.after(
352 delay, lambda self=self, factor=factor,increment=increment:
353 self._count(factor,'running', increment))
354
355 def _setHMS(self):
356 self._hourCounterEntry.setentry('%02d' % self._hour)
357 self._minuteCounterEntry.setentry('%02d' % self._minute)
358 self._secondCounterEntry.setentry('%02d' % self._second)
359
360 def _stopUpDown(self, button):
361 if self._timerId is not None:
362 self.after_cancel(self._timerId)
363 self._timerId = None
364 button.configure(relief=self._relief)
365 self._flag = 'stopped'
366
367 def _invoke(self, event):
368 cmd = self['command']
369 if callable(cmd):
370 cmd()
371
372 def invoke(self):
373 cmd = self['command']
374 if callable(cmd):
375 return cmd()
376
377 def destroy(self):
378 if self._timerId is not None:
379 self.after_cancel(self._timerId)
380 self._timerId = None
381 Pmw.MegaWidget.destroy(self)