Replacing sizers structure for locations tree by a treectrl in Topology panel in order to make refreshing of this panel faster
authorlaurent
Fri, 09 Dec 2011 10:32:06 +0100
changeset 650 26236e691330
parent 649 c48023b6f0ec
child 651 cbeb769b0a56
Replacing sizers structure for locations tree by a treectrl in Topology panel in order to make refreshing of this panel faster
Beremiz.py
LPCBeremiz.py
--- a/Beremiz.py	Fri Dec 09 10:26:56 2011 +0100
+++ b/Beremiz.py	Fri Dec 09 10:32:06 2011 +0100
@@ -26,6 +26,7 @@
 updateinfo_url = None
 
 import os, sys, getopt, wx
+import __builtin__
 from wx.lib.agw.advancedsplash import AdvancedSplash
 import tempfile
 import shutil
@@ -70,9 +71,9 @@
         buildpath = None
     
     if os.path.exists("BEREMIZ_DEBUG"):
-        __builtins__.BMZ_DBG = True
+        __builtin__.__dict__["BMZ_DBG"] = True
     else :
-        __builtins__.BMZ_DBG = False
+        __builtin__.__dict__["BMZ_DBG"] = False
 
     app = wx.PySimpleApp(redirect=BMZ_DBG)
     app.SetAppName('beremiz')
@@ -106,7 +107,6 @@
 
 # Import module for internationalization
 import gettext
-import __builtin__
 
 # Get folder containing translation files
 localedir = os.path.join(CWD,"locale")
@@ -148,7 +148,7 @@
 from wxPopen import ProcessLogger
 
 from docutils import *
-from PLCOpenEditor import IDEFrame, Viewer, AppendMenu, TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, SCALING, PAGETITLES
+from PLCOpenEditor import IDEFrame, Viewer, AppendMenu, TITLE, TOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, TYPESTREE, INSTANCESTREE, LIBRARYTREE, SCALING, PAGETITLES, USE_AUI
 from PLCControler import LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY
 
 SCROLLBAR_UNIT = 10
@@ -423,7 +423,7 @@
         self.SetAcceleratorTable(wx.AcceleratorTable(accels))
         
         self.PLCConfig = wx.ScrolledWindow(id=ID_BEREMIZPLCCONFIG,
-              name='PLCConfig', parent=self.LeftNoteBook, pos=wx.Point(0, 0),
+              name='PLCConfig', parent=self.BottomNoteBook, pos=wx.Point(0, 0),
               size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER|wx.HSCROLL|wx.VSCROLL)
         self.PLCConfig.SetBackgroundColour(wx.WHITE)
         self.PLCConfig.Bind(wx.EVT_LEFT_DOWN, self.OnPanelLeftDown)
@@ -436,7 +436,8 @@
                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
         self.LogConsole.Bind(wx.EVT_LEFT_DCLICK, self.OnLogConsoleDClick)
         self.BottomNoteBook.AddPage(self.LogConsole, _("Log Console"))
-        self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
+        if USE_AUI:
+            self.BottomNoteBook.Split(self.BottomNoteBook.GetPageIndex(self.LogConsole), wx.RIGHT)
         
         self._init_beremiz_sizers()
 
@@ -454,6 +455,23 @@
         
         self.PluginInfos = {}
         
+        # Define Tree item icon list
+        self.LocationImageList = wx.ImageList(16, 16)
+        self.LocationImageDict = {}
+        
+        # Icons for location items
+        for imgname, itemtype in [
+            ("CONFIGURATION", LOCATION_PLUGIN),
+            ("RESOURCE",      LOCATION_MODULE),
+            ("PROGRAM",       LOCATION_GROUP),
+            ("VAR_INPUT",     LOCATION_VAR_INPUT),
+            ("VAR_OUTPUT",    LOCATION_VAR_OUTPUT),
+            ("VAR_LOCAL",     LOCATION_VAR_MEMORY)]:
+            self.LocationImageDict[itemtype]=self.LocationImageList.Add(wx.Bitmap(os.path.join(base_folder, "plcopeneditor", 'Images', '%s.png'%imgname)))
+        
+        # Add beremiz's icon in top left corner of the frame
+        self.SetIcon(wx.Icon(Bpath( "images", "brz.ico"), wx.BITMAP_TYPE_ICO))
+        
         if projectOpen is not None and os.path.isdir(projectOpen):
             self.PluginRoot = PluginsRoot(self, self.Log)
             self.Controler = self.PluginRoot
