--- a/editors/Viewer.py Fri Jun 14 10:52:08 2013 +0200
+++ b/editors/Viewer.py Fri Jun 14 10:54:21 2013 +0200
@@ -1650,6 +1650,12 @@
wx.CallAfter(func, self.rubberBand.GetCurrentExtent(), *args)
return AddMenuCallBack
+ def GetAddToWireMenuCallBack(self, func, *args):
+ args += (self.SelectedElement,)
+ def AddToWireMenuCallBack(event):
+ func(wx.Rect(0, 0, 0, 0), *args)
+ return AddToWireMenuCallBack
+
def GetClipboardCallBack(self, func):
def ClipboardCallback(event):
wx.CallAfter(func)
@@ -1738,10 +1744,15 @@
elif not self.Debug and connector is not None and not event.ControlDown():
self.DrawingWire = True
scaled_pos = GetScaledEventPosition(event, dc, self.Scaling)
- if (connector.GetDirection() == EAST):
- wire = Wire(self, [wx.Point(pos.x, pos.y), EAST], [wx.Point(scaled_pos.x, scaled_pos.y), WEST])
- else:
- wire = Wire(self, [wx.Point(pos.x, pos.y), WEST], [wx.Point(scaled_pos.x, scaled_pos.y), EAST])
+ directions = {
+ EAST: [EAST, WEST],
+ WEST: [WEST, EAST],
+ NORTH: [NORTH, SOUTH],
+ SOUTH: [SOUTH, NORTH]}[connector.GetDirection()]
+ wire = Wire(self, *map(list, zip(
+ [wx.Point(pos.x, pos.y),
+ wx.Point(scaled_pos.x, scaled_pos.y)],
+ directions)))
wire.oldPos = scaled_pos
wire.Handle = (HANDLE_POINT, 0)
wire.ProcessDragging(0, 0, event, None)
@@ -1755,6 +1766,7 @@
self.HighlightedElement = wire
self.RefreshVisibleElements()
self.SelectedElement.SetHighlighted(True)
+ self.SelectedElement.StartConnected.HighlightParentBlock(True)
else:
if self.SelectedElement is not None and self.SelectedElement != element:
self.SelectedElement.SetSelected(False)
@@ -1847,14 +1859,70 @@
self.SelectedElement.HighlightPoint(pos)
self.RefreshBuffer()
elif connector is None or self.SelectedElement.GetDragging():
- self.DrawingWire = False
- rect = self.SelectedElement.GetRedrawRect()
- wire = self.SelectedElement
- self.SelectedElement = self.SelectedElement.StartConnected.GetParentBlock()
- self.SelectedElement.SetSelected(True)
- rect.Union(self.SelectedElement.GetRedrawRect())
- wire.Delete()
- self.RefreshRect(self.GetScrolledRect(rect), False)
+ start_connector = self.SelectedElement.GetStartConnected()
+ start_direction = start_connector.GetDirection()
+
+ items = []
+
+ if self.CurrentLanguage == "SFC" and start_direction == SOUTH:
+ items.extend([
+ (_(u'Initial Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, True)),
+ (_(u'Step'), self.GetAddToWireMenuCallBack(self.AddNewStep, False)),
+ (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, False)),
+ (_(u'Divergence'), self.GetAddToWireMenuCallBack(self.AddNewDivergence)),
+ (_(u'Jump'), self.GetAddToWireMenuCallBack(self.AddNewJump)),
+ ])
+
+ elif start_direction == EAST:
+
+ if isinstance(start_connector.GetParentBlock(), SFC_Step):
+ items.append(
+ (_(u'Action Block'), self.GetAddToWireMenuCallBack(self.AddNewActionBlock))
+ )
+ else:
+ items.extend([
+ (_(u'Block'), self.GetAddToWireMenuCallBack(self.AddNewBlock)),
+ (_(u'Variable'), self.GetAddToWireMenuCallBack(self.AddNewVariable, True)),
+ (_(u'Connection'), self.GetAddToWireMenuCallBack(self.AddNewConnection)),
+ ])
+
+ if self.CurrentLanguage != "FBD":
+ items.append(
+ (_(u'Contact'), self.GetAddToWireMenuCallBack(self.AddNewContact))
+ )
+ if self.CurrentLanguage == "LD":
+ items.extend([
+ (_(u'Coil'), self.GetAddToWireMenuCallBack(self.AddNewCoil)),
+ (_(u'Power Rail'), self.GetAddToWireMenuCallBack(self.AddNewPowerRail)),
+ ])
+ if self.CurrentLanguage == "SFC":
+ items.append(
+ (_(u'Transition'), self.GetAddToWireMenuCallBack(self.AddNewTransition, True))
+ )
+
+ if len(items) > 0:
+ if self.Editor.HasCapture():
+ self.Editor.ReleaseMouse()
+
+ # Popup contextual menu
+ menu = wx.Menu()
+ self.AddMenuItems(menu,
+ [(wx.NewId(), wx.ITEM_NORMAL, text, '', callback)
+ for text, callback in items])
+ self.PopupMenu(menu)
+
+ self.SelectedElement.StartConnected.HighlightParentBlock(False)
+ if self.DrawingWire:
+ self.DrawingWire = False
+ rect = self.SelectedElement.GetRedrawRect()
+ wire = self.SelectedElement
+ self.SelectedElement = self.SelectedElement.StartConnected.GetParentBlock()
+ self.SelectedElement.SetSelected(True)
+ rect.Union(self.SelectedElement.GetRedrawRect())
+ wire.Delete()
+ self.RefreshRect(self.GetScrolledRect(rect), False)
+ else:
+ self.SelectedElement.SetSelected(True)
else:
if self.Debug:
Graphic_Element.OnLeftUp(self.SelectedElement, event, dc, self.Scaling)
@@ -2196,7 +2264,36 @@
height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1]
return width, height
- def AddNewBlock(self, bbox):
+ def AddNewElement(self, element, bbox, wire=None, connector=None):
+ min_width, min_height = (element.GetMinSize(True)
+ if isinstance(element, (LD_PowerRail,
+ SFC_Divergence))
+ else element.GetMinSize())
+ element.SetSize(*self.GetScaledSize(
+ max(bbox.width, min_width), max(bbox.height, min_height)))
+ if wire is not None:
+ if connector is None:
+ connector = element.GetConnectors()["inputs"][0]
+ point = wire.GetPoint(-1)
+ rel_pos = connector.GetRelPosition()
+ direction = connector.GetDirection()
+ element.SetPosition(
+ point[0] - rel_pos[0] - direction[0] * CONNECTOR_SIZE,
+ point[1] - rel_pos[1] - direction[1] * CONNECTOR_SIZE,
+ )
+ connector.Connect((wire, -1))
+ wire.Refresh()
+ self.DrawingWire = False
+ else:
+ element.SetPosition(bbox.x, bbox.y)
+ self.AddBlock(element)
+ element.RefreshModel()
+ self.RefreshBuffer()
+ self.RefreshScrollBars()
+ self.RefreshVisibleElements()
+ element.Refresh()
+
+ def AddNewBlock(self, bbox, wire=None):
dialog = FBDBlockDialog(self.ParentWindow, self.Controler, self.TagName)
dialog.SetPreviewFont(self.GetFont())
dialog.SetMinElementSize((bbox.width, bbox.height))
@@ -2208,21 +2305,17 @@
values["extension"], values["inputs"],
executionControl = values["executionControl"],
executionOrder = values["executionOrder"])
- block.SetPosition(bbox.x, bbox.y)
- block.SetSize(*self.GetScaledSize(values["width"], values["height"]))
- self.AddBlock(block)
- self.Controler.AddEditedElementBlock(self.TagName, id, values["type"], values.get("name", None))
- self.RefreshBlockModel(block)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- self.RefreshVariablePanel()
- self.ParentWindow.RefreshPouInstanceVariablesPanel()
- block.Refresh()
+ connector = None
+ for input_connector in block.GetConnectors()["inputs"]:
+ if input_connector.IsCompatible(
+ wire.GetStartConnectedType()):
+ connector = input_connector
+ break
+ self.AddNewElement(block, bbox, wire, connector)
dialog.Destroy()
- def AddNewVariable(self, bbox):
- dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName)
+ def AddNewVariable(self, bbox, exclude_input=False, wire=None):
+ dialog = FBDVariableDialog(self.ParentWindow, self.Controler, self.TagName, exclude_input)
dialog.SetPreviewFont(self.GetFont())
dialog.SetMinElementSize((bbox.width, bbox.height))
if dialog.ShowModal() == wx.ID_OK:
@@ -2230,36 +2323,30 @@
values = dialog.GetValues()
variable = FBD_Variable(self, values["class"], values["expression"], values["var_type"], id)
variable.SetExecutionOrder(values["executionOrder"])
- variable.SetPosition(bbox.x, bbox.y)
- variable.SetSize(*self.GetScaledSize(values["width"], values["height"]))
- self.AddBlock(variable)
self.Controler.AddEditedElementVariable(self.TagName, id, values["class"])
- self.RefreshVariableModel(variable)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- variable.Refresh()
+ self.AddNewElement(variable, bbox, wire)
dialog.Destroy()
- def AddNewConnection(self, bbox):
- dialog = ConnectionDialog(self.ParentWindow, self.Controler, self.TagName)
- dialog.SetPreviewFont(self.GetFont())
- dialog.SetMinElementSize((bbox.width, bbox.height))
- if dialog.ShowModal() == wx.ID_OK:
+ def AddNewConnection(self, bbox, wire=None):
+ if wire is not None:
+ values = {
+ "type": CONNECTOR,
+ "name": self.Controler.GenerateNewName(
+ self.TagName, None, "Connection%d", 0)}
+ else:
+ dialog = ConnectionDialog(self.ParentWindow, self.Controler, self.TagName)
+ dialog.SetPreviewFont(self.GetFont())
+ dialog.SetMinElementSize((bbox.width, bbox.height))
+ values = (dialog.GetValues()
+ if dialog.ShowModal() == wx.ID_OK
+ else None)
+ dialog.Destroy()
+ if values is not None:
id = self.GetNewId()
- values = dialog.GetValues()
connection = FBD_Connector(self, values["type"], values["name"], id)
- connection.SetPosition(bbox.x, bbox.y)
- connection.SetSize(*self.GetScaledSize(values["width"], values["height"]))
- self.AddBlock(connection)
self.Controler.AddEditedElementConnection(self.TagName, id, values["type"])
- self.RefreshConnectionModel(connection)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- connection.Refresh()
- dialog.Destroy()
-
+ self.AddNewElement(connection, bbox, wire)
+
def AddNewComment(self, bbox):
dialog = wx.TextEntryDialog(self.ParentWindow,
_("Edit comment"),
@@ -2282,7 +2369,7 @@
comment.Refresh()
dialog.Destroy()
- def AddNewContact(self, bbox):
+ def AddNewContact(self, bbox, wire=None):
dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "contact")
dialog.SetPreviewFont(self.GetFont())
dialog.SetMinElementSize((bbox.width, bbox.height))
@@ -2290,18 +2377,11 @@
id = self.GetNewId()
values = dialog.GetValues()
contact = LD_Contact(self, values["modifier"], values["variable"], id)
- contact.SetPosition(bbox.x, bbox.y)
- contact.SetSize(*self.GetScaledSize(values["width"], values["height"]))
- self.AddBlock(contact)
self.Controler.AddEditedElementContact(self.TagName, id)
- self.RefreshContactModel(contact)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- contact.Refresh()
+ self.AddNewElement(contact, bbox, wire)
dialog.Destroy()
- def AddNewCoil(self, bbox):
+ def AddNewCoil(self, bbox, wire=None):
dialog = LDElementDialog(self.ParentWindow, self.Controler, self.TagName, "coil")
dialog.SetPreviewFont(self.GetFont())
dialog.SetMinElementSize((bbox.width, bbox.height))
@@ -2309,89 +2389,80 @@
id = self.GetNewId()
values = dialog.GetValues()
coil = LD_Coil(self, values["modifier"], values["variable"], id)
- coil.SetPosition(bbox.x, bbox.y)
- coil.SetSize(*self.GetScaledSize(values["width"], values["height"]))
- self.AddBlock(coil)
self.Controler.AddEditedElementCoil(self.TagName, id)
- self.RefreshCoilModel(coil)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- coil.Refresh()
+ self.AddNewElement(coil, bbox, wire)
dialog.Destroy()
- def AddNewPowerRail(self, bbox):
- dialog = LDPowerRailDialog(self.ParentWindow, self.Controler, self.TagName)
- dialog.SetPreviewFont(self.GetFont())
- dialog.SetMinElementSize((bbox.width, bbox.height))
- if dialog.ShowModal() == wx.ID_OK:
+ def AddNewPowerRail(self, bbox, wire=None):
+ if wire is not None:
+ values = {
+ "type": RIGHTRAIL,
+ "pin_number": 1}
+ else:
+ dialog = LDPowerRailDialog(self.ParentWindow, self.Controler, self.TagName)
+ dialog.SetPreviewFont(self.GetFont())
+ dialog.SetMinElementSize((bbox.width, bbox.height))
+ values = (dialog.GetValues()
+ if dialog.ShowModal() == wx.ID_OK
+ else None)
+ dialog.Destroy()
+ if values is not None:
id = self.GetNewId()
- values = dialog.GetValues()
powerrail = LD_PowerRail(self, values["type"], id, values["pin_number"])
- powerrail.SetPosition(bbox.x, bbox.y)
- powerrail.SetSize(*self.GetScaledSize(values["width"], values["height"]))
- self.AddBlock(powerrail)
self.Controler.AddEditedElementPowerRail(self.TagName, id, values["type"])
- self.RefreshPowerRailModel(powerrail)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- powerrail.Refresh()
- dialog.Destroy()
-
- def AddNewStep(self, bbox, initial = False):
- dialog = SFCStepDialog(self.ParentWindow, self.Controler, self.TagName, initial)
- dialog.SetPreviewFont(self.GetFont())
- dialog.SetMinElementSize((bbox.width, bbox.height))
- if dialog.ShowModal() == wx.ID_OK:
+ self.AddNewElement(powerrail, bbox, wire)
+
+ def AddNewStep(self, bbox, initial=False, wire=None):
+ if wire is not None:
+ values = {
+ "name": self.Controler.GenerateNewName(
+ self.TagName, None, "Step%d", 0),
+ "input": True,
+ "output": False,
+ "action":False}
+ else:
+ dialog = SFCStepDialog(self.ParentWindow, self.Controler, self.TagName, initial)
+ dialog.SetPreviewFont(self.GetFont())
+ dialog.SetMinElementSize((bbox.width, bbox.height))
+ values = (dialog.GetValues()
+ if dialog.ShowModal() == wx.ID_OK
+ else None)
+ dialog.Destroy()
+ if values is not None:
id = self.GetNewId()
- values = dialog.GetValues()
step = SFC_Step(self, values["name"], initial, id)
- if values["input"]:
- step.AddInput()
+ self.Controler.AddEditedElementStep(self.TagName, id)
+ for connector in ["input", "output", "action"]:
+ getattr(step, ("Add"
+ if values[connector]
+ else "Remove") + connector.capitalize())()
+ self.AddNewElement(step, bbox, wire)
+
+ def AddNewTransition(self, bbox, connection=False, wire=None):
+ if wire is not None and connection:
+ values = {
+ "type": "connection",
+ "value": None,
+ "priority": 0}
+ else:
+ dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.TagName, self.GetDrawingMode() == FREEDRAWING_MODE)
+ dialog.SetPreviewFont(self.GetFont())
+ dialog.SetMinElementSize((bbox.width, bbox.height))
+ values = (dialog.GetValues()
+ if dialog.ShowModal() == wx.ID_OK
+ else None)
+ dialog.Destroy()
+ if values is not None:
+ id = self.GetNewId()
+ transition = SFC_Transition(self, values["type"], values["value"], values["priority"], id)
+ self.Controler.AddEditedElementTransition(self.TagName, id)
+ if connection:
+ connector = transition.GetConditionConnector()
else:
- step.RemoveInput()
- if values["output"]:
- step.AddOutput()
- else:
- step.RemoveOutput()
- if values["action"]:
- step.AddAction()
- else:
- step.RemoveAction()
- step.SetPosition(bbox.x, bbox.y)
- min_width, min_height = step.GetMinSize()
- step.SetSize(*self.GetScaledSize(max(bbox.width, min_width), max(bbox.height, min_height)))
- self.AddBlock(step)
- self.Controler.AddEditedElementStep(self.TagName, id)
- self.RefreshStepModel(step)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- step.Refresh()
- dialog.Destroy()
-
- def AddNewTransition(self, bbox):
- dialog = SFCTransitionDialog(self.ParentWindow, self.Controler, self.TagName, self.GetDrawingMode() == FREEDRAWING_MODE)
- dialog.SetPreviewFont(self.GetFont())
- dialog.SetMinElementSize((bbox.width, bbox.height))
- if dialog.ShowModal() == wx.ID_OK:
- id = self.GetNewId()
- values = dialog.GetValues()
- transition = SFC_Transition(self, values["type"], values["value"], values["priority"], id)
- transition.SetPosition(bbox.x, bbox.y)
- min_width, min_height = transition.GetMinSize()
- transition.SetSize(*self.GetScaledSize(max(bbox.width, min_width), max(bbox.height, min_height)))
- self.AddBlock(transition)
- self.Controler.AddEditedElementTransition(self.TagName, id)
- self.RefreshTransitionModel(transition)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- transition.Refresh()
- dialog.Destroy()
-
- def AddNewDivergence(self, bbox):
+ connector = transition.GetConnectors()["inputs"][0]
+ self.AddNewElement(transition, bbox, wire, connector)
+
+ def AddNewDivergence(self, bbox, wire=None):
dialog = SFCDivergenceDialog(self.ParentWindow, self.Controler, self.TagName)
dialog.SetPreviewFont(self.GetFont())
dialog.SetMinElementSize((bbox.width, bbox.height))
@@ -2399,19 +2470,11 @@
id = self.GetNewId()
values = dialog.GetValues()
divergence = SFC_Divergence(self, values["type"], values["number"], id)
- divergence.SetPosition(bbox.x, bbox.y)
- min_width, min_height = divergence.GetMinSize(True)
- divergence.SetSize(*self.GetScaledSize(max(bbox.width, min_width), max(bbox.height, min_height)))
- self.AddBlock(divergence)
self.Controler.AddEditedElementDivergence(self.TagName, id, values["type"])
- self.RefreshDivergenceModel(divergence)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- divergence.Refresh()
+ self.AddNewElement(divergence, bbox, wire)
dialog.Destroy()
- def AddNewJump(self, bbox):
+ def AddNewJump(self, bbox, wire=None):
choices = []
for block in self.Blocks.itervalues():
if isinstance(block, SFC_Step):
@@ -2421,39 +2484,21 @@
choices, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
if dialog.ShowModal() == wx.ID_OK:
id = self.GetNewId()
- value = dialog.GetStringSelection()
- jump = SFC_Jump(self, value, id)
- jump.SetPosition(bbox.x, bbox.y)
- min_width, min_height = jump.GetMinSize()
- jump.SetSize(*self.GetScaledSize(max(bbox.width, min_width), max(bbox.height, min_height)))
- self.AddBlock(jump)
+ jump = SFC_Jump(self, dialog.GetStringSelection(), id)
self.Controler.AddEditedElementJump(self.TagName, id)
- self.RefreshJumpModel(jump)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- jump.Refresh()
+ self.AddNewElement(jump, bbox, wire)
dialog.Destroy()
- def AddNewActionBlock(self, bbox):
+ def AddNewActionBlock(self, bbox, wire=None):
dialog = ActionBlockDialog(self.ParentWindow)
dialog.SetQualifierList(self.Controler.GetQualifierTypes())
dialog.SetActionList(self.Controler.GetEditedElementActions(self.TagName, self.Debug))
dialog.SetVariableList(self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug))
if dialog.ShowModal() == wx.ID_OK:
- actions = dialog.GetValues()
id = self.GetNewId()
- actionblock = SFC_ActionBlock(self, actions, id)
- actionblock.SetPosition(bbox.x, bbox.y)
- min_width, min_height = actionblock.GetMinSize()
- actionblock.SetSize(*self.GetScaledSize(max(bbox.width, min_width), max(bbox.height, min_height)))
- self.AddBlock(actionblock)
+ actionblock = SFC_ActionBlock(self, dialog.GetValues(), id)
self.Controler.AddEditedElementActionBlock(self.TagName, id)
- self.RefreshActionBlockModel(actionblock)
- self.RefreshBuffer()
- self.RefreshScrollBars()
- self.RefreshVisibleElements()
- actionblock.Refresh()
+ self.AddNewElement(actionblock, bbox, wire)
dialog.Destroy()
#-------------------------------------------------------------------------------