This file contains the SVN revision history for customtreectrl, at revision 69864.
Available information include commit date, the name of the committer, the file size, the SVN log messages and a diff from the previous version (if available).
The following log message was entered by the committer:
CustomTreeCtrl: add the ability to use horizontal line separators between tree items. Show it in the demo by randomly adding separators in the tree.
Version SVN diff:
--- wxPython/3rdParty/AGW/agw/customtreectrl.py 2011/11/01 19:42:21 69627
+++ wxPython/3rdParty/AGW/agw/customtreectrl.py 2011/11/29 20:11:02 69864
@@ -3,7 +3,7 @@
# Inspired By And Heavily Based On wxGenericTreeCtrl.
#
# Andrea Gavana, @ 17 May 2006
-# Latest Revision: 17 Aug 2011, 15.00 GMT
+# Latest Revision: 29 Nov 2011, 15.00 GMT
#
#
# TODO List
@@ -83,6 +83,18 @@
* Changing the style of the lines that connect the items (in terms of `wx.Pen` styles);
* Using an image as a L{CustomTreeCtrl} background (currently only in "tile" mode);
* Adding images to any item in the leftmost area of the L{CustomTreeCtrl} client window.
+* Separator-type items which are simply visual indicators that are meant to set apart
+ or divide tree items, with the following caveats:
+
+ - Separator items should not have children, labels, data or an associated window;
+ - You can change the color of individual separators by using L{SetItemTextColour}, or you can use
+ L{SetSeparatorColour} to change the color of all separators. The default separator colour
+ is that returned by `wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)`;
+ - Separators can be selected just like any other tree item;
+ - Separators cannot have text;
+ - Separators cannot have children;
+ - Separators cannot be edited via the ``EVT_TREE_BEGIN_LABEL_EDIT`` event.
+
And a lot more. Check the demo for an almost complete review of the functionalities.
@@ -273,14 +285,14 @@
L{CustomTreeCtrl} is distributed under the wxPython license.
-Latest Revision: Andrea Gavana @ 17 Aug 2011, 15.00 GMT
+Latest Revision: Andrea Gavana @ 29 Nov 2011, 15.00 GMT
-Version 2.4
+Version 2.5
"""
# Version Info
-__version__ = "2.4"
+__version__ = "2.5"
import wx
from wx.lib.expando import ExpandoTextCtrl
@@ -1448,7 +1460,7 @@
L{CustomTreeCtrl}. This is a generic implementation of `wx.TreeItem`.
"""
- def __init__(self, parent, text="", ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
+ def __init__(self, parent, text="", ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False):
"""
Default class constructor.
For internal use: do not call it in your code!
@@ -1473,7 +1485,8 @@
:param integer `selImage`: an index within the normal image list specifying the image to
use for the item in selected state; if `image` > -1 and `selImage` is -1, the
same image is used for both selected and unselected items;
- :param object `data`: associate the given Python object `data` with the item.
+ :param object `data`: associate the given Python object `data` with the item;
+ :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise.
:note: Regarding radiobutton-type items (with `ct_type` = 2), the following
approach is used:
@@ -1484,7 +1497,19 @@
must be unchecked.
- If a radiobutton node becomes unchecked, then all of its child nodes will become
inactive.
-
+
+
+ :note: Separator items should not have children, labels, data or an associated window.
+ Other issues/features associated to separator items:
+
+ - You can change the color of individual separators by using L{SetItemTextColour}, or you can use
+ L{SetSeparatorColour} to change the color of all separators. The default separator colour
+ is that returned by `wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)`;
+ - Separators can be selected just like any other tree item;
+ - Separators cannot have text;
+ - Separators cannot have children;
+ - Separators cannot be edited via the ``EVT_TREE_BEGIN_LABEL_EDIT`` event.
+
"""
# since there can be very many of these, we save size by chosing
@@ -1498,6 +1523,8 @@
self._attr = None # attributes???
+ self._separator = separator
+
# tree ctrl images for the normal, selected, expanded and
# expanded+selected states
self._images = [-1, -1, -1, -1]
@@ -1558,6 +1585,16 @@
return True
+ def IsSeparator(self):
+ """
+ Returns whether the item is meant to be an horizontal line separator or not.
+
+ :return: ``True`` if this item is a separator, ``False`` otherwise.
+ """
+
+ return self._separator
+
+
def GetChildren(self):
"""
Returns the item's children.
@@ -1784,8 +1821,13 @@
:param `wnd`: a non-toplevel window to be displayed next to the item, any
subclass of `wx.Window`.
+
+ :raise: `Exception` if the input `item` is a separator and `wnd` is not ``None``.
"""
+ if self.IsSeparator() and wnd is not None:
+ raise Exception("Separator items can not have an associated window")
+
self._wnd = wnd
if wnd.GetSizer(): # the window is a complex one hold by a sizer
@@ -2277,8 +2319,13 @@
Sets the item text.
:param string `text`: the new item label.
+
+ :raise: `Exception` if the item is a separator.
"""
+ if self.IsSeparator():
+ raise Exception("Separator items can not have text")
+
self._text = text
@@ -2669,6 +2716,9 @@
else:
self._drawingfunction = wx.RendererNative.Get().DrawTreeItemButton
+ # Set the separator pen default colour
+ self._separatorPen = wx.Pen(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT))
+
# Create our container... at last!
wx.PyScrolledWindow.__init__(self, parent, id, pos, size, style|wx.HSCROLL|wx.VSCROLL, name)
@@ -3444,7 +3494,7 @@
def GetItemTextColour(self, item):
"""
- Returns the item text colour.
+ Returns the item text colour or separator horizontal line colour.
:param `item`: an instance of L{GenericTreeItem}.
@@ -3500,8 +3550,13 @@
:param `item`: an instance of L{GenericTreeItem};
:param string `text`: the new item label.
+
+ :raise: `Exception` if the input `item` is a separator.
"""
+ if item.IsSeparator():
+ raise Exception("Separator items can not have text")
+
dc = wx.ClientDC(self)
item.SetText(text)
self.CalculateSize(item, dc)
@@ -3616,7 +3671,7 @@
def SetItemTextColour(self, item, colour):
"""
- Sets the item text colour.
+ Sets the item text colour or separator horizontal line colour.
:param `item`: an instance of L{GenericTreeItem};
:param `colour`: a valid `wx.Colour` instance.
@@ -3624,7 +3679,7 @@
item.Attr().SetTextColour(colour)
self.RefreshLine(item)
-
+
def SetItemBackgroundColour(self, item, colour):
"""
@@ -4036,6 +4091,37 @@
return self._backgroundImage
+ def SetSeparatorColour(self, colour):
+ """
+ Sets the pen colour for separator-type items.
+
+ :param `colour` a valid instance of `wx.Colour`.
+ """
+
+ self._separatorPen = wx.Pen(colour, 1)
+ self.Refresh()
+
+
+ def GetSeparatorColour(self, colour):
+ """
+ Returns the pen colour for separator-type items.
+
+ :return An instance of `wx.Colour` representing the separator pen colour.
+ """
+
+ return self._separatorPen.GetColour()
+
+
+ def IsItemSeparator(self, item):
+ """
+ Returns whether an item is of separator type or not.
+
+ :param `item`: an instance of L{GenericTreeItem}.
+ """
+
+ return item.IsSeparator()
+
+
def GetItemWindow(self, item):
"""
Returns the window associated to the item (if any).
@@ -4055,8 +4141,13 @@
:param `item`: an instance of L{GenericTreeItem};
:param `wnd`: if not ``None``, a non-toplevel window to be displayed next to
the item.
+
+ :raise: `Exception` if the input `item` is a separator and `wnd` is not ``None``.
"""
+ if item.IsSeparator() and wnd is not None:
+ raise Exception("Separator items can not have an associated window")
+
if wnd is not None:
self._hasWindows = True
if item not in self._itemWithWindow:
@@ -4623,7 +4714,7 @@
# operations
# -----------------------------------------------------------------------------
- def DoInsertItem(self, parentId, previous, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
+ def DoInsertItem(self, parentId, previous, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False):
"""
Actually inserts an item in the tree.
@@ -4640,7 +4731,8 @@
:param integer `selImage`: an index within the normal image list specifying the image to
use for the item in selected state; if `image` > -1 and `selImage` is -1, the
same image is used for both selected and unselected items;
- :param object `data`: associate the given Python object `data` with the item.
+ :param object `data`: associate the given Python object `data` with the item;
+ :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise.
:return: An instance of L{GenericTreeItem} upon successful insertion.
@@ -4650,7 +4742,12 @@
set for L{CustomTreeCtrl};
- The item has multiline text (with line-breaks in it) but the ``TR_HAS_VARIABLE_ROW_HEIGHT``
flag has not been set for L{CustomTreeCtrl};
- - The `ct_type` attribute is less than ``0`` or greater than ``2``.
+ - The `ct_type` attribute is less than ``0`` or greater than ``2``;
+ - The parent item is a separator;
+ - The item is a separator but it has text or an associated window.
+
+
+ :note: Separator items should not have children, text labels or an associated window.
"""
if wnd is not None and not self.HasAGWFlag(TR_HAS_VARIABLE_ROW_HEIGHT):
@@ -4661,6 +4758,12 @@
if ct_type < 0 or ct_type > 2:
raise Exception("\nERROR: Item Type Should Be 0 (Normal), 1 (CheckBox) or 2 (RadioButton). ")
+
+ if separator:
+ if wnd:
+ raise Exception("Separator items can not have associated windows")
+ if text.strip():
+ raise Exception("Separator items can not text labels")
parent = parentId
@@ -4670,7 +4773,7 @@
self._dirty = True # do this first so stuff below doesn't cause flicker
- item = GenericTreeItem(parent, text, ct_type, wnd, image, selImage, data)
+ item = GenericTreeItem(parent, text, ct_type, wnd, image, selImage, data, separator)
if wnd is not None:
self._hasWindows = True
@@ -4747,7 +4850,7 @@
return self._anchor
- def PrependItem(self, parent, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
+ def PrependItem(self, parent, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False):
"""
Prepends an item as a first child of parent.
@@ -4763,17 +4866,18 @@
:param integer `selImage`: an index within the normal image list specifying the image to
use for the item in selected state; if `image` > -1 and `selImage` is -1, the
same image is used for both selected and unselected items;
- :param object `data`: associate the given Python object `data` with the item.
+ :param object `data`: associate the given Python object `data` with the item;
+ :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise.
:return: An instance of L{GenericTreeItem} upon successful insertion.
:see: L{DoInsertItem} for possible exceptions generated by this method.
"""
- return self.DoInsertItem(parent, 0, text, ct_type, wnd, image, selImage, data)
+ return self.DoInsertItem(parent, 0, text, ct_type, wnd, image, selImage, data, separator)
- def InsertItemByItem(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
+ def InsertItemByItem(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False):
"""
Inserts an item after the given previous.
@@ -4791,8 +4895,9 @@
:param integer `selImage`: an index within the normal image list specifying the image to
use for the item in selected state; if `image` > -1 and `selImage` is -1, the
same image is used for both selected and unselected items;
- :param object `data`: associate the given Python object `data` with the item.
-
+ :param object `data`: associate the given Python object `data` with the item;
+ :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise.
+
:return: An instance of L{GenericTreeItem} upon successful insertion.
:raise: `Exception` if the previous item is not a sibling.
@@ -4814,10 +4919,10 @@
except:
raise Exception("ERROR: Previous Item In CustomTreeCtrl.InsertItem() Is Not A Sibling")
- return self.DoInsertItem(parentId, index+1, text, ct_type, wnd, image, selImage, data)
+ return self.DoInsertItem(parentId, index+1, text, ct_type, wnd, image, selImage, data, separator)
- def InsertItemByIndex(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
+ def InsertItemByIndex(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False):
"""
Inserts an item after the given previous.
@@ -4834,8 +4939,9 @@
:param integer `selImage`: an index within the normal image list specifying the image to
use for the item in selected state; if `image` > -1 and `selImage` is -1, the
same image is used for both selected and unselected items;
- :param object `data`: associate the given Python object `data` with the item.
-
+ :param object `data`: associate the given Python object `data` with the item;
+ :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise.
+
:return: An instance of L{GenericTreeItem} upon successful insertion.
:see: L{DoInsertItem} for possible exceptions generated by this method.
@@ -4847,10 +4953,10 @@
# should we give a warning here?
return self.AddRoot(text, ct_type, wnd, image, selImage, data)
- return self.DoInsertItem(parentId, idPrevious, text, ct_type, wnd, image, selImage, data)
+ return self.DoInsertItem(parentId, idPrevious, text, ct_type, wnd, image, selImage, data, separator)
- def InsertItem(self, parentId, input, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
+ def InsertItem(self, parentId, input, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False):
"""
Inserts an item after the given previous.
@@ -4863,9 +4969,9 @@
"""
if type(input) == type(1):
- return self.InsertItemByIndex(parentId, input, text, ct_type, wnd, image, selImage, data)
+ return self.InsertItemByIndex(parentId, input, text, ct_type, wnd, image, selImage, data, separator)
else:
- return self.InsertItemByItem(parentId, input, text, ct_type, wnd, image, selImage, data)
+ return self.InsertItemByItem(parentId, input, text, ct_type, wnd, image, selImage, data, separator)
def AppendItem(self, parentId, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None):
@@ -4900,6 +5006,52 @@
return self.DoInsertItem(parent, len(parent.GetChildren()), text, ct_type, wnd, image, selImage, data)
+ def AppendSeparator(self, parentId):
+ """
+ Appends an horizontal line separator as a last child of its parent.
+
+ :param `parentId`: an instance of L{GenericTreeItem} representing the
+ separator's parent.
+
+ :return: An instance of L{GenericTreeItem} upon successful insertion.
+
+ :see: L{DoInsertItem} for possible exceptions generated by this method.
+ """
+
+ parent = parentId
+ return self.DoInsertItem(parent, len(parent.GetChildren()), "", separator=True)
+
+
+ def InsertSeparator(self, parentId, input):
+ """
+ Inserts a separator item after the given previous.
+
+ :return: An instance of L{GenericTreeItem} upon successful insertion.
+
+ :see: L{InsertItemByIndex} and L{InsertItemByItem} for an explanation of
+ the input parameters.
+
+ :see: L{DoInsertItem} for possible exceptions generated by this method.
+ """
+
+ return self.InsertItem(parentId, input, "", separator=True)
+
+
+ def PrependSeparator(self, parent):
+ """
+ Prepends a separator item as a first child of parent.
+
+ :param `parent`: an instance of L{GenericTreeItem} representing the
+ item's parent.
+
+ :return: An instance of L{GenericTreeItem} upon successful insertion.
+
+ :see: L{DoInsertItem} for possible exceptions generated by this method.
+ """
+
+ return self.PrependItem(parent, 0, separator=True)
+
+
def SendDeleteEvent(self, item):
"""
Actually sends the ``EVT_TREE_DELETE_ITEM`` event.
@@ -6211,10 +6363,12 @@
dc.SetTextForeground(self.GetHyperTextNewColour())
text_w, text_h, dummy = dc.GetMultiLineTextExtent(item.GetText())
-
+ w, h = self.GetClientSize()
+
image = item.GetCurrentImage()
checkimage = item.GetCurrentCheckedImage()
leftimage = _NO_IMAGE
+ separator = item.IsSeparator()
if self._imageListLeft:
leftimage = item.GetLeftImage()
@@ -6270,7 +6424,6 @@
if self.HasAGWFlag(TR_FULL_ROW_HIGHLIGHT):
x = 0
- w, h = self.GetClientSize()
itemrect = wx.Rect(x, item.GetY()+offset, w, total_h-offset)
@@ -6311,9 +6464,14 @@
if wnd:
wndx, wndy = item.GetWindowSize()
+ if separator:
+ item_width = w
+ else:
+ item_width = item.GetWidth() - image_w - wcheck + 2 - wndx
+
itemrect = wx.Rect(item.GetX() + wcheck + image_w - 2,
item.GetY()+offset,
- item.GetWidth() - image_w - wcheck + 2 - wndx,
+ item_width,
total_h-offset)
if self._usegradients:
@@ -6337,9 +6495,15 @@
elif drawItemBackground:
minusicon = wcheck + image_w - 2
+
+ if separator:
+ item_width = w
+ else:
+ item_width = item.GetWidth()-minusicon,
+
itemrect = wx.Rect(item.GetX()+minusicon,
item.GetY()+offset,
- item.GetWidth()-minusicon,
+ item_width,
total_h-offset)
if self._usegradients and self._hasFocus:
@@ -6417,13 +6581,28 @@
elif align == 2:
# Rightmost alignment of windows
- wndx = self.GetClientSize().x - item.GetWindowSize().x - 2
+ wndx = w - item.GetWindowSize().x - 2
if not wnd.IsShown():
wnd.Show()
if wnd.GetPosition() != (wndx, ya):
wnd.SetPosition((wndx, ya))
+ if separator:
+ oldPen = dc.GetPen()
+
+ if item.IsEnabled():
+ if attr and attr.HasTextColour():
+ separatorPen = wx.Pen(attr.GetTextColour(), 1)
+ else:
+ separatorPen = self._separatorPen
+ else:
+ separatorPen = wx.GREY_PEN
+
+ dc.SetPen(separatorPen)
+ dc.DrawLine(item.GetX()+2, item.GetY()+total_h/2, w, item.GetY()+total_h/2)
+ dc.SetPen(oldPen)
+
# restore normal font
dc.SetFont(self._normalFont)
@@ -7172,9 +7351,14 @@
Internal function. Starts the editing of an item label, sending a
``EVT_TREE_BEGIN_LABEL_EDIT`` event.
- :param `item`: an instance of L{GenericTreeItem}.
+ :param `item`: an instance of L{GenericTreeItem}.
+
+ :warning: Separator-type items can not be edited.
"""
+ if item.IsSeparator():
+ return
+
te = TreeEvent(wxEVT_TREE_BEGIN_LABEL_EDIT, self.GetId())
te._item = item
te.SetEventObject(self)
@@ -7724,7 +7908,11 @@
self.absoluteWindows[level] = image_w+text_w+wcheck+2
elif align == 1:
self.absoluteWindows[level] = max(self.absoluteWindows[level], image_w+text_w+wcheck+2)
-
+
+ if item.IsSeparator():
+ totalWidth = self.GetClientSize()[0]
+ totalHeight = total_h
+
item.SetWidth(totalWidth)
item.SetHeight(totalHeight)
@@ -8136,3 +8324,4 @@
GetClassDefaultAttributes = classmethod(GetClassDefaultAttributes)
+