1 #!/usr/bin/env python |
1 #!/usr/bin/env python |
2 # -*- coding: utf-8 -*- |
2 # -*- coding: utf-8 -*- |
3 |
3 |
4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor |
4 # This file is part of Beremiz, a Integrated Development Environment for |
5 #based on the plcopen standard. |
5 # programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
6 # |
6 # |
7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
7 # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
8 # |
8 # |
9 #See COPYING file for copyrights details. |
9 # See COPYING file for copyrights details. |
10 # |
10 # |
11 #This library is free software; you can redistribute it and/or |
11 # This program is free software; you can redistribute it and/or |
12 #modify it under the terms of the GNU General Public |
12 # modify it under the terms of the GNU General Public License |
13 #License as published by the Free Software Foundation; either |
13 # as published by the Free Software Foundation; either version 2 |
14 #version 2.1 of the License, or (at your option) any later version. |
14 # of the License, or (at your option) any later version. |
15 # |
15 # |
16 #This library is distributed in the hope that it will be useful, |
16 # This program is distributed in the hope that it will be useful, |
17 #but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 #General Public License for more details. |
19 # GNU General Public License for more details. |
20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 # You should have received a copy of the GNU General Public License |
22 #License along with this library; if not, write to the Free Software |
22 # along with this program; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
24 |
24 |
25 import wx |
25 import wx |
26 from math import * |
26 from math import * |
27 from types import * |
27 from types import * |
28 import datetime |
28 import datetime |
1349 def SetEdge(self, edge): |
1349 def SetEdge(self, edge): |
1350 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1350 if self.ParentBlock.IsOfType("BOOL", self.Type): |
1351 self.Edge = edge |
1351 self.Edge = edge |
1352 self.Negated = False |
1352 self.Negated = False |
1353 |
1353 |
|
1354 # assume that pointer is already inside of this connector |
|
1355 def ConnectionAvailable(self, direction=None, exclude=True): |
|
1356 wire_nums = len(self.Wires) |
|
1357 |
|
1358 connector_free = (wire_nums<= 0) |
|
1359 connector_max_used = ((wire_nums > 0) and self.OneConnected) |
|
1360 if (self.Parent.CurrentLanguage in ["SFC", "LD"]) and (self.Type == "BOOL"): |
|
1361 connector_max_used = False; |
|
1362 |
|
1363 # connector is available for new connection |
|
1364 connect = connector_free or not connector_max_used |
|
1365 return connect, connector_max_used |
|
1366 |
1354 # Tests if the point given is near from the end point of this connector |
1367 # Tests if the point given is near from the end point of this connector |
1355 def TestPoint(self, pt, direction = None, exclude = True): |
1368 def TestPoint(self, pt, direction=None, exclude=True): |
1356 parent_pos = self.ParentBlock.GetPosition() |
1369 inside = False; |
1357 if (not (len(self.Wires) > 0 and self.OneConnected and exclude) or self.Type == "BOOL")\ |
1370 check_point = (not exclude) and (direction is None or self.Direction == direction); |
1358 and direction is None or self.Direction == direction: |
1371 |
|
1372 if check_point: |
1359 # Calculate a square around the end point of this connector |
1373 # Calculate a square around the end point of this connector |
|
1374 parent_pos = self.ParentBlock.GetPosition() |
1360 x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1375 x = parent_pos[0] + self.Pos.x + self.Direction[0] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1361 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1376 y = parent_pos[1] + self.Pos.y + self.Direction[1] * CONNECTOR_SIZE - ANCHOR_DISTANCE |
1362 width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE |
1377 width = ANCHOR_DISTANCE * 2 + abs(self.Direction[0]) * CONNECTOR_SIZE |
1363 height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE |
1378 height = ANCHOR_DISTANCE * 2 + abs(self.Direction[1]) * CONNECTOR_SIZE |
1364 rect = wx.Rect(x, y, width, height) |
1379 rect = wx.Rect(x, y, width, height) |
1365 return rect.InsideXY(pt.x, pt.y) |
1380 inside = rect.InsideXY(pt.x, pt.y); |
1366 return False |
1381 |
|
1382 return inside |
1367 |
1383 |
1368 # Draws the highlightment of this element if it is highlighted |
1384 # Draws the highlightment of this element if it is highlighted |
1369 def DrawHighlightment(self, dc): |
1385 def DrawHighlightment(self, dc): |
1370 scalex, scaley = dc.GetUserScale() |
1386 scalex, scaley = dc.GetUserScale() |
1371 dc.SetUserScale(1, 1) |
1387 dc.SetUserScale(1, 1) |
1549 self.ComputedValue = None |
1565 self.ComputedValue = None |
1550 self.OverStart = False |
1566 self.OverStart = False |
1551 self.OverEnd = False |
1567 self.OverEnd = False |
1552 self.ComputingType = False |
1568 self.ComputingType = False |
1553 self.Font = parent.GetMiniFont() |
1569 self.Font = parent.GetMiniFont() |
|
1570 self.ErrHighlight = False |
1554 |
1571 |
1555 def GetDefinition(self): |
1572 def GetDefinition(self): |
1556 if self.StartConnected is not None and self.EndConnected is not None: |
1573 if self.StartConnected is not None and self.EndConnected is not None: |
1557 startblock = self.StartConnected.GetParentBlock() |
1574 startblock = self.StartConnected.GetParentBlock() |
1558 endblock = self.EndConnected.GetParentBlock() |
1575 endblock = self.EndConnected.GetParentBlock() |
2588 |
2605 |
2589 # Draws the highlightment of this element if it is highlighted |
2606 # Draws the highlightment of this element if it is highlighted |
2590 def DrawHighlightment(self, dc): |
2607 def DrawHighlightment(self, dc): |
2591 scalex, scaley = dc.GetUserScale() |
2608 scalex, scaley = dc.GetUserScale() |
2592 dc.SetUserScale(1, 1) |
2609 dc.SetUserScale(1, 1) |
2593 dc.SetPen(MiterPen(HIGHLIGHTCOLOR, (2 * scalex + 5))) |
2610 # If user trying to connect wire with wrong input, highlight will become red. |
2594 dc.SetBrush(wx.Brush(HIGHLIGHTCOLOR)) |
2611 if self.ErrHighlight == True and not (self.EndConnected): |
|
2612 highlightcolor = wx.RED |
|
2613 else: |
|
2614 highlightcolor = HIGHLIGHTCOLOR |
|
2615 dc.SetPen(MiterPen(highlightcolor, (2 * scalex + 5))) |
|
2616 dc.SetBrush(wx.Brush(highlightcolor)) |
2595 dc.SetLogicalFunction(wx.AND) |
2617 dc.SetLogicalFunction(wx.AND) |
2596 # Draw the start and end points if they are not connected or the mouse is over them |
2618 # Draw the start and end points if they are not connected or the mouse is over them |
2597 if len(self.Points) > 0 and (not self.StartConnected or self.OverStart): |
2619 if len(self.Points) > 0 and (not self.StartConnected or self.OverStart): |
2598 dc.DrawCircle(round(self.Points[0].x * scalex), |
2620 dc.DrawCircle(round(self.Points[0].x * scalex), |
2599 round(self.Points[0].y * scaley), |
2621 round(self.Points[0].y * scaley), |
2871 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2893 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2872 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10), |
2894 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10), |
2873 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1]), |
2895 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1]), |
2874 wx.Point(self.Pos.x, self.Pos.y + self.Size[1])] |
2896 wx.Point(self.Pos.x, self.Pos.y + self.Size[1])] |
2875 dc.DrawPolygon(polygon) |
2897 dc.DrawPolygon(polygon) |
|
2898 |
|
2899 # dc.SetBrush call is workaround for the issue with wx.PrinterDC |
|
2900 # with wxPython 3.0 on GNU/Linux (don't remove it) |
|
2901 dc.SetBrush(wx.WHITE_BRUSH) |
2876 lines = [wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2902 lines = [wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y), |
2877 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y + 10), |
2903 wx.Point(self.Pos.x + self.Size[0] - 10, self.Pos.y + 10), |
2878 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10)] |
2904 wx.Point(self.Pos.x + self.Size[0], self.Pos.y + 10)] |
2879 dc.DrawLines(lines) |
2905 dc.DrawLines(lines) |
|
2906 |
2880 # Draws the comment content |
2907 # Draws the comment content |
2881 y = self.Pos.y + 10 |
2908 y = self.Pos.y + 10 |
2882 for idx, line in enumerate(self.Content.splitlines()): |
2909 for idx, line in enumerate(self.Content.splitlines()): |
2883 first = True |
2910 first = True |
2884 linetext = "" |
2911 linetext = "" |