[Commits] (alecf) fix bug 2885 - finally get cross-platform
gradients working - windows, linux and even mac..!
commits at osafoundation.org
commits at osafoundation.org
Fri Apr 29 18:44:10 PDT 2005
Commit by: alecf
Modified files:
chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py 1.87 1.88
Log message:
fix bug 2885 - finally get cross-platform gradients working - windows, linux and even mac..!
- use power-of-two sized pixmaps
- stop messing with device origins
- correctly shade these odd-sized pixmaps by hashing them by both offset and width, so that each pixmap is location-specific
- fix shading on day view and on all-day items
Bugzilla links:
http://bugzilla.osafoundation.org/show_bug.cgi?id=2885
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py.diff?r1=text&tr1=1.87&r2=text&tr2=1.88
Index: chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py
diff -u chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.87 chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.88
--- chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py:1.87 Thu Apr 28 13:20:27 2005
+++ chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py Fri Apr 29 18:44:08 2005
@@ -1,8 +1,8 @@
""" Canvas for calendaring blocks
"""
-__version__ = "$Revision: 1.87 $"
-__date__ = "$Date: 2005/04/28 20:20:27 $"
+__version__ = "$Revision: 1.88 $"
+__date__ = "$Date: 2005/04/30 01:44:08 $"
__copyright__ = "Copyright (c) 2004 Open Source Applications Foundation"
__license__ = "http://osafoundation.org/Chandler_0.1_license_terms.htm"
@@ -152,11 +152,10 @@
def GetMaxEditorSize(self):
return self._bounds.GetSize()
- def GetStatusPen(self, styles):
+ def GetStatusPen(self, color):
# probably should use styles to determine a good pen color
item = self.GetItem()
- eventColors = styles.blockItem.getEventColors(item)
- color = eventColors.outlineColor
+
if (item.transparency == "confirmed"):
pen = wx.Pen(color, 4)
elif (item.transparency == "fyi"):
@@ -392,7 +391,7 @@
return wx.Rect(startPosition.x, startPosition.y, cellWidth, cellHeight)
- def Draw(self, dc, boundingRect, styles, bitmapBrush):
+ def Draw(self, dc, boundingRect, styles, selected):
item = self._item
time = item.startTime
@@ -404,22 +403,27 @@
(cx,cy,cwidth,cheight) = dc.GetClippingBox()
if not cwidth == cheight == 0:
clipRect = wx.Rect(x,y,width,height)
-
- # save the current pen, we'll need it
- drawingPen = dc.GetPen()
- origin = dc.GetDeviceOrigin()
- newOrigin = copy.copy(origin)
+
+ eventColors = styles.blockItem.getEventColors(item)
+ if selected:
+ penColor = eventColors.selectedOutlineColor
+ gradientLeft = eventColors.selectedGradientLeft
+ gradientRight = eventColors.selectedGradientRight
+ textColor = eventColors.selectedTextColor
+ else:
+ penColor = eventColors.outlineColor
+ gradientLeft = eventColors.gradientLeft
+ gradientRight = eventColors.gradientRight
+ textColor = eventColors.textColor
+
+ dc.SetTextForeground(textColor)
for rectIndex, itemRect in enumerate(self._boundsRects):
- newOrigin.x += itemRect.x
- dc.SetDeviceOriginPoint(newOrigin)
- itemRect = copy.copy(itemRect)
- itemRect.x = 0
- brush = wx.Brush(wx.WHITE,wx.STIPPLE)
- brush.SetStipple(bitmapBrush)
+ brush = styles.GetGradientBrush(itemRect.x, itemRect.width,
+ gradientLeft, gradientRight)
+ dc.SetPen(wx.Pen(penColor))
dc.SetBrush(brush)
- dc.SetPen(drawingPen)
# properly round the corners - first and last
# boundsRect gets some rounding, and they
@@ -434,7 +438,7 @@
self.DrawDRectangle(dc, itemRect, hasTopRightRounded, hasBottomRightRounded)
- pen = self.GetStatusPen(styles)
+ pen = self.GetStatusPen(penColor)
cornerRadius = 0
pen.SetCap(wx.CAP_BUTT)
@@ -471,7 +475,6 @@
dc.DestroyClippingRegion()
if clipRect:
dc.SetClippingRect(clipRect)
- dc.SetDeviceOriginPoint(origin)
def DrawDRectangle(self, dc, rect, hasTopRightRounded=True, hasBottomRightRounded=True):
"""
@@ -511,14 +514,27 @@
dc.DrawLine(rect.x, rect.y, rect.x, rect.y + rect.height)
class HeaderCanvasItem(CalendarCanvasItem):
- def Draw(self, dc, styles):
+ def Draw(self, dc, styles, selected):
item = self._item
itemRect = self._bounds
+ eventColors = styles.blockItem.getEventColors(item)
+ if selected:
+ brush = styles.GetGradientBrush(itemRect.x, itemRect.width,
+ eventColors.selectedGradientLeft,
+ eventColors.selectedGradientRight)
+ pen = wx.Pen(eventColors.selectedOutlineColor)
+ else:
+ brush = wx.TRANSPARENT_BRUSH
+ pen = wx.TRANSPARENT_PEN
+
+ dc.SetTextForeground(eventColors.textColor)
+ dc.SetPen(pen)
+ dc.SetBrush(brush)
dc.DrawRectangleRect(itemRect)
# draw little rectangle to the left of the item
- pen = self.GetStatusPen(styles)
+ pen = self.GetStatusPen(eventColors.outlineColor)
pen.SetCap(wx.CAP_BUTT)
dc.SetPen(pen)
@@ -915,7 +931,7 @@
# just cause a repaint - hopefully this cascades to child windows?
self.Refresh()
- def MakeGradientBitmap(self, width, leftColor, rightColor):
+ def MakeGradientBrush(self, offset, width, leftColor, rightColor):
"""
Creates a gradient brush from leftColor to rightColor, specified
as color tuples (r,g,b)
@@ -949,26 +965,42 @@
# assign a sliding scale of floating point values from left to right
# in the bitmap
- bits = ""
+ offset %= bitmapWidth
for x in xrange(bitmapWidth):
- pixel = x % width
- sat = satStart + satStep*pixel
+
+ # first offset the gradient within the bitmap
+ # gradientIndex is the index of the color, i.e. the nth
+ # color between leftColor and rightColor
+
+ # First offset within the bitmap. The + bitmapWidth % bitmapWidth
+ # ensures we're dealing with x<offset correctly
+ gradientIndex = (x - offset + bitmapWidth) % bitmapWidth
+
+ # now offset within the gradient range
+ gradientIndex %= width
+
+ # now calculate the actual color from the gradient index
+ sat = satStart + satStep*gradientIndex
newColor = rgb2color(*hsv_to_rgb(hue, sat, value))
image.SetRGB(x,0,*newColor)
+
# and now we have to go from Image -> Bitmap. Yuck.
- return wx.BitmapFromImage(image)
+ bitmap = wx.BitmapFromImage(image)
+ brush = wx.Brush(wx.WHITE, wx.STIPPLE)
+ brush.SetStipple(bitmap)
+ return brush
- def GetGradientBitmap(self, width, leftColor, rightColor):
+ def GetGradientBrush(self, offset, width, leftColor, rightColor):
"""
Gets an appropriately sized gradient brush from the cache,
or creates one if necessary
"""
- key = (width, leftColor, rightColor)
- bitmap = self._gradientCache.get(key, None)
- if not bitmap:
- bitmap = self.MakeGradientBitmap(*key)
- self._gradientCache[key] = bitmap
- return bitmap
+ key = (offset, width, leftColor, rightColor)
+ brush = self._gradientCache.get(key, None)
+ if not brush:
+ brush = self.MakeGradientBrush(*key)
+ self._gradientCache[key] = brush
+ return brush
class wxWeekHeaderWidgets(wx.Panel):
@@ -1201,38 +1233,20 @@
styles = self.parent
- #dc.SetTextForeground(styles.eventLabelColor)
dc.SetFont(styles.eventLabelFont)
- dc.SetPen(wx.TRANSPARENT_PEN)
- dc.SetBrush(wx.WHITE_BRUSH)
selectedBox = None
for canvasItem in self.canvasItemList:
- dc.SetPen(wx.TRANSPARENT_PEN)
# save the selected box to be drawn last
item = canvasItem.GetItem()
if self.parent.blockItem.selection is item:
selectedBox = canvasItem
else:
- eventColors = styles.blockItem.getEventColors(item)
- #dc.SetPen(wx.Pen(eventColors.outlineColor))
- #dc.SetBrush(wx.Brush(eventColors.gradientLeft))
- dc.SetTextForeground(eventColors.textColor)
- canvasItem.Draw(dc, styles)
+ canvasItem.Draw(dc, styles, False)
if selectedBox:
- eventColors = styles.blockItem.getEventColors(selectedBox.GetItem())
- dc.SetPen(wx.Pen(eventColors.selectedOutlineColor))
- bitmap = styles.GetGradientBitmap(self.parent.dayWidth,
- eventColors.selectedGradientLeft,
- eventColors.selectedGradientRight)
- brush = wx.Brush(wx.WHITE,wx.STIPPLE)
- brush.SetStipple(bitmap)
- dc.SetBrush(brush)
- dc.SetTextForeground(eventColors.selectedTextColor)
-
- selectedBox.Draw(dc, styles)
+ selectedBox.Draw(dc, styles, True)
# Draw a line across the bottom of the header
dc.SetPen(styles.majorLinePen)
@@ -1561,23 +1575,11 @@
if self.parent.blockItem.selection is item:
selectedBox = canvasItem
else:
- eventColors = styles.blockItem.getEventColors(item)
- dc.SetPen(wx.Pen(eventColors.outlineColor))
- bitmap = styles.GetGradientBitmap(self.dayWidth, eventColors.gradientLeft,
- eventColors.gradientRight)
- dc.SetTextForeground(eventColors.textColor)
-
- canvasItem.Draw(dc, boundingRect, styles, bitmap)
+ canvasItem.Draw(dc, boundingRect, styles, False)
# now draw the current item on top of everything else
if selectedBox:
- item = selectedBox.GetItem()
- eventColors = styles.blockItem.getEventColors(item)
- dc.SetPen(wx.Pen(eventColors.selectedOutlineColor))
- bitmap = styles.GetGradientBitmap(self.dayWidth, eventColors.selectedGradientLeft,
- eventColors.selectedGradientRight)
- dc.SetTextForeground(eventColors.selectedTextColor)
- selectedBox.Draw(dc, boundingRect, styles, bitmap)
+ selectedBox.Draw(dc, boundingRect, styles, True)
def CheckConflicts(self):
for itemIndex, canvasItem in enumerate(self.canvasItemList):
More information about the Commits
mailing list