Title: [commits] (jeffrey) [16102] [APP] Shade today
Revision
16102
Author
jeffrey
Date
2007-12-10 17:51:22 -0800 (Mon, 10 Dec 2007)

Log Message

[APP] Shade today
- Draw "phantom" rectangles for selection outside existing lozenges

Modified Paths

Diff

Modified: branches/rearchitecture/Chandler-Platform/ocap/wxui/calendar_canvas.py (16101 => 16102)

--- branches/rearchitecture/Chandler-Platform/ocap/wxui/calendar_canvas.py	2007-12-10 23:29:51 UTC (rev 16101)
+++ branches/rearchitecture/Chandler-Platform/ocap/wxui/calendar_canvas.py	2007-12-11 01:51:22 UTC (rev 16102)
@@ -65,6 +65,8 @@
 MINOR_LINE_COLOR = wx.Color(217, 217, 217)
 MAJOR_LINE_COLOR = wx.Color(204, 204, 204)
 LEGEND_COLOR     = wx.Color(128, 128, 128)
+TODAY_COLOR      = wx.Color(229, 229, 229, 128)
+PHANTOM_COLOR    = wx.Color(203, 203, 203, 128)
 
 SetRangeEvent,     EVT_SET_RANGE      = wx.lib.newevent.NewEvent()
 SetRangeModeEvent, EVT_SET_RANGE_MODE = wx.lib.newevent.NewEvent()
@@ -266,6 +268,9 @@
 
         self.range_start = None
         self.range_mode = 'week'
+        
+        self.phantom_start = None
+        self.phantom_end = None
 
         if time_formatter is None:
             self.time_formatter = default_time_formatter
@@ -329,6 +334,9 @@
         else:
             combined_dc.DrawBitmap(self._background_buffer, 0, 0)
 
+        self.ShadeToday(combined_dc)
+        self.DrawPhantom(combined_dc)
+
         if self.draw_lozenges_from_cache:
             combined_dc.DrawBitmap(self._lozenge_buffer, 0, 0)
         else:
@@ -360,34 +368,34 @@
                         self.DrawLozenge(gc, event, rect, truncate, draw_text)
 
     def DrawDraggedLozenge(self, dc):
-        if self.drag_id:
-            gc = wx.GraphicsContext.Create(dc)
-            drag_time = self.TimeFromPosition(self.drag_position)
-            if self.drag_type == 'resize' and drag_time:
-                real_event = self.events.get(self.drag_id)
-                drag_event = Event(id=None)
-                for slot in drag_event.__slots__:
-                    if slot != 'id':
-                        setattr(drag_event, slot, getattr(real_event, slot))
-                drag_time = self.TimeFromPosition(self.drag_position)
-                if self.drag_edge in (wx.TOP, wx.LEFT):
-                    drag_event.duration = max(timedelta(0), drag_event.end - drag_time)
-                    max_start = real_event.end
-                    if self.drag_edge == wx.LEFT:
-                        max_start -= timedelta(1)
-                    drag_event.start = min(drag_time, max_start)
-                else:
-                    drag_event.duration = max(timedelta(0),
-                                              drag_time - drag_event.start)
-                    if self.drag_edge == wx.RIGHT:
-                        drag_event.duration += timedelta(1)
-                depth, max_depth = self.EventDepth(self.drag_id)
-                for interval in self.intervals:
-                    if drag_event.overlaps(interval):                            
-                        args = drag_event, interval, depth, max_depth
-                        rect, truncate, draw_text = self.LozengeGeometry(*args)
-                        self.DrawLozenge(gc, drag_event, rect, truncate,
-                                         draw_text, dragging=True)
+        if not self.drag_id:
+            return
+        
+        gc = wx.GraphicsContext.Create(dc)
+        real_event = self.events.get(self.drag_id)
+        drag_event = Event(id=None)
+        for slot in drag_event.__slots__:
+            if slot != 'id':
+                setattr(drag_event, slot, getattr(real_event, slot))
+        delta = self.DragEndAdjust()
+        drag_time = (self.TimeFromPosition(self.drag_position)
+                     if self.drag_position else None)
+        if self.drag_edge in (wx.TOP, wx.LEFT):
+            drag_start = drag_time if drag_time else real_event.start
+            drag_event.duration = max(delta, drag_event.end - drag_start)
+            max_start = real_event.end - delta
+            drag_event.start = min(drag_start, max_start)
+        elif self.drag_edge in (wx.BOTTOM, wx.RIGHT):
+            drag_end = drag_time if drag_time else real_event.end
+            duration = drag_end - drag_event.start + delta
+            drag_event.duration = max(delta, duration)
+        depth, max_depth = self.EventDepth(self.drag_id)
+        for interval in self.intervals:
+            if drag_event.overlaps(interval):
+                args = drag_event, interval, depth, max_depth
+                rect, truncate, draw_text = self.LozengeGeometry(*args)
+                self.DrawLozenge(gc, drag_event, rect, truncate,
+                                 draw_text, dragging=self.dragging)
 
     def EventDepth(self, event_id):
         """Return the depth, max_depth tuple for the event's first lozenge."""
