From addb1906c92526858574e08b380f76c006c036e8 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 25 Sep 2018 15:18:22 -0700 Subject: [PATCH] Merge branch 'HelioGuilherme66-40xcustomtreectrl' into wxPy-4.0.x (cherry picked from commit 32ae30b988d9ec836569746667b05afa6b74bf3b) --- CHANGES.rst | 4 ++ demo/agw/CustomTreeCtrl.py | 94 ++++++++++++++++++++++++++-- demo/agw/bitmaps/recording.gif | Bin 0 -> 852 bytes wx/lib/agw/customtreectrl.py | 108 ++++++++++++++++++++++++--------- 4 files changed, 173 insertions(+), 33 deletions(-) create mode 100644 demo/agw/bitmaps/recording.gif diff --git a/CHANGES.rst b/CHANGES.rst index b1bce607..a22e23f9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -114,6 +114,10 @@ Changes in this release include the following: * Fix rendering and mouse sensitivity in UltimateListCtrl when adding HyperText items. (#1010) +* Added a parameter to lib.agw.CustomTreeCtrl.SetItemWindow(), to allow + positioning the Window (a small image) on the left of text in a + CustomTreeItem. (#PR886). + diff --git a/demo/agw/CustomTreeCtrl.py b/demo/agw/CustomTreeCtrl.py index 6b9e4c10..a9180c10 100644 --- a/demo/agw/CustomTreeCtrl.py +++ b/demo/agw/CustomTreeCtrl.py @@ -848,8 +848,8 @@ class CustomTreeCtrlDemo(wx.Panel): check = wx.CheckBox(pnl, -1, event) eventssizer.Add(check, 0, tags, 3) - if event in ["EVT_TREE_ITEM_EXPANDED", "EVT_TREE_ITEM_COLLAPSED", - "EVT_TREE_SEL_CHANGED", "EVT_TREE_SEL_CHANGING"]: + if event in ["EVT_TREE_ITEM_EXPANDED", "EVT_TREE_ITEM_EXPANDING", "EVT_TREE_ITEM_COLLAPSED", + "EVT_TREE_ITEM_COLLAPSING", "EVT_TREE_SEL_CHANGED", "EVT_TREE_SEL_CHANGING"]: check.SetValue(1) @@ -921,6 +921,9 @@ class CustomTreeCtrlDemo(wx.Panel): leftimagelist = wx.CheckBox(pnl, -1, "Use Left ImageList") leftimagelist.Bind(wx.EVT_CHECKBOX, self.OnLeftImageList) + self.windowposition = wx.CheckBox(pnl, -1, "Use Image Window Left of Label") + self.windowposition.Bind(wx.EVT_CHECKBOX, self.OnWindowPos) + colourssizer.Add(sizer1, 0, wx.EXPAND) colourssizer.Add(sizer2, 0, wx.EXPAND) colourssizer.Add(sizer3, 0, wx.EXPAND) @@ -928,6 +931,7 @@ class CustomTreeCtrlDemo(wx.Panel): colourssizer.Add(sizer5, 0, wx.EXPAND) colourssizer.Add(sizer6, 0, wx.EXPAND) colourssizer.Add(leftimagelist, 0, wx.ALL, 5) + colourssizer.Add(self.windowposition, 0, wx.ALL, 5) sizera = wx.BoxSizer(wx.HORIZONTAL) self.checknormal = wx.CheckBox(pnl, -1, "Standard Colours") @@ -1012,6 +1016,7 @@ class CustomTreeCtrlDemo(wx.Panel): self.tree.Destroy() self.tree = newtree # Todo: The settings in the leftpanel should be reset too + # self.PopulateLeftPanel(self.tree.styles, self.tree.events) # Crashes on LeftImage selection def OnCheckStyle(self, event): @@ -1175,6 +1180,18 @@ class CustomTreeCtrlDemo(wx.Panel): self.tree.Refresh() + def OnWindowPos(self, event): + + checked = event.IsChecked() + self.tree.window_on_the_right = not checked + animIcon = self.tree.FindItem(self.tree.GetRootItem(), "item 1-f-4") + parentIcon = self.tree.GetItemParent(animIcon) + self.tree.Expand(parentIcon) + self.tree.Collapse(parentIcon) + self.tree.EnsureVisible(animIcon) + self.tree.RefreshItemWithWindows() # only if the style TR_ALIGN_WINDOWS_RIGHT is used + self.tree.Refresh() # Ineffective (only updates when collapse/expand) + def OnCheckNormal(self, event): self.radiohorizontal.Enable(False) @@ -1291,6 +1308,11 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): self.events = events self.styles = treestyles self.item = None + self.windowed_item = None + # To set the position on Window image (default==True) + self.window_on_the_right = True + self._animctrl = None + self.anim_gif_item = None # EVT_TREE_ITEM_CHECKED to update position il = wx.ImageList(16, 16) @@ -1326,6 +1348,12 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): combobox.Bind(wx.EVT_COMBOBOX, self.OnComboBox) lenArtIds = len(ArtIDs) - 2 + # This is for SetWindow on TreeItem, when collapsed is on the right, on the left otherwise + self.img = list() + self.img.append(wx.Bitmap("./bitmaps/pause.png", wx.BITMAP_TYPE_PNG)) + self.img.append(wx.Bitmap("./bitmaps/play.png", wx.BITMAP_TYPE_PNG)) + self.Image = wx.StaticBitmap(self, -1, bitmap=self.img[0]) + for x in range(15): if x == 1: child = self.AppendItem(self.root, "Item %d" % x + "\nHello World\nHappy wxPython-ing!") @@ -1342,7 +1370,7 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): if random.randint(0, 5) == 0: self.AppendSeparator(self.root) - for y in range(5): + for y in range(6): if y == 0 and x == 1: last = self.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y)), ct_type=2, wnd=self.gauge) elif y == 1 and x == 2: @@ -1354,6 +1382,10 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): last = self.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y))) elif y == 4 and x == 1: last = self.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y)), wnd=combobox) + elif y == 5 and x == 1: + last = self.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y))) + last.SetWindow(self.Image, self.window_on_the_right) # Add the Window on on_the_right=True + self.windowed_item = last else: last = self.AppendItem(child, "item %d-%s" % (x, chr(ord("a")+y)), ct_type=2) @@ -1372,6 +1404,9 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): item = self.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z), ct_type=1) if random.randint(0, 3) == 1: self.SetItem3State(item, True) + if z == 4 and y == 5 and x == 1: + self._add_animated_gif(item, self.window_on_the_right) + self.anim_gif_item = item elif 0 < z <= 2: item = self.AppendItem(last, "item %d-%s-%d" % (x, chr(ord("a")+y), z), ct_type=2) elif z == 0: @@ -1405,7 +1440,9 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): if not hasattr(mainframe, "leftpanel"): self.Bind(CT.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded) + self.Bind(CT.EVT_TREE_ITEM_EXPANDING, self.OnItemExpanding) self.Bind(CT.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed) + self.Bind(CT.EVT_TREE_ITEM_COLLAPSING, self.OnItemCollapsing) self.Bind(CT.EVT_TREE_SEL_CHANGED, self.OnSelChanged) self.Bind(CT.EVT_TREE_SEL_CHANGING, self.OnSelChanging) self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) @@ -1838,7 +1875,13 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): item = event.GetItem() if item: self.log.write("OnItemExpanding: %s" % self.GetItemText(item) + "\n") - + if item == self.windowed_item: + item.DeleteWindow() + self.Image = wx.StaticBitmap(self, -1, bitmap=self.img[1]) + item.SetWindow(self.Image, self.window_on_the_right) + child = self.GetLastChild(item) + if child == self.anim_gif_item: + self._add_animated_gif(self.anim_gif_item, self.window_on_the_right) event.Skip() @@ -1854,9 +1897,48 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): item = event.GetItem() if item: self.log.write("OnItemCollapsing: %s" % self.GetItemText(item) + "\n") - + if item == self.windowed_item: + item.DeleteWindow() + self.Image = wx.StaticBitmap(self, -1, bitmap=self.img[0]) + item.SetWindow(self.Image, self.window_on_the_right) + # Lets hide all Windows + self._collapse_node(item, lambda t: self._hideanimation(t)) event.Skip() + def _collapse_node(self, item, func): + item_was_expanded = self.IsExpanded(item) + if item != self.GetRootItem(): + func(item) + if not self.IsExpanded(item): + return + + for child in item.GetChildren(): + self._collapse_node(child, func) + + if not item_was_expanded: + self.Collapse(item) + + def _hideanimation(self, item): + itemwindow = item.GetWindow() + if itemwindow: + itemwindow.Hide() + + def _add_animated_gif(self, item, on_the_right): + if self._animctrl: + self._animctrl.Stop() + self._animctrl.Animation.Destroy() + self._animctrl.Destroy() + self._animctrl = None + + from wx.adv import Animation, AnimationCtrl + img = os.path.join(bitmapDir, 'recording.gif') + ani = Animation(img) + obj = self + rect = (item.GetX()+20, item.GetY()+1) # Overlaps item icon + self._animctrl = AnimationCtrl(obj, -1, ani, rect) + self._animctrl.SetBackgroundColour(obj.GetBackgroundColour()) + item.SetWindow(self._animctrl, on_the_right) + self._animctrl.Play() def OnSelChanged(self, event): @@ -1928,6 +2010,8 @@ class CustomTreeCtrl(CT.CustomTreeCtrl): item = event.GetItem() self.log.write("Item " + self.GetItemText(item) + " Has Been Checked!\n") + if item == self.anim_gif_item: + self._add_animated_gif(item, self.window_on_the_right) event.Skip() diff --git a/demo/agw/bitmaps/recording.gif b/demo/agw/bitmaps/recording.gif new file mode 100644 index 0000000000000000000000000000000000000000..6c2972b1d60d2a34135065d55869b4e46c64fc58 GIT binary patch literal 852 zcmZ?wbhEHb6krfwc+AW2V8)CWGiKbFFyR6ab#$EQ=s3{OumgxHDmGM9tSBg0P*5-- zA>ls^DE{a6a}5c0b_{Se(lcOYWME)W{Kub^Se%-oke{bel$xAhl)|9+lZBCsfuBJK zC=IknfPsM}^215b)vSy>Mr&ju10|9RLt4t#v|p6s6y;g}@ZLrihTQ!7?5*d%?7kUg zdEmTz%u^PZ1@9+F%Xn^G{J}9}-?ARhD-{O0s(aUWOD$6oSY5gyH&W#t*RFK?PM`xY zZ8HGbrrMa1q^jnnp>@@4UP##@xgDF{SyvgwocFJ}y#0`mtLltB)G}y`{PNn)T}bo#&Dne{uFt;=rcg7_L9e zN5cr_h`u|I_bqnc{Mq+ZmBjPyp89Gp-?r!nJl`mwIsJks3pR5!K<1=2W~O0t$D63v d-)EF}2c&0U4+)AiQ_BaGh9p&@lZGkK8UR{mNTmP( literal 0 HcmV?d00001 diff --git a/wx/lib/agw/customtreectrl.py b/wx/lib/agw/customtreectrl.py index 219ed19d..4ab4e01a 100644 --- a/wx/lib/agw/customtreectrl.py +++ b/wx/lib/agw/customtreectrl.py @@ -3,8 +3,8 @@ # Inspired By And Heavily Based On wxGenericTreeCtrl. # # Andrea Gavana, @ 17 May 2006 -# Latest Revision: 09 Jan 2014, 23.00 GMT -# +# Latest Revision: 02 Jul 2018, 00.10 GMT +# Modified by Helio Guilherme, @ 26 Apr 2018 # # TODO List # @@ -299,14 +299,14 @@ License And Version :class:`CustomTreeCtrl` is distributed under the wxPython license. -Latest Revision: Andrea Gavana @ 09 Jan 2014, 23.00 GMT +Latest Revision: Helio Guilherme @ 09 Aug 2018, 21.35 GMT -Version 2.6 +Version 2.7 """ # Version Info -__version__ = "2.6" +__version__ = "2.7" import wx from wx.lib.expando import ExpandoTextCtrl @@ -1554,7 +1554,7 @@ class GenericTreeItem(object): :class:`CustomTreeCtrl`. This is a generic implementation of :class:`TreeItem`. """ - def __init__(self, parent, text="", ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): + def __init__(self, parent, text="", ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False, on_the_right=True): """ Default class constructor. For internal use: do not call it in your code! @@ -1581,6 +1581,8 @@ class GenericTreeItem(object): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :note: Regarding radiobutton-type items (with `ct_type` = 2), the following approach is used: @@ -1663,9 +1665,10 @@ class GenericTreeItem(object): self._enabled = False self._wnd = wnd # are we holding a window? + self._windowontheright = on_the_right # on the right, or left? if wnd: - self.SetWindow(wnd) + self.SetWindow(wnd, on_the_right) def IsOk(self): @@ -1909,13 +1912,16 @@ class GenericTreeItem(object): self._width = w - def SetWindow(self, wnd): + def SetWindow(self, wnd, on_the_right=True): """ Sets the window associated to the item. :param `wnd`: a non-toplevel window to be displayed next to the item, any subclass of :class:`wx.Window`. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. New in wxPython 4.0.4. + :raise: `Exception` if the input `item` is a separator and `wnd` is not ``None``. """ @@ -1923,6 +1929,7 @@ class GenericTreeItem(object): raise Exception("Separator items can not have an associated window") self._wnd = wnd + self._windowontheright = on_the_right if wnd.GetSizer(): # the window is a complex one hold by a sizer size = wnd.GetBestSize() @@ -1935,6 +1942,11 @@ class GenericTreeItem(object): # Do better strategies exist? self._wnd.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) + # We also have to bind the wx.EVT_TREE_ITEM_COLLAPSING for the + # associated window, for example when it is an agw.animate.AnimationCtrl, + # otherwise it would stay visible. See the demo for an example. + self._wnd.Bind(wx.EVT_TREE_ITEM_COLLAPSING, self.OnTreeItemCollapsing) + self._height = size.GetHeight() + 2 self._width = size.GetWidth() self._windowsize = size @@ -1948,6 +1960,7 @@ class GenericTreeItem(object): self._windowenabled = self._enabled + def GetWindow(self): """ Returns the window associated to the item (if any). @@ -2023,6 +2036,27 @@ class GenericTreeItem(object): event.Skip() + def OnTreeItemCollapsing(self, event): + """ + Handles the ``wx.EVT_TREE_ITEM_COLLAPSING`` event for the window associated with the item. + + :param `event`: a :class:`GenericTreeItem` to be processed. + """ + # Helio: This is not OK? + # Should it be more "internal" code? + # It is working on the user application. + for item in event.GetItem().GetChildren(): + itemwindow = item.GetWindow() + if itemwindow: # Hides the attached window if added + itemwindow.Hide() + + # Hides the attached window if added + #if self._wnd: + # self._wnd.Hide() + + event.Skip() + + def GetType(self): """ Returns the item type. @@ -4270,13 +4304,15 @@ class CustomTreeCtrl(wx.ScrolledWindow): return item.GetWindow() - def SetItemWindow(self, item, wnd): + def SetItemWindow(self, item, wnd, on_the_right=True): """ Sets the window for the given item. :param `item`: an instance of :class:`GenericTreeItem`; :param `wnd`: if not ``None``, a non-toplevel window to be displayed next to the item. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. New in wxPython 4.0.4. :raise: `Exception` if the input `item` is a separator and `wnd` is not ``None``. """ @@ -4293,7 +4329,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): else: self.DeleteItemWindow(item) - item.SetWindow(wnd) + item.SetWindow(wnd, on_the_right) self.CalculatePositions() self.Refresh() self.AdjustMyScrollbars() @@ -4850,7 +4886,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): # operations # ----------------------------------------------------------------------------- - def DoInsertItem(self, parentId, previous, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): + def DoInsertItem(self, parentId, previous, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False, on_the_right=True): """ Actually inserts an item in the tree. @@ -4869,6 +4905,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :return: An instance of :class:`GenericTreeItem` upon successful insertion. @@ -4909,7 +4947,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._dirty = True # do this first so stuff below doesn't cause flicker - item = GenericTreeItem(parent, text, ct_type, wnd, image, selImage, data, separator) + item = GenericTreeItem(parent, text, ct_type, wnd, image, selImage, data, separator, on_the_right) if wnd is not None: self._hasWindows = True @@ -4920,7 +4958,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): return item - def AddRoot(self, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None): + def AddRoot(self, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, on_the_right=True): """ Adds a root item to the :class:`CustomTreeCtrl`. @@ -4935,6 +4973,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): 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 bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :return: An instance of :class:`GenericTreeItem` upon successful insertion. @@ -4967,7 +5007,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): self._dirty = True # do this first so stuff below doesn't cause flicker - self._anchor = GenericTreeItem(None, text, ct_type, wnd, image, selImage, data) + self._anchor = GenericTreeItem(None, text, ct_type, wnd, image, selImage, data, on_the_right) if wnd is not None: self._hasWindows = True @@ -4989,7 +5029,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): return self._anchor - def PrependItem(self, parent, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): + def PrependItem(self, parent, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False, on_the_right=True): """ Prepends an item as a first child of parent. @@ -5007,16 +5047,18 @@ class CustomTreeCtrl(wx.ScrolledWindow): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :return: An instance of :class:`GenericTreeItem` upon successful insertion. :see: :meth:`~CustomTreeCtrl.DoInsertItem` for possible exceptions generated by this method. """ - return self.DoInsertItem(parent, 0, text, ct_type, wnd, image, selImage, data, separator) + return self.DoInsertItem(parent, 0, text, ct_type, wnd, image, selImage, data, separator, on_the_right) - def InsertItemByItem(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): + def InsertItemByItem(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False, on_the_right=True): """ Inserts an item after the given previous. @@ -5036,6 +5078,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :return: An instance of :class:`GenericTreeItem` upon successful insertion. @@ -5048,7 +5092,7 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not parent: # should we give a warning here? - return self.AddRoot(text, ct_type, wnd, image, selImage, data) + return self.AddRoot(text, ct_type, wnd, image, selImage, data, on_the_right) index = -1 if idPrevious: @@ -5058,10 +5102,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): 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, separator) + return self.DoInsertItem(parentId, index+1, text, ct_type, wnd, image, selImage, data, separator, on_the_right) - def InsertItemByIndex(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): + def InsertItemByIndex(self, parentId, idPrevious, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False, on_the_right=True): """ Inserts an item after the given previous. @@ -5080,6 +5124,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): same image is used for both selected and unselected items; :param object `data`: associate the given Python object `data` with the item; :param bool `separator`: ``True`` if the item is a separator, ``False`` otherwise. + :param bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :return: An instance of :class:`GenericTreeItem` upon successful insertion. @@ -5092,10 +5138,10 @@ class CustomTreeCtrl(wx.ScrolledWindow): # 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, separator) + return self.DoInsertItem(parentId, idPrevious, text, ct_type, wnd, image, selImage, data, separator, on_the_right) - def InsertItem(self, parentId, input, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False): + def InsertItem(self, parentId, input, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, separator=False, on_the_right=True): """ Inserts an item after the given previous. @@ -5108,12 +5154,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): """ if type(input) == type(1): - return self.InsertItemByIndex(parentId, input, text, ct_type, wnd, image, selImage, data, separator) + return self.InsertItemByIndex(parentId, input, text, ct_type, wnd, image, selImage, data, separator, on_the_right) else: - return self.InsertItemByItem(parentId, input, text, ct_type, wnd, image, selImage, data, separator) + return self.InsertItemByItem(parentId, input, text, ct_type, wnd, image, selImage, data, separator, on_the_right) - def AppendItem(self, parentId, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None): + def AppendItem(self, parentId, text, ct_type=0, wnd=None, image=-1, selImage=-1, data=None, on_the_right=True): """ Appends an item as a last child of its parent. @@ -5130,6 +5176,8 @@ class CustomTreeCtrl(wx.ScrolledWindow): 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 bool `on_the_right`: ``True`` positions the window on the right of text, ``False`` + on the left of text and overlapping the image. :return: An instance of :class:`GenericTreeItem` upon successful insertion. @@ -5140,9 +5188,9 @@ class CustomTreeCtrl(wx.ScrolledWindow): if not parent: # should we give a warning here? - return self.AddRoot(text, ct_type, wnd, image, selImage, data) + return self.AddRoot(text, ct_type, wnd, image, selImage, data, on_the_right) - return self.DoInsertItem(parent, len(parent.GetChildren()), text, ct_type, wnd, image, selImage, data) + return self.DoInsertItem(parent, len(parent.GetChildren()), text, ct_type, wnd, image, selImage, data, False, on_the_right) def AppendSeparator(self, parentId): @@ -6723,8 +6771,12 @@ class CustomTreeCtrl(wx.ScrolledWindow): dc.DrawLabel(itemText, textrect) wnd = item.GetWindow() + on_right = item._windowontheright # Helio: Should I make a getter? if wnd: - wndx = wcheck + image_w + item.GetX() + text_w + 4 + if on_right: # Helio: Original behaviour + wndx = wcheck + image_w + item.GetX() + text_w + 4 + else: + wndx = wcheck + item.GetX() xa, ya = self.CalcScrolledPosition((0, item.GetY())) wndx += xa if item.GetHeight() > item.GetWindowSize()[1]: