graphics/GraphicCommons.py
changeset 327 7fd5233ce5ce
parent 321 5b37e16f7b2a
child 328 500588ea29e8
equal deleted inserted replaced
326:c82807b17128 327:7fd5233ce5ce
   309     # Create a new graphic element
   309     # Create a new graphic element
   310     def __init__(self, parent, id = None):
   310     def __init__(self, parent, id = None):
   311         self.Parent = parent
   311         self.Parent = parent
   312         self.Id = id
   312         self.Id = id
   313         self.oldPos = None
   313         self.oldPos = None
       
   314         self.StartPos = None
       
   315         self.CurrentDrag = None
   314         self.Handle = (None,None)
   316         self.Handle = (None,None)
   315         self.Dragging = False
   317         self.Dragging = False
   316         self.Selected = False
   318         self.Selected = False
   317         self.Highlighted = False
   319         self.Highlighted = False
   318         self.Pos = wx.Point(0, 0)
   320         self.Pos = wx.Point(0, 0)
   482         else:
   484         else:
   483             self.Handle = (HANDLE_MOVE, None)
   485             self.Handle = (HANDLE_MOVE, None)
   484             self.SetSelected(False)
   486             self.SetSelected(False)
   485         # Initializes the last position
   487         # Initializes the last position
   486         self.oldPos = GetScaledEventPosition(event, dc, scaling)
   488         self.oldPos = GetScaledEventPosition(event, dc, scaling)
       
   489         self.StartPos = wx.Point(self.Pos.x, self.Pos.y)
       
   490         self.CurrentDrag = wx.Point(0, 0)
   487     
   491     
   488     # Method called when a LeftUp event have been generated
   492     # Method called when a LeftUp event have been generated
   489     def OnLeftUp(self, event, dc, scaling):
   493     def OnLeftUp(self, event, dc, scaling):
   490         # If a dragging have been initiated
   494         # If a dragging have been initiated
   491         if self.Dragging and self.oldPos:
   495         if self.Dragging and self.oldPos:
   527             # If movement is greater than MIN_MOVE then a dragging is initiated
   531             # If movement is greater than MIN_MOVE then a dragging is initiated
   528             if not self.Dragging and (abs(movex) > MIN_MOVE or abs(movey) > MIN_MOVE):
   532             if not self.Dragging and (abs(movex) > MIN_MOVE or abs(movey) > MIN_MOVE):
   529                 self.Dragging = True
   533                 self.Dragging = True
   530             # If a dragging have been initiated, refreshes the element state
   534             # If a dragging have been initiated, refreshes the element state
   531             if self.Dragging:
   535             if self.Dragging:
   532                 dragx, dragy = self.ProcessDragging(movex, movey, event.ShiftDown(), scaling)
   536                 dragx, dragy = self.ProcessDragging(movex, movey, event, scaling)
   533                 self.oldPos.x += dragx
   537                 if event.ControlDown():
   534                 self.oldPos.y += dragy
   538                     self.oldPos.x = self.StartPos.x + self.CurrentDrag.x
       
   539                     self.oldPos.y = self.StartPos.y + self.CurrentDrag.y
       
   540                 else:
       
   541                     self.oldPos.x += dragx
       
   542                     self.oldPos.y += dragy
   535                 return dragx, dragy
   543                 return dragx, dragy
   536             return movex, movey
   544             return movex, movey
   537         # If cursor just pass over the element, changes the cursor if it is on a handle
   545         # If cursor just pass over the element, changes the cursor if it is on a handle
   538         else:
   546         else:
   539             pos = event.GetLogicalPosition(dc)
   547             pos = event.GetLogicalPosition(dc)
   557     def Resize(self, x, y, width, height):
   565     def Resize(self, x, y, width, height):
   558         self.Move(x, y)
   566         self.Move(x, y)
   559         self.SetSize(width, height)
   567         self.SetSize(width, height)
   560     
   568     
   561     # Refreshes the element state according to move defined and handle selected
   569     # Refreshes the element state according to move defined and handle selected
   562     def ProcessDragging(self, movex, movey, centered, scaling, width_fac = 1, height_fac = 1):
   570     def ProcessDragging(self, movex, movey, event, scaling, width_fac = 1, height_fac = 1):
   563         handle_type, handle = self.Handle
   571         handle_type, handle = self.Handle
   564         # If it is a resize handle, calculate the values from resizing
   572         # If it is a resize handle, calculate the values from resizing
   565         if handle_type == HANDLE_RESIZE:
   573         if handle_type == HANDLE_RESIZE:
   566             if scaling is not None:
   574             if scaling is not None:
   567                 scaling = (scaling[0] * width_fac, scaling[1] * height_fac)
   575                 scaling = (scaling[0] * width_fac, scaling[1] * height_fac)
   568             x = y = start_x = start_y = 0
   576             x = y = start_x = start_y = 0
   569             width, height = start_width, start_height = self.GetSize()
   577             width, height = start_width, start_height = self.GetSize()
       
   578             proportion = float(start_width) / float(start_height)
   570             if handle[0] == 1:
   579             if handle[0] == 1:
   571                 movex = max(-self.BoundingBox.x, movex)
   580                 movex = max(-self.BoundingBox.x, movex)
   572                 if scaling is not None:
   581                 if scaling is not None:
   573                     movex = -(round(float(width - movex) / float(scaling[0])) * scaling[0] - width)
   582                     movex = -(round(float(width - movex) / float(scaling[0])) * scaling[0] - width)
   574                 x = movex
   583                 x = movex
   575                 if centered:
   584                 if event.ShiftDown():
   576                     width -= 2 * movex
   585                     width -= 2 * movex
   577                 else:
   586                 else:
   578                     width -= movex
   587                     width -= movex
   579             elif handle[0] == 3:
   588             elif handle[0] == 3:
   580                 if scaling is not None:
   589                 if scaling is not None:
   581                     movex = round(float(width + movex) / float(scaling[0])) * scaling[0] - width
   590                     movex = round(float(width + movex) / float(scaling[0])) * scaling[0] - width
   582                 if centered:
   591                 if event.ShiftDown():
   583                     x = -movex
   592                     x = -movex
   584                     width += 2 * movex
   593                     width += 2 * movex
   585                 else:
   594                 else:
   586                     width += movex
   595                     width += movex
   587             if handle[1] == 1:
   596             if handle[1] == 1:
   588                 movey = max(-self.BoundingBox.y, movey)
   597                 movey = max(-self.BoundingBox.y, movey)
   589                 if scaling is not None:
   598                 if scaling is not None:
   590                     movey = -(round(float(height - movey) / float(scaling[1])) * scaling[1] - height)
   599                     movey = -(round(float(height - movey) / float(scaling[1])) * scaling[1] - height)
   591                 y = movey
   600                 y = movey
   592                 if centered:
   601                 if event.ShiftDown():
   593                     height -= 2 * movey
   602                     height -= 2 * movey
   594                 else:
   603                 else:
   595                     height -= movey
   604                     height -= movey
   596             elif handle[1] == 3:
   605             elif handle[1] == 3:
   597                 if scaling is not None:
   606                 if scaling is not None:
   598                     movey = round(float(height + movey) / float(scaling[1])) * scaling[1] - height
   607                     movey = round(float(height + movey) / float(scaling[1])) * scaling[1] - height
   599                 if centered:
   608                 if event.ShiftDown():
   600                     y = -movey
   609                     y = -movey
   601                     height += 2 * movey
   610                     height += 2 * movey
   602                 else:
   611                 else:
   603                     height += movey
   612                     height += movey
   604             # Verify that new size is not lesser than minimum
   613             # Verify that new size is not lesser than minimum
   621             movex = max(-self.BoundingBox.x, movex)
   630             movex = max(-self.BoundingBox.x, movex)
   622             movey = max(-self.BoundingBox.y, movey)
   631             movey = max(-self.BoundingBox.y, movey)
   623             if scaling is not None:
   632             if scaling is not None:
   624                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
   633                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
   625                 movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
   634                 movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
       
   635             if event.ControlDown():
       
   636                 self.CurrentDrag.x = self.CurrentDrag.x + movex
       
   637                 self.CurrentDrag.y = self.CurrentDrag.y + movey
       
   638                 if abs(self.CurrentDrag.x) > abs(self.CurrentDrag.y):
       
   639                     movex = self.StartPos.x + self.CurrentDrag.x - self.Pos.x
       
   640                     movey = self.StartPos.y - self.Pos.y
       
   641                 else:
       
   642                     movex = self.StartPos.x - self.Pos.x
       
   643                     movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y   
   626             self.Move(movex, movey)
   644             self.Move(movex, movey)
   627             return movex, movey
   645             return movex, movey
   628         return 0, 0
   646         return 0, 0
   629     
   647     
   630     def AddError(self, infos, start, end):
   648     def AddError(self, infos, start, end):
   837         self.RefreshWireExclusion()
   855         self.RefreshWireExclusion()
   838         self.RefreshBoundingBox()
   856         self.RefreshBoundingBox()
   839     
   857     
   840     # Move this group of elements
   858     # Move this group of elements
   841     def Move(self, movex, movey):
   859     def Move(self, movex, movey):
       
   860         print self.Pos, self.StartPos
   842         # Move all the elements of the group
   861         # Move all the elements of the group
   843         for element in self.Elements:
   862         for element in self.Elements:
   844             if not isinstance(element, Wire):
   863             if not isinstance(element, Wire):
   845                 element.Move(movex, movey, self.WireExcluded)
   864                 element.Move(movex, movey, self.WireExcluded)
   846             elif element in self.WireExcluded:
   865             elif element in self.WireExcluded:
   861                 maxx = max(maxx, bbox.x + bbox.width)
   880                 maxx = max(maxx, bbox.x + bbox.width)
   862                 maxy = max(maxy, bbox.y + bbox.height)
   881                 maxy = max(maxy, bbox.y + bbox.height)
   863             self.BoundingBox = wx.Rect(minx, miny, maxx - minx, maxy - miny)
   882             self.BoundingBox = wx.Rect(minx, miny, maxx - minx, maxy - miny)
   864         else:
   883         else:
   865             self.BoundingBox = wx.Rect(0, 0, 0, 0)
   884             self.BoundingBox = wx.Rect(0, 0, 0, 0)
       
   885         self.Pos = wx.Point(self.BoundingBox.x, self.BoundingBox.y)
       
   886         self.Size = wx.Size(self.BoundingBox.width, self.BoundingBox.height)
   866 
   887 
   867     # Forbids to change the group position
   888     # Forbids to change the group position
   868     def SetPosition(x, y):
   889     def SetPosition(x, y):
   869         pass
   890         pass
   870     
   891     
  2108             # Execute the default method for a graphic element
  2129             # Execute the default method for a graphic element
  2109             Graphic_Element.OnRightUp(self, event, dc, scaling)
  2130             Graphic_Element.OnRightUp(self, event, dc, scaling)
  2110     
  2131     
  2111     # Method called when a LeftDClick event has been generated
  2132     # Method called when a LeftDClick event has been generated
  2112     def OnLeftDClick(self, event, dc, scaling):
  2133     def OnLeftDClick(self, event, dc, scaling):
       
  2134         rect = self.GetRedrawRect()
  2113         if event.ControlDown():
  2135         if event.ControlDown():
  2114             direction = (self.StartPoint[1], self.EndPoint[1])
  2136             direction = (self.StartPoint[1], self.EndPoint[1])
  2115             if direction in [(EAST, WEST), (WEST, EAST)]:
  2137             if direction in [(EAST, WEST), (WEST, EAST)]:
  2116                 avgy = (self.StartPoint[0].y + self.EndPoint[0].y) / 2
  2138                 avgy = round(float((self.StartPoint[0].y + self.EndPoint[0].y) / 2) / scaling[1]) * scaling[1]
  2117                 if self.StartConnected is not None:
  2139                 if self.StartConnected is not None:
       
  2140                     movey = avgy - self.StartPoint[0].y
  2118                     startblock = self.StartConnected.GetParentBlock()
  2141                     startblock = self.StartConnected.GetParentBlock()
  2119                     startblock.Move(0, avgy - self.StartPoint[0].y)
  2142                     startblock.Move(0, movey)
  2120                     startblock.RefreshModel()
  2143                     startblock.RefreshModel()
       
  2144                     rect.Union(startblock.GetRedrawRect(0, movey))
  2121                 else:
  2145                 else:
  2122                     self.MoveStartPoint(wx.Point(self.StartPoint[0].x, avgy))
  2146                     self.MoveStartPoint(wx.Point(self.StartPoint[0].x, avgy))
  2123                 if self.EndConnected is not None:
  2147                 if self.EndConnected is not None:
       
  2148                     movey = avgy - self.EndPoint[0].y
  2124                     endblock = self.EndConnected.GetParentBlock()
  2149                     endblock = self.EndConnected.GetParentBlock()
  2125                     endblock.Move(0, avgy - self.EndPoint[0].y)
  2150                     endblock.Move(0, movey)
  2126                     endblock.RefreshModel()
  2151                     endblock.RefreshModel()
       
  2152                     rect.Union(endblock.GetRedrawRect(0, movey))
  2127                 else:
  2153                 else:
  2128                     self.MoveEndPoint(wx.Point(self.EndPoint[0].x, avgy))
  2154                     self.MoveEndPoint(wx.Point(self.EndPoint[0].x, avgy))
       
  2155                 self.Parent.RefreshBuffer()
  2129             elif direction in [(NORTH, SOUTH), (SOUTH, NORTH)]:
  2156             elif direction in [(NORTH, SOUTH), (SOUTH, NORTH)]:
  2130                 avgx = (self.StartPoint[0].x + self.EndPoint[0].x) / 2
  2157                 avgx = round(float((self.StartPoint[0].x + self.EndPoint[0].x) / 2) / scaling[0]) * scaling[0]
  2131                 if self.StartConnected is not None:
  2158                 if self.StartConnected is not None:
       
  2159                     movex = avgx - self.StartPoint[0].x
  2132                     startblock = self.StartConnected.GetParentBlock()
  2160                     startblock = self.StartConnected.GetParentBlock()
  2133                     startblock.Move(avgx - self.StartPoint[0].x, 0)
  2161                     startblock.Move(movex, 0)
  2134                     startblock.RefreshModel()
  2162                     startblock.RefreshModel()
       
  2163                     rect.Union(startblock.GetRedrawRect(movex, 0))
  2135                 else:
  2164                 else:
  2136                     self.MoveStartPoint(wx.Point(avgx, self.StartPoint[0].y))
  2165                     self.MoveStartPoint(wx.Point(avgx, self.StartPoint[0].y))
  2137                 if self.EndConnected is not None:
  2166                 if self.EndConnected is not None:
       
  2167                     movex = avgx - self.EndPoint[0].x
  2138                     endblock = self.EndConnected.GetParentBlock()
  2168                     endblock = self.EndConnected.GetParentBlock()
  2139                     endblock.Move(avgx - self.EndPoint[0].x, 0)
  2169                     endblock.Move(movex, 0)
  2140                     endblock.RefreshModel()
  2170                     endblock.RefreshModel()
       
  2171                     rect.Union(endblock.GetRedrawRect(movex, 0))
  2141                 else:
  2172                 else:
  2142                     self.MoveEndPoint(wx.Point(avgx, self.EndPoint[0].y))
  2173                     self.MoveEndPoint(wx.Point(avgx, self.EndPoint[0].y))
  2143             self.Parent.RefreshBuffer()
  2174                 self.Parent.RefreshBuffer()
  2144         else:
  2175         else:
  2145             rect = self.GetRedrawRect()
       
  2146             self.ResetPoints()
  2176             self.ResetPoints()
  2147             self.GeneratePoints()
  2177             self.GeneratePoints()
  2148             self.RefreshModel()
  2178             self.RefreshModel()
  2149             self.Parent.RefreshBuffer()
  2179             self.Parent.RefreshBuffer()
  2150             self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False)
  2180         rect.Union(self.GetRedrawRect())
       
  2181         self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False)
  2151         
  2182         
  2152     # Method called when a Motion event has been generated
  2183     # Method called when a Motion event has been generated
  2153     def OnMotion(self, event, dc, scaling):
  2184     def OnMotion(self, event, dc, scaling):
  2154         pos = GetScaledEventPosition(event, dc, scaling)
  2185         pos = GetScaledEventPosition(event, dc, scaling)
  2155         if not event.Dragging():
  2186         if not event.Dragging():
  2181         else:
  2212         else:
  2182             # Execute the default method for a graphic element
  2213             # Execute the default method for a graphic element
  2183             return Graphic_Element.OnMotion(self, event, dc, scaling)
  2214             return Graphic_Element.OnMotion(self, event, dc, scaling)
  2184     
  2215     
  2185     # Refreshes the wire state according to move defined and handle selected
  2216     # Refreshes the wire state according to move defined and handle selected
  2186     def ProcessDragging(self, movex, movey, centered, scaling):
  2217     def ProcessDragging(self, movex, movey, event, scaling):
  2187         handle_type, handle = self.Handle
  2218         handle_type, handle = self.Handle
  2188         # A point has been handled
  2219         # A point has been handled
  2189         if handle_type == HANDLE_POINT:
  2220         if handle_type == HANDLE_POINT:
  2190             movex = max(-self.Points[handle].x + POINT_RADIUS, movex)
  2221             movex = max(-self.Points[handle].x + POINT_RADIUS, movex)
  2191             movey = max(-self.Points[handle].y + POINT_RADIUS, movey)
  2222             movey = max(-self.Points[handle].y + POINT_RADIUS, movey)
  2233         # A segment has been handled, move a segment
  2264         # A segment has been handled, move a segment
  2234         elif handle_type == HANDLE_SEGMENT:
  2265         elif handle_type == HANDLE_SEGMENT:
  2235             return self.MoveSegment(handle[0], movex, movey, scaling)
  2266             return self.MoveSegment(handle[0], movex, movey, scaling)
  2236         # Execute the default method for a graphic element
  2267         # Execute the default method for a graphic element
  2237         else:
  2268         else:
  2238             return Graphic_Element.ProcessDragging(self, movex, movey, centered, scaling)
  2269             return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
  2239     
  2270     
  2240     # Refreshes the wire model
  2271     # Refreshes the wire model
  2241     def RefreshModel(self, move=True):
  2272     def RefreshModel(self, move=True):
  2242         if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]:
  2273         if self.StartConnected and self.StartPoint[1] in [WEST, NORTH]:
  2243             self.StartConnected.RefreshParentBlock()
  2274             self.StartConnected.RefreshParentBlock()