@@ -580,7 +588,50 @@
             text_rect = rect
         return (start_rect, rect, end_rect)
 
+    def PhantomDepth(self, dt):
+        return 0
 
+    def DrawPhantom(self, dc):
+        """Highlight a rectangle for a not-yet-created event."""
+        if not self.phantom_start:
+            return
+        start = self.phantom_start
+        end = self.phantom_end
+        if not end:
+            end = self.phantom_start + timedelta(hours=1)
+        gc = wx.GraphicsContext.Create(dc)
+        start, end = min(start, end), max(start, end)
+        end += self.DragEndAdjust()
+        phantom = Event(start=start, duration=end - start)
+        for interval in self.intervals:
+            if phantom.overlaps(interval):
+                start = max(phantom.start, interval.start)
+                end = min(phantom.end, interval.end)
+                rect = self.RectFromTime(start, end,
+                                         self.PhantomDepth(self.phantom_start))
+                self.ShadeRect(gc, rect, PHANTOM_COLOR)
+
+
+    def ShadeToday(self, dc):
+        # don't shade today in day mode
+        if self.range_mode == 'day':
+            return
+
+        # next make sure today is in view
+        today = datetime.combine(datetime.today(), time(0))
+        if today < self.range_start or today >= self.end:
+            return
+        
+        rect = self.RectFromTime(today, today + timedelta(1))
+        gc = wx.GraphicsContext.Create(dc)
+        self.ShadeRect(gc, rect, TODAY_COLOR)
+
+    def ShadeRect(self, gc, rect, color):
+        path = gc.CreatePath()
+        path.AddRectangle(*rect)
+        gc.SetBrush(wx.Brush(color))
+        gc.FillPath(path)
+
     def DrawBackground(self, gc):
         gc.SetPen(wx.Pen(MINOR_LINE_COLOR))
         gc.StrokePath(self.GetHalfHourLinePath(gc))
@@ -706,6 +757,9 @@
         new_local = set(id for id in selected_ids      if id in self.events)
         old_local = set(id for id in self.selected_ids if id in self.events)
         self.selected_ids = selected_ids
+        if selected_ids != [None] or self.phantom_end:
+            self.phantom_start = self.phantom_end = None
+            self.Refresh()
         
         if new_local != old_local:
             selected_events = set(self.events[id] for id in new_local)
@@ -780,7 +834,6 @@
     draggable_edges = wx.TOP, wx.BOTTOM    
 
     def InitDragging(self):
-        self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
         self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
         self.default_cursor = wx.StockCursor(wx.CURSOR_DEFAULT)
         self.top_bottom_cursor = wx.StockCursor(wx.CURSOR_SIZENS)
@@ -800,17 +853,38 @@
     def OnMouse(self, event):
         threshold = 5
         position = wx.Point2D(*self.CalcUnscrolledPosition(event.GetPosition()))
+        
         if event.LeftDown():
             self.click_position = position
+            info = self.TopInfoFromPosition(position)
+            self.phantom_end = None
+            if info:
+                selected_id = info[0].id
+                self.drag_id = selected_id
+                self.phantom_start = None
+            else:
+                selected_id = None
+                self.phantom_start = roundTime(self.TimeFromPosition(position))
+            self.Refresh()
+            wx.PostEvent(self, SelectItemsEvent(selected_ids=[selected_id]))
             print "left down", self.TimeFromPosition(position)
