- 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
- 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
