graphics/GraphicCommons.py
changeset 58 39cd981ff242
parent 56 7187e1c00975
child 60 ef940f442b8d
equal deleted inserted replaced
57:9bf197698af0 58:39cd981ff242
     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 PLCOpenEditor, a library implementing an IEC 61131-3 editor
     5 #based on the plcopen standard. 
     5 #based on the plcopen standard. 
     6 #
     6 #
     7 #Copyright (C): 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 library 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
    14 #version 2.1 of the License, or (at your option) any later version.
    14 #version 2.1 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 library 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 GNU
    19 #Lesser General Public License for more details.
    19 #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
    22 #License along with this library; if not, write to the Free Software
    22 #License along with this library; if not, write to the Free Software
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    24 
    84  MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION] = range(15)
    84  MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION] = range(15)
    85 
    85 
    86 # Contants for defining which drawing mode is selected for app
    86 # Contants for defining which drawing mode is selected for app
    87 [FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2]
    87 [FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2]
    88 
    88 
       
    89 CURSORS = None
       
    90 
       
    91 def ResetCursors():
       
    92     global CURSORS
       
    93     if CURSORS == None:
       
    94         CURSORS = [wxNullCursor, 
       
    95                    wxStockCursor(wxCURSOR_HAND),
       
    96                    wxStockCursor(wxCURSOR_SIZENWSE),
       
    97                    wxStockCursor(wxCURSOR_SIZENESW),
       
    98                    wxStockCursor(wxCURSOR_SIZEWE),
       
    99                    wxStockCursor(wxCURSOR_SIZENS)]
       
   100            
       
   101 HANDLE_CURSORS = {
       
   102     (1, 1) : 2,
       
   103     (3, 3) : 2,
       
   104     (1, 3) : 3,
       
   105     (3, 1) : 3,
       
   106     (1, 2) : 4,
       
   107     (3, 2) : 4,
       
   108     (2, 1) : 5,
       
   109     (2, 3) : 5
       
   110 }
    89 
   111 
    90 """
   112 """
    91 Basic vector operations for calculate wire points
   113 Basic vector operations for calculate wire points
    92 """
   114 """
    93 
   115 
   263         self.Dragging = False
   285         self.Dragging = False
   264         self.Selected = False
   286         self.Selected = False
   265         self.Pos = wxPoint(0, 0)
   287         self.Pos = wxPoint(0, 0)
   266         self.Size = wxSize(0, 0)
   288         self.Size = wxSize(0, 0)
   267         self.BoundingBox = wxRect(0, 0, 0, 0)
   289         self.BoundingBox = wxRect(0, 0, 0, 0)
       
   290         self.CurrentCursor = 0
       
   291         ResetCursors()
   268     
   292     
   269     # Make a clone of this element
   293     # Make a clone of this element
   270     def Clone(self):
   294     def Clone(self):
   271         return Graphic_Element(self.Parent, self.Id)
   295         return Graphic_Element(self.Parent, self.Id)
   272     
   296     
   337     def SetSelected(self, selected):
   361     def SetSelected(self, selected):
   338         self.Selected = selected
   362         self.Selected = selected
   339     
   363     
   340     # Test if the point is on a handle of this element
   364     # Test if the point is on a handle of this element
   341     def TestHandle(self, pt):
   365     def TestHandle(self, pt):
       
   366         extern_rect = wxRect(self.BoundingBox.x - HANDLE_SIZE - 2, self.BoundingBox.y - HANDLE_SIZE - 2, 
       
   367             self.BoundingBox.width + 2 * HANDLE_SIZE + 4, self.BoundingBox.height + 2 * HANDLE_SIZE + 4)
       
   368         intern_rect = wxRect(self.BoundingBox.x - 2, self.BoundingBox.y - 2, 
       
   369             self.BoundingBox.width + 4, self.BoundingBox.height + 4)
   342         # Verify that this element is selected
   370         # Verify that this element is selected
   343         if self.Selected:
   371         if self.Selected and extern_rect.InsideXY(pt.x, pt.y) and not intern_rect.InsideXY(pt.x, pt.y):
   344             # Find if point is on a handle horizontally
   372             # Find if point is on a handle horizontally
   345             if self.BoundingBox.x - HANDLE_SIZE - 2 <= pt.x < self.BoundingBox.x - 2:
   373             if self.BoundingBox.x - HANDLE_SIZE - 2 <= pt.x < self.BoundingBox.x - 2:
   346                 handle_x = 1
   374                 handle_x = 1
   347             elif self.BoundingBox.x + (self.BoundingBox.width - HANDLE_SIZE) / 2 <= pt.x < self.BoundingBox.x + (self.BoundingBox.width + HANDLE_SIZE) / 2:
   375             elif self.BoundingBox.x + (self.BoundingBox.width - HANDLE_SIZE) / 2 <= pt.x < self.BoundingBox.x + (self.BoundingBox.width + HANDLE_SIZE) / 2:
   348                 handle_x = 2
   376                 handle_x = 2
   366     
   394     
   367     # Method called when a LeftDown event have been generated
   395     # Method called when a LeftDown event have been generated
   368     def OnLeftDown(self, event, dc, scaling):
   396     def OnLeftDown(self, event, dc, scaling):
   369         pos = event.GetLogicalPosition(dc)
   397         pos = event.GetLogicalPosition(dc)
   370         # Test if an handle have been clicked
   398         # Test if an handle have been clicked
   371         result = self.TestHandle(pos)
   399         handle = self.TestHandle(pos)
   372         # Find which type of handle have been clicked,
   400         # Find which type of handle have been clicked,
   373         # Save a resize event and change the cursor
   401         # Save a resize event and change the cursor
   374         if result == (1, 1) or result == (3, 3):
   402         cursor = HANDLE_CURSORS.get(handle, 1)
   375             self.Handle = (HANDLE_RESIZE, result)
   403         if cursor != self.CurrentCursor:
   376             self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZENWSE))
   404             self.Parent.SetCursor(CURSORS[cursor])
   377         elif result == (1, 3) or result == (3, 1):
   405             self.CurrentCursor = cursor
   378             self.Handle = (HANDLE_RESIZE, result)
   406         if cursor > 1:
   379             self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZENESW))
   407             self.Handle = (HANDLE_RESIZE, handle)
   380         elif result == (1, 2) or result == (3, 2):
       
   381             self.Handle = (HANDLE_RESIZE, result)
       
   382             self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZEWE))
       
   383         elif result == (2, 1) or result == (2, 3):
       
   384             self.Handle = (HANDLE_RESIZE, result)
       
   385             self.Parent.SetCursor(wxStockCursor(wxCURSOR_SIZENS))
       
   386         # If no handle have been clicked, save a move event, and change the cursor
       
   387         else:
   408         else:
   388             self.Handle = (HANDLE_MOVE, None)
   409             self.Handle = (HANDLE_MOVE, None)
   389             self.Parent.SetCursor(wxStockCursor(wxCURSOR_HAND))
       
   390             self.SetSelected(False)
   410             self.SetSelected(False)
   391         # Initializes the last position
   411         # Initializes the last position
   392         self.oldPos = GetScaledEventPosition(event, dc, scaling)
   412         self.oldPos = GetScaledEventPosition(event, dc, scaling)
   393     
   413     
   394     # Method called when a LeftUp event have been generated
   414     # Method called when a LeftUp event have been generated
   400             movex = pos.x - self.oldPos.x
   420             movex = pos.x - self.oldPos.x
   401             movey = pos.y - self.oldPos.y
   421             movey = pos.y - self.oldPos.y
   402             self.ProcessDragging(movex, movey)
   422             self.ProcessDragging(movex, movey)
   403             self.RefreshModel()
   423             self.RefreshModel()
   404             self.Parent.RefreshBuffer()
   424             self.Parent.RefreshBuffer()
       
   425         if self.CurrentCursor != 0:
       
   426             self.Parent.SetCursor(CURSORS[0])
       
   427             self.CurrentCursor = 0
   405         self.SetSelected(True)
   428         self.SetSelected(True)
   406         self.oldPos = None
   429         self.oldPos = None
   407 
   430 
   408     # Method called when a RightUp event have been generated
   431     # Method called when a RightUp event have been generated
   409     def OnRightUp(self, event, dc, scaling):
   432     def OnRightUp(self, event, dc, scaling):
   431                 self.ProcessDragging(movex, movey)
   454                 self.ProcessDragging(movex, movey)
   432         # If cursor just pass over the element, changes the cursor if it is on a handle
   455         # If cursor just pass over the element, changes the cursor if it is on a handle
   433         else:
   456         else:
   434             pos = event.GetLogicalPosition(dc)
   457             pos = event.GetLogicalPosition(dc)
   435             handle = self.TestHandle(pos)
   458             handle = self.TestHandle(pos)
   436             if handle == (1, 1) or handle == (3, 3):
   459             # Find which type of handle have been clicked,
   437                 wxCallAfter(self.Parent.SetCursor, wxStockCursor(wxCURSOR_SIZENWSE))
   460             # Save a resize event and change the cursor
   438             elif handle == (1, 3) or handle == (3, 1):
   461             cursor = HANDLE_CURSORS.get(handle, 0)
   439                 wxCallAfter(self.Parent.SetCursor, wxStockCursor(wxCURSOR_SIZENESW))
   462             if cursor != self.CurrentCursor:
   440             elif handle == (1, 2) or handle == (3, 2):
   463                 self.Parent.SetCursor(CURSORS[cursor])
   441                 wxCallAfter(self.Parent.SetCursor, wxStockCursor(wxCURSOR_SIZEWE))
   464                 self.CurrentCursor = cursor
   442             elif handle == (2, 1) or handle == (2, 3):
   465 
   443                 wxCallAfter(self.Parent.SetCursor, wxStockCursor(wxCURSOR_SIZENS))
       
   444             else:
       
   445                 wxCallAfter(self.Parent.SetCursor, wxNullCursor)
       
   446     
       
   447     # Moves the element
   466     # Moves the element
   448     def Move(self, dx, dy, exclude = []):
   467     def Move(self, dx, dy, exclude = []):
   449         self.Pos.x += dx
   468         self.Pos.x += dx
   450         self.Pos.y += dy
   469         self.Pos.y += dy
   451         self.RefreshConnected(exclude)
   470         self.RefreshConnected(exclude)