]> git.saurik.com Git - wxWidgets.git/blob - utils/wxPython/lib/calendar.py
wizard.h added to the list of headers
[wxWidgets.git] / utils / wxPython / lib / calendar.py
1 #! /usr/local/bin/python
2 #----------------------------------------------------------------------------
3 # Name: calendar.py
4 # Purpose: Calendar display control
5 #
6 # Author: Lorne White (email: lwhite1@planet.eon.net)
7 #
8 # Created:
9 # Version 0.5 1999/11/03
10 # Licence: wxWindows license
11 #----------------------------------------------------------------------------
12
13 from wxPython.wx import *
14
15 from CDate import *
16 import string, time
17
18
19 CalDays = [6, 0, 1, 2, 3, 4, 5]
20 AbrWeekday = {6:"Sun", 0:"Mon", 1:"Tue", 2:"Wed", 3:"Thu", 4:"Fri", 5:"Sat"}
21 _MIDSIZE = 100
22
23
24 # calendar drawing routing
25
26 class CalDraw:
27 def __init__(self):
28 self.rg = {}
29 self.y_st = 15 # start of vertical draw default
30
31 def SetSize(self, size):
32 self.sizew = size.width
33 self.sizeh = size.height
34
35 # draw the various elements of the calendar
36
37 def DrawCal(self, DC, sel_lst):
38 self.DC = DC
39
40 self.DrawBorder()
41
42 if self.hide_title is FALSE:
43 self.DrawMonth()
44
45 self.Center()
46
47 self.DrawGrid()
48 self.GetRect()
49
50 self.DrawSel(sel_lst) # highlighted days
51 self.DrawWeek()
52 self.DrawNum()
53
54 # draw border around the outside of the main display rectangle
55
56 def DrawBorder(self):
57 rect = wxRect(0, 0, self.sizew, self.sizeh) # full display window area
58 self.DC.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
59
60 def DrawNumVal(self):
61 self.DrawNum()
62
63 # calculate the calendar days and offset position
64
65 def SetCal(self, year, month):
66 self.year = year
67 self.month = month
68
69 day = 1
70 t = Date(year, month, day)
71 dow = t.day_of_week # start day in month
72 dim = t.days_in_month # number of days in month
73 start_pos = dow+1
74 self.st_pos = start_pos
75
76 self.cal = []
77 for i in range(start_pos):
78 self.cal.append('')
79 i = 1
80 while i <= dim:
81 self.cal.append(str(i))
82 i = i + 1
83 return start_pos
84
85 # get the display rectange list of the day grid
86
87 def GetRect(self):
88 cnt = 0
89 for y in self.gridy[1:-1]:
90 for x in self.gridx[:-1]:
91 rect = wxRect(x, y, self.dl_w, self.dl_h) # create rect region
92 self.rg[cnt] = rect
93 cnt = cnt + 1
94 return self.rg
95
96 def GetCal(self):
97 return self.cal
98
99 def GetOffset(self):
100 return self.st_pos
101
102 # month and year title
103
104 def DrawMonth(self):
105 month = Month[self.month]
106
107 sizef = 12
108 if self.sizeh < _MIDSIZE:
109 sizef = 10
110
111 f = wxFont(sizef, self.font, wxNORMAL, self.bold)
112 self.DC.SetFont(f)
113
114 tw,th = self.DC.GetTextExtent(month)
115 adjust = (self.sizew-tw)/2
116 self.DC.DrawText(month, adjust, 10)
117
118 year = str(self.year)
119 tw,th = self.DC.GetTextExtent(year)
120 adjust = self.sizew-tw-20
121
122 self.y_st = th * 3
123
124 f = wxFont(sizef, self.font, wxNORMAL, self.bold)
125 self.DC.SetFont(f)
126 self.DC.DrawText(year, adjust, 10)
127
128 # draw the week days
129
130 def DrawWeek(self):
131 sizef = 10
132 if self.sizeh < _MIDSIZE:
133 sizef = 8
134
135 f = wxFont(sizef, self.font, wxNORMAL, self.bold)
136 self.DC.SetFont(f)
137
138 cnt_x = 0
139 cnt_y = 0
140 width = self.gridx[1]-self.gridx[0]
141 height = self.gridy[1] - self.gridy[0]
142
143 for val in CalDays:
144 day = AbrWeekday[val]
145 if self.sizew < 200:
146 day = day[0]
147 dw,dh = self.DC.GetTextExtent(day)
148 diffx = (width-dw)/2
149 diffy = (height-dh)/2
150
151 x = self.gridx[cnt_x]
152 y = self.gridy[cnt_y]
153 self.DC.DrawText(day, x+diffx, y+diffy)
154 cnt_x = cnt_x + 1
155
156 # draw the day numbers
157
158 def DrawNum(self):
159 sizef = 10
160 if self.sizeh < _MIDSIZE:
161 sizef = 8
162 f = wxFont(sizef, self.font, wxNORMAL, self.bold)
163 self.DC.SetFont(f)
164
165 cnt_x = 0
166 cnt_y = 1
167 for val in self.cal:
168 x = self.gridx[cnt_x]
169 y = self.gridy[cnt_y]
170 self.DC.DrawText(val, x+5, y+5)
171 if cnt_x < 6:
172 cnt_x = cnt_x + 1
173 else:
174 cnt_x = 0
175 cnt_y = cnt_y + 1
176
177 # calculate the dimensions in the center of the drawing area
178
179 def Center(self):
180 self.x_st = 10
181 self.y_end = 10
182
183 bdw = self.x_st * 2
184 bdh = self.y_st + self.y_end
185
186 self.dl_w = (self.sizew-bdw)/7
187 self.dl_h = (self.sizeh-bdh)/7
188
189 self.cwidth = self.dl_w * 7
190 self.cheight = self.dl_h * 6 + self.dl_h/2
191
192 # highlighted selectioned days
193
194 def DrawSel(self, sel_lst):
195 for key in sel_lst:
196 brush = wxBrush(wxNamedColour(self.high_color), wxSOLID)
197 self.DC.SetBrush(brush)
198 if self.hide_grid is FALSE:
199 self.DC.SetPen(wxPen(wxNamedColour(self.grid_color), 0))
200 else:
201 self.DC.SetPen(wxPen(wxNamedColour(self.back_color), 0))
202 nkey = key + self.st_pos -1
203 rect = self.rg[nkey]
204 self.DC.DrawRectangle(rect.x, rect.y, rect.width+1, rect.height+1)
205
206 # calculate and draw the grid lines
207
208 def DrawGrid(self):
209 self.DC.SetPen(wxPen(wxNamedColour(self.grid_color), 0))
210
211 self.gridx = []
212 self.gridy = []
213
214 x1 = self.x_st
215 y1 = self.y_st
216 y1 = self.y_st
217 y2 = self.y_st + self.cheight
218 for i in range(8):
219 if self.hide_grid is FALSE:
220 self.DC.DrawLine(x1, y1, x1, y2)
221 self.gridx.append(x1)
222 x1 = x1 + self.dl_w
223
224 x1 = self.x_st
225 y1 = self.y_st
226 x2 = self.x_st + self.cwidth
227 for i in range(8):
228 if self.hide_grid is FALSE:
229 self.DC.DrawLine(x1, y1, x2, y1)
230 self.gridy.append(y1)
231 if i == 0:
232 y1 = y1 + self.dl_h/2
233 else:
234 y1 = y1 + self.dl_h
235
236
237 class wxCalendar(wxWindow):
238 def __init__(self, parent, id, pos=wxDefaultPosition, size=wxDefaultSize):
239 wxWindow.__init__(self, parent, id, pos, size)
240
241 # set the calendar control attributes
242
243 self.grid_color = 'BLACK'
244 self.back_color = 'WHITE'
245 self.sel_color = 'RED'
246 self.high_color = 'LIGHT BLUE'
247 self.font = wxSWISS
248 self.bold = wxNORMAL
249
250 self.SetBackgroundColour(wxNamedColor(self.back_color))
251 self.Connect(-1, -1, wxEVT_LEFT_DOWN, self.OnLeftEvent)
252 self.Connect(-1, -1, wxEVT_LEFT_DCLICK, self.OnLeftDEvent)
253 self.Connect(-1, -1, wxEVT_RIGHT_DOWN, self.OnRightEvent)
254 self.Connect(-1, -1, wxEVT_RIGHT_DCLICK, self.OnRightDEvent)
255
256 self.sel_key = None # last used by
257 self.sel_lst = [] # highlighted selected days
258
259 self.SetNow() # default calendar for current month
260
261 self.size = None
262 self.hide_title = FALSE
263 self.hide_grid = FALSE
264 self.set_day = None
265
266 # control some of the main calendar attributes
267
268 def HideTitle(self):
269 self.hide_title = TRUE
270
271 def HideGrid(self):
272 self.hide_grid = TRUE
273
274 # determine the calendar rectangle click area and draw a selection
275
276 def ProcessClick(self, event):
277 self.x, self.y = event.GetX(), event.GetY()
278 key = self.GetDayHit(self.x, self.y)
279 self.SelectDay(key)
280
281 # tab mouse click events and process
282
283 def OnLeftEvent(self, event):
284 self.click = 'LEFT'
285 self.ProcessClick(event)
286
287 def OnLeftDEvent(self, event):
288 self.click = 'DLEFT'
289 self.ProcessClick(event)
290
291 def OnRightEvent(self, event):
292 self.click = 'RIGHT'
293 self.ProcessClick(event)
294
295 def OnRightDEvent(self, event):
296 self.click = 'DRIGHT'
297 self.ProcessClick(event)
298
299 def SetSize(self, set_size):
300 self.size = set_size
301
302 def SetSelDay(self, sel):
303 self.sel_lst = sel # list of highlighted days
304
305 # get the current date
306
307 def SetNow(self):
308 dt = now()
309 self.month = dt.month
310 self.year = dt.year
311 self.day = dt.day
312
313 # set the current day
314
315 def SetCurrentDay(self):
316 self.SetNow()
317 self.set_day = self.day
318
319 # get the date, day, month, year set in calendar
320
321 def GetDate(self):
322 return self.day, self.month, self.year
323
324 def GetDay(self):
325 return self.day
326
327 def GetMonth(self):
328 return self.month
329
330 def GetYear(self):
331 return self.year
332
333 # set the day, month, and year
334
335 def SetDayValue(self, day):
336 self.set_day = day
337
338 def SetMonth(self, month):
339 if month >= 1 and month <= 12:
340 self.month = month
341 else:
342 self.month = 1
343 self.set_day = None
344
345 def SetYear(self, year):
346 self.year = year
347
348 # increment year and month
349
350 def IncYear(self):
351 self.year = self.year + 1
352 self.set_day = None
353
354 def DecYear(self):
355 self.year = self.year - 1
356 self.set_day = None
357
358 def IncMonth(self):
359 self.month = self.month + 1
360 if self.month > 12:
361 self.month = 1
362 self.year = self.year + 1
363 self.set_day = None
364
365 def DecMonth(self):
366 self.month = self.month - 1
367 if self.month < 1:
368 self.month = 12
369 self.year = self.year - 1
370 self.set_day = None
371
372 # test to see if the selection has a date and create event
373
374 def TestDay(self, key):
375 try:
376 self.day = int(self.cal[key])
377 except:
378 return None
379 if self.day == "":
380 return None
381 else:
382 evt = wxPyCommandEvent(2100, self.GetId())
383 evt.click, evt.day, evt.month, evt.year = self.click, self.day, self.month, self.year
384 self.GetEventHandler().ProcessEvent(evt)
385
386 self.set_day = self.day
387 return key
388
389 # find the clicked area rectangle
390
391 def GetDayHit(self, mx, my):
392 for key in self.rg.keys():
393 val = self.rg[key]
394 rt = wxRegion()
395 rt.Union(val)
396 if rt.Contains(mx, my) != 0:
397 result = self.TestDay(key)
398 return result
399 return None
400
401 # calendar drawing
402
403 def OnPaint(self, event):
404 DC = wxPaintDC(self)
405 self.DoDrawing(DC)
406
407 def DoDrawing(self, DC):
408 DC = wxPaintDC(self)
409 DC.BeginDrawing()
410
411 self.cal = cal = CalDraw()
412 if self.size is None:
413 size = self.GetClientSize()
414 else:
415 size = self.size
416
417 # drawing attributes
418
419 cal.hide_title = self.hide_title
420 cal.hide_grid = self.hide_grid
421
422 cal.grid_color = self.grid_color
423 cal.high_color = self.high_color
424 cal.back_color = self.back_color
425 cal.font = self.font
426 cal.bold = self.bold
427
428 cal.SetSize(size)
429 cal.SetCal(self.year, self.month)
430 cal.DrawCal(DC, self.sel_lst)
431
432 self.rg = cal.GetRect()
433 self.cal = cal.GetCal()
434 self.st_pos = cal.GetOffset()
435 self.ymax = DC.MaxY()
436
437 if self.set_day != None:
438 self.SetDay(self.set_day)
439 DC.EndDrawing()
440
441 # draw the selection rectangle
442
443 def DrawRect(self, key, color = 'BLACK', width = 0):
444 if key == None:
445 return
446 DC = wxClientDC(self)
447 DC.BeginDrawing()
448
449 brush = wxBrush(wxColour(0, 0xFF, 0x80), wxTRANSPARENT)
450 DC.SetBrush(brush)
451 DC.SetPen(wxPen(wxNamedColour(color), width))
452
453 rect = self.rg[key]
454 DC.DrawRectangle(rect.x, rect.y, rect.width+1, rect.height+1)
455
456 DC.EndDrawing()
457
458 # set the day selection
459
460 def SetDay(self, day):
461 day = day + self.st_pos - 1
462 self.SelectDay(day)
463
464 def SelectDay(self, key):
465 sel_size = 1
466 self.DrawRect(self.sel_key, self.back_color, sel_size) # clear large selection
467 if self.hide_grid is FALSE:
468 self.DrawRect(self.sel_key, self.grid_color)
469
470 self.DrawRect(key, self.sel_color, sel_size)
471 self.sel_key = key # store last used by
472 self.select_day = None
473
474 def ClearDsp(self):
475 self.Clear()
476
477