@@ -472,10 +490,6 @@
                 self.RefreshAll()
         if self.EnableDebug:
             self.DebugVariablePanel.SetDataProducer(self.PluginRoot)
-                
-        
-        # Add beremiz's icon in top left corner of the frame
-        self.SetIcon(wx.Icon(Bpath( "images", "brz.ico"), wx.BITMAP_TYPE_ICO))
         
         self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
         
@@ -816,23 +830,36 @@
             if force:
                 locations_infos["root"]["expanded"] = False
 
-    def ExpandLocation(self, locations_infos, group, force = False):
-        for child in locations_infos[group]["children"]:
-            locations_infos[child]["left"].Show()
-            locations_infos[child]["right"].Show()
-            if force or locations_infos[child]["expanded"]:
-                self.ExpandLocation(locations_infos, child, force)
-                if force:
-                    locations_infos[child]["expanded"] = True
-    
-    def CollapseLocation(self, locations_infos, group, force = False):
-        for child in locations_infos[group]["children"]:
-            locations_infos[child]["left"].Hide()
-            locations_infos[child]["right"].Hide()
-            self.CollapseLocation(locations_infos, child, force)
+    def ExpandLocation(self, locations_infos, group, force = False, refresh_size=True):
+        locations_infos[group]["expanded"] = True
+        if group == "root":
+            if locations_infos[group]["left"] is not None:
+                locations_infos[group]["left"].Show()
+            if locations_infos[group]["right"] is not None:
+                locations_infos[group]["right"].Show()
+        elif locations_infos["root"]["left"] is not None:
+            locations_infos["root"]["left"].Expand(locations_infos[group]["item"])
             if force:
-                locations_infos[child]["expanded"] = False
-
+                for child in locations_infos[group]["children"]:
+                    self.ExpandLocation(locations_infos, child, force, False)
+        if locations_infos["root"]["left"] is not None and refresh_size:
+            self.RefreshTreeCtrlSize(locations_infos["root"]["left"])
+        
+    def CollapseLocation(self, locations_infos, group, force = False, refresh_size=True):
+        locations_infos[group]["expanded"] = False
+        if group == "root":
+            if locations_infos[group]["left"] is not None:
+                locations_infos[group]["left"].Hide()
+            if locations_infos[group]["right"] is not None:
+                locations_infos[group]["right"].Hide()
+        elif locations_infos["root"]["left"] is not None:
+            locations_infos["root"]["left"].Collapse(locations_infos[group]["item"])
+            if force:
+                for child in locations_infos[group]["children"]:
+                    self.CollapseLocation(locations_infos, child, force, False)
+        if locations_infos["root"]["left"] is not None and refresh_size:
+            self.RefreshTreeCtrlSize(locations_infos["root"]["left"])
+                
     def GenerateTreeBranch(self, plugin):
         leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
         if plugin.PlugTestModified():
@@ -851,7 +878,9 @@
             plugin_locations = plugin.GetVariableLocationTree()["children"]
             if not self.PluginInfos[plugin].has_key("locations_infos"):
                 self.PluginInfos[plugin]["locations_infos"] = {"root": {"expanded" : False}}
-                
+            
+            self.PluginInfos[plugin]["locations_infos"]["root"]["left"] = None
+            self.PluginInfos[plugin]["locations_infos"]["root"]["right"] = None
             self.PluginInfos[plugin]["locations_infos"]["root"]["children"] = []
         
         self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
@@ -1047,122 +1076,112 @@
             self.GenerateTreeBranch(child)
             if not self.PluginInfos[child]["expanded"]:
                 self.CollapsePlugin(child)
+        
         if len(plugin_locations) > 0:
             locations_infos = self.PluginInfos[plugin]["locations_infos"]
+            treectrl = wx.TreeCtrl(self.PLCConfig, -1, size=wx.DefaultSize, 
+                                   style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.NO_BORDER|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_LINES_AT_ROOT)
+            treectrl.SetImageList(self.LocationImageList)
+            treectrl.Bind(wx.EVT_TREE_BEGIN_DRAG, self.GenerateLocationBeginDragFunction(locations_infos))
+            treectrl.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.GenerateLocationExpandCollapseFunction(locations_infos, True))
+            treectrl.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.GenerateLocationExpandCollapseFunction(locations_infos, False))
+            
+            treectrl.AddRoot("")
+            self.PluginTreeSizer.AddWindow(treectrl, 0, border=0, flag=0)
+            
+            rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
+            rightwindow.SetBackgroundColour(wx.WHITE)
+            self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
+            
+            locations_infos["root"]["left"] = treectrl
+            locations_infos["root"]["right"] = rightwindow
             for location in plugin_locations:
                 locations_infos["root"]["children"].append("root.%s" % location["name"])
