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 *
16 from DateTime
import *
17 using_mxDateTime
= true
20 using_mxDateTime
= false
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"}
28 # calendar drawing routing
33 self
.y_st
= 15 # start of vertical draw default
35 def SetSize(self
, size
):
36 self
.sizew
= size
.width
37 self
.sizeh
= size
.height
39 # draw the various elements of the calendar
41 def DrawCal(self
, DC
, sel_lst
):
46 if self
.hide_title
is FALSE
:
54 self
.DrawSel(sel_lst
) # highlighted days
58 # draw border around the outside of the main display rectangle
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
)
67 # calculate the calendar days and offset position
69 def SetCal(self
, year
, month
):
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
78 self
.st_pos
= start_pos
81 for i
in range(start_pos
):
85 self
.cal
.append(str(i
))
89 # get the display rectange list of the day grid
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
106 # month and year title
109 month
= Month
[self
.month
]
115 f
= wxFont(sizef
, self
.font
, wxNORMAL
, wxNORMAL
)
118 tw
,th
= self
.DC
.GetTextExtent(month
)
119 adjust
= (self
.sizew
-tw
)/2
120 self
.DC
.DrawText(month
, adjust
, 10)
122 year
= str(self
.year
)
123 tw
,th
= self
.DC
.GetTextExtent(year
)
124 adjust
= self
.sizew
-tw
-20
128 f
= wxFont(sizef
, self
.font
, wxNORMAL
, wxNORMAL
)
130 self
.DC
.DrawText(year
, adjust
, 10)
139 f
= wxFont(sizef
, self
.font
, wxNORMAL
, wxNORMAL
)
144 width
= self
.gridx
[1]-self
.gridx
[0]
145 height
= self
.gridy
[1] - self
.gridy
[0]
148 day
= AbrWeekday
[val
]
151 dw
,dh
= self
.DC
.GetTextExtent(day
)
153 diffy
= (height
-dh
)/2
155 x
= self
.gridx
[cnt_x
]
156 y
= self
.gridy
[cnt_y
]
157 self
.DC
.DrawText(day
, x
+diffx
, y
+diffy
)
160 # draw the day numbers
166 f
= wxFont(sizef
, self
.font
, wxNORMAL
, wxNORMAL
)
172 x
= self
.gridx
[cnt_x
]
173 y
= self
.gridy
[cnt_y
]
174 self
.DC
.DrawText(val
, x
+5, y
+5)
181 # calculate the dimensions in the center of the drawing area
188 bdh
= self
.y_st
+ self
.y_end
190 self
.dl_w
= (self
.sizew
-bdw
)/7
191 self
.dl_h
= (self
.sizeh
-bdh
)/7
193 self
.cwidth
= self
.dl_w
* 7
194 self
.cheight
= self
.dl_h
* 6 + self
.dl_h
/2
196 # highlighted selectioned days
198 def DrawSel(self
, 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))
205 self
.DC
.SetPen(wxPen(wxNamedColour(self
.back_color
), 0))
206 nkey
= key
+ self
.st_pos
-1
208 self
.DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
+1, rect
.height
+1)
210 # calculate and draw the grid lines
213 self
.DC
.SetPen(wxPen(wxNamedColour(self
.grid_color
), 0))
221 y2
= self
.y_st
+ self
.cheight
223 if self
.hide_grid
is FALSE
:
224 self
.DC
.DrawLine(x1
, y1
, x1
, y2
)
225 self
.gridx
.append(x1
)
230 x2
= self
.x_st
+ self
.cwidth
232 if self
.hide_grid
is FALSE
:
233 self
.DC
.DrawLine(x1
, y1
, x2
, y1
)
234 self
.gridy
.append(y1
)
236 y1
= y1
+ self
.dl_h
/2
241 class Calendar(wxWindow
):
242 def __init__(self
, parent
, id, pos
=wxDefaultPosition
, size
=wxDefaultSize
):
243 wxWindow
.__init
__(self
, parent
, id, pos
, size
)
245 # set the calendar control attributes
247 self
.grid_color
= 'BLACK'
248 self
.back_color
= 'WHITE'
249 self
.sel_color
= 'RED'
250 self
.high_color
= 'LIGHT BLUE'
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
)
259 self
.sel_key
= None # last used by
260 self
.sel_lst
= [] # highlighted selected days
262 self
.SetNow() # default calendar for current month
265 self
.hide_title
= FALSE
266 self
.hide_grid
= FALSE
269 # control some of the main calendar attributes
272 self
.hide_title
= TRUE
275 self
.hide_grid
= TRUE
277 # determine the calendar rectangle click area and draw a selection
279 def ProcessClick(self
, event
):
280 self
.x
, self
.y
= event
.GetX(), event
.GetY()
281 key
= self
.GetDayHit(self
.x
, self
.y
)
284 # tab mouse click events and process
286 def OnLeftEvent(self
, event
):
288 self
.ProcessClick(event
)
290 def OnLeftDEvent(self
, event
):
292 self
.ProcessClick(event
)
294 def OnRightEvent(self
, event
):
296 self
.ProcessClick(event
)
298 def OnRightDEvent(self
, event
):
299 self
.click
= 'DRIGHT'
300 self
.ProcessClick(event
)
302 def SetSize(self
, set_size
):
305 def SetSelDay(self
, sel
):
306 self
.sel_lst
= sel
# list of highlighted days
308 # get the current date
312 self
.month
= dt
.month
316 # set the current day
318 def SetCurrentDay(self
):
320 self
.set_day
= self
.day
322 # get the date, day, month, year set in calendar
325 return self
.day
, self
.month
, self
.year
336 # set the day, month, and year
338 def SetDayValue(self
, day
):
341 def SetMonth(self
, month
):
342 if month
>= 1 and month
<= 12:
348 def SetYear(self
, year
):
351 # increment year and month
354 self
.year
= self
.year
+ 1
358 self
.year
= self
.year
- 1
362 self
.month
= self
.month
+ 1
365 self
.year
= self
.year
+ 1
369 self
.month
= self
.month
- 1
372 self
.year
= self
.year
- 1
375 # test to see if the selection has a date and create event
377 def TestDay(self
, key
):
379 self
.day
= int(self
.cal
[key
])
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
)
389 self
.set_day
= self
.day
392 # find the clicked area rectangle
394 def GetDayHit(self
, mx
, my
):
395 for key
in self
.rg
.keys():
399 if rt
.Contains(mx
, my
) != 0:
400 result
= self
.TestDay(key
)
406 def OnPaint(self
, event
):
410 def DoDrawing(self
, DC
):
414 self
.cal
= cal
= CalDraw()
415 if self
.size
is None:
416 size
= self
.GetClientSize()
422 cal
.hide_title
= self
.hide_title
423 cal
.hide_grid
= self
.hide_grid
425 cal
.grid_color
= self
.grid_color
426 cal
.high_color
= self
.high_color
427 cal
.back_color
= self
.back_color
431 cal
.SetCal(self
.year
, self
.month
)
432 cal
.DrawCal(DC
, self
.sel_lst
)
434 self
.rg
= cal
.GetRect()
435 self
.cal
= cal
.GetCal()
436 self
.st_pos
= cal
.GetOffset()
437 self
.ymax
= DC
.MaxY()
439 if self
.set_day
!= None:
440 self
.SetDay(self
.set_day
)
443 # draw the selection rectangle
445 def DrawRect(self
, key
, color
= 'BLACK', width
= 0):
448 DC
= wxClientDC(self
)
451 brush
= wxBrush(wxColour(0, 0xFF, 0x80), wxTRANSPARENT
)
453 DC
.SetPen(wxPen(wxNamedColour(color
), width
))
456 DC
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
+1, rect
.height
+1)
460 # set the day selection
462 def SetDay(self
, day
):
463 day
= day
+ self
.st_pos
- 1
466 def SelectDay(self
, key
):
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
)
472 self
.DrawRect(key
, self
.sel_color
, sel_size
)
473 self
.sel_key
= key
# store last used by
474 self
.select_day
= None