Title: [commits] (jeffrey) [15938] [APP] Fix calendar drawing on the Mac.
Revision
15938
Author
jeffrey
Date
2007-11-28 13:31:21 -0800 (Wed, 28 Nov 2007)

Log Message

[APP] Fix calendar drawing on the Mac. The Mac's default matrix
flips the Y axis, so when creating matrices to transform rects
explicitly set their initial state to the identity matrix.

Modified Paths

Diff

Modified: branches/rearchitecture/Chandler-Platform/ocap/wxui/calendar.py (15937 => 15938)

--- branches/rearchitecture/Chandler-Platform/ocap/wxui/calendar.py	2007-11-28 21:30:52 UTC (rev 15937)
+++ branches/rearchitecture/Chandler-Platform/ocap/wxui/calendar.py	2007-11-28 21:31:21 UTC (rev 15938)
@@ -69,7 +69,13 @@
     gradient_left = wx.Color(0, 63, 127),
     gradient_right = wx.Color(0, 102, 204),
 )
-    
+
+if wx.Platform == '__WXMSW__':
+    DEFAULT_FONT_SIZE = 8
+else:
+    DEFAULT_FONT_SIZE = 9
+
+
 class Event(InitializeSlots):
     __slots__ = ('id', 'title', 'start', 'duration', 'color', 'swatch_colors')
     def __cmp__(self, other):
@@ -109,9 +115,9 @@
             self.start = event.start
         if self.end is None or event.end > self.end:
             self.end = event.end
-        
+
         bisect.insort(self.event_list, event)
-        
+
         for level in self.levels:
             for level_event in level:
                 if event.overlaps(level_event):
@@ -172,7 +178,7 @@
 class Calendar(wx.ScrolledWindow):
     def __init__(self, time_formatter=None, *arguments, **keywords):
         super(Calendar, self).__init__ (*arguments, **keywords)
-        
+
         self.Bind(wx.EVT_PAINT, self.OnPaint)
         self.Bind(wx.EVT_SIZE,  self.OnSize)
         self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
@@ -183,43 +189,42 @@
         self.matrix = None
         self.hour_height = BASE_HOUR_HEIGHT
         self.margin_right = wx.SystemSettings_GetMetric(wx.SYS_VSCROLL_X)
-                
+
         self.business_start = 9
         self.business_end   = 17
         # CreateMeasuringContext has the wrong SWIG directive applied as of 11/2007,
         # so this won't work
         #measure = wx.GraphicsContext.CreateMeasuringContext()
         measure = wx.GraphicsContext.Create(self)
