graphics/GraphicCommons.py
changeset 145 4fb225afddf4
parent 144 b67a5de5a24a
child 155 b695f7459ef6
equal deleted inserted replaced
144:b67a5de5a24a 145:4fb225afddf4
   377         rect.width = self.BoundingBox.width + 2 * (HANDLE_SIZE + abs(movex)) + 4
   377         rect.width = self.BoundingBox.width + 2 * (HANDLE_SIZE + abs(movex)) + 4
   378         rect.height = self.BoundingBox.height + 2 * (HANDLE_SIZE + abs(movey)) + 4
   378         rect.height = self.BoundingBox.height + 2 * (HANDLE_SIZE + abs(movey)) + 4
   379         return rect
   379         return rect
   380     
   380     
   381     def Refresh(self, rect = None):
   381     def Refresh(self, rect = None):
   382         self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()))
   382         if rect is not None:
       
   383             self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect))
       
   384         else:
       
   385             self.Parent.RefreshRect(self.Parent.GetScrolledRect(self.GetRedrawRect()))
   383     
   386     
   384     # Change the variable that indicates if this element is selected
   387     # Change the variable that indicates if this element is selected
   385     def SetSelected(self, selected):
   388     def SetSelected(self, selected):
   386         self.Selected = selected
   389         self.Selected = selected
   387         self.Refresh()
   390         self.Refresh()
   443     
   446     
   444     # Method called when a LeftUp event have been generated
   447     # Method called when a LeftUp event have been generated
   445     def OnLeftUp(self, event, dc, scaling):
   448     def OnLeftUp(self, event, dc, scaling):
   446         # If a dragging have been initiated
   449         # If a dragging have been initiated
   447         if self.Dragging and self.oldPos:
   450         if self.Dragging and self.oldPos:
   448             # Calculate the movement of cursor and refreshes the element state
       
   449             pos = GetScaledEventPosition(event, dc, scaling)
       
   450             movex = pos.x - self.oldPos.x
       
   451             movey = pos.y - self.oldPos.y
       
   452             self.ProcessDragging(movex, movey)
       
   453             self.RefreshModel()
   451             self.RefreshModel()
   454             self.Parent.RefreshBuffer()
   452             self.Parent.RefreshBuffer()
   455         if self.CurrentCursor != 0:
   453         if self.CurrentCursor != 0:
   456             self.Parent.SetCursor(CURSORS[0])
   454             self.Parent.SetCursor(CURSORS[0])
   457             self.CurrentCursor = 0
   455             self.CurrentCursor = 0
   458         self.SetSelected(True)
   456         self.SetSelected(True)
   459         self.oldPos = None
   457         self.oldPos = None
   460 
   458 
       
   459     # Method called when a RightDown event have been generated
       
   460     def OnRightDown(self, event, dc, scaling):
       
   461         pass
       
   462 
   461     # Method called when a RightUp event have been generated
   463     # Method called when a RightUp event have been generated
   462     def OnRightUp(self, event, dc, scaling):
   464     def OnRightUp(self, event, dc, scaling):
       
   465         if self.Dragging and self.oldPos:
       
   466             self.RefreshModel()
       
   467             self.Parent.RefreshBuffer()
       
   468         if self.CurrentCursor != 0:
       
   469             self.Parent.SetCursor(CURSORS[0])
       
   470             self.CurrentCursor = 0
   463         self.SetSelected(True)
   471         self.SetSelected(True)
   464         self.oldPos = None
   472         self.oldPos = None
   465 
   473 
   466     # Method called when a LeftDClick event have been generated
   474     # Method called when a LeftDClick event have been generated
   467     def OnLeftDClick(self, event, dc, scaling):
   475     def OnLeftDClick(self, event, dc, scaling):
   470     # Method called when a Motion event have been generated
   478     # Method called when a Motion event have been generated
   471     def OnMotion(self, event, dc, scaling):
   479     def OnMotion(self, event, dc, scaling):
   472         # If the cursor is dragging and the element have been clicked
   480         # If the cursor is dragging and the element have been clicked
   473         if event.Dragging() and self.oldPos:
   481         if event.Dragging() and self.oldPos:
   474             # Calculate the movement of cursor
   482             # Calculate the movement of cursor
   475             pos = GetScaledEventPosition(event, dc, scaling)
   483             pos = event.GetLogicalPosition(dc)
   476             movex = pos.x - self.oldPos.x
   484             movex = pos.x - self.oldPos.x
   477             movey = pos.y - self.oldPos.y
   485             movey = pos.y - self.oldPos.y
   478             # If movement is greater than MIN_MOVE then a dragging is initiated
   486             # If movement is greater than MIN_MOVE then a dragging is initiated
   479             if not self.Dragging and (abs(movex) > MIN_MOVE or abs(movey) > MIN_MOVE):
   487             if not self.Dragging and (abs(movex) > MIN_MOVE or abs(movey) > MIN_MOVE):
   480                 self.Dragging = True
   488                 self.Dragging = True
   481             # If a dragging have been initiated, refreshes the element state
   489             # If a dragging have been initiated, refreshes the element state
   482             if self.Dragging:
   490             if self.Dragging:
   483                 dragx, dragy = self.ProcessDragging(movex, movey)
   491                 dragx, dragy = self.ProcessDragging(movex, movey, scaling)
   484                 self.oldPos.x += dragx
   492                 self.oldPos.x += dragx
   485                 self.oldPos.y += dragy
   493                 self.oldPos.y += dragy
   486                 return dragx, dragy
   494                 return dragx, dragy
   487             return movex, movey
   495             return movex, movey
   488         # If cursor just pass over the element, changes the cursor if it is on a handle
   496         # If cursor just pass over the element, changes the cursor if it is on a handle
   508     def Resize(self, x, y, width, height):
   516     def Resize(self, x, y, width, height):
   509         self.Move(x, y)
   517         self.Move(x, y)
   510         self.SetSize(width, height)
   518         self.SetSize(width, height)
   511     
   519     
   512     # Refreshes the element state according to move defined and handle selected
   520     # Refreshes the element state according to move defined and handle selected
   513     def ProcessDragging(self, movex, movey):
   521     def ProcessDragging(self, movex, movey, scaling):
   514         handle_type, handle = self.Handle
   522         handle_type, handle = self.Handle
   515         # If it is a resize handle, calculate the values from resizing
   523         # If it is a resize handle, calculate the values from resizing
   516         if handle_type == HANDLE_RESIZE:
   524         if handle_type == HANDLE_RESIZE:
   517             x = y = start_x = start_y = 0
   525             x = y = start_x = start_y = 0
   518             width, height = start_width, start_height = self.GetSize()
   526             width, height = start_width, start_height = self.GetSize()
   519             if handle[0] == 1:
   527             if handle[0] == 1:
   520                 x = movex = max(-self.BoundingBox.x, movex)
   528                 movex = max(-self.BoundingBox.x, movex)
       
   529                 if scaling is not None:
       
   530                     movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
       
   531                 x = movex
   521                 width -= movex
   532                 width -= movex
   522             elif handle[0] == 3:
   533             elif handle[0] == 3:
       
   534                 if scaling is not None:
       
   535                     movex = round(float(self.Pos.x + width + movex) / float(scaling[0])) * scaling[0] - self.Pos.x - width
   523                 width += movex
   536                 width += movex
   524             if handle[1] == 1:
   537             if handle[1] == 1:
   525                 y = movey = max(-self.BoundingBox.y, movey)
   538                 movey = max(-self.BoundingBox.y, movey)
       
   539                 if scaling is not None:
       
   540                     movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
       
   541                 y = movey
   526                 height -= movey
   542                 height -= movey
   527             elif handle[1] == 3:
   543             elif handle[1] == 3:
       
   544                 if scaling is not None:
       
   545                     movey = round(float(self.Pos.y + height + movey) / float(scaling[1])) * scaling[1] - self.Pos.y - height
   528                 height += movey
   546                 height += movey
   529             # Verify that new size is not lesser than minimum
   547             # Verify that new size is not lesser than minimum
   530             min_width, min_height = self.GetMinSize()
   548             min_width, min_height = self.GetMinSize()
   531             if handle[0] != 2 and (width >= min_width or width > self.Size[0]):
   549             if handle[0] != 2 and (width >= min_width or width > self.Size[0]):
   532                 start_x = x
   550                 start_x = x
   543             return movex, movey
   561             return movex, movey
   544         # If it is a move handle, Move this element
   562         # If it is a move handle, Move this element
   545         elif handle_type == HANDLE_MOVE:
   563         elif handle_type == HANDLE_MOVE:
   546             movex = max(-self.BoundingBox.x, movex)
   564             movex = max(-self.BoundingBox.x, movex)
   547             movey = max(-self.BoundingBox.y, movey)
   565             movey = max(-self.BoundingBox.y, movey)
       
   566             if scaling is not None:
       
   567                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
       
   568                 movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
   548             self.Move(movex, movey)
   569             self.Move(movex, movey)
   549             return movex, movey
   570             return movex, movey
   550         return 0, 0
   571         return 0, 0
   551     
   572     
   552     # Override this method for defining the method to call for refreshing the model of this element
   573     # Override this method for defining the method to call for refreshing the model of this element
  1186     # Returns connector to which end point is connected
  1207     # Returns connector to which end point is connected
  1187     def GetEndConnectedType(self):
  1208     def GetEndConnectedType(self):
  1188         if self.EndConnected:
  1209         if self.EndConnected:
  1189             return self.EndConnected.GetType()
  1210             return self.EndConnected.GetType()
  1190         return None
  1211         return None
       
  1212     
       
  1213     def GetOtherConnected(self, connector):
       
  1214         if self.StartConnected == connector:
       
  1215             return self.EndConnected
       
  1216         else:
       
  1217             return self.StartConnected
  1191     
  1218     
  1192     def GetOtherConnectedType(self, handle):
  1219     def GetOtherConnectedType(self, handle):
  1193         if handle == 0:
  1220         if handle == 0:
  1194             return self.GetEndConnectedType()
  1221             return self.GetEndConnectedType()
  1195         else:
  1222         else:
  1675     # to given point
  1702     # to given point
  1676     def ConnectStartPoint(self, point, connector):
  1703     def ConnectStartPoint(self, point, connector):
  1677         if point:
  1704         if point:
  1678             self.MoveStartPoint(point)
  1705             self.MoveStartPoint(point)
  1679         self.StartConnected = connector
  1706         self.StartConnected = connector
       
  1707         self.RefreshBoundingBox()
  1680     
  1708     
  1681     # Unconnects wire start point
  1709     # Unconnects wire start point
  1682     def UnConnectStartPoint(self, delete = False):
  1710     def UnConnectStartPoint(self, delete = False):
  1683         if delete:
  1711         if delete:
  1684             self.StartConnected = None
  1712             self.StartConnected = None
  1685             self.Delete()
  1713             self.Delete()
  1686         elif self.StartConnected:
  1714         elif self.StartConnected:
  1687             self.StartConnected.UnConnect(self, unconnect = False)
  1715             self.StartConnected.UnConnect(self, unconnect = False)
  1688             self.StartConnected = None
  1716             self.StartConnected = None
       
  1717             self.RefreshBoundingBox()
  1689     
  1718     
  1690     # Moves the wire end point and update the wire points
  1719     # Moves the wire end point and update the wire points
  1691     def MoveEndPoint(self, point):
  1720     def MoveEndPoint(self, point):
  1692         if len(self.Points) > 1:
  1721         if len(self.Points) > 1:
  1693             self.EndPoint[0] = point
  1722             self.EndPoint[0] = point
  1708     # to given point
  1737     # to given point
  1709     def ConnectEndPoint(self, point, connector):
  1738     def ConnectEndPoint(self, point, connector):
  1710         if point:
  1739         if point:
  1711             self.MoveEndPoint(point)
  1740             self.MoveEndPoint(point)
  1712         self.EndConnected = connector
  1741         self.EndConnected = connector
       
  1742         self.RefreshBoundingBox()
  1713     
  1743     
  1714     # Unconnects wire end point
  1744     # Unconnects wire end point
  1715     def UnConnectEndPoint(self, delete = False):
  1745     def UnConnectEndPoint(self, delete = False):
  1716         if delete:
  1746         if delete:
  1717             self.EndConnected = None
  1747             self.EndConnected = None
  1718             self.Delete()
  1748             self.Delete()
  1719         elif self.EndConnected:
  1749         elif self.EndConnected:
  1720             self.EndConnected.UnConnect(self, unconnect = False)
  1750             self.EndConnected.UnConnect(self, unconnect = False)
  1721             self.EndConnected = None
  1751             self.EndConnected = None
       
  1752             self.RefreshBoundingBox()
  1722     
  1753     
  1723     # Moves the wire segment given by its index
  1754     # Moves the wire segment given by its index
  1724     def MoveSegment(self, idx, movex, movey):
  1755     def MoveSegment(self, idx, movex, movey, scaling):
  1725         if 0 < idx < len(self.Segments) - 1:
  1756         if 0 < idx < len(self.Segments) - 1:
  1726             if self.Segments[idx] in (NORTH, SOUTH):
  1757             if self.Segments[idx] in (NORTH, SOUTH):
  1727                 start_x = self.Points[idx].x
  1758                 start_x = self.Points[idx].x
       
  1759                 if scaling is not None:
       
  1760                     movex = round(float(self.Points[idx].x + movex) / float(scaling[0])) * scaling[0] - self.Points[idx].x
  1728                 self.Points[idx].x += movex
  1761                 self.Points[idx].x += movex
  1729                 self.Points[idx + 1].x += movex
  1762                 self.Points[idx + 1].x += movex
  1730                 self.GeneratePoints()
  1763                 self.GeneratePoints()
  1731                 if start_x != self.Points[idx].x:
  1764                 if start_x != self.Points[idx].x:
  1732                     return self.Points[idx].x - start_x, 0
  1765                     return self.Points[idx].x - start_x, 0
  1733             elif self.Segments[idx] in (EAST, WEST):
  1766             elif self.Segments[idx] in (EAST, WEST):
  1734                 start_y = self.Points[idx].y
  1767                 start_y = self.Points[idx].y
       
  1768                 if scaling is not None:
       
  1769                     movey = round(float(self.Points[idx].y + movey) / float(scaling[1])) * scaling[1] - self.Points[idx].y
  1735                 self.Points[idx].y += movey
  1770                 self.Points[idx].y += movey
  1736                 self.Points[idx + 1].y += movey
  1771                 self.Points[idx + 1].y += movey
  1737                 self.GeneratePoints()
  1772                 self.GeneratePoints()
  1738                 if start_y != self.Points[idx].y:
  1773                 if start_y != self.Points[idx].y:
  1739                     return 0, self.Points[idx].y - start_y
  1774                     return 0, self.Points[idx].y - start_y
  1834                     endblock.RefreshModel()
  1869                     endblock.RefreshModel()
  1835                 else:
  1870                 else:
  1836                     self.MoveEndPoint(wx.Point(avgx, self.EndPoint[0].y))
  1871                     self.MoveEndPoint(wx.Point(avgx, self.EndPoint[0].y))
  1837             self.Parent.RefreshBuffer()
  1872             self.Parent.RefreshBuffer()
  1838         else:
  1873         else:
       
  1874             rect = self.GetRedrawRect()
  1839             self.ResetPoints()
  1875             self.ResetPoints()
  1840             self.GeneratePoints()
  1876             self.GeneratePoints()
  1841             self.RefreshModel()
  1877             self.RefreshModel()
  1842             self.Parent.RefreshBuffer()
  1878             self.Parent.RefreshBuffer()
       
  1879             self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect))
  1843         
  1880         
  1844     # Method called when a Motion event has been generated
  1881     # Method called when a Motion event has been generated
  1845     def OnMotion(self, event, dc, scaling):
  1882     def OnMotion(self, event, dc, scaling):
  1846         pos = GetScaledEventPosition(event, dc, scaling)
  1883         pos = GetScaledEventPosition(event, dc, scaling)
  1847         if not event.Dragging():
  1884         if not event.Dragging():
  1873         else:
  1910         else:
  1874             # Execute the default method for a graphic element
  1911             # Execute the default method for a graphic element
  1875             return Graphic_Element.OnMotion(self, event, dc, scaling)
  1912             return Graphic_Element.OnMotion(self, event, dc, scaling)
  1876     
  1913     
  1877     # Refreshes the wire state according to move defined and handle selected
  1914     # Refreshes the wire state according to move defined and handle selected
  1878     def ProcessDragging(self, movex, movey):
  1915     def ProcessDragging(self, movex, movey, scaling):
  1879         handle_type, handle = self.Handle
  1916         handle_type, handle = self.Handle
  1880         # A point has been handled
  1917         # A point has been handled
  1881         if handle_type == HANDLE_POINT:
  1918         if handle_type == HANDLE_POINT:
  1882             movex = max(-self.Points[handle].x + POINT_RADIUS, movex)
  1919             movex = max(-self.Points[handle].x + POINT_RADIUS, movex)
  1883             movey = max(-self.Points[handle].y + POINT_RADIUS, movey)
  1920             movey = max(-self.Points[handle].y + POINT_RADIUS, movey)
       
  1921             if scaling is not None:
       
  1922                 movex = round(float(self.Points[handle].x + movex) / float(scaling[0])) * scaling[0] - self.Points[handle].x
       
  1923                 movey = round(float(self.Points[handle].y + movey) / float(scaling[1])) * scaling[1] - self.Points[handle].y
  1884             # Try to connect point to a connector
  1924             # Try to connect point to a connector
  1885             new_pos = wx.Point(self.Points[handle].x + movex, self.Points[handle].y + movey)
  1925             new_pos = wx.Point(self.Points[handle].x + movex, self.Points[handle].y + movey)
  1886             connector = self.Parent.FindBlockConnector(new_pos)
  1926             connector = self.Parent.FindBlockConnector(new_pos)
  1887             if connector:
  1927             if connector:
  1888                 if handle == 0 and self.EndConnected != connector and connector.IsCompatible(self.GetEndConnectedType()):
  1928                 if handle == 0 and self.EndConnected != connector and connector.IsCompatible(self.GetEndConnectedType()):
  1919                     self.UnConnectEndPoint()
  1959                     self.UnConnectEndPoint()
  1920                 self.MoveEndPoint(new_pos)
  1960                 self.MoveEndPoint(new_pos)
  1921             return movex, movey
  1961             return movex, movey
  1922         # A segment has been handled, move a segment
  1962         # A segment has been handled, move a segment
  1923         elif handle_type == HANDLE_SEGMENT:
  1963         elif handle_type == HANDLE_SEGMENT:
  1924             return self.MoveSegment(handle[0], movex, movey)
  1964             return self.MoveSegment(handle[0], movex, movey, scaling)
  1925         # Execute the default method for a graphic element
  1965         # Execute the default method for a graphic element
  1926         else:
  1966         else:
  1927             return Graphic_Element.ProcessDragging(self, movex, movey)
  1967             return Graphic_Element.ProcessDragging(self, movex, movey, scaling)
  1928     
  1968     
  1929     # Refreshes the wire model
  1969     # Refreshes the wire model
  1930     def RefreshModel(self, move=True):
  1970     def RefreshModel(self, move=True):
  1931         if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]:
  1971         if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]:
  1932             self.StartConnected.RefreshParentBlock()
  1972             self.StartConnected.RefreshParentBlock()
  1947             posx = min(self.Points[i].x, self.Points[i + 1].x) - 2
  1987             posx = min(self.Points[i].x, self.Points[i + 1].x) - 2
  1948             posy = min(self.Points[i].y, self.Points[i + 1].y) - 2
  1988             posy = min(self.Points[i].y, self.Points[i + 1].y) - 2
  1949             width = abs(self.Points[i + 1].x - self.Points[i].x) + 5
  1989             width = abs(self.Points[i + 1].x - self.Points[i].x) + 5
  1950             height = abs(self.Points[i + 1].y - self.Points[i].y) + 5
  1990             height = abs(self.Points[i + 1].y - self.Points[i].y) + 5
  1951             dc.DrawRectangle(posx, posy, width, height)
  1991             dc.DrawRectangle(posx, posy, width, height)
       
  1992         dc.SetLogicalFunction(wx.COPY)
  1952         if self.StartConnected is not None:
  1993         if self.StartConnected is not None:
  1953             self.StartConnected.DrawHighlightment(dc)
  1994             self.StartConnected.DrawHighlightment(dc)
       
  1995             self.StartConnected.Draw(dc)
  1954         if self.EndConnected is not None:
  1996         if self.EndConnected is not None:
  1955             self.EndConnected.DrawHighlightment(dc)
  1997             self.EndConnected.DrawHighlightment(dc)
  1956         dc.SetLogicalFunction(wx.COPY)
  1998             self.EndConnected.Draw(dc)
  1957         
  1999         
  1958     # Draws the wire lines and points
  2000     # Draws the wire lines and points
  1959     def Draw(self, dc):
  2001     def Draw(self, dc):
  1960         Graphic_Element.Draw(self, dc)
  2002         Graphic_Element.Draw(self, dc)
  1961         dc.SetPen(wx.BLACK_PEN)
  2003         dc.SetPen(wx.BLACK_PEN)
  1994         self.Content = content
  2036         self.Content = content
  1995         self.Pos = wx.Point(0, 0)
  2037         self.Pos = wx.Point(0, 0)
  1996         self.Size = wx.Size(0, 0)
  2038         self.Size = wx.Size(0, 0)
  1997     
  2039     
  1998     # Make a clone of this comment
  2040     # Make a clone of this comment
  1999     def Clone(self, id = None):
  2041     def Clone(self, id = None, pos = None):
  2000         comment = Comment(self.Parent, self.Content, id)
  2042         comment = Comment(self.Parent, self.Content, id)
       
  2043         if pos is not None:
       
  2044             comment.SetPosition(pos.x, pos.y)
  2001         comment.SetSize(self.Size[0], self.Size[1])
  2045         comment.SetSize(self.Size[0], self.Size[1])
  2002         return comment
  2046         return comment
  2003     
  2047     
  2004     # Method for keeping compatibility with others
  2048     # Method for keeping compatibility with others
  2005     def Clean(self):
  2049     def Clean(self):