--- a/svghmi/ui.py Thu May 20 12:16:51 2021 +0200
+++ b/svghmi/ui.py Mon May 31 10:08:02 2021 +0200
@@ -27,17 +27,25 @@
ScriptDirectory = paths.AbsDir(__file__)
+HMITreeDndMagicWord = "text/beremiz-hmitree" class HMITreeSelector(wx.TreeCtrl):
def __init__(self, parent):
- global on_hmitree_update
wx.TreeCtrl.__init__(self, parent, style=(
+ self.ordered_items = [] + self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeNodeSelection) + self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnTreeBeginDrag) def _recurseTree(self, current_hmitree_root, current_tc_root):
for c in current_hmitree_root.children:
if hasattr(c, "children"):
@@ -52,6 +60,37 @@
tc_child = self.AppendItem(current_tc_root, display_name)
self.SetPyData(tc_child, c)
+ def OnTreeNodeSelection(self, event): + items = self.GetSelections() + items_pydata = [self.GetPyData(item) for item in items] + # append new items to ordered item list + for item_pydata in items_pydata: + if item_pydata not in self.ordered_items: + self.ordered_items.append(item_pydata) + # filter out vanished items + for item_pydata in self.ordered_items + if item_pydata in items_pydata] + self.parent.OnHMITreeNodeSelection(self.ordered_items) + def OnTreeBeginDrag(self, event): + Called when a drag is started in tree + @param event: wx.TreeEvent + # Just send a recognizable mime-type, drop destination + # will get python data from parent + data = wx.CustomDataObject(HMITreeDndMagicWord) + dragSource = wx.DropSource(self) + dragSource.SetData(data) + dragSource.DoDragDrop() def MakeTree(self, hmi_tree_root=None):
@@ -127,21 +166,32 @@
-class PathEditor(wx.Panel):
- def __init__(self, parent, path):
+class PathDropTarget(wx.DropTarget): + def __init__(self, parent): + data = wx.CustomDataObject(HMITreeDndMagicWord) + wx.DropTarget.__init__(self, data) + self.ParentWindow = parent + def OnDrop(self, x, y): + self.ParentWindow.OnHMITreeDnD() - wx.Panel.__init__(self, parent)
- label = path.get("name") + ": " + path.text + "(" + path.get("accepts") + ")"
+class ParamEditor(wx.Panel): + def __init__(self, parent, paramdesc): + wx.Panel.__init__(self, parent.main_panel) + label = paramdesc.get("name")+ ": " + paramdesc.get("accepts") + label += "\n\"" + paramdesc.text + "\"" self.desc = wx.StaticText(self, label=label)
- self.focus_sbmp = wx.StaticBitmap(self, -1, wx.ArtProvider.GetBitmap(wx.ART_GO_FORWARD, wx.ART_TOOLBAR, (32,32)))
- self.valid_bmp = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_TOOLBAR, (32,32))
- self.invalid_bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, (32,32))
+ self.valid_bmp = wx.ArtProvider.GetBitmap(wx.ART_TICK_MARK, wx.ART_TOOLBAR, (16,16)) + self.invalid_bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_TOOLBAR, (16,16)) self.validity_sbmp = wx.StaticBitmap(self, -1, self.invalid_bmp)
self.edit = wx.TextCtrl(self)
- self.edit_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0)
- self.edit_sizer.AddGrowableCol(1)
+ self.edit_sizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0) + self.edit_sizer.AddGrowableCol(0) self.edit_sizer.AddGrowableRow(0)
- self.edit_sizer.Add(self.focus_sbmp, flag=wx.GROW)
self.edit_sizer.Add(self.edit, flag=wx.GROW)
self.edit_sizer.Add(self.validity_sbmp, flag=wx.GROW)
self.main_sizer = wx.BoxSizer(wx.VERTICAL)
@@ -150,6 +200,28 @@
self.SetSizer(self.main_sizer)
self.main_sizer.Fit(self)
+class ArgEditor(ParamEditor): +class PathEditor(ParamEditor): + def __init__(self, parent, pathdesc): + ParamEditor.__init__(self, parent, pathdesc) + self.ParentObj = parent + DropTarget = PathDropTarget(self) + self.edit.SetDropTarget(DropTarget) + self.Bind(wx.EVT_TEXT_ENTER, self.OnPathChanged, self.edit) + def OnHMITreeDnD(self): + self.ParentObj.GotPathDnDOn(self) + def SetPathValue(self, value): + self.edit.SetValue(value) + def OnPathChanged(self, event): + # TODO : update validity _conf_key = "SVGHMIWidgetLib"
@@ -162,7 +234,7 @@
- self.hmitree_node = None
+ self.hmitree_nodes = [] self.Config = wx.ConfigBase.Get()
@@ -197,11 +269,22 @@
self.main_sizer.AddGrowableCol(0)
self.main_sizer.AddGrowableRow(2)
+ self.staticmsg = wx.StaticText(self, label = _("Drag selected Widget from here to Inkscape")) self.preview = wx.Panel(self.main_panel, size=(-1, _preview_height + _preview_margin*2))
- self.staticmsg = wx.StaticText(self)
self.signature_sizer = wx.BoxSizer(wx.VERTICAL)
+ self.args_box = wx.StaticBox(self.main_panel, -1, + _("Widget's arguments"), + style = wx.ALIGN_RIGHT) + self.args_sizer = wx.StaticBoxSizer(self.args_box, wx.VERTICAL) + self.paths_box = wx.StaticBox(self.main_panel, -1, + _("Widget's variables"), + style = wx.ALIGN_RIGHT) + self.paths_sizer = wx.StaticBoxSizer(self.paths_box, wx.VERTICAL) + self.signature_sizer.Add(self.args_sizer, flag=wx.GROW) + self.signature_sizer.AddSpacer(5) + self.signature_sizer.Add(self.paths_sizer, flag=wx.GROW) + self.main_sizer.Add(self.staticmsg, flag=wx.GROW) self.main_sizer.Add(self.preview, flag=wx.GROW)
- self.main_sizer.Add(self.staticmsg, flag=wx.GROW)
self.main_sizer.Add(self.signature_sizer, flag=wx.GROW)
self.main_panel.SetAutoLayout(True)
@@ -216,21 +299,38 @@
self.picker_desc_splitter.SplitHorizontally(self.picker_panel, self.desc, 400)
self.SplitVertically(self.main_panel, self.picker_desc_splitter, 300)
- self.msg = _("Drag selected Widget from here to Inkscape")
def ResetSignature(self):
- self.signature_sizer.Clear()
+ self.args_sizer.Clear() + for editor in self.args_editors: + self.paths_sizer.Clear() for editor in self.paths_editors:
+ def AddArgToSignature(self, arg): + new_editor = ArgEditor(self, arg) + self.args_editors.append(new_editor) + self.args_sizer.Add(new_editor, flag=wx.GROW) def AddPathToSignature(self, path):
- new_editor = PathEditor(self.main_panel, path)
+ new_editor = PathEditor(self, path) self.paths_editors.append(new_editor)
- self.signature_sizer.Add(new_editor, flag=wx.GROW)
+ self.paths_sizer.Add(new_editor, flag=wx.GROW) + def GotPathDnDOn(self, target_editor): + dndindex = self.paths_editors.index(target_editor) + for selected,editor in zip(self.hmitree_nodes, + self.paths_editors[dndindex:]): + editor.SetPath(selected.hmi_path()) conf = self.Config.Read(_conf_key)
@@ -283,8 +383,6 @@
- self.staticmsg.SetLabel(self.msg)
def GenThumbnail(self, svgpath, thumbpath):
inkpath = get_inkscape_path()
@@ -335,7 +433,14 @@
self.selected_SVG = svgpath if have_thumb else None
- self.AnalyseWidgetAndUpdateUI()
+ self.AnalyseWidgetAndUpdateUI(fname) + self.staticmsg.SetLabel(self.msg) self.msg = _("Widget library must be writable")
@@ -344,9 +449,10 @@
def OnHMITreeNodeSelection(self, hmitree_nodes):
- self.hmitree_node = hmitree_nodes[0] if len(hmitree_nodes) else None
+ self.hmitree_nodes = hmitree_nodes + # [0] if len(hmitree_nodes) else None + # self.ValidateWidget() def OnLeftDown(self, evt):
if self.tempf is not None:
@@ -368,7 +474,7 @@
def GetSubHMITree(self, _context):
return [self.hmitree_node.etree()]
- def AnalyseWidgetAndUpdateUI(self):
+ def AnalyseWidgetAndUpdateUI(self, fname): @@ -389,9 +495,10 @@
except XSLTApplyError as e:
- self.msg += "Widget analysis error: " + e.message
+ self.msg += "Widget " + fname + " analysis error: " + e.message + self.msg += "Widget " + fname + ": OK" print(etree.tostring(signature, pretty_print=True))
widgets = signature.getroot()
@@ -401,10 +508,15 @@
self.desc.SetValue(defs.find("type").text + ":\n" + "\n\n".join(map(
lambda s:s.replace("\n"," ").replace(" ", " "),
defs.find("longdesc").text.split("\n\n"))))
- for arg in defs.iter("arg"):
+ args = [arg for arg in defs.iter("arg")] + self.args_box.Show(len(args)!=0) + self.AddArgToSignature(arg) print(arg.get("accepts"))
- for path in defs.iter("path"):
+ paths = [path for path in defs.iter("path")] + self.paths_box.Show(len(paths)!=0) self.AddPathToSignature(path)
print(path.get("accepts"))
@@ -467,32 +579,13 @@
wx.SplitterWindow.__init__(self, parent,
style=wx.SUNKEN_BORDER | wx.SP_3D)
- self.ordered_items = []
self.SelectionTree = HMITreeSelector(self)
self.Staging = WidgetLibBrowser(self)
self.SplitVertically(self.SelectionTree, self.Staging, 300)
register_for_HMI_tree_updates(weakref.ref(self))
- self.Bind(wx.EVT_TREE_SEL_CHANGED,
- self.OnHMITreeNodeSelection, self.SelectionTree)
- def OnHMITreeNodeSelection(self, event):
- items = self.SelectionTree.GetSelections()
- items_pydata = [self.SelectionTree.GetPyData(item) for item in items]
- # append new items to ordered item list
- for item_pydata in items_pydata:
- if item_pydata not in self.ordered_items:
- self.ordered_items.append(item_pydata)
- # filter out vanished items
- for item_pydata in self.ordered_items
- if item_pydata in items_pydata]
- self.Staging.OnHMITreeNodeSelection(items_pydata)
def HMITreeUpdate(self, hmi_tree_root):
- self.SelectionTree.MakeTree(hmi_tree_root)
+ self.SelectionTree.MakeTree(hmi_tree_root) + def OnHMITreeNodeSelection(self, hmitree_nodes): + self.Staging.OnHMITreeNodeSelection(hmitree_nodes)