- Revision
- 11418
- Author
- jeffrey
- Date
- 2006-08-14 18:38:28 -0700 (Mon, 14 Aug 2006)
Log Message
- Add collection swatches to calendar lozenges, bug 6233
Modified Paths
- trunk/chandler/application/styles.conf
- trunk/chandler/parcels/osaf/framework/blocks/DrawingUtilities.py
- trunk/chandler/parcels/osaf/framework/blocks/calendar/AllDayCanvas.py
- trunk/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py
- trunk/chandler/parcels/osaf/framework/blocks/calendar/TimedCanvas.py
Diff
Modified: trunk/chandler/application/styles.conf (11417 => 11418)
--- trunk/chandler/application/styles.conf 2006-08-14 23:27:16 UTC (rev 11417) +++ trunk/chandler/application/styles.conf 2006-08-15 01:38:28 UTC (rev 11418) @@ -106,7 +106,7 @@ OverlayFYIGradientLeftSaturation = 0.1 OverlayFYIGradientLeftValue = 1.0 -OverlayFYIGradientRightSaturation = 0.05 +OverlayFYIGradientRightSaturation = 0.1 OverlayFYIGradientRightValue = 1.0 OverlayFYIOutlineSaturation = 0.3 @@ -115,6 +115,21 @@ OverlayFYITextSaturation = 1.0 OverlayFYITextValue = 0.8 +#### Default swatch colors + +SelectedSwatchOutlineSaturation = 0.0 +SelectedSwatchOutlineValue = 1.0 + +SelectedFYISwatchOutlineSaturation = 0.0 +SelectedFYISwatchOutlineValue = 1.0 + +OverlaySwatchOutlineSaturation = 0.0 +OverlaySwatchOutlineValue = 1.0 + +OverlayFYISwatchOutlineSaturation = 0.0 +OverlayFYISwatchOutlineValue = 1.0 + + ######## Color-specific lozenge colors ########## # To override gradients/text/outline colors for a particular color, # add an entry whose key is Color + Type where type matches one of the
Modified: trunk/chandler/parcels/osaf/framework/blocks/DrawingUtilities.py (11417 => 11418)
--- trunk/chandler/parcels/osaf/framework/blocks/DrawingUtilities.py 2006-08-14 23:27:16 UTC (rev 11417) +++ trunk/chandler/parcels/osaf/framework/blocks/DrawingUtilities.py 2006-08-15 01:38:28 UTC (rev 11418) @@ -313,6 +313,8 @@ """ assert orientation in ("Horizontal", "Vertical") key = (offset, width, leftColor, rightColor, orientation) + if leftColor == rightColor: + return wx.TheBrushList.FindOrCreateBrush(leftColor, wx.SOLID) brush = self._gradientCache.get(key, None) if brush is None: self.misses += 1
Modified: trunk/chandler/parcels/osaf/framework/blocks/calendar/AllDayCanvas.py (11417 => 11418)
--- trunk/chandler/parcels/osaf/framework/blocks/calendar/AllDayCanvas.py 2006-08-14 23:27:16 UTC (rev 11417) +++ trunk/chandler/parcels/osaf/framework/blocks/calendar/AllDayCanvas.py 2006-08-15 01:38:28 UTC (rev 11418) @@ -571,6 +571,7 @@ class AllDayCanvasItem(CalendarCanvasItem): resizeBufferSize = 5 textMargin = 2 + swatchAdjust = 3 def GetBoundsRects(self): return [self._bounds]
Modified: trunk/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py (11417 => 11418)
--- trunk/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py 2006-08-14 23:27:16 UTC (rev 11417) +++ trunk/chandler/parcels/osaf/framework/blocks/calendar/CalendarCanvas.py 2006-08-15 01:38:28 UTC (rev 11418) @@ -38,7 +38,8 @@ DragAndDrop, Block, SplitterWindow, Styles, BoxContainer, BlockEvent ) from osaf.framework.attributeEditors import AttributeEditors -from osaf.framework.blocks.DrawingUtilities import DrawWrappedText, Gradients, color2rgb, rgb2color +from osaf.framework.blocks.DrawingUtilities import (DrawWrappedText, Gradients, + color2rgb, rgb2color, vector) from osaf.framework.blocks.calendar import CollectionCanvas from osaf.framework import Preferences @@ -68,7 +69,14 @@ ENABLE_DEVICE_ORIGIN = False RADIUS = 8 +SWATCH_HEIGHT = 5 # not counting border +SWATCH_WIDTH = 3 # not counting border +SWATCH_BORDER = 1 +SWATCH_SEPARATION = 2 +SWATCH_WIDTH_VECTOR = vector([SWATCH_WIDTH + 2*SWATCH_BORDER, 0]) +SWATCH_HEIGHT_VECTOR = vector([0, SWATCH_HEIGHT + 2*SWATCH_BORDER]) + # add some space below the time (but on linux there isn't any room) if '__WXGTK__' in wx.PlatformInfo: TIME_BOTTOM_MARGIN = 0 @@ -129,14 +137,32 @@ # hue -> colorName mapping hueMap = dict((int(v), k) for k, v in confstyles.cfg.items('colors')) +suffixes = 'GradientLeft', 'GradientRight', 'Outline', 'Text' +def colorValWithDefault(hue, name): + hueName = hueMap.get(int(hue*360)) + if hueName is not None: + val = confstyles.cfg.get('calendarcanvas', hueName + name) + if val is not None: + return float(val) + return confstyles.cfg.getfloat('calendarcanvas', name) + + +def getLozengeTypeColor(hue, lozengeType): + return rgb2color(*hsv_to_rgb(hue, + colorValWithDefault(hue, lozengeType + 'Saturation'), + colorValWithDefault(hue, lozengeType + 'Value')) + ) + +def getHueForCollection(collection): + color = UserCollection(collection).ensureColor().color + return rgb_to_hsv(*color2rgb(color.red,color.green,color.blue))[0] + class ColorInfo(object): def __init__(self, collection): # sometimes this happens when getContainingCollection fails to find a collection assert collection is not None, "Can't get color for None" - - color = UserCollection(collection).ensureColor().color - self.hue = rgb_to_hsv(*color2rgb(color.red,color.green,color.blue))[0] + self.hue = getHueForCollection(collection) def getColorsProperty(prefix): """ @@ -144,23 +170,10 @@ four RGB colors. """ - suffixes = 'GradientLeft', 'GradientRight', 'Outline', 'Text' names = [prefix + suffix for suffix in suffixes] - - def valWithDefault(hue, name): - hueName = hueMap.get(int(hue*360)) - if hueName is not None: - val = confstyles.cfg.get('calendarcanvas', hueName + name) - if val is not None: - return float(val) - return confstyles.cfg.getfloat('calendarcanvas', name) def getSaturatedColors(self): - satsAndValues = ((valWithDefault(self.hue, name + 'Saturation'), - valWithDefault(self.hue, name + 'Value')) - for name in names) - return [rgb2color(*hsv_to_rgb(self.hue, saturation, value)) for - saturation, value in satsAndValues] + return [getLozengeTypeColor(self.hue, name) for name in names] return property(getSaturatedColors) @@ -278,6 +291,9 @@ self.timeString = formatTime(self.item.startTime) self.colorInfo = ColorInfo(collection) + + self.collection = collection + self.primaryCollection = primaryCollection self.isActive = primaryCollection is collection @@ -332,7 +348,7 @@ return self.colorInfo.visibleColors - def GetAnyTimeOrAllDay(self): + def GetAnyTimeOrAllDay(self): item = self.item anyTime = getattr(item, 'anyTime', False) allDay = getattr(item, 'allDay', False) @@ -393,7 +409,8 @@ if (item.isDeleted() or not item.itsKind.isKindOf(CalendarEventKind)): return - isAnyTimeOrAllDay = self.GetAnyTimeOrAllDay() + isAnyTimeOrAllDay = self.GetAnyTimeOrAllDay() + allCollection = schema.ns('osaf.pim', item.itsView).allCollection # Draw one event - an event consists of one or more bounds clipRect = None @@ -405,7 +422,6 @@ self.getEventColors(selected) dc.SetTextForeground(textColor) - for rectIndex, itemRect in enumerate(self.GetBoundsRects()): if not itemRect.IsEmpty(): @@ -471,6 +487,8 @@ width = itemRect.width - self.textOffset.x - (self.textMargin) + multipleLinesDrawn = False + # only draw date/time on first item if drawEventText: # only draw time on timed events @@ -493,6 +511,7 @@ styles.eventTimeMeasurements) y += self.timeHeight + TIME_BOTTOM_MARGIN + multipleLinesDrawn = True # we may have lost some room in the rectangle from # drawing the time @@ -501,13 +520,67 @@ # for some reason text measurement on the mac is off, # and text tends to look smooshed to the edge, so we # give it a 5 pixel buffer there + + rightMargin = 0 + + # other collection swatches should be drawn if the item is + # in at least one other collection (not counting the + # dashboard). + numCollections = len(item.appearsIn) + if numCollections > 2 or (numCollections == 2 and + item not in allCollection): + + margin = max(RADIUS/2, self.textMargin) + yMargin = vector([0, margin]) + + bottomRight = vector( + [itemRect.x + itemRect.width - margin, + itemRect.y + itemRect.height - margin]) + topRight = vector([itemRect.x + itemRect.width - margin, + itemRect.y + lostHeight + margin]) + + if multipleLinesDrawn: + # when the time was drawn, add yMargin back in, + # because lostHeight includes ample margin + topLeft = topRight - SWATCH_WIDTH_VECTOR - yMargin + self.DrawCollectionSwatches(dc, topLeft, + bottomRight, True) + rightMargin += (margin + SWATCH_WIDTH + + 2 * SWATCH_BORDER) + else: + textWidth = dc.GetFullTextExtent(item.displayName, + styles.eventLabelFont)[0] + + + SWATCH_WIDTH + + 2*SWATCH_BORDER) + doubleWidth = (margin + 2 * oneWidth - + SWATCH_SEPARATION) + + # position lozenges in the middle of the + + if textWidth > width - rightMargin - doubleWidth: + left = topRight[0] - doubleWidth + else: + left = x + textWidth + + right = topRight[0] + top = itemRect.y + RADIUS - self.swatchAdjust + bottom = top + SWATCH_HEIGHT + 2 * SWATCH_BORDER + + count = self.DrawCollectionSwatches(dc, + vector([left, top]), + vector([right, bottom]), + vertical=False) + + rightMargin += (margin + count * oneWidth - + SWATCH_SEPARATION) + + if ('__WXMAC__' in wx.PlatformInfo): - margin = 5 - else: - margin = 0 - + rightMargin += 5 + # now draw the text of the event - textRect = (x,y,width - margin, + textRect = (x,y,width - rightMargin, itemRect.height - lostHeight - self.textOffset.y) dc.SetFont(styles.eventLabelFont) @@ -517,10 +590,57 @@ DrawWrappedText(dc, drawingItem.displayName, textRect, styles.eventLabelMeasurements) - dc.DestroyClippingRegion() - if clipRect: + dc.DestroyClippingRegion() + if clipRect: dc.SetClippingRegion(*clipRect) - + + def DrawCollectionSwatches(self, dc, topLeft, bottomRight, vertical=True): + """ + topLeft and bottomRight must be vectors (lists which can be added and + subtracted like vectors) + """ + app_ns = schema.ns('osaf.app', self.item.itsView) + sidebarCollections = app_ns.sidebarCollection + allCollection = schema.ns('osaf.pim', self.item.itsView).allCollection + if self.isActive: + fillColorLozengeType = 'SelectedGradientLeft' + outlinePre1 = 'Selected' + else: + fillColorLozengeType = 'SelectedFYIGradientLeft' + outlinePre1 = 'Overlay' + if self.invertColors(): + outlinePre2 = 'FYISwatchOutline' + else: + outlinePre2 = 'SwatchOutline' + + hue = getHueForCollection(self.collection) + outlineColor = getLozengeTypeColor(hue, outlinePre1 + outlinePre2) + dc.SetPen(wx.Pen(outlineColor, SWATCH_BORDER)) + + if vertical: + delta = SWATCH_HEIGHT_VECTOR + vector([0, SWATCH_SEPARATION]) + else: + delta = SWATCH_WIDTH_VECTOR + vector([SWATCH_SEPARATION, 0]) + + count = 0 + for coll in reversed([i for i in sidebarCollections if + self.item in i and i not in + (self.collection, allCollection)]): + swatchBR = bottomRight - count * delta + swatchTL = swatchBR - SWATCH_HEIGHT_VECTOR - SWATCH_WIDTH_VECTOR + + if swatchTL[0] < topLeft[0] or swatchTL[1] < topLeft[1]: + break + else: + hue = getHueForCollection(coll) + fillColor = getLozengeTypeColor(hue, fillColorLozengeType) + brush = wx.TheBrushList.FindOrCreateBrush(fillColor, wx.SOLID) + dc.SetBrush(brush) + + dc.DrawRectangle(*swatchTL.join(swatchBR - swatchTL)) + count += 1 + return count + def DrawEventRectangle(self, dc, rect, brush, hasLeftRounded=False, hasTopRightRounded=True,
Modified: trunk/chandler/parcels/osaf/framework/blocks/calendar/TimedCanvas.py (11417 => 11418)
--- trunk/chandler/parcels/osaf/framework/blocks/calendar/TimedCanvas.py 2006-08-14 23:27:16 UTC (rev 11417) +++ trunk/chandler/parcels/osaf/framework/blocks/calendar/TimedCanvas.py 2006-08-15 01:38:28 UTC (rev 11418) @@ -1012,6 +1012,7 @@ class TimedCanvasItem(CalendarCanvasItem): resizeBufferSize = 5 textMargin = 2 + swatchAdjust = 2 RESIZE_MODE_START = 1 RESIZE_MODE_END = 2
_______________________________________________ Commits mailing list [email protected] http://lists.osafoundation.org/mailman/listinfo/commits
