814 if locations_infos is not None: |
828 if locations_infos is not None: |
815 self.CollapseLocation(locations_infos, "root", force) |
829 self.CollapseLocation(locations_infos, "root", force) |
816 if force: |
830 if force: |
817 locations_infos["root"]["expanded"] = False |
831 locations_infos["root"]["expanded"] = False |
818 |
832 |
819 def ExpandLocation(self, locations_infos, group, force = False): |
833 def ExpandLocation(self, locations_infos, group, force = False, refresh_size=True): |
820 for child in locations_infos[group]["children"]: |
834 locations_infos[group]["expanded"] = True |
821 locations_infos[child]["left"].Show() |
835 if group == "root": |
822 locations_infos[child]["right"].Show() |
836 if locations_infos[group]["left"] is not None: |
823 if force or locations_infos[child]["expanded"]: |
837 locations_infos[group]["left"].Show() |
824 self.ExpandLocation(locations_infos, child, force) |
838 if locations_infos[group]["right"] is not None: |
825 if force: |
839 locations_infos[group]["right"].Show() |
826 locations_infos[child]["expanded"] = True |
840 elif locations_infos["root"]["left"] is not None: |
827 |
841 locations_infos["root"]["left"].Expand(locations_infos[group]["item"]) |
828 def CollapseLocation(self, locations_infos, group, force = False): |
|
829 for child in locations_infos[group]["children"]: |
|
830 locations_infos[child]["left"].Hide() |
|
831 locations_infos[child]["right"].Hide() |
|
832 self.CollapseLocation(locations_infos, child, force) |
|
833 if force: |
842 if force: |
834 locations_infos[child]["expanded"] = False |
843 for child in locations_infos[group]["children"]: |
835 |
844 self.ExpandLocation(locations_infos, child, force, False) |
|
845 if locations_infos["root"]["left"] is not None and refresh_size: |
|
846 self.RefreshTreeCtrlSize(locations_infos["root"]["left"]) |
|
847 |
|
848 def CollapseLocation(self, locations_infos, group, force = False, refresh_size=True): |
|
849 locations_infos[group]["expanded"] = False |
|
850 if group == "root": |
|
851 if locations_infos[group]["left"] is not None: |
|
852 locations_infos[group]["left"].Hide() |
|
853 if locations_infos[group]["right"] is not None: |
|
854 locations_infos[group]["right"].Hide() |
|
855 elif locations_infos["root"]["left"] is not None: |
|
856 locations_infos["root"]["left"].Collapse(locations_infos[group]["item"]) |
|
857 if force: |
|
858 for child in locations_infos[group]["children"]: |
|
859 self.CollapseLocation(locations_infos, child, force, False) |
|
860 if locations_infos["root"]["left"] is not None and refresh_size: |
|
861 self.RefreshTreeCtrlSize(locations_infos["root"]["left"]) |
|
862 |
836 def GenerateTreeBranch(self, plugin): |
863 def GenerateTreeBranch(self, plugin): |
837 leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1)) |
864 leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1)) |
838 if plugin.PlugTestModified(): |
865 if plugin.PlugTestModified(): |
839 bkgdclr=CHANGED_WINDOW_COLOUR |
866 bkgdclr=CHANGED_WINDOW_COLOUR |
840 else: |
867 else: |
1045 self.PluginInfos[plugin]["right"] = rightwindow |
1074 self.PluginInfos[plugin]["right"] = rightwindow |
1046 for child in self.PluginInfos[plugin]["children"]: |
1075 for child in self.PluginInfos[plugin]["children"]: |
1047 self.GenerateTreeBranch(child) |
1076 self.GenerateTreeBranch(child) |
1048 if not self.PluginInfos[child]["expanded"]: |
1077 if not self.PluginInfos[child]["expanded"]: |
1049 self.CollapsePlugin(child) |
1078 self.CollapsePlugin(child) |
|
1079 |
1050 if len(plugin_locations) > 0: |
1080 if len(plugin_locations) > 0: |
1051 locations_infos = self.PluginInfos[plugin]["locations_infos"] |
1081 locations_infos = self.PluginInfos[plugin]["locations_infos"] |
|
1082 treectrl = wx.TreeCtrl(self.PLCConfig, -1, size=wx.DefaultSize, |
|
1083 style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.NO_BORDER|wx.TR_HIDE_ROOT|wx.TR_NO_LINES|wx.TR_LINES_AT_ROOT) |
|
1084 treectrl.SetImageList(self.LocationImageList) |
|
1085 treectrl.Bind(wx.EVT_TREE_BEGIN_DRAG, self.GenerateLocationBeginDragFunction(locations_infos)) |
|
1086 treectrl.Bind(wx.EVT_TREE_ITEM_EXPANDED, self.GenerateLocationExpandCollapseFunction(locations_infos, True)) |
|
1087 treectrl.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.GenerateLocationExpandCollapseFunction(locations_infos, False)) |
|
1088 |
|
1089 treectrl.AddRoot("") |
|
1090 self.PluginTreeSizer.AddWindow(treectrl, 0, border=0, flag=0) |
|
1091 |
|
1092 rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1)) |
|
1093 rightwindow.SetBackgroundColour(wx.WHITE) |
|
1094 self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW) |
|
1095 |
|
1096 locations_infos["root"]["left"] = treectrl |
|
1097 locations_infos["root"]["right"] = rightwindow |
1052 for location in plugin_locations: |
1098 for location in plugin_locations: |
1053 locations_infos["root"]["children"].append("root.%s" % location["name"]) |
1099 locations_infos["root"]["children"].append("root.%s" % location["name"]) |
1054 self.GenerateLocationTreeBranch(locations_infos, "root", location) |
1100 self.GenerateLocationTreeBranch(treectrl, treectrl.GetRootItem(), locations_infos, "root", location) |
1055 if not locations_infos["root"]["expanded"]: |
1101 treectrl.Expand(treectrl.GetRootItem()) |
1056 self.CollapseLocation(locations_infos, "root") |
1102 if locations_infos["root"]["expanded"]: |
1057 |
1103 self.ExpandLocation(locations_infos, "root") |
1058 LOCATION_BITMAP = {LOCATION_PLUGIN: "CONFIGURATION", |
1104 else: |
1059 LOCATION_MODULE: "RESOURCE", |
1105 self.RefreshTreeCtrlSize(treectrl) |
1060 LOCATION_GROUP: "PROGRAM", |
1106 |
1061 LOCATION_VAR_INPUT: "VAR_INPUT", |
1107 def GenerateLocationTreeBranch(self, treectrl, root, locations_infos, parent, location): |
1062 LOCATION_VAR_OUTPUT: "VAR_OUTPUT", |
|
1063 LOCATION_VAR_MEMORY: "VAR_LOCAL"} |
|
1064 |
|
1065 def GenerateLocationTreeBranch(self, locations_infos, parent, location): |
|
1066 leftwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1)) |
|
1067 self.PluginTreeSizer.AddWindow(leftwindow, 0, border=0, flag=wx.GROW) |
|
1068 |
|
1069 leftwindowsizer = wx.BoxSizer(wx.HORIZONTAL) |
|
1070 leftwindow.SetSizer(leftwindowsizer) |
|
1071 |
|
1072 rightwindow = wx.Panel(self.PLCConfig, -1, size=wx.Size(-1, -1)) |
|
1073 self.PluginTreeSizer.AddWindow(rightwindow, 0, border=0, flag=wx.GROW) |
|
1074 |
|
1075 location_name = "%s.%s" % (parent, location["name"]) |
1108 location_name = "%s.%s" % (parent, location["name"]) |
1076 if not locations_infos.has_key(location_name): |
1109 if not locations_infos.has_key(location_name): |
1077 locations_infos[location_name] = {"expanded" : False} |
1110 locations_infos[location_name] = {"expanded" : False} |
1078 |
1111 |
1079 if location["type"] in [LOCATION_PLUGIN, LOCATION_MODULE, LOCATION_GROUP]: |
1112 if location["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]: |
1080 if location["type"] == LOCATION_GROUP: |
1113 label = "%(name)s (%(location)s)" % location |
1081 leftwindow.SetBackgroundColour(wx.WHITE) |
1114 elif location["location"] != "": |
1082 rightwindow.SetBackgroundColour(wx.WHITE) |
1115 label = "%(location)s: %(name)s" % location |
1083 else: |
|
1084 leftwindow.SetBackgroundColour(WINDOW_COLOUR) |
|
1085 rightwindow.SetBackgroundColour(WINDOW_COLOUR) |
|
1086 |
|
1087 st = wx.StaticText(leftwindow, -1) |
|
1088 st.SetFont(wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"])) |
|
1089 st.SetLabel(location["location"]) |
|
1090 leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT) |
|
1091 |
|
1092 expandbutton_id = wx.NewId() |
|
1093 expandbutton = wx.lib.buttons.GenBitmapToggleButton(id=expandbutton_id, bitmap=wx.Bitmap(Bpath( 'images', 'plus.png')), |
|
1094 name='ExpandButton', parent=leftwindow, pos=wx.Point(0, 0), |
|
1095 size=wx.Size(13, 13), style=wx.NO_BORDER) |
|
1096 expandbutton.labelDelta = 0 |
|
1097 expandbutton.SetBezelWidth(0) |
|
1098 expandbutton.SetUseFocusIndicator(False) |
|
1099 expandbutton.SetBitmapSelected(wx.Bitmap(Bpath( 'images', 'minus.png'))) |
|
1100 expandbutton.SetToggle(locations_infos[location_name]["expanded"]) |
|
1101 |
|
1102 if len(location["children"]) > 0: |
|
1103 def togglebutton(event): |
|
1104 if expandbutton.GetToggle(): |
|
1105 self.ExpandLocation(locations_infos, location_name) |
|
1106 else: |
|
1107 self.CollapseLocation(locations_infos, location_name) |
|
1108 locations_infos[location_name]["expanded"] = expandbutton.GetToggle() |
|
1109 self.PLCConfigMainSizer.Layout() |
|
1110 self.RefreshScrollBars() |
|
1111 event.Skip() |
|
1112 expandbutton.Bind(wx.EVT_BUTTON, togglebutton, id=expandbutton_id) |
|
1113 else: |
|
1114 expandbutton.Enable(False) |
|
1115 leftwindowsizer.AddWindow(expandbutton, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL) |
|
1116 |
|
1117 else: |
1116 else: |
1118 leftwindow.SetBackgroundColour(wx.WHITE) |
1117 label = location["name"] |
1119 rightwindow.SetBackgroundColour(wx.WHITE) |
1118 item = treectrl.AppendItem(root, label) |
1120 |
1119 treectrl.SetPyData(item, location_name) |
1121 leftwindowsizer.Add(wx.Size(20, 16), 0) |
1120 treectrl.SetItemImage(item, self.LocationImageDict[location["type"]]) |
1122 |
1121 |
1123 sb = wx.StaticBitmap(leftwindow, -1) |
1122 locations_infos[location_name]["item"] = item |
1124 icon = location.get("icon") |
|
1125 if icon is None: |
|
1126 icon = os.path.join(base_folder, "plcopeneditor", 'Images', '%s.png' % self.LOCATION_BITMAP[location["type"]]) |
|
1127 sb.SetBitmap(wx.Bitmap(icon)) |
|
1128 leftwindowsizer.AddWindow(sb, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL) |
|
1129 |
|
1130 st_id = wx.NewId() |
|
1131 st = wx.StaticText(leftwindow, st_id, size=wx.DefaultSize, style=wx.NO_BORDER) |
|
1132 label = location["name"] |
|
1133 if location["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]: |
|
1134 label += " (%s)" % location["location"] |
|
1135 infos = location.copy() |
|
1136 infos.pop("children") |
|
1137 st.SetFont(wx.Font(faces["size"] * 0.5, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])) |
|
1138 leftcallback = self.GenerateLocationLeftDownFunction(infos) |
|
1139 st.Bind(wx.EVT_LEFT_DOWN, leftcallback) |
|
1140 sb.Bind(wx.EVT_LEFT_DOWN, leftcallback) |
|
1141 elif location["type"] == LOCATION_GROUP: |
|
1142 st.SetFont(wx.Font(faces["size"] * 0.6, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])) |
|
1143 else: |
|
1144 st.SetFont(wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, wx.BOLD, faceName = faces["helv"])) |
|
1145 st.SetLabel(label) |
|
1146 leftwindowsizer.AddWindow(st, 0, border=5, flag=wx.RIGHT|wx.ALIGN_CENTER_VERTICAL) |
|
1147 |
|
1148 locations_infos[location_name]["left"] = leftwindow |
|
1149 locations_infos[location_name]["right"] = rightwindow |
|
1150 locations_infos[location_name]["children"] = [] |
1123 locations_infos[location_name]["children"] = [] |
|
1124 infos = location.copy() |
|
1125 infos.pop("children") |
|
1126 locations_infos[location_name]["infos"] = infos |
1151 for child in location["children"]: |
1127 for child in location["children"]: |
1152 child_name = "%s.%s" % (location_name, child["name"]) |
1128 child_name = "%s.%s" % (location_name, child["name"]) |
1153 locations_infos[location_name]["children"].append(child_name) |
1129 locations_infos[location_name]["children"].append(child_name) |
1154 self.GenerateLocationTreeBranch(locations_infos, location_name, child) |
1130 self.GenerateLocationTreeBranch(treectrl, item, locations_infos, location_name, child) |
1155 if not locations_infos[location_name]["expanded"]: |
1131 if locations_infos[location_name]["expanded"]: |
1156 self.CollapseLocation(locations_infos, location_name) |
1132 self.ExpandLocation(locations_infos, location_name) |
1157 |
1133 |
1158 def GenerateLocationLeftDownFunction(self, infos): |
1134 def GenerateLocationBeginDragFunction(self, locations_infos): |
1159 def OnLocationLeftDownFunction(event): |
1135 def OnLocationBeginDragFunction(event): |
1160 data = wx.TextDataObject(str((infos["location"], "location", infos["IEC_type"], infos["name"], infos["description"]))) |
1136 item = event.GetItem() |
1161 dragSource = wx.DropSource(self) |
1137 location_name = locations_infos["root"]["left"].GetPyData(item) |
1162 dragSource.SetData(data) |
1138 if location_name is not None: |
1163 dragSource.DoDragDrop() |
1139 infos = locations_infos[location_name]["infos"] |
|
1140 if infos["type"] in [LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY]: |
|
1141 data = wx.TextDataObject(str((infos["location"], "location", infos["IEC_type"], infos["name"], infos["description"]))) |
|
1142 dragSource = wx.DropSource(self) |
|
1143 dragSource.SetData(data) |
|
1144 dragSource.DoDragDrop() |
|
1145 return OnLocationBeginDragFunction |
|
1146 |
|
1147 def RefreshTreeCtrlSize(self, treectrl): |
|
1148 rect = self.GetTreeCtrlItemRect(treectrl, treectrl.GetRootItem()) |
|
1149 treectrl.SetMinSize(wx.Size(max(rect.width, rect.x + rect.width) + 20, max(rect.height, rect.y + rect.height) + 10)) |
|
1150 self.PLCConfigMainSizer.Layout() |
|
1151 self.PLCConfig.Refresh() |
|
1152 |
|
1153 def GetTreeCtrlItemRect(self, treectrl, item): |
|
1154 item_rect = treectrl.GetBoundingRect(item, True) |
|
1155 if item_rect is not None: |
|
1156 minx, miny = item_rect.x, item_rect.y |
|
1157 maxx, maxy = item_rect.x + item_rect.width, item_rect.y + item_rect.height |
|
1158 else: |
|
1159 minx = miny = maxx = maxy = 0 |
|
1160 |
|
1161 if treectrl.ItemHasChildren(item) and (item == treectrl.GetRootItem() or treectrl.IsExpanded(item)): |
|
1162 if wx.VERSION >= (2, 6, 0): |
|
1163 child, item_cookie = treectrl.GetFirstChild(item) |
|
1164 else: |
|
1165 child, item_cookie = treectrl.GetFirstChild(item, 0) |
|
1166 while child.IsOk(): |
|
1167 child_rect = self.GetTreeCtrlItemRect(treectrl, child) |
|
1168 minx = min(minx, child_rect.x) |
|
1169 miny = min(miny, child_rect.y) |
|
1170 maxx = max(maxx, child_rect.x + child_rect.width) |
|
1171 maxy = max(maxy, child_rect.y + child_rect.height) |
|
1172 child, item_cookie = treectrl.GetNextChild(item, item_cookie) |
|
1173 |
|
1174 return wx.Rect(minx, miny, maxx - minx, maxy - miny) |
|
1175 |
|
1176 def GenerateLocationExpandCollapseFunction(self, locations_infos, expand): |
|
1177 def OnLocationExpandedFunction(event): |
|
1178 item = event.GetItem() |
|
1179 location_name = locations_infos["root"]["left"].GetPyData(item) |
|
1180 if location_name is not None: |
|
1181 locations_infos[location_name]["expanded"] = expand |
|
1182 self.RefreshTreeCtrlSize(locations_infos["root"]["left"]) |
1164 event.Skip() |
1183 event.Skip() |
1165 return OnLocationLeftDownFunction |
1184 return OnLocationExpandedFunction |
1166 |
1185 |
1167 def RefreshAll(self): |
1186 def RefreshAll(self): |
1168 self.RefreshPLCParams() |
1187 self.RefreshPLCParams() |
1169 self.RefreshPluginTree() |
1188 self.RefreshPluginTree() |
1170 |
1189 |