[Commits] (alecf) proper completion of background cell celetion in the calendar:

commits at osafoundation.org commits at osafoundation.org
Fri Apr 8 15:15:07 PDT 2005


Commit by: alecf
Modified files:
chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py 1.31 1.32
chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py 1.57 1.58

Log message:
proper completion of background cell celetion in the calendar:
- abstract out rectangle creation from date range, so it can be used without creating an event
- properly swap begin/end time during a drag, so that background selection works as expected
- rearrange mouse event logic so that the first drag event both starts the drag, and fires an initial OnDraggingItem/etc
- get rid of create-on-drag entirely. It didn't work well in its present form anyway.


ViewCVS links:
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py.diff?r1=text&tr1=1.31&r2=text&tr2=1.32
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py.diff?r1=text&tr1=1.57&r2=text&tr2=1.58

Index: chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py
diff -u chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py:1.31 chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py:1.32
--- chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py:1.31	Thu Apr  7 17:27:39 2005
+++ chandler/parcels/osaf/framework/blocks/calendar/CollectionCanvas.py	Fri Apr  8 15:15:06 2005
@@ -1,8 +1,8 @@
 """ Canvas block for displaying item collections
 """
 
-__version__ = "$Revision: 1.31 $"
-__date__ = "$Date: 2005/04/08 00:27:39 $"
+__version__ = "$Revision: 1.32 $"
+__date__ = "$Date: 2005/04/08 22:15:06 $"
 __copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
 __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
 
@@ -353,7 +353,7 @@
         dy = abs(position.y - self._dragStart.y)
         return dx > tolerance or dy > tolerance
 
-    def _initiateDrag(self):
+    def _initiateDrag(self, unscrolledPosition):
         """
         Potentially begin a drag. This is where we decide if it is a resize-drag 
         or a moving drag. 
@@ -362,9 +362,6 @@
             OnBeginDragItem()
         """
         
-        # start keeping _dragCurrentUnscrolled up to date
-        self._dragCurrentUnscrolled = self._dragStartUnscrolled
-
         if self._originalDragBox.isHitResize(self._dragStartUnscrolled): 
             # start resizing
             self._isResizingItem = True
@@ -376,32 +373,26 @@
             self._isDraggingItem = True
             self.OnBeginDragItem()
             
+        # start keeping _dragCurrentUnscrolled up to date
+        self._dragCurrentUnscrolled = unscrolledPosition
         self.CaptureMouse()
 
-    def _initiateDragWithoutSelection(self):
+    def _initiateDragWithoutSelection(self, unscrolledPosition):
         """
         User has begun to drag, but there is no canvasItem selected
         Possible client events:
             OnCreateItem()
             OnBeginResizeItem()
         """
-        # start keeping _dragCurrentUnscrolled up to date
-        self._dragCurrentUnscrolled = self._dragStartUnscrolled
 
-        itemBox = self.OnCreateItem(self._dragStartUnscrolled, True)
-        if itemBox: # if we have one, start resizing this item
-            self.SetDragBox(itemBox)
-            self._isResizingItem = True
-            self.OnBeginResizeItem()
-            self.SetCursor(wx.StockCursor(wx.CURSOR_SIZENS))
-        else: 
-            # indicate that we're dragging nothing
-            self._isDraggingNone = True
-            self.OnBeginDragNone()
+        # indicate that we're dragging nothing
+        self._isDraggingNone = True
+        self.OnBeginDragNone()
 
-        self.CaptureMouse()
-        
+        # start keeping _dragCurrentUnscrolled up to date
+        self._dragCurrentUnscrolled = unscrolledPosition
 
+        self.CaptureMouse()
         
     def _handleNormalDrag(self, dragInProgress, unscrolledPosition):
         """
@@ -484,7 +475,7 @@
         if hitBox:
             self.OnEditItem(hitBox)
         else:
-            self.OnCreateItem(unscrolledPosition, False)
+            self.OnCreateItem(unscrolledPosition)
             
     def _handleLeftClick(self, position, unscrolledPosition):
         """
@@ -534,19 +525,10 @@
 
         # checks if the event iself is from dragging the mouse
         dragInProgress = event.Dragging() and event.LeftIsDown()
-        
-        # handle events-in-progress such as resizes or drags
-        if self._isDraggingItem:
-            self._handleNormalDrag(dragInProgress, unscrolledPosition)
 
