1 #----------------------------------------------------------------------------
3 # Purpose: Calendar display control
5 # Author: Lorne White (email: lwhite1@planet.eon.net)
8 # Version 0.5 1999/11/03
9 # Licence: wxWindows license
10 #----------------------------------------------------------------------------
12 from wxPython
.wx
import *
18 CalDays
= [6, 0, 1, 2, 3, 4, 5]
19 AbrWeekday
= {6:"Sun", 0:"Mon", 1:"Tue", 2:"Wed", 3:"Thu", 4:"Fri", 5:"Sat"}
23 # calendar drawing routing
28 self
.y_st
= 15 # start of vertical draw default
30 def SetSize(self
, size
):
31 self
.sizew
= size
.width
32 self
.sizeh
= size
.height
34 # draw the various elements of the calendar
36 def DrawCal(self
, DC
, sel_lst
):
41 if self
.hide_title
is FALSE
:
49 self
.DrawSel(sel_lst
) # highlighted days
53 # draw border around the outside of the main display rectangle
56 rect
= wxRect(0, 0, self
.sizew
, self
.sizeh
) # full display window area
57 self
.DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
, rect
.height
)
62 # calculate the calendar days and offset position
64 def SetCal(self
, year
, month
):
69 t
= Date(year
, month
, day
)
70 dow
= t
.day_of_week
# start day in month
71 dim
= t
.days_in_month
# number of days in month
73 self
.st_pos
= start_pos
76 for i
in range(start_pos
):
80 self
.cal
.append(str(i
))
84 # get the display rectange list of the day grid
88 for y
in self
.gridy
[1:-1]:
89 for x
in self
.gridx
[:-1]:
90 rect
= wxRect(x
, y
, self
.dl_w
, self
.dl_h
) # create rect region
101 # month and year title
104 month
= Month
[self
.month
]
107 if self
.sizeh
< _MIDSIZE
:
110 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
113 tw
,th
= self
.DC
.GetTextExtent(month
)
114 adjust
= (self
.sizew
-tw
)/2
115 self
.DC
.DrawText(month
, adjust
, 10)
117 year
= str(self
.year
)
118 tw
,th
= self
.DC
.GetTextExtent(year
)
119 adjust
= self
.sizew
-tw
-20
123 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
125 self
.DC
.DrawText(year
, adjust
, 10)
131 if self
.sizeh
< _MIDSIZE
:
134 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
139 width
= self
.gridx
[1]-self
.gridx
[0]
140 height
= self
.gridy
[1] - self
.gridy
[0]
143 day
= AbrWeekday
[val
]
146 dw
,dh
= self
.DC
.GetTextExtent(day
)
148 diffy
= (height
-dh
)/2
150 x
= self
.gridx
[cnt_x
]
151 y
= self
.gridy
[cnt_y
]
152 self
.DC
.DrawText(day
, x
+diffx
, y
+diffy
)
155 # draw the day numbers
159 if self
.sizeh
< _MIDSIZE
:
161 f
= wxFont(sizef
, self
.font
, wxNORMAL
, self
.bold
)
167 x
= self
.gridx
[cnt_x
]
168 y
= self
.gridy
[cnt_y
]
169 self
.DC
.DrawText(val
, x
+5, y
+5)
176 # calculate the dimensions in the center of the drawing area
183 bdh
= self
.y_st
+ self
.y_end
185 self
.dl_w
= (self
.sizew
-bdw
)/7
186 self
.dl_h
= (self
.sizeh
-bdh
)/7
188 self
.cwidth
= self
.dl_w
* 7
189 self
.cheight
= self
.dl_h
* 6 + self
.dl_h
/2
191 # highlighted selectioned days
193 def DrawSel(self
, sel_lst
):
195 brush
= wxBrush(wxNamedColour(self
.high_color
), wxSOLID
)
196 self
.DC
.SetBrush(brush
)
197 if self
.hide_grid
is FALSE
:
198 self
.DC
.SetPen(wxPen(wxNamedColour(self
.grid_color
), 0))
200 self
.DC
.SetPen(wxPen(wxNamedColour(self
.back_color
), 0))
201 nkey
= key
+ self
.st_pos
-1
203 self
.DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
+1, rect
.height
+1)
205 # calculate and draw the grid lines
208 self
.DC
.SetPen(wxPen(wxNamedColour(self
.grid_color
), 0))
216 y2
= self
.y_st
+ self
.cheight
218 if self
.hide_grid
is FALSE
:
219 self
.DC
.DrawLine(x1
, y1
, x1
, y2
)
220 self
.gridx
.append(x1
)
225 x2
= self
.x_st
+ self
.cwidth
227 if self
.hide_grid
is FALSE
:
228 self
.DC
.DrawLine(x1
, y1
, x2
, y1
)
229 self
.gridy
.append(y1
)
231 y1
= y1
+ self
.dl_h
/2
236 class wxCalendar(wxWindow
):
237 def __init__(self
, parent
, id, pos
=wxDefaultPosition
, size
=wxDefaultSize
):
238 wxWindow
.__init
__(self
, parent
, id, pos
, size
)
240 # set the calendar control attributes
242 self
.grid_color
= 'BLACK'
243 self
.back_color
= 'WHITE'
244 self
.sel_color
= 'RED'
245 self
.high_color
= 'LIGHT BLUE'
249 self
.SetBackgroundColour(wxNamedColor(self
.back_color
))
250 self
.Connect(-1, -1, wxEVT_LEFT_DOWN
, self
.OnLeftEvent
)
251 self
.Connect(-1, -1, wxEVT_LEFT_DCLICK
, self
.OnLeftDEvent
)
252 self
.Connect(-1, -1, wxEVT_RIGHT_DOWN
, self
.OnRightEvent
)
253 self
.Connect(-1, -1, wxEVT_RIGHT_DCLICK
, self
.OnRightDEvent
)
255 self
.sel_key
= None # last used by
256 self
.sel_lst
= [] # highlighted selected days
258 self
.SetNow() # default calendar for current month
261 self
.hide_title
= FALSE
262 self
.hide_grid
= FALSE
265 # control some of the main calendar attributes
268 self
.hide_title
= TRUE
271 self
.hide_grid
= TRUE
273 # determine the calendar rectangle click area and draw a selection
275 def ProcessClick(self
, event
):
276 self
.x
, self
.y
= event
.GetX(), event
.GetY()
277 key
= self
.GetDayHit(self
.x
, self
.y
)
280 # tab mouse click events and process
282 def OnLeftEvent(self
, event
):
284 self
.ProcessClick(event
)
286 def OnLeftDEvent(self
, event
):
288 self
.ProcessClick(event
)
290 def OnRightEvent(self
, event
):
292 self
.ProcessClick(event
)
294 def OnRightDEvent(self
, event
):
295 self
.click
= 'DRIGHT'
296 self
.ProcessClick(event
)
298 def SetSize(self
, set_size
):
301 def SetSelDay(self
, sel
):
302 self
.sel_lst
= sel
# list of highlighted days
304 # get the current date
308 self
.month
= dt
.month
312 # set the current day
314 def SetCurrentDay(self
):
316 self
.set_day
= self
.day
318 # get the date, day, month, year set in calendar
321 return self
.day
, self
.month
, self
.year
332 # set the day, month, and year
334 def SetDayValue(self
, day
):
337 def SetMonth(self
, month
):
338 if month
>= 1 and month
<= 12:
344 def SetYear(self
, year
):
347 # increment year and month
350 self
.year
= self
.year
+ 1
354 self
.year
= self
.year
- 1
358 self
.month
= self
.month
+ 1
361 self
.year
= self
.year
+ 1
365 self
.month
= self
.month
- 1
368 self
.year
= self
.year
- 1
371 # test to see if the selection has a date and create event
373 def TestDay(self
, key
):
375 self
.day
= int(self
.cal
[key
])
381 evt
= wxPyCommandEvent(2100, self
.GetId())
382 evt
.click
, evt
.day
, evt
.month
, evt
.year
= self
.click
, self
.day
, self
.month
, self
.year
383 self
.GetEventHandler().ProcessEvent(evt
)
385 self
.set_day
= self
.day
388 # find the clicked area rectangle
390 def GetDayHit(self
, mx
, my
):
391 for key
in self
.rg
.keys():
395 if rt
.Contains(mx
, my
) != 0:
396 result
= self
.TestDay(key
)
402 def OnPaint(self
, event
):
406 def DoDrawing(self
, DC
):
410 self
.cal
= cal
= CalDraw()
411 if self
.size
is None:
412 size
= self
.GetClientSize()
418 cal
.hide_title
= self
.hide_title
419 cal
.hide_grid
= self
.hide_grid
421 cal
.grid_color
= self
.grid_color
422 cal
.high_color
= self
.high_color
423 cal
.back_color
= self
.back_color
428 cal
.SetCal(self
.year
, self
.month
)
429 cal
.DrawCal(DC
, self
.sel_lst
)
431 self
.rg
= cal
.GetRect()
432 self
.cal
= cal
.GetCal()
433 self
.st_pos
= cal
.GetOffset()
434 self
.ymax
= DC
.MaxY()
436 if self
.set_day
!= None:
437 self
.SetDay(self
.set_day
)
440 # draw the selection rectangle
442 def DrawRect(self
, key
, color
= 'BLACK', width
= 0):
445 DC
= wxClientDC(self
)
448 brush
= wxBrush(wxColour(0, 0xFF, 0x80), wxTRANSPARENT
)
450 DC
.SetPen(wxPen(wxNamedColour(color
), width
))
453 DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
+1, rect
.height
+1)
457 # set the day selection
459 def SetDay(self
, day
):
460 day
= day
+ self
.st_pos
- 1
463 def SelectDay(self
, key
):
465 self
.DrawRect(self
.sel_key
, self
.back_color
, sel_size
) # clear large selection
466 if self
.hide_grid
is FALSE
:
467 self
.DrawRect(self
.sel_key
, self
.grid_color
)
469 self
.DrawRect(key
, self
.sel_color
, sel_size
)
470 self
.sel_key
= key
# store last used by
471 self
.select_day
= None