-        elif event.LeftUp() or event.Entering() or event.Leaving():
+            
+        elif event.LeftUp():
+            if self.phantom_start:
+                if self.phantom_end:
+                    self.phantom_end = roundTime(self.phantom_end)
+                else:
+                    self.phantom_end = self.phantom_start + timedelta(hours=1)
             self.ResetDrag()
             self.Refresh()
+        elif event.Entering() or event.Leaving():
+            self.ResetDrag()
+            self.Refresh()
         if event.Dragging():
             if not self.click_position:
                 print "dragging, but nothing to do"
             elif (not self.dragging and
-                  self.click_position.GetDistance(position) < 10):
+                  self.click_position.GetDistance(position) < threshold):
                 print "dragging within threshold"
             elif not self.drag_type:
                 edge = self.DragEdge(self.click_position)
@@ -820,16 +894,19 @@
                     self.drag_id = ev.id
                     self.drag_edge = edge
                     self.dragging = True
-                    self.Refresh()
-
-            if self.drag_type == 'resize':
-                self.drag_position = position
-                self.Refresh(keep_cache=True)
-            
-            else:
-                pass
-                #drag_and_drop.DoDragAndDrop(self, 'phantom_lozenge')
-                #print "done with DragAndDrop"
+                elif self.phantom_start:
+                    self.drag_type = 'phantom'
+                    self.dragging = True
+            else:    
+                if self.drag_type == 'resize':
+                    self.drag_position = position
+                elif self.drag_type == 'phantom':
+                    self.phantom_end = self.TimeFromPosition(position)
+                else:
+                    pass
+                    #drag_and_drop.DoDragAndDrop(self, 'phantom_lozenge')
+                    #print "done with DragAndDrop"
+            self.Refresh(keep_cache=True)
                 
         elif event.Moving():
             self.UpdateCursor(position)
@@ -848,7 +925,13 @@
     def OnDragResize(self, x, y):
         if not self.dragging: return
         
-
+    def DragEndAdjust(self):
+        """
+        Calculated day should be adjusted upwards by a day when dragging all-day
+        lozenges, but not for timed lozenges.
+        """
+        return timedelta(0)
+        
     def TopInfoFromPosition(self, pos):
         """Return (event, depth, max_depth, range, rect) or None."""
         if not self.matrix: return
@@ -873,12 +956,6 @@
                     if rect.Contains(pos):
                         return event, depth, len(cluster.levels), interval, rect
 
-    def OnClick(self, wx_evt):
-        position = wx.Point2D(*self.CalcUnscrolledPosition(wx_evt.Position))
-        info = self.TopInfoFromPosition(position)
-        selected_id = info[0].id if info else None
-        wx.PostEvent(self, SelectItemsEvent(selected_ids=[selected_id]))
-
     def DragEdge(self, pos):
         """Return the edge for the position's associated lozenge, or 0."""
         m = 5 # margin within the rectangle to consider near enough to edge
@@ -969,7 +1046,22 @@
         truncate = 0 if real_start >= lozenge_start else wx.LEFT
         return truncate | (0 if real_end <= lozenge_end else wx.RIGHT)
 
+    def DragEndAdjust(self):
+        """
+        Calculated day should be adjusted upwards by a day when dragging all-day
+        lozenges, but not for timed lozenges.
+        """
+        return timedelta(1)
 
+    def PhantomDepth(self, dt):
+        """Draw all-day phantoms below all existing events."""
+        event = Event(start = dt, duration = timedelta(1))
+        interval = self.intervals[0]
+        for cluster in interval.clusters:
+            if event.overlaps(cluster):
+                return len([e for e in cluster.event_list if event.overlaps(e)])
+        return 0
+
 class CalendarPanel(wx.Panel):
     def __init__(self, parent, **kw):
         super(CalendarPanel, self).__init__(parent, -1, style=wx.NO_BORDER, **kw)




_______________________________________________
Commits mailing list
[email protected]
http://lists.osafoundation.org/mailman/listinfo/commits

Reply via email to