X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c8f129d0675af4f473f92b90aeb187c90e4053c9..5589b01ba74638fcf94ee21f5581b050ee233156:/wxPython/wx/lib/customtreectrl.py diff --git a/wxPython/wx/lib/customtreectrl.py b/wxPython/wx/lib/customtreectrl.py index 1616f48adb..d987320ca0 100644 --- a/wxPython/wx/lib/customtreectrl.py +++ b/wxPython/wx/lib/customtreectrl.py @@ -95,8 +95,9 @@ Base Functionalities CustomTreeCtrl supports all the wx.TreeCtrl styles, except: - TR_EXTENDED: supports for this style is on the todo list (Am I sure of this?). -Plus it has 2 more styles to handle checkbox-type items: +Plus it has 3 more styles to handle checkbox-type items: - TR_AUTO_CHECK_CHILD : automatically checks/unchecks the item children; + - TR_AUTO_CHECK_PARENT : automatically checks/unchecks the item parent; - TR_AUTO_TOGGLE_CHILD: automatically toggles the item children. All the methods available in wx.TreeCtrl are also available in CustomTreeCtrl. @@ -190,8 +191,9 @@ TR_HIDE_ROOT = wx.TR_HIDE_ROOT # don't display r TR_FULL_ROW_HIGHLIGHT = wx.TR_FULL_ROW_HIGHLIGHT # highlight full horz space -TR_AUTO_CHECK_CHILD = 0x4000 # only meaningful for checkboxes -TR_AUTO_TOGGLE_CHILD = 0x8000 # only meaningful for checkboxes +TR_AUTO_CHECK_CHILD = 0x04000 # only meaningful for checkboxes +TR_AUTO_TOGGLE_CHILD = 0x08000 # only meaningful for checkboxes +TR_AUTO_CHECK_PARENT = 0x10000 # only meaningful for checkboxes TR_DEFAULT_STYLE = wx.TR_DEFAULT_STYLE # default style for the tree control @@ -492,9 +494,9 @@ class DragImage(wx.DragImage): text = item.GetText() font = item.Attr().GetFont() colour = item.Attr().GetTextColour() - if colour is None: + if not colour: colour = wx.BLACK - if font is None: + if not font: font = treeCtrl._normalFont backcolour = treeCtrl.GetBackgroundColour() @@ -942,16 +944,12 @@ class TreeTextCtrl(wx.TextCtrl): x += image_w + wcheck w -= image_w + 4 + wcheck - if wx.Platform == "__WXMAC__": - bs = self.DoGetBestSize() - # edit control height - if h > bs.y - 8: - diff = h - ( bs.y - 8 ) - h -= diff - y += diff / 2 - wx.TextCtrl.__init__(self, self._owner, wx.ID_ANY, self._startValue, wx.Point(x - 4, y), wx.Size(w + 15, h)) + if wx.Platform == "__WXMAC__": + self.SetFont(owner.GetFont()) + bs = self.GetBestSize() + self.SetSize((-1, bs.height)) self.Bind(wx.EVT_CHAR, self.OnChar) self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) @@ -1735,7 +1733,7 @@ def EventFlagsToSelType(style, shiftDown=False, ctrlDown=False): # This Is The Main Class. # ----------------------------------------------------------------------------- -class CustomTreeCtrl(wx.ScrolledWindow): +class CustomTreeCtrl(wx.PyScrolledWindow): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, ctstyle=TR_DEFAULT_STYLE, validator=wx.DefaultValidator, @@ -1768,6 +1766,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): TR_HIDE_ROOT # don't display root node TR_FULL_ROW_HIGHLIGHT # highlight full horizontal space TR_AUTO_CHECK_CHILD # only meaningful for checkboxes + TR_AUTO_CHECK_PARENT # only meaningful for checkboxes TR_AUTO_TOGGLE_CHILD # only meaningful for checkboxes validator: window validator. @@ -1872,12 +1871,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._itemWithWindow = [] if wx.Platform == "__WXMAC__": - - platform, major, minor = wx.GetOsVersion() - ctstyle &= ~TR_LINES_AT_ROOT ctstyle |= TR_NO_LINES + platform, major, minor = wx.GetOsVersion() if major < 10: ctstyle |= TR_ROW_LINES @@ -1894,7 +1891,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._drawingfunction = wx.RendererNative.Get().DrawTreeItemButton # Create our container... at last! - wx.ScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) + wx.PyScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name) # If the tree display has no buttons, but does have # connecting lines, we can use a narrower layout. @@ -1922,15 +1919,19 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) self.Bind(EVT_TREE_ITEM_GETTOOLTIP, self.OnGetToolTip) - self.Bind(wx.EVT_IDLE, self.OnInternalIdle) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) # Sets the focus to ourselves: this is useful if you have items # with associated widgets. self.SetFocus() - return True + def AcceptsFocus(self): + # overridden base class method, allows this ctrl to + # participate in the tab-order, etc. It's overridable because + # of deriving this class from wx.PyScrolledWindow... + return True + def OnDestroy(self, event): """Handles the wx.EVT_WINDOW_DESTROY event.""" @@ -2105,7 +2106,6 @@ class CustomTreeCtrl(wx.ScrolledWindow): return False item.Check(checked) - dc = wx.ClientDC(self) self.RefreshLine(item) self.EnableChildren(item, checked) e = TreeEvent(wxEVT_TREE_ITEM_CHECKED, self.GetId()) @@ -2157,6 +2157,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): if self._windowStyle & TR_AUTO_CHECK_CHILD: ischeck = self.IsItemChecked(item) self.AutoCheckChild(item, ischeck) + if self._windowStyle & TR_AUTO_CHECK_PARENT: + ischeck = self.IsItemChecked(item) + self.AutoCheckParent(item, ischeck) elif self._windowStyle & TR_AUTO_TOGGLE_CHILD: self.AutoToggleChild(item) @@ -2205,6 +2208,28 @@ class CustomTreeCtrl(wx.ScrolledWindow): (child, cookie) = self.GetNextChild(item, cookie) + def AutoCheckParent(self, item, checked): + """Traverses up the tree and checks/unchecks parent items. + Meaningful only for check items.""" + + if not item: + raise "\nERROR: Invalid Tree Item. " + + parent = item.GetParent() + if not parent or parent.GetType() != 1: + return + + (child, cookie) = self.GetFirstChild(parent) + while child: + if child.GetType() == 1 and child.IsEnabled(): + if checked != child.IsChecked(): + return + (child, cookie) = self.GetNextChild(parent, cookie) + + self.CheckItem2(parent, checked, torefresh=True) + self.AutoCheckParent(parent, checked) + + def CheckChilds(self, item, checked=True): """Programatically check/uncheck item children. Does not generate EVT_TREE_CHECK* events.""" @@ -3446,7 +3471,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not item: raise "\nERROR: Invalid Tree Item. " - if not self.HasFlag(TR_HIDE_ROOT) or item != GetRootItem(): + if not self.HasFlag(TR_HIDE_ROOT) or item != self.GetRootItem(): self.Expand(item) if not self.IsExpanded(item): return @@ -4057,9 +4082,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): def DrawVerticalGradient(self, dc, rect, hasfocus): """Gradient fill from colour 1 to colour 2 from top to bottom.""" - dc.DrawRectangleRect(rect) - border = self._borderPen.GetWidth() - + oldpen = dc.GetPen() + oldbrush = dc.GetBrush() dc.SetPen(wx.TRANSPARENT_PEN) # calculate gradient coefficients @@ -4081,21 +4105,25 @@ class CustomTreeCtrl(wx.ScrolledWindow): rf, gf, bf = 0, 0, 0 - for y in xrange(rect.y+border, rect.y + rect.height-border): + for y in xrange(rect.y, rect.y + rect.height): currCol = (r1 + rf, g1 + gf, b1 + bf) dc.SetBrush(wx.Brush(currCol, wx.SOLID)) - dc.DrawRectangle(rect.x+border, y, rect.width-2*border, 1) + dc.DrawRectangle(rect.x, y, rect.width, 1) rf = rf + rstep gf = gf + gstep bf = bf + bstep + dc.SetPen(oldpen) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.DrawRectangleRect(rect) + dc.SetBrush(oldbrush) + def DrawHorizontalGradient(self, dc, rect, hasfocus): """Gradient fill from colour 1 to colour 2 from left to right.""" - dc.DrawRectangleRect(rect) - border = self._borderPen.GetWidth() - + oldpen = dc.GetPen() + oldbrush = dc.GetBrush() dc.SetPen(wx.TRANSPARENT_PEN) # calculate gradient coefficients @@ -4117,15 +4145,20 @@ class CustomTreeCtrl(wx.ScrolledWindow): bstep = float((b2 - b1)) / flrect rf, gf, bf = 0, 0, 0 - - for x in xrange(rect.x+border, rect.x + rect.width-border): + + for x in xrange(rect.x, rect.x + rect.width): currCol = (int(r1 + rf), int(g1 + gf), int(b1 + bf)) dc.SetBrush(wx.Brush(currCol, wx.SOLID)) - dc.DrawRectangle(x, rect.y+border, 1, rect.height-2*border) + dc.DrawRectangle(x, rect.y, 1, rect.height) rf = rf + rstep gf = gf + gstep bf = bf + bstep - + + dc.SetPen(oldpen) + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.DrawRectangleRect(rect) + dc.SetBrush(oldbrush) + def DrawVistaRectangle(self, dc, rect, hasfocus): """Draw the selected item(s) with the Windows Vista style.""" @@ -4147,18 +4180,14 @@ class CustomTreeCtrl(wx.ScrolledWindow): oldpen = dc.GetPen() oldbrush = dc.GetBrush() - dc.SetBrush(wx.TRANSPARENT_BRUSH) - dc.SetPen(wx.Pen(outer)) - dc.DrawRoundedRectangleRect(rect, 3) - rect.Deflate(1, 1) - dc.SetPen(wx.Pen(inner)) - dc.DrawRoundedRectangleRect(rect, 2) - rect.Deflate(1, 1) - + bdrRect = wx.Rect(*rect.Get()) + filRect = wx.Rect(*rect.Get()) + filRect.Deflate(1,1) + r1, g1, b1 = int(top.Red()), int(top.Green()), int(top.Blue()) r2, g2, b2 = int(bottom.Red()), int(bottom.Green()), int(bottom.Blue()) - flrect = float(rect.height) + flrect = float(filRect.height) rstep = float((r2 - r1)) / flrect gstep = float((g2 - g1)) / flrect @@ -4167,14 +4196,21 @@ class CustomTreeCtrl(wx.ScrolledWindow): rf, gf, bf = 0, 0, 0 dc.SetPen(wx.TRANSPARENT_PEN) - for y in xrange(rect.y, rect.y + rect.height): + for y in xrange(filRect.y, filRect.y + filRect.height): currCol = (r1 + rf, g1 + gf, b1 + bf) dc.SetBrush(wx.Brush(currCol, wx.SOLID)) - dc.DrawRectangle(rect.x, y, rect.width, 1) + dc.DrawRectangle(filRect.x, y, filRect.width, 1) rf = rf + rstep gf = gf + gstep bf = bf + bstep + dc.SetBrush(wx.TRANSPARENT_BRUSH) + dc.SetPen(wx.Pen(outer)) + dc.DrawRoundedRectangleRect(bdrRect, 3) + bdrRect.Deflate(1, 1) + dc.SetPen(wx.Pen(inner)) + dc.DrawRoundedRectangleRect(bdrRect, 2) + dc.SetPen(oldpen) dc.SetBrush(oldbrush) @@ -4220,7 +4256,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): total_h = self.GetLineHeight(item) drawItemBackground = False - + if item.IsSelected(): # under mac selections are only a rectangle in case they don't have the focus @@ -4244,13 +4280,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.SetPen(wx.TRANSPARENT_PEN) offset = (self.HasFlag(TR_ROW_LINES) and [1] or [0])[0] - + if self.HasFlag(TR_FULL_ROW_HIGHLIGHT): - - oldpen = dc.GetPen() - dc.SetPen(wx.TRANSPARENT_PEN) - x, y = self.GetPosition() - w, h = self.GetSize() + x = 0 + w, h = self.GetClientSize() itemrect = wx.Rect(x, item.GetY()+offset, w, total_h-offset) @@ -4263,13 +4296,16 @@ class CustomTreeCtrl(wx.ScrolledWindow): elif self._vistaselection: self.DrawVistaRectangle(dc, itemrect, self._hasFocus) else: - dc.DrawRectangleRect(itemrect) + if wx.Platform in ["__WXGTK2__", "__WXMAC__"]: + flags = wx.CONTROL_SELECTED + if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED + wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) + else: + dc.DrawRectangleRect(itemrect) - dc.SetPen(oldpen) - else: - - if item.IsSelected() and image != _NO_IMAGE: + + if item.IsSelected(): # If it's selected, and there's an image, then we should # take care to leave the area under the image painted in the @@ -4280,9 +4316,11 @@ class CustomTreeCtrl(wx.ScrolledWindow): if wnd: wndx, wndy = item.GetWindowSize() - itemrect = wx.Rect(item.GetX() + wcheck + image_w - 2, item.GetY()+offset, - item.GetWidth() - image_w - wcheck + 2 - wndx, total_h-offset) - + itemrect = wx.Rect(item.GetX() + wcheck + image_w - 2, + item.GetY()+offset, + item.GetWidth() - image_w - wcheck + 2 - wndx, + total_h-offset) + if self._usegradients: if self._gradientstyle == 0: # Horizontal self.DrawHorizontalGradient(dc, itemrect, self._hasFocus) @@ -4291,7 +4329,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): elif self._vistaselection: self.DrawVistaRectangle(dc, itemrect, self._hasFocus) else: - dc.DrawRectangleRect(itemrect) + if wx.Platform in ["__WXGTK2__", "__WXMAC__"]: + flags = wx.CONTROL_SELECTED + if self._hasFocus: flags = flags | wx.CONTROL_FOCUSED + wx.RendererNative.Get().DrawItemSelectionRect(self, dc, itemrect, flags) + else: + dc.DrawRectangleRect(itemrect) # On GTK+ 2, drawing a 'normal' background is wrong for themes that # don't allow backgrounds to be customized. Not drawing the background, @@ -4299,7 +4342,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): elif drawItemBackground: minusicon = wcheck + image_w - 2 - itemrect = wx.Rect(item.GetX()+minusicon, item.GetY()+offset, item.GetWidth()-minusicon, total_h-offset) + itemrect = wx.Rect(item.GetX()+minusicon, + item.GetY()+offset, + item.GetWidth()-minusicon, + total_h-offset) if self._usegradients and self._hasFocus: if self._gradientstyle == 0: # Horizontal @@ -4346,6 +4392,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.DrawLabel(item.GetText(), textrect) dc.SetTextForeground(foreground) else: + if wx.Platform == "__WXMAC__" and item.IsSelected() and self._hasFocus: + dc.SetTextForeground(wx.WHITE) dc.DrawLabel(item.GetText(), textrect) wnd = item.GetWindow() @@ -5405,7 +5453,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self.Toggle(item) - def OnInternalIdle(self, event): + def OnInternalIdle(self): """Performs operations in idle time (essentially drawing).""" # Check if we need to select the root item