76 |
76 |
77 # Contants for defining the direction of a connector |
77 # Contants for defining the direction of a connector |
78 [EAST, NORTH, WEST, SOUTH] = [(1,0), (0,-1), (-1,0), (0,1)] |
78 [EAST, NORTH, WEST, SOUTH] = [(1,0), (0,-1), (-1,0), (0,1)] |
79 |
79 |
80 # Contants for defining which mode is selected for each view |
80 # Contants for defining which mode is selected for each view |
81 [MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, MODE_WIRE, |
81 [MODE_SELECTION, MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, |
82 MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP, MODE_TRANSITION, |
82 MODE_COIL, MODE_CONTACT, MODE_POWERRAIL, MODE_INITIALSTEP, MODE_STEP, |
83 MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION] = range(15) |
83 MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION] = range(14) |
|
84 |
|
85 # Contants for defining alignment types for graphic group |
|
86 [ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM] = range(6) |
84 |
87 |
85 # Contants for defining which drawing mode is selected for app |
88 # Contants for defining which drawing mode is selected for app |
86 [FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2] |
89 [FREEDRAWING_MODE, DRIVENDRAWING_MODE] = [1, 2] |
87 |
90 |
88 CURSORS = None |
91 CURSORS = None |
450 if not self.Dragging and (abs(movex) > MIN_MOVE or abs(movey) > MIN_MOVE): |
453 if not self.Dragging and (abs(movex) > MIN_MOVE or abs(movey) > MIN_MOVE): |
451 self.Dragging = True |
454 self.Dragging = True |
452 # If a dragging have been initiated, refreshes the element state |
455 # If a dragging have been initiated, refreshes the element state |
453 if self.Dragging: |
456 if self.Dragging: |
454 dragx, dragy = self.ProcessDragging(movex, movey) |
457 dragx, dragy = self.ProcessDragging(movex, movey) |
455 if dragx: |
458 self.oldPos.x += dragx |
456 self.oldPos.x = pos.x |
459 self.oldPos.y += dragy |
457 if dragy: |
|
458 self.oldPos.y = pos.y |
|
459 return True |
460 return True |
460 # If cursor just pass over the element, changes the cursor if it is on a handle |
461 # If cursor just pass over the element, changes the cursor if it is on a handle |
461 else: |
462 else: |
462 pos = event.GetLogicalPosition(dc) |
463 pos = event.GetLogicalPosition(dc) |
463 handle = self.TestHandle(pos) |
464 handle = self.TestHandle(pos) |
487 # If it is a resize handle, calculate the values from resizing |
488 # If it is a resize handle, calculate the values from resizing |
488 if handle_type == HANDLE_RESIZE: |
489 if handle_type == HANDLE_RESIZE: |
489 x = y = start_x = start_y = 0 |
490 x = y = start_x = start_y = 0 |
490 width, height = start_width, start_height = self.GetSize() |
491 width, height = start_width, start_height = self.GetSize() |
491 if handle[0] == 1: |
492 if handle[0] == 1: |
492 x = movex |
493 x = movex = max(-self.BoundingBox.x, movex) |
493 width -= movex |
494 width -= movex |
494 elif handle[0] == 3: |
495 elif handle[0] == 3: |
495 width += movex |
496 width += movex |
496 if handle[1] == 1: |
497 if handle[1] == 1: |
497 y = movey |
498 y = movey = max(-self.BoundingBox.y, movey) |
498 height -= movey |
499 height -= movey |
499 elif handle[1] == 3: |
500 elif handle[1] == 3: |
500 height += movey |
501 height += movey |
501 # Verify that new size is not lesser than minimum |
502 # Verify that new size is not lesser than minimum |
502 min_width, min_height = self.GetMinSize() |
503 min_width, min_height = self.GetMinSize() |
503 dragx = dragy = False |
|
504 if handle[0] != 2 and (width >= min_width or width > self.Size[0]): |
504 if handle[0] != 2 and (width >= min_width or width > self.Size[0]): |
505 start_x = x |
505 start_x = x |
506 start_width = width |
506 start_width = width |
507 dragx = True |
507 else: |
|
508 movex = 0 |
508 if handle[1] != 2 and (height >= min_height or height > self.Size[1]): |
509 if handle[1] != 2 and (height >= min_height or height > self.Size[1]): |
509 start_y = y |
510 start_y = y |
510 start_height = height |
511 start_height = height |
511 dragy = True |
512 else: |
512 if dragx or dragy: |
513 movey = 0 |
|
514 if movex != 0 or movey != 0: |
513 self.Resize(start_x, start_y, start_width, start_height) |
515 self.Resize(start_x, start_y, start_width, start_height) |
514 return dragx, dragy |
516 return movex, movey |
515 # If it is a move handle, Move this element |
517 # If it is a move handle, Move this element |
516 elif handle_type == HANDLE_MOVE: |
518 elif handle_type == HANDLE_MOVE: |
|
519 movex = max(-self.BoundingBox.x, movex) |
|
520 movey = max(-self.BoundingBox.y, movey) |
517 self.Move(movex, movey) |
521 self.Move(movex, movey) |
518 return True, True |
522 return movex, movey |
519 return False, False |
523 return 0, 0 |
520 |
524 |
521 # Override this method for defining the method to call for refreshing the model of this element |
525 # Override this method for defining the method to call for refreshing the model of this element |
522 def RefreshModel(self, move=True): |
526 def RefreshModel(self, move=True): |
523 pass |
527 pass |
524 |
528 |
616 |
620 |
617 # Returns the elements of the group |
621 # Returns the elements of the group |
618 def GetElements(self): |
622 def GetElements(self): |
619 return self.Elements |
623 return self.Elements |
620 |
624 |
|
625 # Align the group elements |
|
626 def AlignElements(self, horizontally, vertically): |
|
627 minx = self.BoundingBox.x + self.BoundingBox.width |
|
628 miny = self.BoundingBox.y + self.BoundingBox.height |
|
629 maxx = self.BoundingBox.x |
|
630 maxy = self.BoundingBox.y |
|
631 for element in self.Elements: |
|
632 if not isinstance(element, Wire): |
|
633 posx, posy = element.GetPosition() |
|
634 width, height = element.GetSize() |
|
635 minx = min(minx, posx) |
|
636 miny = min(miny, posy) |
|
637 maxx = max(maxx, posx + width) |
|
638 maxy = max(maxy, posy + height) |
|
639 for element in self.Elements: |
|
640 if not isinstance(element, Wire): |
|
641 posx, posy = element.GetPosition() |
|
642 width, height = element.GetSize() |
|
643 movex = movey = 0 |
|
644 if horizontally == ALIGN_LEFT: |
|
645 movex = minx - posx |
|
646 elif horizontally == ALIGN_CENTER: |
|
647 movex = (maxx + minx - width) / 2 - posx |
|
648 elif horizontally == ALIGN_RIGHT: |
|
649 movex = maxx - width - posx |
|
650 if vertically == ALIGN_TOP: |
|
651 movey = miny - posy |
|
652 elif vertically == ALIGN_MIDDLE: |
|
653 movey = (maxy + miny - height) / 2 - posy |
|
654 elif vertically == ALIGN_BOTTOM: |
|
655 movey = maxy - height - posy |
|
656 if movex != 0 or movey != 0: |
|
657 element.Move(movex, movey) |
|
658 element.RefreshModel() |
|
659 self.RefreshWireExclusion() |
|
660 self.RefreshBoundingBox() |
|
661 |
621 # Remove or select the given element if it is or not in the group |
662 # Remove or select the given element if it is or not in the group |
622 def SelectElement(self, element): |
663 def SelectElement(self, element): |
623 if element in self.Elements: |
664 if element in self.Elements: |
624 self.Elements.remove(element) |
665 self.Elements.remove(element) |
625 else: |
666 else: |
672 |
713 |
673 # Change the variable that indicates if the elemente is selected |
714 # Change the variable that indicates if the elemente is selected |
674 def SetSelected(self, selected): |
715 def SetSelected(self, selected): |
675 for element in self.Elements: |
716 for element in self.Elements: |
676 element.SetSelected(selected) |
717 element.SetSelected(selected) |
|
718 |
|
719 # Method called when a RightUp event has been generated |
|
720 def OnRightUp(self, event, dc, scaling): |
|
721 # Popup the menu with special items for a group |
|
722 self.Parent.PopupGroupMenu() |
677 |
723 |
678 # Refreshes the model of all the elements of this group |
724 # Refreshes the model of all the elements of this group |
679 def RefreshModel(self): |
725 def RefreshModel(self): |
680 for element in self.Elements: |
726 for element in self.Elements: |
681 element.RefreshModel() |
727 element.RefreshModel() |
1567 start_x = self.Points[idx].x |
1613 start_x = self.Points[idx].x |
1568 self.Points[idx].x += movex |
1614 self.Points[idx].x += movex |
1569 self.Points[idx + 1].x += movex |
1615 self.Points[idx + 1].x += movex |
1570 self.GeneratePoints() |
1616 self.GeneratePoints() |
1571 if start_x != self.Points[idx].x: |
1617 if start_x != self.Points[idx].x: |
1572 return True, False |
1618 return self.Points[idx].x - start_x, 0 |
1573 elif self.Segments[idx] in (EAST, WEST): |
1619 elif self.Segments[idx] in (EAST, WEST): |
1574 start_y = self.Points[idx].y |
1620 start_y = self.Points[idx].y |
1575 self.Points[idx].y += movey |
1621 self.Points[idx].y += movey |
1576 self.Points[idx + 1].y += movey |
1622 self.Points[idx + 1].y += movey |
1577 self.GeneratePoints() |
1623 self.GeneratePoints() |
1578 if start_y != self.Points[idx].y: |
1624 if start_y != self.Points[idx].y: |
1579 return False, True |
1625 return 0, self.Points[idx].y - start_y |
1580 return False, False |
1626 return 0, 0 |
1581 |
1627 |
1582 # Adds two points in the middle of the handled segment |
1628 # Adds two points in the middle of the handled segment |
1583 def AddSegment(self): |
1629 def AddSegment(self): |
1584 handle_type, handle = self.Handle |
1630 handle_type, handle = self.Handle |
1585 if handle_type == HANDLE_SEGMENT: |
1631 if handle_type == HANDLE_SEGMENT: |
1642 # Execute the default method for a graphic element |
1688 # Execute the default method for a graphic element |
1643 Graphic_Element.OnRightUp(self, event, dc, scaling) |
1689 Graphic_Element.OnRightUp(self, event, dc, scaling) |
1644 |
1690 |
1645 # Method called when a LeftDClick event has been generated |
1691 # Method called when a LeftDClick event has been generated |
1646 def OnLeftDClick(self, event, dc, scaling): |
1692 def OnLeftDClick(self, event, dc, scaling): |
1647 self.ResetPoints() |
1693 if event.ControlDown(): |
1648 self.GeneratePoints() |
1694 direction = (self.StartPoint[1], self.EndPoint[1]) |
1649 self.RefreshModel() |
1695 if direction in [(EAST, WEST), (WEST, EAST)]: |
1650 self.Parent.RefreshBuffer() |
1696 avgy = (self.StartPoint[0].y + self.EndPoint[0].y) / 2 |
|
1697 if self.StartConnected is not None: |
|
1698 startblock = self.StartConnected.GetParentBlock() |
|
1699 startblock.Move(0, avgy - self.StartPoint[0].y) |
|
1700 startblock.RefreshModel() |
|
1701 else: |
|
1702 self.MoveStartPoint(wx.Point(self.StartPoint[0].x, avgy)) |
|
1703 if self.EndConnected is not None: |
|
1704 endblock = self.EndConnected.GetParentBlock() |
|
1705 endblock.Move(0, avgy - self.EndPoint[0].y) |
|
1706 endblock.RefreshModel() |
|
1707 else: |
|
1708 self.MoveEndPoint(wx.Point(self.EndPoint[0].x, avgy)) |
|
1709 elif direction in [(NORTH, SOUTH), (SOUTH, NORTH)]: |
|
1710 avgx = (self.StartPoint[0].x + self.EndPoint[0].x) / 2 |
|
1711 if self.StartConnected is not None: |
|
1712 startblock = self.StartConnected.GetParentBlock() |
|
1713 startblock.Move(avgx - self.StartPoint[0].x, 0) |
|
1714 startblock.RefreshModel() |
|
1715 else: |
|
1716 self.MoveStartPoint(wx.Point(avgx, self.StartPoint[0].y)) |
|
1717 if self.EndConnected is not None: |
|
1718 endblock = self.EndConnected.GetParentBlock() |
|
1719 endblock.Move(avgx - self.EndPoint[0].x, 0) |
|
1720 endblock.RefreshModel() |
|
1721 else: |
|
1722 self.MoveEndPoint(wx.Point(avgx, self.EndPoint[0].y)) |
|
1723 self.Parent.RefreshBuffer() |
|
1724 else: |
|
1725 self.ResetPoints() |
|
1726 self.GeneratePoints() |
|
1727 self.RefreshModel() |
|
1728 self.Parent.RefreshBuffer() |
1651 |
1729 |
1652 # Method called when a Motion event has been generated |
1730 # Method called when a Motion event has been generated |
1653 def OnMotion(self, event, dc, scaling): |
1731 def OnMotion(self, event, dc, scaling): |
1654 pos = GetScaledEventPosition(event, dc, scaling) |
1732 pos = GetScaledEventPosition(event, dc, scaling) |
1655 if not event.Dragging(): |
1733 if not event.Dragging(): |
1685 # Refreshes the wire state according to move defined and handle selected |
1763 # Refreshes the wire state according to move defined and handle selected |
1686 def ProcessDragging(self, movex, movey): |
1764 def ProcessDragging(self, movex, movey): |
1687 handle_type, handle = self.Handle |
1765 handle_type, handle = self.Handle |
1688 # A point has been handled |
1766 # A point has been handled |
1689 if handle_type == HANDLE_POINT: |
1767 if handle_type == HANDLE_POINT: |
|
1768 movex = max(-self.Points[handle].x + POINT_RADIUS, movex) |
|
1769 movey = max(-self.Points[handle].y + POINT_RADIUS, movey) |
1690 # Try to connect point to a connector |
1770 # Try to connect point to a connector |
1691 new_pos = wx.Point(self.Points[handle].x + movex, self.Points[handle].y + movey) |
1771 new_pos = wx.Point(self.Points[handle].x + movex, self.Points[handle].y + movey) |
1692 connector = self.Parent.FindBlockConnector(new_pos) |
1772 connector = self.Parent.FindBlockConnector(new_pos) |
1693 if connector: |
1773 if connector: |
1694 if handle == 0 and self.EndConnected != connector and connector.IsCompatible(self.GetEndConnectedType()): |
1774 if handle == 0 and self.EndConnected != connector and connector.IsCompatible(self.GetEndConnectedType()): |
1695 connector.Connect((self, handle)) |
1775 connector.Connect((self, handle)) |
1696 self.SetStartPointDirection(connector.GetDirection()) |
1776 self.SetStartPointDirection(connector.GetDirection()) |
1697 self.ConnectStartPoint(connector.GetPosition(), connector) |
1777 self.ConnectStartPoint(connector.GetPosition(), connector) |
1698 self.oldPos = connector.GetPosition() |
1778 pos = connector.GetPosition() |
|
1779 movex = pos.x - self.oldPos.x |
|
1780 movey = pos.y - self.oldPos.y |
1699 self.Dragging = False |
1781 self.Dragging = False |
1700 elif handle != 0 and self.StartConnected != connector and connector.IsCompatible(self.GetStartConnectedType()): |
1782 elif handle != 0 and self.StartConnected != connector and connector.IsCompatible(self.GetStartConnectedType()): |
1701 connector.Connect((self, handle)) |
1783 connector.Connect((self, handle)) |
1702 self.SetEndPointDirection(connector.GetDirection()) |
1784 self.SetEndPointDirection(connector.GetDirection()) |
1703 self.ConnectEndPoint(connector.GetPosition(), connector) |
1785 self.ConnectEndPoint(connector.GetPosition(), connector) |
1704 self.oldPos = connector.GetPosition() |
1786 pos = connector.GetPosition() |
|
1787 movex = pos.x - self.oldPos.x |
|
1788 movey = pos.y - self.oldPos.y |
1705 self.Dragging = False |
1789 self.Dragging = False |
1706 elif handle == 0: |
1790 elif handle == 0: |
1707 self.MoveStartPoint(new_pos) |
1791 self.MoveStartPoint(new_pos) |
1708 else: |
1792 else: |
1709 self.MoveEndPoint(new_pos) |
1793 self.MoveEndPoint(new_pos) |
1714 self.MoveStartPoint(new_pos) |
1798 self.MoveStartPoint(new_pos) |
1715 else: |
1799 else: |
1716 if self.EndConnected: |
1800 if self.EndConnected: |
1717 self.UnConnectEndPoint() |
1801 self.UnConnectEndPoint() |
1718 self.MoveEndPoint(new_pos) |
1802 self.MoveEndPoint(new_pos) |
1719 return True, True |
1803 return movex, movey |
1720 # A segment has been handled, move a segment |
1804 # A segment has been handled, move a segment |
1721 elif handle_type == HANDLE_SEGMENT: |
1805 elif handle_type == HANDLE_SEGMENT: |
1722 return self.MoveSegment(handle[0], movex, movey) |
1806 return self.MoveSegment(handle[0], movex, movey) |
1723 # Execute the default method for a graphic element |
1807 # Execute the default method for a graphic element |
1724 else: |
1808 else: |