[Commits] (alecf) More calendar refactoring to support multi-day
events
commits at osafoundation.org
commits at osafoundation.org
Fri Apr 1 15:44:37 PST 2005
Commit by: alecf
Modified files:
chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py 1.28 1.29
chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py 1.49 1.50
Log message:
More calendar refactoring to support multi-day events
- create CalendarCanvasItem which manages location for in-place editing, wrapped text drawing, and status bar pen selection
- hide item and bounds members of CanvasItem, because CanvasItems will soon have multiple bounds - use CalendarCanvasItem to abstract access to these members
- add MonthCanvasItem in case we have a month canvas, and factor out Draw() to this method
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py.diff?r1=text&tr1=1.28&r2=text&tr2=1.29
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py.diff?r1=text&tr1=1.49&r2=text&tr2=1.50
Index: chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py
diff -u chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py:1.28 chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py:1.29
--- chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py:1.28 Tue Mar 29 12:59:39 2005
+++ chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py Fri Apr 1 15:44:35 2005
@@ -1,8 +1,8 @@
""" Canvas block for displaying item collections
"""
-__version__ = "$Revision: 1.28 $"
-__date__ = "$Date: 2005/03/29 20:59:39 $"
+__version__ = "$Revision: 1.29 $"
+__date__ = "$Date: 2005/04/01 23:44:35 $"
__copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -191,8 +191,8 @@
"""
# @@@ scaffolding: resize bounds is the lower 5 pixels
- self.bounds = bounds
- self.item = item
+ self._bounds = bounds
+ self._item = item
def isHit(self, point):
""" Hit testing (used for selection and moving items).
@@ -202,7 +202,7 @@
@return: True if the point hit the item (includes resize region)
@rtype: Boolean
"""
- return self.bounds.Inside(point)
+ return self._bounds.Inside(point)
def isHitResize(self, point):
""" Hit testing of a resize region.
@@ -216,7 +216,7 @@
"""
return False
- def getItem(self):
+ def GetItem(self):
"""
Once we have a hit, give access to the item
for selection, move, resize, etc.
@@ -224,7 +224,8 @@
@return: the item associated with this region on the canvas.
@rtype: Item
"""
- return self.item
+ return self._item
+
class wxCollectionCanvas(wx.ScrolledWindow,
DragAndDrop.DropReceiveWidget,
@@ -315,51 +316,7 @@
def SetDragBox(self, box):
self._currentDragBox = self._originalDragBox = box
- # Drawing utility -- scaffolding, we'll try using editor/renderers
- def DrawWrappedText(self, dc, text, rect):
- # Simple wordwrap, next step is to not overdraw the rect
-
- lines = text.splitlines()
- y = rect.y
- for line in lines:
- x = rect.x
- wrap = 0
- for word in line.split():
- width, height = dc.GetTextExtent(word)
-
- # first see if we want to jump to the next line
- # (careful not to jump if we're already at the beginning of the line)
- if (x != rect.x and x + width > rect.x + rect.width):
- y += height
- x = rect.x
-
- # if we're out of vertical space, just return
- if (y + height > rect.y + rect.height):
- return y
-
- # if we wrapped but we still can't fit the word,
- # just truncate it
- if (x == rect.x and width > rect.width):
- self.DrawClippedText(dc, word, x, y, rect.width)
- y += height
- continue
-
- dc.DrawText(word, x, y)
- x += width
- width, height = dc.GetTextExtent(' ')
- dc.DrawText(' ', x, y)
- x += width
- y += height
- return y
-
- def DrawClippedText(self, dc, word, x, y, maxWidth):
- # keep shortening the word until it fits
- for i in xrange(len(word), 0, -1):
- smallWord = word[0:i] # + "..."
- width, height = dc.GetTextExtent(smallWord)
- if width <= maxWidth:
- dc.DrawText(smallWord, x, y)
- return
+
def DrawCenteredText(self, dc, text, rect):
textExtent = dc.GetTextExtent(text)
@@ -454,7 +411,7 @@
hitBox = box
if hitBox:
- self.OnSelectItem(hitBox.getItem())
+ self.OnSelectItem(hitBox.GetItem())
self.SetDragBox(hitBox)
# notice drag start whether or not we hit something
Index: chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py
diff -u chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.49 chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.50
--- chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.49 Fri Apr 1 08:57:05 2005
+++ chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py Fri Apr 1 15:44:35 2005
@@ -1,8 +1,8 @@
""" Canvas for calendaring blocks
"""
-__version__ = "$Revision: 1.49 $"
-__date__ = "$Date: 2005/04/01 16:57:05 $"
+__version__ = "$Revision: 1.50 $"
+__date__ = "$Date: 2005/04/01 23:44:35 $"
__copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -16,19 +16,90 @@
import osaf.framework.blocks.Block as Block
import osaf.framework.blocks.calendar.CollectionCanvas as CollectionCanvas
-class ColumnarCanvasItem(CollectionCanvas.CanvasItem):
+class CalendarCanvasItem(CollectionCanvas.CanvasItem):
+ """
+ Base class for calendar items. Covers:
+ - editor position & size
+ - text wrapping
+ """
+ def GetEditorPosition(self):
+ return self._bounds.GetPosition()
+
+ def GetMaxEditorSize(self):
+ return self._bounds.GetSize()
+
+ def GetStatusPen(self):
+ item = self.GetItem()
+ if (item.transparency == "confirmed"):
+ pen = wx.Pen(wx.BLACK, 3)
+ elif (item.transparency == "fyi"):
+ pen = wx.Pen(wx.LIGHT_GREY, 3)
+ elif (item.transparency == "tentative"):
+ pen = wx.Pen(wx.BLACK, 3, wx.DOT)
+ return pen
+
+ # Drawing utility -- scaffolding, we'll try using editor/renderers
+ def DrawWrappedText(self, dc, text, rect):
+ # Simple wordwrap, next step is to not overdraw the rect
+
+ result = []
+
+ lines = text.splitlines()
+ y = rect.y
+ for line in lines:
+ x = rect.x
+ wrap = 0
+ for word in line.split():
+ width, height = dc.GetTextExtent(word)
+
+ # first see if we want to jump to the next line
+ # (careful not to jump if we're already at the beginning of the line)
+ if (x != rect.x and x + width > rect.x + rect.width):
+ y += height
+ x = rect.x
+
+ # if we're out of vertical space, just return
+ if (y + height > rect.y + rect.height):
+ return y
+
+ # if we wrapped but we still can't fit the word,
+ # just truncate it
+ if (x == rect.x and width > rect.width):
+ self.DrawClippedText(dc, word, x, y, rect.width)
+ y += height
+ continue
+
+ dc.DrawText(word, x, y)
+ x += width
+ width, height = dc.GetTextExtent(' ')
+ dc.DrawText(' ', x, y)
+ x += width
+ y += height
+ return y
+
+ def DrawClippedText(self, dc, word, x, y, maxWidth):
+ # keep shortening the word until it fits
+ for i in xrange(len(word), 0, -1):
+ smallWord = word[0:i] # + "..."
+ width, height = dc.GetTextExtent(smallWord)
+ if width <= maxWidth:
+ dc.DrawText(smallWord, x, y)
+ return
+
+
+class ColumnarCanvasItem(CalendarCanvasItem):
resizeBufferSize = 5
RESIZE_MODE_START = 1
RESIZE_MODE_END = 2
def __init__(self, *arguments, **keywords):
super(ColumnarCanvasItem, self).__init__(*arguments, **keywords)
- self._resizeLowBounds = wx.Rect(self.bounds.x,
- self.bounds.y + self.bounds.height - self.resizeBufferSize,
- self.bounds.width, self.resizeBufferSize)
+ self._resizeLowBounds = wx.Rect(self._bounds.x,
+ self._bounds.y + self._bounds.height - self.resizeBufferSize,
+ self._bounds.width, self.resizeBufferSize)
- self._resizeTopBounds = wx.Rect(self.bounds.x, self.bounds.y,
- self.bounds.width, self.resizeBufferSize)
+ self._resizeTopBounds = wx.Rect(self._bounds.x, self._bounds.y,
+ self._bounds.width, self.resizeBufferSize)
def isHitResize(self, point):
""" Hit testing of a resize region.
@@ -62,8 +133,8 @@
return None
def Draw(self, dc, brushContainer):
- item = self.item
- itemRect = self.bounds
+ item = self._item
+ itemRect = self._bounds
time = item.startTime
# Draw one event
@@ -72,12 +143,7 @@
dc.SetPen(brushContainer.selectionPen)
dc.DrawRoundedRectangleRect(itemRect, radius=10)
- if (item.transparency == "confirmed"):
- pen = wx.Pen(wx.BLACK, 3)
- elif (item.transparency == "fyi"):
- pen = wx.Pen(wx.LIGHT_GREY, 3)
- elif (item.transparency == "tentative"):
- pen = wx.Pen(wx.BLACK, 3, wx.DOT)
+ pen = self.GetStatusPen()
pen.SetCap(wx.CAP_BUTT)
dc.SetPen(pen)
@@ -96,34 +162,23 @@
# only draw time if there is room
te = dc.GetFullTextExtent(timeString, brushContainer.smallBoldFont)
(timeWidth, timeHeight) = te[0], te[1]
- if (timeHeight < itemRect.height/3):
+ if (timeHeight < itemRect.height/2):
dc.SetFont(brushContainer.smallBoldFont)
- y = brushContainer.DrawWrappedText(dc, timeString, timeRect)
+ y = self.DrawWrappedText(dc, timeString, timeRect)
textRect = wx.Rect(x, y, width, itemRect.height - (y - itemRect.y))
dc.SetFont(brushContainer.smallFont)
- brushContainer.DrawWrappedText(dc, item.displayName, textRect)
+ self.DrawWrappedText(dc, item.displayName, textRect)
-class HeaderCanvasItem(CollectionCanvas.CanvasItem):
- def Draw(self, dc, isSelected, brushContainer):
- item = self.item
- itemRect = self.bounds
+class HeaderCanvasItem(CalendarCanvasItem):
+ def Draw(self, dc, brushContainer):
+ item = self._item
+ itemRect = self._bounds
- # draw selection rectangle, if any
- if (isSelected):
- dc.SetBrush(brushContainer.selectionBrush)
- dc.SetPen(brushContainer.selectionPen)
- dc.DrawRectangleRect(itemRect)
-
# draw little rectangle to the left of the item
- if (item.transparency == "confirmed"):
- pen = wx.Pen(wx.BLACK, 3)
- elif (item.transparency == "fyi"):
- pen = wx.Pen(wx.LIGHT_GREY, 3)
- elif (item.transparency == "tentative"):
- pen = wx.Pen(wx.BLACK, 3, wx.DOT)
+ pen = self.GetStatusPen()
pen.SetCap(wx.CAP_BUTT)
dc.SetPen(pen)
@@ -133,9 +188,18 @@
# Shift text
itemRect.x = itemRect.x + 6
itemRect.width = itemRect.width - 6
- # @@@ hack, this should be abstracted somehow
- brushContainer.DrawWrappedText(dc, item.displayName, itemRect)
-
+ self.DrawWrappedText(dc, item.displayName, itemRect)
+
+# hacky - might not work, but we don't even have a month canvas working right now
+class MonthCanvasItem(CalendarCanvasItem):
+ def Draw(self, dc, isSelected):
+ if (self.blockItem.selection is item):
+ dc.SetPen(wx.BLACK_PEN)
+ dc.SetBrush(wx.WHITE_BRUSH)
+ dc.DrawRectangleRect(itemRect)
+
+ self.DrawWrappedText(dc, self.GetItem().displayName, itemRect)
+
class CalendarEventHandler(object):
@@ -563,10 +627,15 @@
self.canvasItemList.append(canvasItem)
# keep track of the current drag/resize box
- if self._currentDragBox and self._currentDragBox.item == item:
+ if self._currentDragBox and self._currentDragBox.GetItem() == item:
self._currentDragBox = canvasItem
- canvasItem.Draw(dc, self.parent.blockItem.selection is item, self)
+ if (self.parent.blockItem.selection is item):
+ dc.SetBrush(self.selectionBrush)
+ dc.SetPen(self.selectionPen)
+ dc.DrawRectangleRect(itemRect)
+
+ canvasItem.Draw(dc, self)
y += h
@@ -595,7 +664,7 @@
return
newTime = self.getDateTimeFromPosition(unscrolledPosition)
- item = self._currentDragBox.getItem()
+ item = self._currentDragBox.GetItem()
if (newTime.absdate != item.startTime.absdate):
item.ChangeStart(DateTime.DateTime(newTime.year, newTime.month,
newTime.day,
@@ -604,10 +673,10 @@
self.Refresh()
def OnEditItem(self, box):
- position = box.bounds.GetPosition()
- size = box.bounds.GetSize()
+ position = box.GetEditorPosition()
+ size = box.GetMaxEditorSize()
- self.editor.SetItem(box.getItem(), position, size, size.height)
+ self.editor.SetItem(box.GetItem(), position, size, size.height)
def OnDayColumnSelect(self, event):
"""
@@ -806,7 +875,7 @@
self.canvasItemList.append(canvasItem)
# keep track of the current drag/resize box
- if self._currentDragBox and self._currentDragBox.item == item:
+ if self._currentDragBox and self._currentDragBox.GetItem() == item:
self._currentDragBox = canvasItem
# save the selected box to be drawn last
@@ -823,13 +892,13 @@
# handle mouse related actions: move, resize, create, select
def OnEditItem(self, box):
- position = self.CalcScrolledPosition(box.bounds.GetPosition())
- size = box.bounds.GetSize()
+ position = self.CalcScrolledPosition(box.GetEditorPosition())
+ size = box.GetMaxEditorSize()
textPos = wx.Point(position.x + 8, position.y + 15)
textSize = wx.Size(size.width - 13, size.height - 20)
- self.editor.SetItem(box.getItem(), textPos, textSize, self.smallFont.GetPointSize())
+ self.editor.SetItem(box.GetItem(), textPos, textSize, self.smallFont.GetPointSize())
def OnCreateItem(self, unscrolledPosition, createOnDrag):
if createOnDrag:
@@ -867,7 +936,7 @@
def OnResizingItem(self, unscrolledPosition):
newTime = self.getDateTimeFromPosition(unscrolledPosition)
- item = self._currentDragBox.getItem()
+ item = self._currentDragBox.GetItem()
resizeMode = self.GetResizeMode()
delta = DateTime.DateTimeDelta(0, 0, 15)
@@ -912,11 +981,14 @@
#
# so account for the original offset within the ORIGINAL dragbox so the
# mouse cursor stays in the same place relative to the original box
- dy = (self._dragStartUnscrolled.y - self._originalDragBox.bounds.y)
+
+ # @@@ Weird - we need to figure out where the original drag started
+ (boxX,boxY) = self._originalDragBox.GetEditorPosition()
+ dy = (self._dragStartUnscrolled.y - boxY)
position = wx.Point(unscrolledPosition.x, unscrolledPosition.y - dy)
newTime = self.getDateTimeFromPosition(position)
- item = self._currentDragBox.getItem()
+ item = self._currentDragBox.GetItem()
if ((newTime.absdate != item.startTime.absdate) or
(newTime.hour != item.startTime.hour) or
(newTime.minute != item.startTime.minute)):
@@ -1186,15 +1258,10 @@
self.canvasItemList.append(canvasItem)
# keep track of the current drag/resize box
- if self._currentDragBox and self._currentDragBox.item == item:
+ if self._currentDragBox and self._currentDragBox.GetItem() == item:
self._currentDragBox = canvasItem
- if (self.blockItem.selection is item):
- dc.SetPen(wx.BLACK_PEN)
- dc.SetBrush(wx.WHITE_BRUSH)
- dc.DrawRectangleRect(itemRect)
-
- self.DrawWrappedText(dc, item.displayName, itemRect)
+ canvasItem.Draw(dc, itemRect, self.blockItem.selection is item)
y += h
def DrawWeekday(self, dc, weekday, rect):
@@ -1228,7 +1295,7 @@
def OnDraggingItem(self, unscrolledPosition):
newTime = self.getDateTimeFromPosition(unscrolledPosition)
- item = self._currentDragBox.getItem()
+ item = self._currentDragBox.GetItem()
if (newTime.absdate != item.startTime.absdate):
item.ChangeStart(DateTime.DateTime(newTime.year, newTime.month,
newTime.day,
More information about the Commits
mailing list