]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/customtreectrl.py
Show GridCellAutoWrapStringRenderer
[wxWidgets.git] / wxPython / wx / lib / customtreectrl.py
index ae7b8cd69e6d73c9837cfa14f119026b6e30a03c..d987320ca0995015256b3904ff7a91206e085ebe 100644 (file)
@@ -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,7 +1919,6 @@ 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
@@ -1930,6 +1926,12 @@ class CustomTreeCtrl(wx.ScrolledWindow):
         self.SetFocus()
 
 
+    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."""
@@ -2104,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())
@@ -2156,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)
 
@@ -2204,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."""
 
@@ -3445,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
@@ -4056,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
@@ -4080,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
@@ -4116,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."""
@@ -4146,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
@@ -4166,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)
 
@@ -4219,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
@@ -4243,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 = 0
-            w, h = self.GetSize()
+            w, h = self.GetClientSize()
 
             itemrect = wx.Rect(x, item.GetY()+offset, w, total_h-offset)
             
@@ -4262,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
@@ -4279,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)
@@ -4290,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,
@@ -4298,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
@@ -4345,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()
@@ -5404,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