-        # handle resizing
-        elif self._isResizingItem:
-            self._handleResizeDrag(dragInProgress, unscrolledPosition)
-            
-        elif self._isDraggingNone:
-            self._handleNoneDrag(dragInProgress, unscrolledPosition)
-                
-        else: 
+        if not (self._isDraggingItem or
+                self._isResizingItem or
+                self._isDraggingNone):
             # just handle normal mouse events
 
             self._updateCursor(unscrolledPosition)
@@ -558,17 +540,26 @@
                 self._handleLeftClick(position, unscrolledPosition)
 
             # look for the beginning of a drag
-            # _dragStart seems to be used as a way to allow someone to
-            # cancel/ignore a drag in progress - see _initiateDragWithoutSelection
-            elif (dragInProgress):
-                
-                if (self._shouldBeginDrag(position)):
-                    if self._originalDragBox: 
-                        self._initiateDrag()
-                            
-                    else: # try creating an item
-                        self._initiateDragWithoutSelection()
+            elif (dragInProgress and self._shouldBeginDrag(position)):
+                if self._originalDragBox: 
+                    self._initiateDrag(unscrolledPosition)
+                        
+                else: # try creating an item
+                    self._initiateDragWithoutSelection(unscrolledPosition)
 
+        # now handle events-in-progress such as resizes or drags
+        # note that we may be doing both, since we might begin a drag,
+        # and then need to actually handle the drag
+        if self._isDraggingItem:
+            self._handleNormalDrag(dragInProgress, unscrolledPosition)
+
+        # handle resizing
+        elif self._isResizingItem:
+            self._handleResizeDrag(dragInProgress, unscrolledPosition)
+            
+        elif self._isDraggingNone:
+            self._handleNoneDrag(dragInProgress, unscrolledPosition)
+                
     def ScrollIntoView(self, unscrolledPosition):
         clientSize = self.GetClientSize()
         
@@ -586,7 +577,7 @@
     def GrabFocusHack(self):
         pass
 
-    def OnCreateItem(self, position, createOnDrag):
+    def OnCreateItem(self, position):
         """ Creates a new item on the canvas.
 
         Subclasses can define to create a new item on the canvas.
@@ -597,10 +588,6 @@
 
         @param position: unscrolled coordinates, location of the new item
         @type position: wx.Point
-        @param createOnDrag: True if in the middle of a drag (vs double click) 
-        @type createOnDrag: Boolean
-        @return: the CanvasItem for the newly created item, if createOnDrag
-        @rtype: CanvasItem
         """
         return None
 

Index: chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py
diff -u chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.57 chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.58
--- chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.57	Thu Apr  7 17:27:39 2005
+++ chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py	Fri Apr  8 15:15:06 2005
@@ -1,8 +1,8 @@
 """ Canvas for calendaring blocks
 """
 
-__version__ = "$Revision: 1.57 $"
-__date__ = "$Date: 2005/04/08 00:27:39 $"
+__version__ = "$Revision: 1.58 $"
+__date__ = "$Date: 2005/04/08 22:15:06 $"
 __copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
 __license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
 
@@ -163,7 +163,11 @@
         self._calendarCanvas = calendarCanvas
 
     def UpdateDrawingRects(self):
-        self._boundsRects = list(self.GenerateBoundsRects(self._calendarCanvas))
+        item = self.GetItem()
+        indent = self.GetIndentLevel() * 5
+        self._boundsRects = list(self.GenerateBoundsRects(self._calendarCanvas,
+                                                          item.startTime,
+                                                          item.endTime, indent))
         self._bounds = self._boundsRects[0]
 
         r = self._boundsRects[-1]
@@ -225,7 +229,7 @@
         if hasattr(self, '_forceResizeMode'):
             del self._forceResizeMode
     
-    def GenerateBoundsRects(self, calendarCanvas):
+    def GenerateBoundsRects(calendarCanvas, startTime, endTime, indent):
         """
         Generate a bounds rectangle for each day period. For example, an event
         that goes from noon monday to noon wednesday would have three bounds rectangles:
@@ -234,28 +238,33 @@
             one from midnight wednesday morning to noon wednesday
         """
         # calculate how many unique days this appears on 
-        item = self.GetItem()
-        days = int(item.endTime.absdays) - int(item.startTime.absdays) + 1
+        days = int(endTime.absdays) - int(startTime.absdays) + 1
         
         for i in xrange(days):
             
             # first calculate the midnight time for the beginning and end
             # of the current day
-            absDay = int(item.startTime.absdays) + i
+            absDay = int(startTime.absdays) + i
             absDayStart = DateTime.DateTimeFromAbsDays(absDay)
             absDayEnd = DateTime.DateTimeFromAbsDays(absDay + 1)
             
