graphics/GraphicCommons.py
changeset 327 7fd5233ce5ce
parent 321 5b37e16f7b2a
child 328 500588ea29e8
--- a/graphics/GraphicCommons.py	Wed Mar 18 15:54:37 2009 +0100
+++ b/graphics/GraphicCommons.py	Wed Mar 18 15:56:45 2009 +0100
@@ -311,6 +311,8 @@
         self.Parent = parent
         self.Id = id
         self.oldPos = None
+        self.StartPos = None
+        self.CurrentDrag = None
         self.Handle = (None,None)
         self.Dragging = False
         self.Selected = False
@@ -484,6 +486,8 @@
             self.SetSelected(False)
         # Initializes the last position
         self.oldPos = GetScaledEventPosition(event, dc, scaling)
+        self.StartPos = wx.Point(self.Pos.x, self.Pos.y)
+        self.CurrentDrag = wx.Point(0, 0)
     
     # Method called when a LeftUp event have been generated
     def OnLeftUp(self, event, dc, scaling):
@@ -529,9 +533,13 @@
                 self.Dragging = True
             # If a dragging have been initiated, refreshes the element state
             if self.Dragging:
-                dragx, dragy = self.ProcessDragging(movex, movey, event.ShiftDown(), scaling)
-                self.oldPos.x += dragx
-                self.oldPos.y += dragy
+                dragx, dragy = self.ProcessDragging(movex, movey, event, scaling)
+                if event.ControlDown():
+                    self.oldPos.x = self.StartPos.x + self.CurrentDrag.x
+                    self.oldPos.y = self.StartPos.y + self.CurrentDrag.y
+                else:
+                    self.oldPos.x += dragx
+                    self.oldPos.y += dragy
                 return dragx, dragy
             return movex, movey
         # If cursor just pass over the element, changes the cursor if it is on a handle
@@ -559,7 +567,7 @@
         self.SetSize(width, height)
     
     # Refreshes the element state according to move defined and handle selected
-    def ProcessDragging(self, movex, movey, centered, scaling, width_fac = 1, height_fac = 1):
+    def ProcessDragging(self, movex, movey, event, scaling, width_fac = 1, height_fac = 1):
         handle_type, handle = self.Handle
         # If it is a resize handle, calculate the values from resizing
         if handle_type == HANDLE_RESIZE:
@@ -567,19 +575,20 @@
                 scaling = (scaling[0] * width_fac, scaling[1] * height_fac)
             x = y = start_x = start_y = 0
             width, height = start_width, start_height = self.GetSize()
+            proportion = float(start_width) / float(start_height)
             if handle[0] == 1:
                 movex = max(-self.BoundingBox.x, movex)
                 if scaling is not None:
                     movex = -(round(float(width - movex) / float(scaling[0])) * scaling[0] - width)
                 x = movex
-                if centered:
+                if event.ShiftDown():
                     width -= 2 * movex
                 else:
                     width -= movex
             elif handle[0] == 3:
                 if scaling is not None:
                     movex = round(float(width + movex) / float(scaling[0])) * scaling[0] - width
-                if centered:
+                if event.ShiftDown():
                     x = -movex
                     width += 2 * movex
                 else:
@@ -589,14 +598,14 @@
                 if scaling is not None:
                     movey = -(round(float(height - movey) / float(scaling[1])) * scaling[1] - height)
                 y = movey
-                if centered:
+                if event.ShiftDown():
                     height -= 2 * movey
                 else:
                     height -= movey
             elif handle[1] == 3:
                 if scaling is not None:
                     movey = round(float(height + movey) / float(scaling[1])) * scaling[1] - height
-                if centered:
+                if event.ShiftDown():
                     y = -movey
                     height += 2 * movey
                 else:
@@ -623,6 +632,15 @@
             if scaling is not None:
                 movex = round(float(self.Pos.x + movex) / float(scaling[0])) * scaling[0] - self.Pos.x
                 movey = round(float(self.Pos.y + movey) / float(scaling[1])) * scaling[1] - self.Pos.y
+            if event.ControlDown():
+                self.CurrentDrag.x = self.CurrentDrag.x + movex
+                self.CurrentDrag.y = self.CurrentDrag.y + movey
+                if abs(self.CurrentDrag.x) > abs(self.CurrentDrag.y):
+                    movex = self.StartPos.x + self.CurrentDrag.x - self.Pos.x
+                    movey = self.StartPos.y - self.Pos.y
+                else:
+                    movex = self.StartPos.x - self.Pos.x
+                    movey = self.StartPos.y + self.CurrentDrag.y - self.Pos.y   
             self.Move(movex, movey)
             return movex, movey
         return 0, 0
@@ -839,6 +857,7 @@
     
     # Move this group of elements
     def Move(self, movex, movey):
