24 |
24 |
25 import wx |
25 import wx |
26 |
26 |
27 from GraphicCommons import * |
27 from GraphicCommons import * |
28 from plcopen.structures import * |
28 from plcopen.structures import * |
29 from plcopen.structures import IsOfType |
|
30 |
29 |
31 #------------------------------------------------------------------------------- |
30 #------------------------------------------------------------------------------- |
32 # Function Block Diagram Block |
31 # Function Block Diagram Block |
33 #------------------------------------------------------------------------------- |
32 #------------------------------------------------------------------------------- |
34 |
33 |
49 self.Inputs = [] |
48 self.Inputs = [] |
50 self.Outputs = [] |
49 self.Outputs = [] |
51 self.Colour = wx.BLACK |
50 self.Colour = wx.BLACK |
52 self.Pen = wx.BLACK_PEN |
51 self.Pen = wx.BLACK_PEN |
53 self.SetType(type, extension, inputs, connectors) |
52 self.SetType(type, extension, inputs, connectors) |
|
53 self.Errors = {} |
54 |
54 |
55 # Make a clone of this FBD_Block |
55 # Make a clone of this FBD_Block |
56 def Clone(self, parent, id = None, name = "", pos = None): |
56 def Clone(self, parent, id = None, name = "", pos = None): |
57 if self.Name != "" and name == "": |
57 if self.Name != "" and name == "": |
58 name = self.Name |
58 name = self.Name |
181 resulttype = connectortype |
181 resulttype = connectortype |
182 for input in self.Inputs: |
182 for input in self.Inputs: |
183 name = input.GetName() |
183 name = input.GetName() |
184 if input != connector and (name.startswith("IN") or name in ["MN", "MX"]): |
184 if input != connector and (name.startswith("IN") or name in ["MN", "MX"]): |
185 inputtype = input.GetConnectedType() |
185 inputtype = input.GetConnectedType() |
186 if resulttype is None or inputtype is not None and IsOfType(inputtype, resulttype): |
186 if resulttype is None or inputtype is not None and self.IsOfType(inputtype, resulttype): |
187 resulttype = inputtype |
187 resulttype = inputtype |
188 for output in self.Outputs: |
188 for output in self.Outputs: |
189 name = output.GetName() |
189 name = output.GetName() |
190 if output != connector and name == "OUT" and not IsEndType(output.GetType()): |
190 if output != connector and name == "OUT" and not self.IsEndType(output.GetType()): |
191 outputtype = output.GetConnectedType() |
191 outputtype = output.GetConnectedType() |
192 if resulttype is None or outputtype is not None and IsOfType(outputtype, resulttype): |
192 if resulttype is None or outputtype is not None and self.IsOfType(outputtype, resulttype): |
193 resulttype = outputtype |
193 resulttype = outputtype |
194 return resulttype |
194 return resulttype |
195 |
195 |
196 # Returns all the block connectors |
196 # Returns all the block connectors |
197 def GetConnectors(self): |
197 def GetConnectors(self): |
216 self.Type = type |
216 self.Type = type |
217 self.TypeSize = self.Parent.GetTextExtent(self.Type) |
217 self.TypeSize = self.Parent.GetTextExtent(self.Type) |
218 self.Extension = extension |
218 self.Extension = extension |
219 # Find the block definition from type given and create the corresponding |
219 # Find the block definition from type given and create the corresponding |
220 # inputs and outputs |
220 # inputs and outputs |
221 blocktype = GetBlockType(type, inputs) |
221 blocktype = self.Parent.GetBlockType(type, inputs) |
222 if blocktype: |
222 if blocktype: |
223 self.Colour = wx.BLACK |
223 self.Colour = wx.BLACK |
224 inputs = [input for input in blocktype["inputs"]] |
224 inputs = [input for input in blocktype["inputs"]] |
225 outputs = [output for output in blocktype["outputs"]] |
225 outputs = [output for output in blocktype["outputs"]] |
226 if blocktype["extensible"]: |
226 if blocktype["extensible"]: |
348 # If block has moved, refresh the model of wires connected to outputs |
348 # If block has moved, refresh the model of wires connected to outputs |
349 if move: |
349 if move: |
350 for output in self.Outputs: |
350 for output in self.Outputs: |
351 output.RefreshWires() |
351 output.RefreshWires() |
352 |
352 |
|
353 def AddError(self, infos, start, end): |
|
354 if infos[0] in ["type", "name"] and start[0] == 0 and end[0] == 0: |
|
355 self.Errors[infos[0]] = (start, end) |
|
356 elif infos[0] == "input" and infos[1] < len(self.Inputs): |
|
357 self.Inputs[infos[1]].AddError(infos[2:], start, end) |
|
358 elif infos[0] == "output" and infos[1] < len(self.Outputs): |
|
359 self.Outputs[infos[1]].AddError(infos[2:], start, end) |
|
360 |
353 # Draws block |
361 # Draws block |
354 def Draw(self, dc): |
362 def Draw(self, dc): |
355 Graphic_Element.Draw(self, dc) |
363 Graphic_Element.Draw(self, dc) |
356 dc.SetPen(self.Pen) |
364 dc.SetPen(self.Pen) |
357 dc.SetBrush(wx.WHITE_BRUSH) |
365 dc.SetBrush(wx.WHITE_BRUSH) |
367 executionorder_size = self.ExecutionOrderSize |
375 executionorder_size = self.ExecutionOrderSize |
368 |
376 |
369 # Draw a rectangle with the block size |
377 # Draw a rectangle with the block size |
370 dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
378 dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
371 # Draw block name and block type |
379 # Draw block name and block type |
372 dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
380 name_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
373 self.Pos.y - (name_size[1] + 2)) |
381 self.Pos.y - (name_size[1] + 2)) |
374 dc.DrawText(self.Type, self.Pos.x + (self.Size[0] - type_size[0]) / 2, |
382 type_pos = (self.Pos.x + (self.Size[0] - type_size[0]) / 2, |
375 self.Pos.y + 5) |
383 self.Pos.y + 5) |
|
384 dc.DrawText(self.Name, name_pos[0], name_pos[1]) |
|
385 dc.DrawText(self.Type, type_pos[0], type_pos[1]) |
376 # Draw inputs and outputs connectors |
386 # Draw inputs and outputs connectors |
377 for input in self.Inputs: |
387 for input in self.Inputs: |
378 input.Draw(dc) |
388 input.Draw(dc) |
379 for output in self.Outputs: |
389 for output in self.Outputs: |
380 output.Draw(dc) |
390 output.Draw(dc) |
381 if self.ExecutionOrder != 0: |
391 if self.ExecutionOrder != 0: |
382 # Draw block execution order |
392 # Draw block execution order |
383 dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0], |
393 dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0], |
384 self.Pos.y + self.Size[1] + 2) |
394 self.Pos.y + self.Size[1] + 2) |
|
395 if "name" in self.Errors: |
|
396 HighlightErrorZone(dc, name_pos[0], name_pos[1], name_size[0], name_size[1]) |
|
397 if "type" in self.Errors: |
|
398 HighlightErrorZone(dc, type_pos[0], type_pos[1], type_size[0], type_size[1]) |
385 dc.SetTextForeground(wx.BLACK) |
399 dc.SetTextForeground(wx.BLACK) |
386 |
400 |
387 |
401 |
388 #------------------------------------------------------------------------------- |
402 #------------------------------------------------------------------------------- |
389 # Function Block Diagram Variable |
403 # Function Block Diagram Variable |
404 self.SetName(name) |
418 self.SetName(name) |
405 self.SetExecutionOrder(executionOrder) |
419 self.SetExecutionOrder(executionOrder) |
406 self.Input = None |
420 self.Input = None |
407 self.Output = None |
421 self.Output = None |
408 self.SetType(type, value_type) |
422 self.SetType(type, value_type) |
|
423 self.Errors = [] |
409 |
424 |
410 # Make a clone of this FBD_Variable |
425 # Make a clone of this FBD_Variable |
411 def Clone(self, parent, id = None, pos = None): |
426 def Clone(self, parent, id = None, pos = None): |
412 variable = FBD_Variable(parent, self.Type, self.Name, self.ValueType, id) |
427 variable = FBD_Variable(parent, self.Type, self.Name, self.ValueType, id) |
413 variable.SetSize(self.Size[0], self.Size[1]) |
428 variable.SetSize(self.Size[0], self.Size[1]) |
592 # of wires connected to output connector |
607 # of wires connected to output connector |
593 if move and self.Type != OUTPUT: |
608 if move and self.Type != OUTPUT: |
594 if self.Output: |
609 if self.Output: |
595 self.Output.RefreshWires() |
610 self.Output.RefreshWires() |
596 |
611 |
|
612 def AddError(self, infos, start, end): |
|
613 if infos[0] == "expression" and start[0] == 0 and end[0] == 0: |
|
614 self.Errors.append((start[1], end[1])) |
|
615 |
597 # Draws variable |
616 # Draws variable |
598 def Draw(self, dc): |
617 def Draw(self, dc): |
599 Graphic_Element.Draw(self, dc) |
618 Graphic_Element.Draw(self, dc) |
600 dc.SetPen(wx.BLACK_PEN) |
619 dc.SetPen(wx.BLACK_PEN) |
601 dc.SetBrush(wx.WHITE_BRUSH) |
620 dc.SetBrush(wx.WHITE_BRUSH) |
605 executionorder_size = dc.GetTextExtent(str(self.ExecutionOrder)) |
624 executionorder_size = dc.GetTextExtent(str(self.ExecutionOrder)) |
606 else: |
625 else: |
607 name_size = self.NameSize |
626 name_size = self.NameSize |
608 executionorder_size = self.ExecutionOrderSize |
627 executionorder_size = self.ExecutionOrderSize |
609 |
628 |
|
629 text_pos = (self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
|
630 self.Pos.y + (self.Size[1] - name_size[1]) / 2) |
610 # Draw a rectangle with the variable size |
631 # Draw a rectangle with the variable size |
611 dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
632 dc.DrawRectangle(self.Pos.x, self.Pos.y, self.Size[0] + 1, self.Size[1] + 1) |
612 # Draw variable name |
633 # Draw variable name |
613 dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - name_size[0]) / 2, |
634 dc.DrawText(self.Name, text_pos[0], text_pos[1]) |
614 self.Pos.y + (self.Size[1] - name_size[1]) / 2) |
|
615 # Draw connectors |
635 # Draw connectors |
616 if self.Input: |
636 if self.Input: |
617 self.Input.Draw(dc) |
637 self.Input.Draw(dc) |
618 if self.Output: |
638 if self.Output: |
619 self.Output.Draw(dc) |
639 self.Output.Draw(dc) |
620 if self.ExecutionOrder != 0: |
640 if self.ExecutionOrder != 0: |
621 # Draw variable execution order |
641 # Draw variable execution order |
622 dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0], |
642 dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - executionorder_size[0], |
623 self.Pos.y + self.Size[1] + 2) |
643 self.Pos.y + self.Size[1] + 2) |
624 |
644 for start, end in self.Errors: |
|
645 offset = dc.GetTextExtent(self.Name[:start]) |
|
646 size = dc.GetTextExtent(self.Name[start:end + 1]) |
|
647 HighlightErrorZone(dc, text_pos[0] + offset[0], text_pos[1], size[0], size[1]) |
625 |
648 |
626 #------------------------------------------------------------------------------- |
649 #------------------------------------------------------------------------------- |
627 # Function Block Diagram Connector |
650 # Function Block Diagram Connector |
628 #------------------------------------------------------------------------------- |
651 #------------------------------------------------------------------------------- |
629 |
652 |