-            boundsStartTime = max(item.startTime, absDayStart)
-            boundsEndTime = min(item.endTime, absDayEnd)
+            boundsStartTime = max(startTime, absDayStart)
+            boundsEndTime = min(endTime, absDayEnd)
             
+            rect = ColumnarCanvasItem.MakeRectForRange(calendarCanvas, boundsStartTime, boundsEndTime)
+            rect.x += indent
+            rect.width -= indent
             try:
-                yield self.MakeRectForRange(calendarCanvas, boundsStartTime, boundsEndTime)
+                yield rect
             except ValueError:
                 pass
+
+    GenerateBoundsRects = staticmethod(GenerateBoundsRects)
         
-    def MakeRectForRange(self, calendarCanvas, startTime, endTime):
+    def MakeRectForRange(calendarCanvas, startTime, endTime):
         """
         Turn a datetime range into a rectangle that can be drawn on the screen
+        This is a static method, and can be used outside this class
         """
         startPosition = calendarCanvas.getPositionFromDateTime(startTime)
         
@@ -269,10 +278,10 @@
         # we really need a way to proportionally size
         # items, so that the right side of the rectangle
         # shrinks as well
-        startPosition.x += self.GetIndentLevel() * 5
-        cellWidth -= self.GetIndentLevel() * 5
         return wx.Rect(startPosition.x, startPosition.y, cellWidth, cellHeight)
 
+    MakeRectForRange = staticmethod(MakeRectForRange)
+
     def Draw(self, dc, boundingRect, brushContainer):
         item = self._item
 
@@ -827,22 +836,21 @@
         if (y > self.fullHeight):
             self.fullHeight = y
                     
-    def OnCreateItem(self, unscrolledPosition, createOnDrag):
-        if not createOnDrag:
-            view = self.parent.blockItem.itsView
-            newTime = self.getDateTimeFromPosition(unscrolledPosition)
-            event = Calendar.CalendarEvent(view=view)
-            event.InitOutgoingAttributes()
-            event.ChangeStart(DateTime.DateTime(newTime.year, newTime.month,
-                                                newTime.day,
-                                                event.startTime.hour,
-                                                event.startTime.minute))
-            event.allDay = True
-
-            self.parent.blockItem.contents.source.add(event)
-            self.OnSelectItem(event)
-            view.commit()
-        return None
+    def OnCreateItem(self, unscrolledPosition):
+        view = self.parent.blockItem.itsView
+        newTime = self.getDateTimeFromPosition(unscrolledPosition)
+        event = Calendar.CalendarEvent(view=view)
+        event.InitOutgoingAttributes()
+        event.ChangeStart(DateTime.DateTime(newTime.year, newTime.month,
+                                            newTime.day,
+                                            event.startTime.hour,
+                                            event.startTime.minute))
+        event.allDay = True
+
+        self.parent.blockItem.contents.source.add(event)
+        self.OnSelectItem(event)
+        view.commit()
+        return event
 
     def OnDraggingItem(self, unscrolledPosition):
         if self.parent.blockItem.dayMode:
@@ -931,10 +939,13 @@
         
         self._bgSelectionStartTime = None
         self._bgSelectionEndTime = None
+        self._bgSelectionDragEnd = True
         
         self.SetVirtualSize((self.GetVirtualSize().width, self.hourHeight*24))
         self.SetScrollRate(0, self._scrollYRate)
         self.Scroll(0, (self.hourHeight*7)/self._scrollYRate)
+        
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
 
     def ScaledScroll(self, dx, dy):
         (scrollX, scrollY) = self.CalcUnscrolledPosition(0,0)
@@ -1039,14 +1050,13 @@
             dc.SetPen(self.majorLinePen)
             dc.SetBrush(self.selectionBrush)
             
-            tlPos = self.getPositionFromDateTime(self._bgSelectionStartTime)
-            brPos = \
-               (self.getPositionFromDateTime(self._bgSelectionEndTime))
-            brPos.x += self.dayWidth
-            brPos.y += halfHourHeight
-            
-            selectionRect = wx.RectPP(tlPos, brPos)
-            dc.DrawRectangleRect(selectionRect)
+            rects = \
+                ColumnarCanvasItem.GenerateBoundsRects(self,
+                                                       self._bgSelectionStartTime,
+                                                       self._bgSelectionEndTime, 
+                                                       0)
+            for rect in rects:
+                dc.DrawRectangleRect(rect)
                     
 
     def sortByStartTime(self, item1, item2):
@@ -1136,6 +1146,10 @@
             canvasItem.CalculateConflictDepth()
 
 