+        print self.Pos, self.StartPos
         # Move all the elements of the group
         for element in self.Elements:
             if not isinstance(element, Wire):
@@ -863,6 +882,8 @@
             self.BoundingBox = wx.Rect(minx, miny, maxx - minx, maxy - miny)
         else:
             self.BoundingBox = wx.Rect(0, 0, 0, 0)
+        self.Pos = wx.Point(self.BoundingBox.x, self.BoundingBox.y)
+        self.Size = wx.Size(self.BoundingBox.width, self.BoundingBox.height)
 
     # Forbids to change the group position
     def SetPosition(x, y):
@@ -2110,44 +2131,54 @@
     
     # Method called when a LeftDClick event has been generated
     def OnLeftDClick(self, event, dc, scaling):
+        rect = self.GetRedrawRect()
         if event.ControlDown():
             direction = (self.StartPoint[1], self.EndPoint[1])
             if direction in [(EAST, WEST), (WEST, EAST)]:
-                avgy = (self.StartPoint[0].y + self.EndPoint[0].y) / 2
+                avgy = round(float((self.StartPoint[0].y + self.EndPoint[0].y) / 2) / scaling[1]) * scaling[1]
                 if self.StartConnected is not None:
+                    movey = avgy - self.StartPoint[0].y
                     startblock = self.StartConnected.GetParentBlock()
-                    startblock.Move(0, avgy - self.StartPoint[0].y)
+                    startblock.Move(0, movey)
                     startblock.RefreshModel()
+                    rect.Union(startblock.GetRedrawRect(0, movey))
                 else:
                     self.MoveStartPoint(wx.Point(self.StartPoint[0].x, avgy))
                 if self.EndConnected is not None:
+                    movey = avgy - self.EndPoint[0].y
                     endblock = self.EndConnected.GetParentBlock()
-                    endblock.Move(0, avgy - self.EndPoint[0].y)
+                    endblock.Move(0, movey)
                     endblock.RefreshModel()
+                    rect.Union(endblock.GetRedrawRect(0, movey))
                 else:
                     self.MoveEndPoint(wx.Point(self.EndPoint[0].x, avgy))
+                self.Parent.RefreshBuffer()
             elif direction in [(NORTH, SOUTH), (SOUTH, NORTH)]:
-                avgx = (self.StartPoint[0].x + self.EndPoint[0].x) / 2
+                avgx = round(float((self.StartPoint[0].x + self.EndPoint[0].x) / 2) / scaling[0]) * scaling[0]
                 if self.StartConnected is not None:
+                    movex = avgx - self.StartPoint[0].x
                     startblock = self.StartConnected.GetParentBlock()
-                    startblock.Move(avgx - self.StartPoint[0].x, 0)
+                    startblock.Move(movex, 0)
                     startblock.RefreshModel()
+                    rect.Union(startblock.GetRedrawRect(movex, 0))
                 else:
                     self.MoveStartPoint(wx.Point(avgx, self.StartPoint[0].y))
                 if self.EndConnected is not None:
+                    movex = avgx - self.EndPoint[0].x
                     endblock = self.EndConnected.GetParentBlock()
-                    endblock.Move(avgx - self.EndPoint[0].x, 0)
+                    endblock.Move(movex, 0)
                     endblock.RefreshModel()
+                    rect.Union(endblock.GetRedrawRect(movex, 0))
                 else:
                     self.MoveEndPoint(wx.Point(avgx, self.EndPoint[0].y))
-            self.Parent.RefreshBuffer()
-        else:
-            rect = self.GetRedrawRect()
+                self.Parent.RefreshBuffer()
+        else:
             self.ResetPoints()
             self.GeneratePoints()
             self.RefreshModel()
             self.Parent.RefreshBuffer()
-            self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False)
+        rect.Union(self.GetRedrawRect())
+        self.Parent.RefreshRect(self.Parent.GetScrolledRect(rect), False)
         
     # Method called when a Motion event has been generated
     def OnMotion(self, event, dc, scaling):
@@ -2183,7 +2214,7 @@
             return Graphic_Element.OnMotion(self, event, dc, scaling)
     
     # Refreshes the wire state according to move defined and handle selected
-    def ProcessDragging(self, movex, movey, centered, scaling):
+    def ProcessDragging(self, movex, movey, event, scaling):
         handle_type, handle = self.Handle
         # A point has been handled
         if handle_type == HANDLE_POINT:
@@ -2235,7 +2266,7 @@
             return self.MoveSegment(handle[0], movex, movey, scaling)
         # Execute the default method for a graphic element
         else:
-            return Graphic_Element.ProcessDragging(self, movex, movey, centered, scaling)
+            return Graphic_Element.ProcessDragging(self, movex, movey, event, scaling)
     
     # Refreshes the wire model
     def RefreshModel(self, move=True):