diff --git a/demo/agw/HyperTreeList.py b/demo/agw/HyperTreeList.py index 7135a4a2..4692876b 100644 --- a/demo/agw/HyperTreeList.py +++ b/demo/agw/HyperTreeList.py @@ -1046,6 +1046,9 @@ class HyperTreeListDemo(wx.Frame): panel.SetSizer(sizer) sizer.Layout() + self.columnBackgroundColours = [wx.LIGHT_GREY for i in range(self.tree.GetColumnCount())] + + self.leftpanel = wx.ScrolledWindow(splitter, -1, style=wx.SUNKEN_BORDER) self.PopulateLeftPanel(self.tree.styles, self.tree.events) @@ -1161,6 +1164,19 @@ class HyperTreeListDemo(wx.Frame): flexgridcolumn.Add(label, 0, wx.ALIGN_CENTER_VERTICAL) flexgridcolumn.Add(self.columncolour, 0) + label = wx.StaticText(self.leftpanel, -1, "Column Background Colour") + label.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "")) + self.columnchoice = wx.Choice(self.leftpanel, -1, choices = ["1","2","3"]) + self.columnchoice.SetSelection(0) + self.columnchoice.Bind(wx.EVT_CHOICE, self.OnColumnChoiceChanged) + self.columnbackgroundcolour = csel.ColourSelect(self.leftpanel, -1, "Choose...", wx.LIGHT_GREY) + self.columnbackgroundcolour.Bind(csel.EVT_COLOURSELECT, self.OnColumnBackgroundColour) + flexgridcolumn.Add(label, 0, wx.ALIGN_CENTER_VERTICAL) + hSizer = wx.BoxSizer(wx.HORIZONTAL) + hSizer.Add(self.columnchoice, 0, wx.RIGHT, 5) + hSizer.Add(self.columnbackgroundcolour) + flexgridcolumn.Add(hSizer) + label = wx.StaticText(self.leftpanel, -1, "Alignment") label.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, "")) alignment = wx.Choice(self.leftpanel, -1, choices=["wx.LEFT", "wx.CENTER", "wx.RIGHT"]) @@ -1359,6 +1375,10 @@ class HyperTreeListDemo(wx.Frame): panelsizer.Add(self.tree, 1, wx.EXPAND) panelsizer.Layout() + for col in range(self.tree.GetColumnCount()): + colColour = self.columnBackgroundColours[col] + self.ColourColumnItems(colColour, col) + panelparent.Thaw() @@ -1411,6 +1431,45 @@ class HyperTreeListDemo(wx.Frame): event.Skip() + def OnColumnChoiceChanged(self, event): + + selectedColumn = self.columnchoice.GetCurrentSelection() + + if selectedColumn in range(3): + colour = self.columnBackgroundColours[selectedColumn] + self.columnbackgroundcolour.SetValue(colour) + + def ColourColumnItems(self, colour, col): + + def ColourItems(item,colour,col): + + next = item + + while next != None: + + self.tree.SetItemBackgroundColour(next, colour, col) + + cookie=0 + child, cockie = self.tree.GetNextChild(next, cookie) + + while child != None: + ColourItems(child, colour, col) + child, cookie = self.tree.GetNextChild(next, cookie) + + next = self.tree.GetNextSibling(next) + + root = self.tree.GetRootItem() + ColourItems(root, colour, col) + + def OnColumnBackgroundColour(self, event): + + columnBackgroundColour = event.GetValue() + selectedColumn = self.columnchoice.GetCurrentSelection() + self.columnBackgroundColours[selectedColumn] = columnBackgroundColour + + self.ColourColumnItems(columnBackgroundColour, selectedColumn) + + event.Skip() def OnColumnAlignment(self, event): diff --git a/unittests/test_lib_agw_hypertreelist.py b/unittests/test_lib_agw_hypertreelist.py index c9b4014f..802e83cf 100644 --- a/unittests/test_lib_agw_hypertreelist.py +++ b/unittests/test_lib_agw_hypertreelist.py @@ -71,12 +71,53 @@ class lib_agw_hypertreelist_Tests(wtc.WidgetTestCase): HTL.TR_TWIST_BUTTONS HTL.TR_VIRTUAL HTL.TREE_HITTEST_ONITEMCHECKICON + HTL.TR_FILL_WHOLE_COLUMN_BACKGROUND def test_lib_agw_hypertreelistEvents(self): HTL.EVT_TREE_ITEM_CHECKED HTL.EVT_TREE_ITEM_CHECKING HTL.EVT_TREE_ITEM_HYPERLINK + def test_lib_agw_hypertreelistSetItemColour(self): + tree = HTL.HyperTreeList(self.frame) + tree.AddColumn("First column") + root = tree.AddRoot('root item') + child = tree.AppendItem(root, 'child item') + + self.assertEqual(None, tree.GetItemBackgroundColour(root)) + + colour = wx.RED + tree.SetItemBackgroundColour(child, colour) + self.assertEqual(colour, tree.GetItemBackgroundColour(child)) + + def test_lib_agw_hypertreelistSetItemColourOfColumns(self): + tree = HTL.HyperTreeList(self.frame) + tree.AddColumn("First column") + tree.AddColumn("Second column") + tree.AddColumn("Third column") + root = tree.AddRoot('root item') + child = tree.AppendItem(root, 'child item') + + colColour0 = wx.GREEN + colColour2 = wx.RED + tree.SetItemBackgroundColour(child, colColour0) + tree.SetItemBackgroundColour(child, colColour2, column=2) + + self.assertEqual(colColour2, tree.GetItemBackgroundColour(child, column=2)) + self.assertNotEqual(tree.GetItemBackgroundColour(child), + tree.GetItemBackgroundColour(child,column=2)) + self.assertEqual(None, tree.GetItemBackgroundColour(child, column=1)) + + def test_lib_agw_hypertreelistColourWholeItemColumns(self): + + tree = HTL.HyperTreeList(self.frame, agwStyle=HTL.TR_DEFAULT_STYLE| + HTL.TR_FILL_WHOLE_COLUMN_BACKGROUND) + tree.AddColumn("First column") + tree.AddColumn("Second column") + root = tree.AddRoot('root item') + + tree.SetItemBackgroundColour(root, wx.RED) + tree.SetItemBackgroundColour(root, wx.GREEN, column=1) #--------------------------------------------------------------------------- diff --git a/wx/lib/agw/hypertreelist.py b/wx/lib/agw/hypertreelist.py index 3143de20..93fd01ac 100644 --- a/wx/lib/agw/hypertreelist.py +++ b/wx/lib/agw/hypertreelist.py @@ -371,6 +371,12 @@ TR_NO_HEADER = 0x40000 """ Use this style to hide the columns header. """ # -------------------------------------------------------------------------- +# -------------------------------------------------------------------------- +# Additional HyperTreeList style for filling the whole background of the +# item columns +TR_FILL_WHOLE_COLUMN_BACKGROUND = 0x200000 +""" Use this style to fill the whole background of the item columns. """ +# -------------------------------------------------------------------------- # -------------------------------------------------------------------------- # Additional HyperTreeList style autosize the columns based on the widest @@ -1333,6 +1339,7 @@ class TreeListItem(GenericTreeItem): GenericTreeItem.__init__(self, parent, text, ct_type, wnd, image, selImage, data) self._wnd = [None] # are we holding a window? + self._bgColour = [None] if wnd: self.SetWindow(wnd) @@ -1401,7 +1408,7 @@ class TreeListItem(GenericTreeItem): # Hidden items are never evaluated. if self.IsHidden(): return None, flags, wx.NOT_FOUND - + # for a hidden root node, don't evaluate it, but do evaluate children if not theCtrl.HasAGWFlag(wx.TR_HIDE_ROOT) or level > 0: @@ -1804,6 +1811,36 @@ class TreeListItem(GenericTreeItem): return False return self._enabled + def GetBackgroundColour(self, column=0): + """ + Returns the associated background colour + + :param `column` an integer specifying the column index. + """ + + if column >= len(self._bgColour): + return None + + return self._bgColour[column] + + def SetBackgroundColour(self, colour, column=0): + """ + Sets the associated background colour + + :param `colour`: a valid :class:`wx.Colour` instance. + :param integer `column` + """ + + if type(self._bgColour) != type([]): + self._bgColour = [self._bgColour] + + if column < len(self._bgColour): + self._bgColour[column] = colour + elif column < self._owner.GetColumnCount(): + self._bgColour.extend([None] * (column - len(self._bgColour) + 1)) + self._bgColour[column] = colour + + #----------------------------------------------------------------------------- # EditTextCtrl (internal) #----------------------------------------------------------------------------- @@ -2298,6 +2335,32 @@ class TreeListMainWindow(CustomTreeCtrl): """ item.DeleteWindow(column=column) + def GetItemBackgroundColour(self, item, column=0): + """ + Returns the column background colour of the item + + :param `item`: an instance of :class:`TreeListItem` + :param integer `column` + """ + + return item.GetBackgroundColour(column) + + def SetItemBackgroundColour(self, item, colour, column=0): + """ + Sets the column background colour of the item + + :param `item`: an instance of :class:`TreeListItem` + :param `colour`: a valid :class:`wx.Colour` instance. + :param integer `column` + """ + + item.SetBackgroundColour(colour, column) + + if column == 0: + item.Attr().SetBackgroundColour(colour) + + self.RefreshLine(item) + # ---------------------------------------------------------------------------- # navigation # ---------------------------------------------------------------------------- @@ -2394,7 +2457,7 @@ class TreeListMainWindow(CustomTreeCtrl): if not self.HasAGWFlag(TR_HIDE_ROOT): if self.IsVisible(root): return root - + return self.GetNextVisible(root) @@ -3021,14 +3084,30 @@ class TreeListMainWindow(CustomTreeCtrl): # except for custom item backgrounds, works for both kinds of theme. elif drawItemBackground: - itemrect = wx.Rect(text_x-2, item.GetY() + off_h, text_w+2*_MARGIN, total_h - off_h) + if self.HasAGWFlag(TR_FILL_WHOLE_COLUMN_BACKGROUND): + itemrect = wx.Rect(text_x-2, item.GetY() + off_h, col_w-2*_MARGIN, total_h - off_h) + else: + itemrect = wx.Rect(text_x-2, item.GetY() + off_h, text_w+2*_MARGIN, total_h - off_h) dc.SetBrush(wx.Brush(colBg)) + dc.SetPen(wx.TRANSPARENT_PEN) dc.DrawRectangle(itemrect) else: dc.SetTextForeground(colText) else: + + if self.HasAGWFlag(TR_FILL_WHOLE_COLUMN_BACKGROUND): + itemrect = wx.Rect(text_x-2, item.GetY() + off_h, col_w-2*_MARGIN, total_h - off_h) + else: + itemrect = wx.Rect(text_x-2, item.GetY() + off_h, text_w+2*_MARGIN, total_h - off_h) + colBgX = item.GetBackgroundColour(i) + + if colBgX != None and i != 0: + dc.SetBrush(wx.Brush(colBgX, wx.SOLID)) + dc.SetPen(wx.TRANSPARENT_PEN) + dc.DrawRectangle(itemrect) + dc.SetTextForeground(colText) if self.HasAGWFlag(TR_COLUMN_LINES): # vertical lines between columns @@ -3168,14 +3247,18 @@ class TreeListMainWindow(CustomTreeCtrl): draw_row_lines = self.HasAGWFlag(TR_ROW_LINES) if self.IsExposed(exposed_x, exposed_y, _MAX_WIDTH, h + int(draw_row_lines)): - if draw_row_lines: - total_width = self._owner.GetHeaderWindow().GetWidth() - # if the background colour is white, choose a - # contrasting colour for the lines - pen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.PENSTYLE_SOLID) - dc.SetPen((self.GetBackgroundColour() == wx.WHITE and [pen] or [wx.WHITE_PEN])[0]) - dc.DrawLine(0, y_top, total_width, y_top) - dc.DrawLine(0, y_top+h, total_width, y_top+h) + # fill background below twist buttons + if self.HasAGWFlag(TR_FILL_WHOLE_COLUMN_BACKGROUND): + attr = item.GetAttributes() + + if attr and attr.HasBackgroundColour(): + width = self._owner.GetEventHandler().GetColumn(self._main_column).GetWidth() + colBg = attr.GetBackgroundColour() + itemrect = wx.Rect(x_maincol, y-h-1, width, h+1) + + dc.SetBrush(wx.Brush(colBg, wx.SOLID)) + dc.SetPen(wx.TRANSPARENT_PEN) + dc.DrawRectangle(itemrect) # draw item self.PaintItem(item, dc) @@ -3252,6 +3335,17 @@ class TreeListMainWindow(CustomTreeCtrl): flag = (item.IsExpanded() and [wx.CONTROL_EXPANDED] or [0])[0] wx.RendererNative.GetDefault().DrawTreeItemButton(self, dc, rect, flag) + if draw_row_lines: + total_width = self._owner.GetHeaderWindow().GetWidth() + # if the background colour is white, choose a + # contrasting colour for the lines + pen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DLIGHT), 1, wx.PENSTYLE_SOLID) + dc.SetPen((self.GetBackgroundColour() == wx.WHITE and [pen] or [wx.WHITE_PEN])[0]) + dc.DrawLine(0, y_top, total_width, y_top) + dc.DrawLine(0, y_top+h, total_width, y_top+h) + + + # restore DC objects dc.SetBrush(wx.WHITE_BRUSH) dc.SetPen(self._dottedPen) @@ -3861,7 +3955,7 @@ class TreeListMainWindow(CustomTreeCtrl): # Hidden items have a height of 0. item.SetHeight(0) return - + attr = item.GetAttributes() if attr and attr.HasFont():