+    def OnKeyPressed(self, event):
+        # create an event here - unfortunately the panel can't get focus, so it
+        # can't recieve keystrokes yet...
+        pass
             
     # handle mouse related actions: move, resize, create, select
     
@@ -1148,7 +1162,13 @@
         
     def OnSelectNone(self, unscrolledPosition):
         self._bgSelectionStartTime = self.getDateTimeFromPosition(unscrolledPosition)
-        self._bgSelectionEndTime = self._bgSelectionStartTime
+        self._bgSelectionDragEnd = True
+        self._bgSelectionEndTime = self._bgSelectionStartTime + \
+            DateTime.RelativeDateTime(minutes=30)
+            
+        # set focus on the calendar so that we can receive key events
+        # (as of this writing, wxPanel can't recieve focus, so this is a no-op)
+        self.SetFocus()
         super(wxWeekColumnCanvas, self).OnSelectNone(unscrolledPosition)
         
     def OnEditItem(self, box):
@@ -1160,7 +1180,7 @@
 
         self.editor.SetItem(box.GetItem(), textPos, textSize, self.smallFont.GetPointSize()) 
 
-    def OnCreateItem(self, unscrolledPosition, createOnDrag):
+    def OnCreateItem(self, unscrolledPosition):
         # @@@ this code might want to live somewhere else, refactored
         view = self.parent.blockItem.itsView
         event = Calendar.CalendarEvent(view=view)
@@ -1172,15 +1192,11 @@
         # see bug 2749 for some background
         self.parent.blockItem.contents.source.add(event)
         
-        if createOnDrag:
-            self._bgSelectionStartTime = self.bgSelectionEndTime = None
-        else:
-
-            self.OnSelectItem(event)
+        self.OnSelectItem(event)
 
-            # @@@ Bug#1854 currently this is too slow,
-            # and the event causes flicker
-            #view.commit()
+        # @@@ Bug#1854 currently this is too slow,
+        # and the event causes flicker
+        #view.commit()
         canvasItem = ColumnarCanvasItem(event, self)
         
         # only problem here is that we haven't checked for conflicts
@@ -1238,9 +1254,15 @@
         pass
         
     def OnDraggingNone(self, unscrolledPosition):
-        self._bgSelectionEndTime = self.getDateTimeFromPosition(unscrolledPosition)
+        dragDateTime = self.getDateTimeFromPosition(unscrolledPosition)
+        if self._bgSelectionDragEnd:
+            self._bgSelectionEndTime = dragDateTime
+        else:
+            self._bgSelectionStartTime = dragDateTime
+            
         if (self._bgSelectionEndTime < self._bgSelectionStartTime):
-            # swap values
+            # swap values, drag the other end
+            self._bgSelectionDragEnd = not self._bgSelectionDragEnd
             (self._bgSelectionStartTime, self._bgSelectionEndTime) = \
                 (self._bgSelectionEndTime, self._bgSelectionStartTime)
         self.Refresh()
@@ -1553,25 +1575,24 @@
 
     # handle mouse related actions: move, create
 
-    def OnCreateItem(self, unscrolledPosition, createOnDrag):
-        if not createOnDrag:
-            # @@@ this code might want to live somewhere else, refactored
-            view = self.blockItem.itsView
-            newTime = self.getDateTimeFromPosition(unscrolledPosition)
-            event = Calendar.CalendarEvent(view=view)
-            event.InitOutgoingAttributes()
-            event.ChangeStart(DateTime.DateTime(newTime.year, newTime.month,
-                                                newTime.day,
-                                                event.startTime.hour,
-                                                event.startTime.minute))
-
-            self.blockItem.contents.source.add(event)
-            self.OnSelectItem(event)
-            
-            # @@@ Bug#1854 currently this is too slow,
-            # and the event causes flicker
-            view.commit()
-        return None
+    def OnCreateItem(self, unscrolledPosition):
+        # @@@ this code might want to live somewhere else, refactored
+        view = self.blockItem.itsView
+        newTime = self.getDateTimeFromPosition(unscrolledPosition)
+        event = Calendar.CalendarEvent(view=view)
+        event.InitOutgoingAttributes()
+        event.ChangeStart(DateTime.DateTime(newTime.year, newTime.month,
+                                            newTime.day,
+                                            event.startTime.hour,
+                                            event.startTime.minute))
+
+        self.blockItem.contents.source.add(event)
+        self.OnSelectItem(event)
+        
+        # @@@ Bug#1854 currently this is too slow,
+        # and the event causes flicker
+        view.commit()
+        return event
 
     def OnDraggingItem(self, unscrolledPosition):
         newTime = self.getDateTimeFromPosition(unscrolledPosition)



More information about the Commits mailing list