-        
-        self.legend_font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
+
+        self.legend_font = wx.Font(DEFAULT_FONT_SIZE, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
         self.legend_font_height = font_height(measure, self.legend_font)
         self.legend_strings = [str(i) for i in range(1,13)] * 2
 
-        self.time_font = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
+        self.time_font = wx.Font(DEFAULT_FONT_SIZE, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
         self.time_font_height = font_height(measure, self.time_font)
-        
+
         self.title_font = self.legend_font
         self.title_font_height = font_height(measure, self.title_font)
 
         self.range_start = None
         self.range_mode = 'week'
-        
+
         if time_formatter is None:
             self.time_formatter = default_time_formatter
         else:
             self.time_formatter = time_formatter
-        
+
         # caching
         self.draw_from_cache = False
         self._buffer = None
 
-
     def Refresh(self, *args):
         """
         Set a flag so we know if the paint event is happening because of a
         programatic call to Refresh, or if it is a 'natural' refresh due to
         things like scrolling or the window being damaged by another window. 
-        
+
         """
         self.draw_from_cache = False
         super(Calendar, self).Refresh(*args)
@@ -265,13 +270,15 @@
         gc = wx.GraphicsContext.Create(dc)
 
         width, height = self.GetSize()
-        gc.PushState()
-        gc.Translate(MARGIN_LEFT, 0)
-        gc.Scale((width - MARGIN_LEFT - self.margin_right)/BASE_WIDTH,
-                 self.hour_height/BASE_HOUR_HEIGHT)
+
         self.matrix = gc.GetTransform()
-        gc.PopState()
-        
+        # create a matrix to transform rectangles with. The Mac default transform is a y-flip,
+        # so explicitly set the initial matrix
+        self.matrix.Set(1,0,0,1,0,0)
+        self.matrix.Translate(MARGIN_LEFT, 0)
+        self.matrix.Scale((width - MARGIN_LEFT - self.margin_right)/BASE_WIDTH,
+                          self.hour_height/BASE_HOUR_HEIGHT)
+
         self.DrawBackground(gc)
 
         for day in self.days:
@@ -299,15 +306,15 @@
             else:
                 rect.Inset(depth/(max_depth - 1)*BASE_DAY_WIDTH*0.2, 0, 0, 0)
                 rect.width = BASE_DAY_WIDTH * 0.8
-
+        
         rect = TransformRect(self.matrix, rect)
         rect.Inset(HALO_WIDTH, HALO_WIDTH)
 
         line_height = self.title_font_height
         min_height = 2*TEXT_Y_MARGIN + line_height
         if rect.height < min_height:
-            rect.SetBottom(min(self.hour_height * 24, rect.y + min_height))
-            
+            rect.SetBottom(min(self.hour_height * 24 - 1, rect.y + min_height))
+    
         if column == 0 and depth == 0:
             # don't let the halo overlap the legend border by too much
             rect.Inset(.5, 0, 0, 0)
@@ -317,19 +324,18 @@
             truncate |= wx.TOP
         if event.end > end:
             truncate |= wx.BOTTOM
-        
+
         if event.start < start:
             # continuation lozenge, just draw a small-radius lozenge
             DrawFilledLozenge(gc, rect, SMALL_RADIUS, truncate = truncate)
-        
+
         # draw one line?  Draw time?  Draw title on first line?
         # Room for how many swatches (min 2)?
-        
+
         if event.start >= start:
             radius = SMALL_RADIUS if rect.height != min_height else min_height/2
-            print radius, event.id
             DrawFilledLozenge(gc, rect, radius, truncate = truncate)
-            
+
             time_height = (TEXT_Y_MARGIN + TIME_BOTTOM_MARGIN +
                            self.time_font_height)
 
@@ -352,20 +358,19 @@
                 gc.SetFont(self.title_font, DefaultColors.text)
                 # need to wrap text
                 DrawWrappedText(gc, event.title, rect)
-                
+
             gc.ResetClip()
 
-
     def DrawBackground(self, gc):
         gc.SetPen(wx.Pen(MINOR_LINE_COLOR))
         path = self.GetDayLinePath(gc)
         path.AddPath(self.GetHalfHourLinePath(gc))
         gc.StrokePath(path)
-        
+
         gc.SetPen(wx.Pen(MAJOR_LINE_COLOR))
         path = (self.GetHourLinePath(gc))
         gc.StrokePath(path)
-        
+
         self.DrawLegend(gc)
 
     def GetDayLinePath(self, gc):
@@ -400,7 +405,7 @@
         """
         Draw legend hours for a timed canvas.  Draw a thick line separating the
         legend from the calendar, with business hours shaded differently.
-        
+
         """
         light_pen = wx.Pen(MAJOR_LINE_COLOR, LEGEND_BORDER_WIDTH)
         dark_pen  = wx.Pen(LEGEND_COLOR,     LEGEND_BORDER_WIDTH)
@@ -413,15 +418,16 @@
         # a pixel
         light_pen.SetCap(wx.CAP_PROJECTING)
         dark_pen.SetCap( wx.CAP_PROJECTING)
-        
+
         # adjust matrix for the extra right hand side of the pen
         matrix = gc.GetTransform()
+        matrix.Set(1,0,0,1,0,0)
         matrix.Translate( (1 - LEGEND_BORDER_WIDTH) / 2, 0)
         matrix.Concat(self.matrix)
-        
+
         main_line_start = matrix.TransformPoint(0, 1)
         main_line_end   = matrix.TransformPoint(0, BOTTOM_EDGE - 1)
-        
+
         business_line_start = 0, self.business_start*BASE_HOUR_HEIGHT + 1
         business_line_start = matrix.TransformPoint(*business_line_start)
 
@@ -437,7 +443,7 @@
         # draw the legend text
         gc.SetFont(self.legend_font, LEGEND_COLOR)
         x, real_hour_height = matrix.TransformPoint(0, BASE_HOUR_HEIGHT)
-        
+
         for hour, text in enumerate(self.legend_strings[:-1]):
             hour += 1
             width, height = gc.GetTextExtent(text)
@@ -470,19 +476,19 @@
         self.range_mode = range_mode
         if self.range_start is not None:
             self.SetRange(self, self.range_start)
-        
+
     def ChangeEvent(self, id, **kw):
         """
         Create an event for id or adjust an existing one, adjust ordering of
         lozenge clusters the event appears in.
-        
+
         """
         if not self.events.has_key(id):
             self.events[id] = Event(id=id)
         event = self.events[id]
         for key, value in kw.iteritems():
             setattr(event, key, value)
-        
+
         for day in self.days:
             if event.overlaps(day):
                 day.change(event)
@@ -490,7 +496,7 @@
             elif event in day.event_list:
                 day.remove(event)
                 self.Refresh(False)
-    
+
     def RemoveEvent(self, id):
         """Remove an event from the events displayed."""
         pass
@@ -517,7 +523,7 @@
 def GetLozengePath(gc, rect, truncate, radius):
     """
     Return a rounded rectangle path with certain edges truncated (not rounded).
-    
+
     truncate should be a bitfield of any combination of wx.RIGHT, wx.TOP,
     wx.LEFT, and wx.BOTTOM.
     
@@ -527,15 +533,15 @@
     if not truncate:
         path.AddRoundedRectangle(x, y, width, height, radius)
         return path
-        
+
     corners = wx.Rect2D(*rect)
     adjust = wx.Point2D(0, radius)
-    
+
     start = corners.GetRightTop()
     if not (truncate & (wx.RIGHT | wx.TOP)):
         start += adjust
     path.MoveToPoint(start)
-        
+
     edge_vectors = {wx.LEFT  | wx.TOP    : corners.GetLeftTop(),
                     wx.RIGHT | wx.TOP    : corners.GetRightTop(),
                     wx.LEFT  | wx.BOTTOM : corners.GetLeftBottom(),
@@ -556,7 +562,7 @@
             adjust.SetPolarCoordinates(90*(i - 2), radius)
             point += adjust
             path.AddArc(point, radius, radians(i*90), radians((i + 1)*90))
-        
+
     return path
 
 def TransformRect(matrix, rect):




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

Reply via email to