-                self.GenerateLocationTreeBranch(locations_infos, "root", location)
-            if not locations_infos["root"]["expanded"]:
-                self.CollapseLocation(locations_infos, "root")
-        
-    LOCATION_BITMAP = {LOCATION_PLUGIN: "CONFIGURATION",
-                       LOCATION_MODULE: "RESOURCE",
-                       LOCATION_GROUP: "PROGRAM",
-                       LOCATION_VAR_INPUT: "VAR_INPUT",
-                       LOCATION_VAR_OUTPUT: "VAR_OUTPUT",
-                       LOCATION_VAR_MEMORY: "VAR_LOCAL"}
-    
-    def GenerateLocationTreeBranch(self, locations_infos, parent, location):
-        leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
-        self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
-        
-        leftwindowsizer = wx.BoxSizer(wx.HORIZONTAL)
-        leftwindow.SetSizer(leftwindowsizer)
-        
-        rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
-        self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
-        
+                self.GenerateLocationTreeBranch(treectrl, treectrl.GetRootItem(), locations_infos, "root", location)
+                treectrl.Expand(treectrl.GetRootItem())
+            if locations_infos["root"]["expanded"]:
+                self.ExpandLocation(locations_infos, "root")
+            else:
+                self.RefreshTreeCtrlSize(treectrl)
+    
+    def GenerateLocationTreeBranch(self, treectrl, root, locations_infos, parent, location):
         location_name = "%s.%s" % (parent, location["name"])
         if not locations_infos.has_key(location_name):
             locations_infos[location_name] = {"expanded" : False}
         
