2 Copyright 2007, 2008 Free Software Foundation, Inc.
3 This file is part of GNU Radio
5 GNU Radio Companion is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 GNU Radio Companion is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 ##@package grc.gui.elements.Connection
20 #The graphical connection for input/output ports.
23 from Element import Element
25 from grc.Constants import CONNECTOR_ARROW_BASE,CONNECTOR_ARROW_HEIGHT
27 class Connection(Element):
28 """A graphical connection for ports."""
30 def get_coordinate(self):
32 Get the 0,0 coordinate.
33 Coordinates are irrelevant in connection.
38 def get_rotation(self):
40 Get the 0 degree rotation.
41 Rotations are irrelevant in connection.
47 """Precalculate relative coordinates."""
49 self._source_rot = None
50 self._sink_coor = None
51 self._source_coor = None
52 #get the source coordinate
53 connector_length = self.get_source().get_connector_length()
54 self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.get_source().get_rotation())
55 #get the sink coordinate
56 connector_length = self.get_sink().get_connector_length() + CONNECTOR_ARROW_HEIGHT
57 self.x2, self.y2 = Utils.get_rotated_coordinate((-connector_length, 0), self.get_sink().get_rotation())
60 Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, -CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
61 Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, CONNECTOR_ARROW_BASE/2), self.get_sink().get_rotation()),
63 self._update_after_move()
65 def _update_after_move(self):
66 """Calculate coordinates."""
69 source = self.get_source()
70 X, Y = source.get_connector_coordinate()
71 x1, y1 = self.x1 + X, self.y1 + Y
72 self.add_line((x1, y1), (X, Y))
74 sink = self.get_sink()
75 X, Y = sink.get_connector_coordinate()
76 x2, y2 = self.x2 + X, self.y2 + Y
77 self.add_line((x2, y2), (X, Y))
79 self._arrow = [(x+X, y+Y) for x,y in self.arrow]
80 #add the horizontal and vertical lines in this connection
81 if abs(source.get_connector_direction() - sink.get_connector_direction()) == 180:
82 #2 possible point sets to create a 3-line connector
83 mid_x, mid_y = (x1 + x2)/2.0, (y1 + y2)/2.0
84 points = [((mid_x, y1), (mid_x, y2)), ((x1, mid_y), (x2, mid_y))]
85 #source connector -> points[0][0] should be in the direction of source (if possible)
86 if Utils.get_angle_from_coordinates((x1, y1), points[0][0]) != source.get_connector_direction(): points.reverse()
87 #points[0][0] -> sink connector should not be in the direction of sink
88 if Utils.get_angle_from_coordinates(points[0][0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
89 #points[0][0] -> source connector should not be in the direction of source
90 if Utils.get_angle_from_coordinates(points[0][0], (x1, y1)) == source.get_connector_direction(): points.reverse()
91 #create 3-line connector
92 p1, p2 = map(int, points[0][0]), map(int, points[0][1])
93 self.add_line((x1, y1), p1)
95 self.add_line((x2, y2), p2)
97 #2 possible points to create a right-angled connector
98 points = [(x1, y2), (x2, y1)]
99 #source connector -> points[0] should be in the direction of source (if possible)
100 if Utils.get_angle_from_coordinates((x1, y1), points[0]) != source.get_connector_direction(): points.reverse()
101 #points[0] -> sink connector should not be in the direction of sink
102 if Utils.get_angle_from_coordinates(points[0], (x2, y2)) == sink.get_connector_direction(): points.reverse()
103 #points[0] -> source connector should not be in the direction of source
104 if Utils.get_angle_from_coordinates(points[0], (x1, y1)) == source.get_connector_direction(): points.reverse()
105 #create right-angled connector
106 self.add_line((x1, y1), points[0])
107 self.add_line((x2, y2), points[0])
109 def draw(self, window):
112 @param window the gtk window to draw on
114 sink = self.get_sink()
115 source = self.get_source()
117 if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.update()
118 elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate(): self._update_after_move()
120 self._sink_rot = sink.get_rotation()
121 self._source_rot = source.get_rotation()
122 self._sink_coor = sink.get_coordinate()
123 self._source_coor = source.get_coordinate()
125 fg_color = self.get_enabled() and Colors.FG_COLOR or Colors.DISABLED_FG_COLOR
126 Element.draw(self, window, FG_color=fg_color)
128 if self.is_valid(): gc.foreground = Colors.FG_COLOR
129 else: gc.foreground = Colors.ERROR_COLOR
130 #draw arrow on sink port
131 window.draw_polygon(gc, True, self._arrow)