1 #! /usr/local/bin/python
2 #----------------------------------------------------------------------------
4 # Purpose: Calendar display control
6 # Author: Lorne White (email: lwhite1@planet.eon.net)
9 # Version 0.5 1999/11/03
10 # Licence: wxWindows license
11 #----------------------------------------------------------------------------
13 from wxPython
.wx
import *
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"}
24 # calendar drawing routing
29 self
.y_st
= 15 # start of vertical draw default
31 def SetSize(self
, size
):
32 self
.sizew
= size
.width
33 self
.sizeh
= size
.height
35 # draw the various elements of the calendar
37 def DrawCal(self
, DC
, sel_lst
):
42 if self
.hide_title
is FALSE
:
50 self
.DrawSel(sel_lst
) # highlighted days
54 # draw border around the outside of the main display rectangle
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
)
63 # calculate the calendar days and offset position
65 def SetCal(self
, year
, month
):
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
74 self
.st_pos
= start_pos
77 for i
in range(start_pos
):
81 self
.cal
.append(str(i
))
85 # get the display rectange list of the day grid
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
102 # month and year title
105 month
= Month
[self
.month
]
108 if self
.sizeh
< _MIDSIZE
:
111 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
114 tw
,th
= self
.DC
.GetTextExtent(month
)
115 adjust
= (self
.sizew
-tw
)/2
116 self
.DC
.DrawText(month
, adjust
, 10)
118 year
= str(self
.year
)
119 tw
,th
= self
.DC
.GetTextExtent(year
)
120 adjust
= self
.sizew
-tw
-20
124 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
126 self
.DC
.DrawText(year
, adjust
, 10)
132 if self
.sizeh
< _MIDSIZE
:
135 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
140 width
= self
.gridx
[1]-self
.gridx
[0]
141 height
= self
.gridy
[1] - self
.gridy
[0]
144 day
= AbrWeekday
[val
]
147 dw
,dh
= self
.DC
.GetTextExtent(day
)
149 diffy
= (height
-dh
)/2
151 x
= self
.gridx
[cnt_x
]
152 y
= self
.gridy
[cnt_y
]
153 self
.DC
.DrawText(day
, x
+diffx
, y
+diffy
)
156 # draw the day numbers
160 if self
.sizeh
< _MIDSIZE
:
162 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
168 x
= self
.gridx
[cnt_x
]
169 y
= self
.gridy
[cnt_y
]
170 self
.DC
.DrawText(val
, x
+5, y
+5)
177 # calculate the dimensions in the center of the drawing area
184 bdh
= self
.y_st
+ self
.y_end
186 self
.dl_w
= (self
.sizew
-bdw
)/7
187 self
.dl_h
= (self
.sizeh
-bdh
)/7
189 self
.cwidth
= self
.dl_w
* 7
190 self
.cheight
= self
.dl_h
* 6 + self
.dl_h
/2
192 # highlighted selectioned days
194 def DrawSel(self
, 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))
201 self
.DC
.SetPen(wxPen(wxNamedColour(self
.back_color
), 0))
202 nkey
= key
+ self
.st_pos
-1
204 self
.DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
+1, rect
.height
+1)
206 # calculate and draw the grid lines
209 self
.DC
.SetPen(wxPen(wxNamedColour(self
.grid_color
), 0))
217 y2
= self
.y_st
+ self
.cheight
219 if self
.hide_grid
is FALSE
:
220 self
.DC
.DrawLine(x1
, y1
, x1
, y2
)
221 self
.gridx
.append(x1
)
226 x2
= self
.x_st
+ self
.cwidth
228 if self
.hide_grid
is FALSE
:
229 self
.DC
.DrawLine(x1
, y1
, x2
, y1
)
230 self
.gridy
.append(y1
)
232 y1
= y1
+ self
.dl_h
/2
237 class wxCalendar(wxWindow
):
238 def __init__(self
, parent
, id, pos
=wxDefaultPosition
, size
=wxDefaultSize
):
239 wxWindow
.__init
__(self
, parent
, id, pos
, size
)
241 # set the calendar control attributes
243 self
.grid_color
= 'BLACK'
244 self
.back_color
= 'WHITE'
245 self
.sel_color
= 'RED'
246 self
.high_color
= 'LIGHT BLUE'
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
)
256 self
.sel_key
= None # last used by
257 self
.sel_lst
= [] # highlighted selected days
259 self
.SetNow() # default calendar for current month
262 self
.hide_title
= FALSE
263 self
.hide_grid
= FALSE
266 # control some of the main calendar attributes
269 self
.hide_title
= TRUE
272 self
.hide_grid
= TRUE
274 # determine the calendar rectangle click area and draw a selection
276 def ProcessClick(self
, event
):
277 self
.x
, self
.y
= event
.GetX(), event
.GetY()
278 key
= self
.GetDayHit(self
.x
, self
.y
)
281 # tab mouse click events and process
283 def OnLeftEvent(self
, event
):
285 self
.ProcessClick(event
)
287 def OnLeftDEvent(self
, event
):
289 self
.ProcessClick(event
)
291 def OnRightEvent(self
, event
):
293 self
.ProcessClick(event
)
295 def OnRightDEvent(self
, event
):
296 self
.click
= 'DRIGHT'
297 self
.ProcessClick(event
)
299 def SetSize(self
, set_size
):
302 def SetSelDay(self
, sel
):
303 self
.sel_lst
= sel
# list of highlighted days
305 # get the current date
309 self
.month
= dt
.month
313 # set the current day
315 def SetCurrentDay(self
):
317 self
.set_day
= self
.day
319 # get the date, day, month, year set in calendar
322 return self
.day
, self
.month
, self
.year
333 # set the day, month, and year
335 def SetDayValue(self
, day
):
338 def SetMonth(self
, month
):
339 if month
>= 1 and month
<= 12:
345 def SetYear(self
, year
):
348 # increment year and month
351 self
.year
= self
.year
+ 1
355 self
.year
= self
.year
- 1
359 self
.month
= self
.month
+ 1
362 self
.year
= self
.year
+ 1
366 self
.month
= self
.month
- 1
369 self
.year
= self
.year
- 1
372 # test to see if the selection has a date and create event
374 def TestDay(self
, key
):
376 self
.day
= int(self
.cal
[key
])
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
)
386 self
.set_day
= self
.day
389 # find the clicked area rectangle
391 def GetDayHit(self
, mx
, my
):
392 for key
in self
.rg
.keys():
396 if rt
.Contains(mx
, my
) != 0:
397 result
= self
.TestDay(key
)
403 def OnPaint(self
, event
):
407 def DoDrawing(self
, DC
):
411 self
.cal
= cal
= CalDraw()
412 if self
.size
is None:
413 size
= self
.GetClientSize()
419 cal
.hide_title
= self
.hide_title
420 cal
.hide_grid
= self
.hide_grid
422 cal
.grid_color
= self
.grid_color
423 cal
.high_color
= self
.high_color
424 cal
.back_color
= self
.back_color
429 cal
.SetCal(self
.year
, self
.month
)
430 cal
.DrawCal(DC
, self
.sel_lst
)
432 self
.rg
= cal
.GetRect()
433 self
.cal
= cal
.GetCal()
434 self
.st_pos
= cal
.GetOffset()
435 self
.ymax
= DC
.MaxY()
437 if self
.set_day
!= None:
438 self
.SetDay(self
.set_day
)
441 # draw the selection rectangle
443 def DrawRect(self
, key
, color
= 'BLACK', width
= 0):
446 DC
= wxClientDC(self
)
449 brush
= wxBrush(wxColour(0, 0xFF, 0x80), wxTRANSPARENT
)
451 DC
.SetPen(wxPen(wxNamedColour(color
), width
))
454 DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
+1, rect
.height
+1)
458 # set the day selection
460 def SetDay(self
, day
):
461 day
= day
+ self
.st_pos
- 1
464 def SelectDay(self
, key
):
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
)
470 self
.DrawRect(key
, self
.sel_color
, sel_size
)
471 self
.sel_key
= key
# store last used by
472 self
.select_day
= None