# HG changeset patch # User lbessard # Date 1220794152 -7200 # Node ID d9391572655fc5731eb947af25f9f81fc73f1eb2 # Parent 166ee9d2e23364394836a3fb7138263e6131800c Adding support for Debugging in PLCOpenEditor diff -r 166ee9d2e233 -r d9391572655f PLCOpenEditor.py --- a/PLCOpenEditor.py Sun Sep 07 15:27:53 2008 +0200 +++ b/PLCOpenEditor.py Sun Sep 07 15:29:12 2008 +0200 @@ -390,13 +390,11 @@ typestreestyle = wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER if not self.Debug: - typestreestyle |= wx.TR_HIDE_ROOT + typestreestyle |= wx.TR_EDIT_LABELS self.TypesTree = wx.TreeCtrl(id=ID_PLCOPENEDITORTYPESTREE, name='TypesTree', parent=self.TreeNoteBook, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=typestreestyle) - self.TreeNoteBook.AddPage(self.TypesTree, "Types") - if not self.Debug: if wx.Platform == '__WXMSW__': self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnTypesTreeRightUp, @@ -425,14 +423,15 @@ name='InstancesTree', parent=self.TreeNoteBook, pos=wx.Point(0, 0), size=wx.Size(0, 0), style=wx.TR_HAS_BUTTONS|wx.TR_SINGLE|wx.SUNKEN_BORDER) - self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") - if self.Debug: self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnInstancesTreeBeginDrag, id=ID_PLCOPENEDITORINSTANCESTREE) self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnInstancesTreeItemActivated, id=ID_PLCOPENEDITORINSTANCESTREE) + self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") + self.TreeNoteBook.AddPage(self.TypesTree, "Types") + if wx.VERSION < (2, 8, 0): self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED, name='TabsOpened', parent=self.MainSplitter, pos=wx.Point(0, @@ -451,6 +450,9 @@ self.OnPouSelectedChanged) self.AUIManager.AddPane(self.TabsOpened, wx.aui.AuiPaneInfo().CentrePane()) else: + self.TreeNoteBook.AddPage(self.TypesTree, "Types") + self.TreeNoteBook.AddPage(self.InstancesTree, "Instances") + if wx.VERSION < (2, 8, 0): self.ToolBar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.TB_FLAT|wx.NO_BORDER, ID_PLCOPENEDITORTOOLBAR, 'ToolBar') @@ -651,10 +653,13 @@ return self.DrawingMode def RefreshTitle(self): + name = "PLCOpenEditor" + if self.Debug: + name += " (Debug)" if self.Controler.HasOpenedProject() > 0: - self.SetTitle("PLCOpenEditor - %s"%self.Controler.GetFilename()) - else: - self.SetTitle("PLCOpenEditor") + self.SetTitle("%s - %s"%(name, self.Controler.GetFilename())) + else: + self.SetTitle(name) def ShowProperties(self): old_values = self.Controler.GetProjectProperties(self.Debug) @@ -3643,7 +3648,9 @@ editor = wx.grid.GridCellChoiceEditor() excluded = [] if self.Parent.PouIsUsed: - excluded.extend(["Input","Output","InOut"]) + excluded.extend(["Input","Output","InOut"]) + if self.Parent.IsFunctionBlockType(self.data[row]["Type"]): + excluded.extend(["Local","Temp"]) editor.SetParameters(",".join([choice for choice in self.Parent.ClassList if choice not in excluded])) elif colname in ["Retain", "Constant"]: editor = wx.grid.GridCellChoiceEditor() @@ -3960,6 +3967,14 @@ def SetTagName(self, tagname): self.TagName = tagname + def IsFunctionBlockType(self, name): + bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) + pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) + if poutype != "function" and bodytype in ["ST", "IL"]: + return False + else: + return name in self.Controler.GetFunctionBlockTypes(self.TagName, self.ParentWindow.Debug) + def RefreshView(self): self.PouNames = self.Controler.GetProjectPouNames(self.ParentWindow.Debug) @@ -4099,6 +4114,7 @@ def OnVariablesGridEditorShown(self, event): row, col = event.GetRow(), event.GetCol() + classtype = self.Table.GetValueByName(row, "Class") if self.Table.GetColLabelValue(col) == "Type": type_menu = wx.Menu(title='') base_menu = wx.Menu(title='') @@ -4108,17 +4124,20 @@ self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id) type_menu.AppendMenu(wx.NewId(), "Base Types", base_menu) datatype_menu = wx.Menu(title='') - for datatype in self.Controler.GetDataTypes(basetypes = False, debug = self.Debug): + for datatype in self.Controler.GetDataTypes(basetypes = False, debug = self.ParentWindow.Debug): new_id = wx.NewId() AppendMenu(datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype) self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id) type_menu.AppendMenu(wx.NewId(), "User Data Types", datatype_menu) functionblock_menu = wx.Menu(title='') - for functionblock_type in self.Controler.GetFunctionBlockTypes(debug = self.Debug): - new_id = wx.NewId() - AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) - self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id) - type_menu.AppendMenu(wx.NewId(), "Function Block Types", functionblock_menu) + bodytype = self.Controler.GetEditedElementBodyType(self.TagName, self.ParentWindow.Debug) + pouname, poutype = self.Controler.GetEditedElementType(self.TagName, self.ParentWindow.Debug) + if classtype in ["Input","Output","InOut","External","Global"] or poutype != "function" and bodytype in ["ST", "IL"]: + for functionblock_type in self.Controler.GetFunctionBlockTypes(self.TagName, self.ParentWindow.Debug): + new_id = wx.NewId() + AppendMenu(functionblock_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type) + self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id) + type_menu.AppendMenu(wx.NewId(), "Function Block Types", functionblock_menu) rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col)) self.VariablesGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize()) event.Veto() diff -r 166ee9d2e233 -r d9391572655f Viewer.py --- a/Viewer.py Sun Sep 07 15:27:53 2008 +0200 +++ b/Viewer.py Sun Sep 07 15:29:12 2008 +0200 @@ -102,10 +102,13 @@ message = "Programs can't be used by other POUs!" elif values[1] in ["function", "functionBlock", "program"]: name, type = self.ParentWindow.Controler.GetEditedElementType(self.ParentWindow.GetTagName(), self.ParentWindow.Debug) + words = self.ParentWindow.TagName.split("::") if name == values[0]: message = "\"%s\" can't use itself!"%name elif type == "function" and values[1] != "function": - message = "Function Blocks can't be used by Functions!" + message = "Function Blocks can't be used in Functions!" + elif words[0] == "T" and values[1] != "function": + message = "Function Blocks can't be used in Transitions!" elif self.ParentWindow.Controler.PouIsUsedBy(name, values[0], self.ParentWindow.Debug): message = "\"%s\" is already used by \"%s\"!"%(name, values[0]) else: @@ -351,6 +354,7 @@ self.Bind(wx.EVT_MOTION, self.OnViewerMotion) self.Bind(wx.EVT_CHAR, self.OnChar) self.Bind(wx.EVT_SCROLLWIN, self.OnScrollWindow) + self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheelWindow) self.Bind(wx.EVT_SIZE, self.OnMoveWindow) def GetScrolledRect(self, rect): @@ -397,6 +401,10 @@ self.PrepareDC(dc) return dc + def GetMiniFont(self): + font = self.GetFont() + return wx.Font(font.GetPointSize() * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]) + #------------------------------------------------------------------------------- # Element management functions #------------------------------------------------------------------------------- @@ -574,23 +582,70 @@ if connectorname == "": connectorname = "OUT" iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname) - self.Subscribed[wire] = iec_path.upper() - self.Controler.SubscribeDebugIECVariable(iec_path.upper(), wire) + if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), wire) is not None: + self.Subscribed[wire] = iec_path.upper() + else: + wire.SetValue("undefined") + elif isinstance(block, FBD_Variable): + iec_path = "%s.%s"%(self.InstancePath, block.GetName()) + if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), wire) is not None: + self.Subscribed[wire] = iec_path.upper() + else: + wire.SetValue("undefined") + elif isinstance(block, FBD_Connector): + wire.SetValue("undefined") if self.Debug: for block in self.Blocks.keys(): - if isinstance(block, (LD_Contact, LD_Coil)): - block.SetValue(False) - block.SpreadCurrent() + block.SpreadCurrent() if isinstance(block, LD_Contact): iec_path = "%s.%s"%(self.InstancePath, block.GetName()) - self.Subscribed[block] = iec_path.upper() - self.Controler.SubscribeDebugIECVariable(iec_path.upper(), block) - + if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), block) is not None: + self.Subscribed[block] = iec_path.upper() + elif isinstance(block, SFC_Step): + iec_path = "%s.%s.X"%(self.InstancePath, block.GetName()) + if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), block) is not None: + self.Subscribed[block] = iec_path.upper() + elif isinstance(block, SFC_Transition): + connectors = block.GetConnectors() + previous_steps = self.GetPreviousSteps(connectors["input"]) + next_steps = self.GetNextSteps(connectors["output"]) + iec_path = "%s.%s->%s"%(self.InstancePath, ",".join(previous_steps), ",".join(next_steps)) + if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), block) is not None: + self.Subscribed[block] = iec_path.upper() + else: + print "Unknown IEC_Path", iec_path + self.RefreshVisibleElements() self.ShowErrors() self.Refresh(False) + def GetPreviousSteps(self, connector): + steps = [] + for wire, handle in connector.GetWires(): + previous = wire.GetOtherConnected(connector).GetParentBlock() + if isinstance(previous, SFC_Step): + steps.append(previous.GetName()) + elif isinstance(previous, SFC_Divergence) and previous.GetType() in [SIMULTANEOUS_CONVERGENCE, SELECTION_DIVERGENCE]: + connectors = previous.GetConnectors() + for input in connectors["inputs"]: + steps.extend(self.GetPreviousSteps(input)) + return steps + + def GetNextSteps(self, connector): + steps = [] + for wire, handle in connector.GetWires(): + next = wire.GetOtherConnected(connector).GetParentBlock() + if isinstance(next, SFC_Step): + steps.append(next.GetName()) + elif isinstance(next, SFC_Jump): + steps.append(next.GetTarget()) + elif isinstance(next, SFC_Divergence) and next.GetType() in [SIMULTANEOUS_DIVERGENCE, SELECTION_CONVERGENCE]: + connectors = next.GetConnectors() + for output in connectors["outputs"]: + steps.extend(self.GetNextSteps(output)) + return steps + def GetMaxSize(self): maxx = maxy = 0 for element in self.GetElements(): @@ -1525,7 +1580,11 @@ dialog.Destroy() def AddNewVariable(self, bbox): - dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler) + words = self.TagName.split("::") + if words[0] == "T": + dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler, words[2]) + else: + dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetMinVariableSize((bbox.width, bbox.height)) varlist = [] @@ -1827,7 +1886,11 @@ dialog.Destroy() def EditVariableContent(self, variable): - dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler) + words = self.TagName.split("::") + if words[0] == "T": + dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler, words[2]) + else: + dialog = VariablePropertiesDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) dialog.SetMinVariableSize(variable.GetSize()) varlist = [] @@ -2470,6 +2533,12 @@ self.RefreshVisibleElements(yp = event.GetPosition()) event.Skip() + def OnMouseWheelWindow(self, event): + x, y = self.GetViewStart() + yp = max(0, min(y - event.GetWheelRotation() / event.GetWheelDelta() * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1])) + self.RefreshVisibleElements(yp = yp) + self.Scroll(x, yp) + def OnMoveWindow(self, event): self.GetBestSize() self.RefreshScrollBars() diff -r 166ee9d2e233 -r d9391572655f graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Sun Sep 07 15:27:53 2008 +0200 +++ b/graphics/GraphicCommons.py Sun Sep 07 15:29:12 2008 +0200 @@ -976,8 +976,10 @@ current = False for wire, handle in self.Wires: value = wire.GetValue() - if isinstance(value, BooleanType): + if current != "undefined" and isinstance(value, BooleanType): current |= wire.GetValue() + elif value == "undefined": + current = "undefined" return current def SpreadCurrent(self, spreading): @@ -1195,6 +1197,8 @@ dc.SetPen(wx.RED_PEN) elif isinstance(self.Value, BooleanType) and self.Value: dc.SetPen(wx.GREEN_PEN) + elif self.Value == "undefined": + dc.SetPen(wx.Pen(wx.NamedColour("orange"))) else: dc.SetPen(self.Pen) dc.SetBrush(wx.WHITE_BRUSH) @@ -1271,11 +1275,11 @@ self.Valid = True self.Value = None self.ValueSize = None + self.ComputedValue = None self.OverStart = False self.OverEnd = False self.ComputingType = False - parent_font = parent.GetFont() - self.Font = wx.Font(parent_font.GetPointSize() * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = parent_font.GetFaceName()) + self.Font = parent.GetMiniFont() def Flush(self): self.StartConnected = None @@ -1376,19 +1380,19 @@ return False def SetValue(self, value): - if value is not None and not isinstance(value, BooleanType): - if isinstance(value, StringType): - value = "\"%s\""%value - else: - value = str(value) - if len(value) > 4: - value = value[:4] + "_" if self.Value != value: self.Value = value - if isinstance(self.Value, StringType): + if value is not None and not isinstance(value, BooleanType): + if isinstance(value, StringType): + self.ComputedValue = "\"%s\""%value + else: + self.ComputedValue = str(value) + if len(self.ComputedValue) > 4: + self.ComputedValue = self.ComputedValue[:4] + "..." + if isinstance(self.ComputedValue, StringType): dc = wx.ClientDC(self.Parent) dc.SetFont(self.Font) - self.ValueSize = dc.GetTextExtent(self.Value) + self.ValueSize = dc.GetTextExtent(self.ComputedValue) else: self.ValueSize = None if self.StartConnected: @@ -2183,6 +2187,8 @@ dc.SetPen(wx.RED_PEN) elif isinstance(self.Value, BooleanType) and self.Value: dc.SetPen(wx.GREEN_PEN) + elif self.Value == "undefined": + dc.SetPen(wx.Pen(wx.NamedColour("orange"))) else: dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.BLACK_BRUSH) @@ -2201,22 +2207,22 @@ self.Points[self.SelectedSegment + 1].x, self.Points[self.SelectedSegment + 1].y) if self.SelectedSegment == len(self.Segments) - 1: dc.DrawPoint(self.Points[-1].x, self.Points[-1].y) - if self.Value is not None and not isinstance(self.Value, BooleanType): + if self.Value is not None and not isinstance(self.Value, BooleanType) and self.Value != "undefined": dc.SetFont(self.Font) dc.SetTextForeground(wx.NamedColour("purple")) width, height = self.ValueSize if self.BoundingBox[2] > width * 4 or self.BoundingBox[3] > height * 4: - x = self.Points[0].x + width * self.StartPoint[1][0] / 2 + x = self.Points[0].x + width * (self.StartPoint[1][0] - 1) / 2 y = self.Points[0].y + height * (self.StartPoint[1][1] - 1) / 2 - dc.DrawText(self.Value, x, y) - x = self.Points[-1].x + width * self.EndPoint[1][0] / 2 + dc.DrawText(self.ComputedValue, x, y) + x = self.Points[-1].x + width * (self.EndPoint[1][0] - 1) / 2 y = self.Points[-1].y + height * (self.EndPoint[1][1] - 1) / 2 - dc.DrawText(self.Value, x, y) + dc.DrawText(self.ComputedValue, x, y) else: middle = len(self.Segments) / 2 + len(self.Segments) % 2 - 1 x = (self.Points[middle].x + self.Points[middle + 1].x - width) / 2 y = (self.Points[middle].y + self.Points[middle + 1].y - height) / 2 - dc.DrawText(self.Value, x, y) + dc.DrawText(self.ComputedValue, x, y) dc.SetFont(self.Parent.GetFont()) dc.SetTextForeground(wx.BLACK) diff -r 166ee9d2e233 -r d9391572655f graphics/LD_Objects.py --- a/graphics/LD_Objects.py Sun Sep 07 15:27:53 2008 +0200 +++ b/graphics/LD_Objects.py Sun Sep 07 15:29:12 2008 +0200 @@ -400,8 +400,10 @@ self.SpreadCurrent() def SpreadCurrent(self): - spreading = self.Input.ReceivingCurrent() - if self.Value is not None: + if self.Parent.Debug: + if self.Value is None: + self.Value = False + spreading = self.Input.ReceivingCurrent() if self.Type == CONTACT_NORMAL: spreading &= self.Value elif self.Type == CONTACT_REVERSE: @@ -412,11 +414,11 @@ spreading &= self.Value and not self.PreviousValue else: spreading = False - if spreading and not self.PreviousSpreading: - self.Output.SpreadCurrent(True) - elif not spreading and self.PreviousSpreading: - self.Output.SpreadCurrent(False) - self.PreviousSpreading = spreading + if spreading and not self.PreviousSpreading: + self.Output.SpreadCurrent(True) + elif not spreading and self.PreviousSpreading: + self.Output.SpreadCurrent(False) + self.PreviousSpreading = spreading # Make a clone of this LD_Contact def Clone(self, parent, id = None, pos = None): @@ -687,20 +689,16 @@ self.Output.Flush() self.Output = None - def SetValue(self, value): - if self.Value != value: - self.Value = value - self.Refresh() - def SpreadCurrent(self): - self.PreviousValue = self.Value - self.Value = self.Input.ReceivingCurrent() - if self.Value and not self.PreviousValue: - self.Output.SpreadCurrent(True) - elif not self.Value and self.PreviousValue: - self.Output.SpreadCurrent(False) - if self.Value != self.PreviousValue: - self.Refresh() + if self.Parent.Debug: + self.PreviousValue = self.Value + self.Value = self.Input.ReceivingCurrent() + if self.Value and not self.PreviousValue: + self.Output.SpreadCurrent(True) + elif not self.Value and self.PreviousValue: + self.Output.SpreadCurrent(False) + if self.Value != self.PreviousValue: + self.Refresh() # Make a clone of this LD_Coil def Clone(self, parent, id = None, pos = None): diff -r 166ee9d2e233 -r d9391572655f graphics/SFC_Objects.py --- a/graphics/SFC_Objects.py Sun Sep 07 15:27:53 2008 +0200 +++ b/graphics/SFC_Objects.py Sun Sep 07 15:29:12 2008 +0200 @@ -58,6 +58,9 @@ self.Input = None self.Output = None self.Action = None + self.Value = None + self.PreviousValue = None + self.PreviousSpreading = False def Flush(self): if self.Input is not None: @@ -70,6 +73,26 @@ self.Action.Flush() self.Action = None + def SetValue(self, value): + self.PreviousValue = self.Value + self.Value = value + if self.Value != self.PreviousValue: + self.Refresh() + self.SpreadCurrent() + + def SpreadCurrent(self): + if self.Parent.Debug: + spreading = self.Value + if spreading and not self.PreviousSpreading: + self.Output.SpreadCurrent(True) + if self.Action is not None: + self.Action.SpreadCurrent(True) + elif not spreading and self.PreviousSpreading: + self.Output.SpreadCurrent(False) + if self.Action is not None: + self.Action.SpreadCurrent(False) + self.PreviousSpreading = spreading + # Make a clone of this SFC_Step def Clone(self, parent, id = None, name = "Step", pos = None): step = SFC_Step(parent, name, self.Initial, id) @@ -472,7 +495,10 @@ # Draws step def Draw(self, dc): Graphic_Element.Draw(self, dc) - dc.SetPen(wx.BLACK_PEN) + if self.Value: + dc.SetPen(wx.GREEN_PEN) + else: + dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.WHITE_BRUSH) if getattr(dc, "printing", False): @@ -522,6 +548,9 @@ self.SetType(type, condition) self.SetPriority(priority) self.Errors = {} + self.Value = None + self.PreviousValue = None + self.PreviousSpreading = False def Flush(self): if self.Input is not None: @@ -534,6 +563,24 @@ self.Condition.Flush() self.Condition = None + def SetValue(self, value): + self.PreviousValue = self.Value + self.Value = value + if self.Value != self.PreviousValue: + self.Refresh() + self.SpreadCurrent() + + def SpreadCurrent(self): + if self.Parent.Debug: + if self.Value is None: + self.Value = False + spreading = self.Input.ReceivingCurrent() & self.Value + if spreading and not self.PreviousSpreading: + self.Output.SpreadCurrent(True) + elif not spreading and self.PreviousSpreading: + self.Output.SpreadCurrent(False) + self.PreviousSpreading = spreading + # Make a clone of this SFC_Transition def Clone(self, parent, id = None, pos = None): transition = SFC_Transition(parent, self.Type, self.Condition, self.Priority, id) @@ -851,8 +898,12 @@ # Draws transition def Draw(self, dc): Graphic_Element.Draw(self, dc) - dc.SetPen(wx.BLACK_PEN) - dc.SetBrush(wx.BLACK_BRUSH) + if self.Value: + dc.SetPen(wx.GREEN_PEN) + dc.SetBrush(wx.GREEN_BRUSH) + else: + dc.SetPen(wx.BLACK_PEN) + dc.SetBrush(wx.BLACK_BRUSH) if getattr(dc, "printing", False): if self.Type != "connection": @@ -929,6 +980,8 @@ for i in xrange(number): self.Inputs.append(Connector(self, "", None, wx.Point(i * SFC_DEFAULT_SEQUENCE_INTERVAL, 0), NORTH, onlyone = True)) self.Outputs = [Connector(self, "", None, wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH, onlyone = True)] + self.Value = None + self.PreviousValue = None def Flush(self): for input in self.Inputs: @@ -938,6 +991,30 @@ output.Flush() self.Outputs = [] + def SpreadCurrent(self): + if self.Parent.Debug: + self.PreviousValue = self.Value + if self.Type == SELECTION_CONVERGENCE: + self.Value = False + for input in self.Inputs: + self.Value |= input.ReceivingCurrent() + elif self.Type == SIMULTANEOUS_CONVERGENCE: + self.Value = True + for input in self.Inputs: + self.Value &= input.ReceivingCurrent() + elif self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]: + self.Value = self.Inputs[0].ReceivingCurrent() + else: + self.Value = False + if self.Value and not self.PreviousValue: + self.Refresh() + for output in self.Outputs: + output.SpreadCurrent(True) + elif not self.Value and self.PreviousValue: + self.Refresh() + for output in self.Outputs: + output.SpreadCurrent(False) + # Make a clone of this SFC_Divergence def Clone(self, parent, id = None, pos = None): divergence = SFC_Divergence(parent, self.Type, max(len(self.Inputs), len(self.Outputs)), id) @@ -1313,8 +1390,12 @@ # Draws divergence def Draw(self, dc): Graphic_Element.Draw(self, dc) - dc.SetPen(wx.BLACK_PEN) - dc.SetBrush(wx.BLACK_BRUSH) + if self.Value: + dc.SetPen(wx.GREEN_PEN) + dc.SetBrush(wx.GREEN_BRUSH) + else: + dc.SetPen(wx.BLACK_PEN) + dc.SetBrush(wx.BLACK_BRUSH) # Draw plain rectangle for representing the divergence if self.Type in [SELECTION_DIVERGENCE, SELECTION_CONVERGENCE]: dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) @@ -1349,12 +1430,21 @@ self.Errors = {} # Create an input and output connector self.Input = Connector(self, "", None, wx.Point(self.Size[0] / 2, 0), NORTH, onlyone = True) + self.Value = None + self.PreviousValue = None def Flush(self): if self.Input is not None: self.Input.Flush() self.Input = None + def SpreadCurrent(self): + if self.Parent.Debug: + self.PreviousValue = self.Value + self.Value = self.Input.ReceivingCurrent() + if self.Value != self.PreviousValue: + self.Refresh() + # Make a clone of this SFC_Jump def Clone(self, parent, id = None, pos = None): jump = SFC_Jump(parent, self.Target, id) @@ -1531,8 +1621,12 @@ # Draws divergence def Draw(self, dc): Graphic_Element.Draw(self, dc) - dc.SetPen(wx.BLACK_PEN) - dc.SetBrush(wx.BLACK_BRUSH) + if self.Value: + dc.SetPen(wx.GREEN_PEN) + dc.SetBrush(wx.GREEN_BRUSH) + else: + dc.SetPen(wx.BLACK_PEN) + dc.SetBrush(wx.BLACK_BRUSH) if getattr(dc, "printing", False): target_size = dc.GetTextExtent(self.Target) @@ -1576,12 +1670,21 @@ # Create an input and output connector self.Input = Connector(self, "", None, wx.Point(0, SFC_ACTION_MIN_SIZE[1] / 2), WEST, onlyone = True) self.SetActions(actions) + self.Value = None + self.PreviousValue = None def Flush(self): if self.Input is not None: self.Input.Flush() self.Input = None + def SpreadCurrent(self): + if self.Parent.Debug: + self.PreviousValue = self.Value + self.Value = self.Input.ReceivingCurrent() + if self.Value != self.PreviousValue: + self.Refresh() + # Make a clone of this SFC_ActionBlock def Clone(self, parent, id = None, pos = None): actions = [action.copy() for action in self.Actions] @@ -1751,7 +1854,10 @@ # Draws divergence def Draw(self, dc): Graphic_Element.Draw(self, dc) - dc.SetPen(wx.BLACK_PEN) + if self.Value: + dc.SetPen(wx.GREEN_PEN) + else: + dc.SetPen(wx.BLACK_PEN) dc.SetBrush(wx.WHITE_BRUSH) colsize = [self.ColSize[0], self.Size[0] - self.ColSize[0] - self.ColSize[2], self.ColSize[2]] # Draw plain rectangle for representing the action block