-        if location["type"] in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP]:
-            if location["type"] == LOCATION_GROUP:
-                leftwindow.SetBackgroundColour(wx.WHITE)
-                rightwindow.SetBackgroundColour(wx.WHITE)
-            else:
-                leftwindow.SetBackgroundColour(WINDOW_COLOUR)
-                rightwindow.SetBackgroundColour(WINDOW_COLOUR)
-            
-            st = wx.StaticText(leftwindow, -1)
-            st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
-            st.SetLabel(location["location"])
-            leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT)
-            
-            expandbutton_id = wx.NewId()
-            expandbutton = wx.lib.buttons.GenBitmapToggleButton(id=expandbutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'plus.png')),
-                  name='ExpandButton', parent=leftwindow, pos=wx.Point(0, 0),
-                  size=wx.Size(13, 13), style=wx.NO_BORDER)
-            expandbutton.labelDelta = 0
-            expandbutton.SetBezelWidth(0)
-            expandbutton.SetUseFocusIndicator(False)
-            expandbutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'minus.png')))
-            expandbutton.SetToggle(locations_infos[location_name]["expanded"])
-                
-            if len(location["children"]) > 0:
-                def togglebutton(event):
-                    if expandbutton.GetToggle():
-                        self.ExpandLocation(locations_infos, location_name)
-                    else:
-                        self.CollapseLocation(locations_infos, location_name)
-                    locations_infos[location_name]["expanded"] = expandbutton.GetToggle()
-                    self.PLCConfigMainSizer.Layout()
-                    self.RefreshScrollBars()
-                    event.Skip()
-                expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id)
-            else:
-                expandbutton.Enable(False)
-            leftwindowsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
-            
+        if location["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]:
+            label = "%(name)s (%(location)s)" % location
+        elif location["location"] != "":
+            label = "%(location)s: %(name)s" % location
         else:
-            leftwindow.SetBackgroundColour(wx.WHITE)
-            rightwindow.SetBackgroundColour(wx.WHITE)
-            
-            leftwindowsizer.Add(wx.Size(20, 16), 0)
-        
-        sb = wx.StaticBitmap(leftwindow, -1)
-        icon = location.get("icon")
-        if icon is None:
-            icon = os.path.join(base_folder, "plcopeneditor", 'Images', '%s.png' % self.LOCATION_BITMAP[location["type"]])
-        sb.SetBitmap(wx.Bitmap(icon))
-        leftwindowsizer.AddWindow(sb, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
-        
-        st_id = wx.NewId()
-        st = wx.StaticText(leftwindow, st_id, size=wx.DefaultSize, style=wx.NO_BORDER)
-        label = location["name"]
-        if location["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]:
-            label += " (%s)" % location["location"]
-            infos = location.copy()
-            infos.pop("children")
-            st.SetFont(wx.Font(faces["size"] * 0.5, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]))
-            leftcallback = self.GenerateLocationLeftDownFunction(infos)
-            st.Bind(wx.EVT_LEFT_DOWN, leftcallback)
-            sb.Bind(wx.EVT_LEFT_DOWN, leftcallback)
-        elif location["type"] == LOCATION_GROUP:
-            st.SetFont(wx.Font(faces["size"] * 0.6, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]))
-        else:
-            st.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"]))
-        st.SetLabel(label)
-        leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
-        
-        locations_infos[location_name]["left"] = leftwindow
-        locations_infos[location_name]["right"] = rightwindow
+            label = location["name"]
+        item = treectrl.AppendItem(root, label)
+        treectrl.SetPyData(item, location_name)
+        treectrl.SetItemImage(item, self.LocationImageDict[location["type"]])
+        
+        locations_infos[location_name]["item"] = item
         locations_infos[location_name]["children"] = []
+        infos = location.copy()
+        infos.pop("children")
+        locations_infos[location_name]["infos"] = infos
         for child in location["children"]:
             child_name = "%s.%s" % (location_name, child["name"])
             locations_infos[location_name]["children"].append(child_name)
-            self.GenerateLocationTreeBranch(locations_infos, location_name, child)
-        if not locations_infos[location_name]["expanded"]:
-            self.CollapseLocation(locations_infos, location_name)
-    
-    def GenerateLocationLeftDownFunction(self, infos):
-        def OnLocationLeftDownFunction(event):
-            data = wx.TextDataObject(str((infos["location"], "location", infos["IEC_type"], infos["name"], infos["description"])))
-            dragSource = wx.DropSource(self)
-            dragSource.SetData(data)
-            dragSource.DoDragDrop()
+            self.GenerateLocationTreeBranch(treectrl, item, locations_infos, location_name, child)
+        if locations_infos[location_name]["expanded"]:
+            self.ExpandLocation(locations_infos, location_name)
+    
+    def GenerateLocationBeginDragFunction(self, locations_infos):
+        def OnLocationBeginDragFunction(event):
+            item = event.GetItem()
+            location_name = locations_infos["root"]["left"].GetPyData(item)
+            if location_name is not None:
+                infos = locations_infos[location_name]["infos"]
+                if infos["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]:
+                    data = wx.TextDataObject(str((infos["location"], "location", infos["IEC_type"], infos["name"], infos["description"])))
+                    dragSource = wx.DropSource(self)
+                    dragSource.SetData(data)
+                    dragSource.DoDragDrop()
+        return OnLocationBeginDragFunction
+    
+    def RefreshTreeCtrlSize(self, treectrl):
+        rect = self.GetTreeCtrlItemRect(treectrl, treectrl.GetRootItem())
+        treectrl.SetMinSize(wx.Size(max(rect.width, rect.x + rect.width) + 20, max(rect.height, rect.y + rect.height) + 10))
+        self.PLCConfigMainSizer.Layout()
+        self.PLCConfig.Refresh()
+    
+    def GetTreeCtrlItemRect(self, treectrl, item):
+        item_rect = treectrl.GetBoundingRect(item, True)
+        if item_rect is not None:
+            minx, miny = item_rect.x, item_rect.y
+            maxx, maxy = item_rect.x + item_rect.width, item_rect.y + item_rect.height
+        else:
+            minx = miny = maxx = maxy = 0
+        
+        if treectrl.ItemHasChildren(item) and (item == treectrl.GetRootItem() or treectrl.IsExpanded(item)):
+            if wx.VERSION >= (2, 6, 0):
+                child, item_cookie = treectrl.GetFirstChild(item)
+            else:
+                child, item_cookie = treectrl.GetFirstChild(item, 0)
+            while child.IsOk():
+                child_rect = self.GetTreeCtrlItemRect(treectrl, child)
+                minx = min(minx, child_rect.x)
+                miny = min(miny, child_rect.y)
+                maxx = max(maxx, child_rect.x + child_rect.width)
+                maxy = max(maxy, child_rect.y + child_rect.height)
+                child, item_cookie = treectrl.GetNextChild(item, item_cookie)
+                
+        return wx.Rect(minx, miny, maxx - minx, maxy - miny)
+    
+    def GenerateLocationExpandCollapseFunction(self, locations_infos, expand):
+        def OnLocationExpandedFunction(event):
+            item = event.GetItem()
+            location_name = locations_infos["root"]["left"].GetPyData(item)
+            if location_name is not None:
+                locations_infos[location_name]["expanded"] = expand
+                self.RefreshTreeCtrlSize(locations_infos["root"]["left"])
             event.Skip()
-        return OnLocationLeftDownFunction
+        return OnLocationExpandedFunction
     
     def RefreshAll(self):
         self.RefreshPLCParams()
--- a/LPCBeremiz.py	Fri Dec 09 10:26:56 2011 +0100
+++ b/LPCBeremiz.py	Fri Dec 09 10:32:06 2011 +0100
@@ -6,6 +6,7 @@
 __version__ = "$Revision$"
 
 import os, sys, getopt, wx, tempfile
+import __builtin__
 from types import TupleType, StringType, UnicodeType
 
 CWD = os.path.split(os.path.realpath(__file__))[0]
@@ -43,9 +44,9 @@
             sys.exit()
 
     if os.path.exists("LPC_DEBUG"):
-        __builtins__.BMZ_DBG = True
+        __builtin__.__dict__["BMZ_DBG"] = True
     else :
-        __builtins__.BMZ_DBG = False
+        __builtin__.__dict__["BMZ_DBG"] = False
 
 app = wx.PySimpleApp(redirect=BMZ_DBG)
 app.SetAppName('beremiz')
@@ -53,7 +54,6 @@
 
 # Import module for internationalization
 import gettext
-import __builtin__
 
 if __name__ == '__main__':
     __builtin__.__dict__['_'] = wx.GetTranslation#unicode_translation
@@ -1022,7 +1022,9 @@
             plugin_locations = plugin_infos["children"]
             if not self.PluginInfos[plugin].has_key("locations_infos"):
                 self.PluginInfos[plugin]["locations_infos"] = {"root": {"expanded" : False}}
-                
+            
+            self.PluginInfos[plugin]["locations_infos"]["root"]["left"] = None
+            self.PluginInfos[plugin]["locations_infos"]["root"]["right"] = None
             self.PluginInfos[plugin]["locations_infos"]["root"]["children"] = []
         
         self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW)
@@ -1077,8 +1079,10 @@
         sb = wx.StaticBitmap(leftwindow, -1)
         icon = plugin_infos.get("icon", None)
         if icon is None:
-            icon = os.path.join(base_folder, "plcopeneditor", 'Images', '%s.png' % self.LOCATION_BITMAP[plugin_infos["type"]])
-        sb.SetBitmap(wx.Bitmap(icon))
+            icon_bitmap = self.LocationImageList.GetBitmap(self.LocationImageDict[plugin_infos["type"]])
+        else: 
+            icon_bitmap = wx.Bitmap(icon)
+        sb.SetBitmap(icon_bitmap)
         leftwindowsizer.AddWindow(sb, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
         
         st_id = wx.NewId()
@@ -1098,13 +1102,30 @@
             self.GenerateTreeBranch(child)
             if not self.PluginInfos[child]["expanded"]:
                 self.CollapsePlugin(child)
+        
         if len(plugin_locations) > 0:
             locations_infos = self.PluginInfos[plugin]["locations_infos"]
+            treectrl = wx.TreeCtrl(self.PLCConfig, -1, size=wx.DefaultSize, 
+                                   style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.NO_BORDER|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_LINES_AT_ROOT)
+            treectrl.SetImageList(self.LocationImageList)
+            treectrl.Bind(wx.EVT_TREE_BEGIN_DRAG, self.GenerateLocationBeginDragFunction(locations_infos))
+            treectrl.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.GenerateLocationExpandCollapseFunction(locations_infos, True))
+            treectrl.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.GenerateLocationExpandCollapseFunction(locations_infos, False))
+            
+            treectrl.AddRoot("")
+            self.PluginTreeSizer.AddWindow(treectrl, 0, border=0, flag=0)
+            
+            rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1))
+            rightwindow.SetBackgroundColour(wx.WHITE)
+            self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW)
+            
+            locations_infos["root"]["left"] = treectrl
+            locations_infos["root"]["right"] = rightwindow
             for location in plugin_locations:
                 locations_infos["root"]["children"].append("root.%s" % location["name"])
-                self.GenerateLocationTreeBranch(locations_infos, "root", location)
-            if not locations_infos["root"]["expanded"]:
-                self.CollapseLocation(locations_infos, "root")
+                self.GenerateLocationTreeBranch(treectrl, treectrl.GetRootItem(), locations_infos, "root", location)
+            if locations_infos["root"]["expanded"]:
+                self.ExpandLocation(locations_infos, "root")
 
 class StdoutPseudoFile: