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