diff options
author | Sebastian Koslowski <koslowski@kit.edu> | 2016-07-13 10:31:12 +0200 |
---|---|---|
committer | Sebastian Koslowski <koslowski@kit.edu> | 2016-07-13 16:35:50 +0200 |
commit | cf71e261f1438d51adf857fd8b926cfdda0a51ab (patch) | |
tree | fe854f31fd090d910daee74b0043744362918edb | |
parent | 11c4f515b250ccdef366da222c10d16229f5d347 (diff) |
grc: gtk3: update gui element class
-rw-r--r-- | grc/core/Element.py | 7 | ||||
-rw-r--r-- | grc/core/FlowGraph.py | 7 | ||||
-rw-r--r-- | grc/gui/Block.py | 46 | ||||
-rw-r--r-- | grc/gui/Connection.py | 32 | ||||
-rw-r--r-- | grc/gui/Element.py | 94 | ||||
-rw-r--r-- | grc/gui/FlowGraph.py | 11 | ||||
-rw-r--r-- | grc/gui/Port.py | 80 |
7 files changed, 107 insertions, 170 deletions
diff --git a/grc/core/Element.py b/grc/core/Element.py index f07bb113e1..cd0514beb6 100644 --- a/grc/core/Element.py +++ b/grc/core/Element.py @@ -34,6 +34,13 @@ class lazy_property(object): return weak_value +def property_nop_write(func): + """Make this a property with a nop setter""" + def nop(self, value): + pass + return property(fget=func, fset=nop) + + class Element(object): def __init__(self, parent=None): diff --git a/grc/core/FlowGraph.py b/grc/core/FlowGraph.py index 16bcb3b9f6..c626f7b0cd 100644 --- a/grc/core/FlowGraph.py +++ b/grc/core/FlowGraph.py @@ -549,10 +549,11 @@ def _initialize_dummy_block(block, block_n): block.is_valid = lambda: False block.get_enabled = lambda: False for param_n in block_n.get('param', []): - if param_n['key'] not in block.params: - new_param_n = {'key': param_n['key'], 'name': param_n['key'], 'type': 'string'} + key = param_n['key'] + if key not in block.params: + new_param_n = {'key': key, 'name': key, 'type': 'string'} param = block.parent_platform.Param(block=block, n=new_param_n) - block.params.append(param) + block.params[key] = param def _dummy_block_add_port(block, key, dir): diff --git a/grc/gui/Block.py b/grc/gui/Block.py index 7321a0495b..e0899136f3 100644 --- a/grc/gui/Block.py +++ b/grc/gui/Block.py @@ -47,7 +47,7 @@ class Block(_Block, Element): _Block.__init__(self, flow_graph, n) self.states.update(_coordinate=(0, 0), _rotation=0) - self.W = self.H = 0 + self.width = self.height = 0 Element.__init__(self) # needs the states and initial sizes self._surface_layouts = [ @@ -77,14 +77,15 @@ class Block(_Block, Element): coor: the coordinate tuple (x, y) """ if Actions.TOGGLE_SNAP_TO_GRID.get_active(): - offset_x, offset_y = (0, self.H/2) if self.is_horizontal() else (self.H/2, 0) + offset_x, offset_y = (0, self.height / 2) if self.is_horizontal() else (self.height / 2, 0) coor = ( Utils.align_to_grid(coor[0] + offset_x) - offset_x, Utils.align_to_grid(coor[1] + offset_y) - offset_y ) self.states['_coordinate'] = coor - def get_rotation(self): + @property + def rotation(self): """ Get the rotation from the position param. @@ -93,7 +94,8 @@ class Block(_Block, Element): """ return self.states['_rotation'] - def set_rotation(self, rot): + @rotation.setter + def rotation(self, rot): """ Set the rotation into the position param. @@ -107,25 +109,25 @@ class Block(_Block, Element): self.clear() if self.is_horizontal(): - self.add_area(0, 0, self.W, self.H) + self.areas.append([0, 0, self.width, self.height]) elif self.is_vertical(): - self.add_area(0, 0, self.H, self.W) + self.areas.append([0, 0, self.height, self.width]) for ports, has_busses in zip((self.active_sources, self.active_sinks), self.has_busses): if not ports: continue - port_separation = PORT_SEPARATION if not has_busses else ports[0].H + PORT_SPACING - offset = (self.H - (len(ports) - 1) * port_separation - ports[0].H) / 2 + port_separation = PORT_SEPARATION if not has_busses else ports[0].height + PORT_SPACING + offset = (self.height - (len(ports) - 1) * port_separation - ports[0].height) / 2 for index, port in enumerate(ports): port.create_shapes() port.set_coordinate({ - 0: (+self.W, offset), - 90: (offset, -port.W), - 180: (-port.W, offset), - 270: (offset, +self.W), + 0: (+self.width, offset), + 90: (offset, -port.width), + 180: (-port.width, offset), + 270: (offset, +self.width), }[port.get_connector_direction()]) - offset += PORT_SEPARATION if not has_busses else port.H + PORT_SPACING + offset += PORT_SEPARATION if not has_busses else port.height + PORT_SPACING port.connector_length = Constants.CONNECTOR_EXTENSION_MINIMAL + \ Constants.CONNECTOR_EXTENSION_INCREMENT * index @@ -176,7 +178,7 @@ class Block(_Block, Element): def get_min_height_for_ports(): min_height = 2 * PORT_BORDER_SEPARATION + len(ports) * PORT_SEPARATION if ports: - min_height -= ports[-1].H + min_height -= ports[-1].height return min_height height = max( [ # labels @@ -187,11 +189,11 @@ class Block(_Block, Element): ] + [ # bus ports only 2 * PORT_BORDER_SEPARATION + - sum([port.H + PORT_SPACING for port in ports if port.get_type() == 'bus']) - PORT_SPACING + sum([port.height + PORT_SPACING for port in ports if port.get_type() == 'bus']) - PORT_SPACING for ports in (self.get_sources_gui(), self.get_sinks_gui()) ] ) - self.W, self.H = width, height = Utils.align_to_grid((width, height)) + self.width, self.height = width, height = Utils.align_to_grid((width, height)) self._surface_layout_offsets = [ (width - label_width) / 2.0, @@ -209,9 +211,9 @@ class Block(_Block, Element): max_width = 0 for port in ports: port.create_labels() - max_width = max(max_width, port.W) + max_width = max(max_width, port.width) for port in ports: - port.W = max_width + port.width = max_width def create_comment_layout(self): markups = [] @@ -243,7 +245,7 @@ class Block(_Block, Element): """ bg_color = self._bg_color border_color = ( - Colors.HIGHLIGHT_COLOR if self.is_highlighted() else + Colors.HIGHLIGHT_COLOR if self.highlighted else Colors.MISSING_BLOCK_BORDER_COLOR if self.is_dummy_block else Colors.BORDER_COLOR ) @@ -257,7 +259,7 @@ class Block(_Block, Element): # title and params label if self.is_vertical(): cr.rotate(-math.pi / 2) - cr.translate(-self.W, 0) + cr.translate(-self.width, 0) cr.translate(*self._surface_layout_offsets) for layout in self._surface_layouts: @@ -292,9 +294,9 @@ class Block(_Block, Element): x, y = self.get_coordinate() if self.is_horizontal(): - y += self.H + BLOCK_LABEL_PADDING + y += self.height + BLOCK_LABEL_PADDING else: - x += self.H + BLOCK_LABEL_PADDING + x += self.height + BLOCK_LABEL_PADDING cr.save() cr.translate(x, y) diff --git a/grc/gui/Connection.py b/grc/gui/Connection.py index 5e3353c5c1..5bd25fb2e6 100644 --- a/grc/gui/Connection.py +++ b/grc/gui/Connection.py @@ -19,13 +19,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA from __future__ import absolute_import -from six.moves import map - -from . import Colors -from . import Utils +from . import Colors, Utils from .Constants import CONNECTOR_ARROW_BASE, CONNECTOR_ARROW_HEIGHT from .Element import Element +from ..core.Element import property_nop_write from ..core.Connection import Connection as _Connection @@ -42,7 +40,8 @@ class Connection(Element, _Connection): def __init__(self, **kwargs): Element.__init__(self) _Connection.__init__(self, **kwargs) - self._color2 = self._arrow_color = self._color = None + + self._color =self._color2 = self._arrow_color = None self._sink_rot = self._source_rot = None self._sink_coor = self._source_coor = None @@ -50,7 +49,8 @@ class Connection(Element, _Connection): def get_coordinate(self): return self.source_port.get_connector_coordinate() - def get_rotation(self): + @property_nop_write + def rotation(self): """ Get the 0 degree rotation. Rotations are irrelevant in connection. @@ -72,14 +72,14 @@ class Connection(Element, _Connection): connector_length = self.source_port.connector_length except: return # todo: why? - self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.source_port.get_rotation()) + self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.source_port.rotation) #get the sink coordinate connector_length = self.sink_port.connector_length + CONNECTOR_ARROW_HEIGHT - self.x2, self.y2 = Utils.get_rotated_coordinate((-connector_length, 0), self.sink_port.get_rotation()) + self.x2, self.y2 = Utils.get_rotated_coordinate((-connector_length, 0), self.sink_port.rotation) #build the arrow self.arrow = [(0, 0), - Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, -CONNECTOR_ARROW_BASE/2), self.sink_port.get_rotation()), - Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, CONNECTOR_ARROW_BASE/2), self.sink_port.get_rotation()), + Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, -CONNECTOR_ARROW_BASE/2), self.sink_port.rotation), + Utils.get_rotated_coordinate((-CONNECTOR_ARROW_HEIGHT, CONNECTOR_ARROW_BASE/2), self.sink_port.rotation), ] source_domain = self.source_port.domain sink_domain = self.sink_port.domain @@ -133,7 +133,7 @@ class Connection(Element, _Connection): points, alt = alt, points # create 3-line connector i1, i2 = points - self.add_line(p0, p1, i1, i2, p2, p3) + self.lines.append([p0, p1, i1, i2, p2, p3]) else: # 2 possible points to create a right-angled connector point, alt = [(x1, y2), (x2, y1)] @@ -147,7 +147,7 @@ class Connection(Element, _Connection): if Utils.get_angle_from_coordinates(point, p1) == source_dir: point, alt = alt, point # create right-angled connector - self.add_line(p0, p1, point, p2, p3) + self.lines.append([p0, p1, point, p2, p3]) def draw(self, widget, cr): """ @@ -156,10 +156,10 @@ class Connection(Element, _Connection): sink = self.sink_port source = self.source_port #check for changes - if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): + if self._sink_rot != sink.rotation or self._source_rot != source.rotation: self.create_shapes() - self._sink_rot = sink.get_rotation() - self._source_rot = source.get_rotation() + self._sink_rot = sink.rotation + self._source_rot = source.rotation elif self._sink_coor != sink.parent_block.get_coordinate() or self._source_coor != source.parent_block.get_coordinate(): self._update_after_move() @@ -167,7 +167,7 @@ class Connection(Element, _Connection): self._source_coor = source.parent_block.get_coordinate() # draw color1, color2 = ( - Colors.HIGHLIGHT_COLOR if self.is_highlighted() else + Colors.HIGHLIGHT_COLOR if self.highlighted else Colors.CONNECTION_DISABLED_COLOR if not self.get_enabled() else color for color in (self._color, self._color2)) diff --git a/grc/gui/Element.py b/grc/gui/Element.py index 9513b44dc6..50cb4aaa97 100644 --- a/grc/gui/Element.py +++ b/grc/gui/Element.py @@ -19,7 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA from __future__ import absolute_import from .Constants import LINE_SELECT_SENSITIVITY -from .Constants import POSSIBLE_ROTATIONS from six.moves import zip @@ -35,12 +34,17 @@ class Element(object): """ Make a new list of rectangular areas and lines, and set the coordinate and the rotation. """ - self.set_rotation(POSSIBLE_ROTATIONS[0]) self.set_coordinate((0, 0)) self.highlighted = False + self.rotation = 0 - self._areas_list = [] - self._lines_list = [] + self.areas = [] + self.lines = [] + + def clear(self): + """Empty the lines and areas.""" + del self.areas[:] + del self.lines[:] def is_horizontal(self, rotation=None): """ @@ -53,7 +57,7 @@ class Element(object): Returns: true if rotation is horizontal """ - rotation = rotation or self.get_rotation() + rotation = rotation or self.rotation return rotation in (0, 180) def is_vertical(self, rotation=None): @@ -67,7 +71,7 @@ class Element(object): Returns: true if rotation is vertical """ - rotation = rotation or self.get_rotation() + rotation = rotation or self.rotation return rotation in (90, 270) def create_labels(self): @@ -99,7 +103,7 @@ class Element(object): """ X, Y = self.get_coordinate() cr.translate(X, Y) - for area in self._areas_list: + for area in self.areas: # aX = X + rX # aY = Y + rY cr.set_source_rgb(*bg_color) @@ -110,7 +114,7 @@ class Element(object): cr.stroke() cr.set_source_rgb(*border_color) - for line in self._lines_list: + for line in self.lines: cr.move_to(*line[0]) for point in line[1:]: cr.line_to(*point) @@ -123,12 +127,7 @@ class Element(object): Args: rotation: multiple of 90 degrees """ - self.set_rotation((self.get_rotation() + rotation)%360) - - def clear(self): - """Empty the lines and areas.""" - del self._areas_list[:] - del self._lines_list[:] + self.rotation = (self.rotation + rotation) % 360 def set_coordinate(self, coor): """ @@ -139,24 +138,6 @@ class Element(object): """ self.coor = coor - def set_highlighted(self, highlighted): - """ - Set the highlight status. - - Args: - highlighted: true to enable highlighting - """ - self.highlighted = highlighted - - def is_highlighted(self): - """ - Get the highlight status. - - Returns: - true if highlighted - """ - return self.highlighted - def get_coordinate(self): """Get the coordinate. @@ -174,27 +155,7 @@ class Element(object): """ deltaX, deltaY = delta_coor X, Y = self.get_coordinate() - self.set_coordinate((X+deltaX, Y+deltaY)) - - def add_area(self, x, y, w, h): - """ - Add an area to the area list. - An area is actually a coordinate relative to the main coordinate - with a width/height pair relative to the area coordinate. - A positive width is to the right of the coordinate. - A positive height is above the coordinate. - The area is associated with a rotation. - """ - self._areas_list.append([x, y, w, h]) - - def add_line(self, *points): - """ - Add a line to the line list. - A line is defined by 2 or more relative coordinates. - Lines must be horizontal or vertical. - The line is associated with a rotation. - """ - self._lines_list.append(points) + self.set_coordinate((X + deltaX, Y + deltaY)) def what_is_selected(self, coor, coor_m=None): """ @@ -219,14 +180,14 @@ class Element(object): if coor_m: x_m, y_m = [a-b for a,b in zip(coor_m, self.get_coordinate())] #handle rectangular areas - for x1, y1, w, h in self._areas_list: + for x1, y1, w, h in self.areas: if in_between(x1, x, x_m) and in_between(y1, y, y_m) or \ in_between(x1+w, x, x_m) and in_between(y1, y, y_m) or \ in_between(x1, x, x_m) and in_between(y1+h, y, y_m) or \ in_between(x1+w, x, x_m) and in_between(y1+h, y, y_m): return self #handle horizontal or vertical lines - for line in self._lines_list: + for line in self.lines: last_point = line[0] for x2, y2 in line[1:]: (x1, y1), last_point = last_point, (x2, y2) @@ -236,10 +197,10 @@ class Element(object): return None else: #handle rectangular areas - for x1, y1, w, h in self._areas_list: + for x1, y1, w, h in self.areas: if in_between(x, x1, x1+w) and in_between(y, y1, y1+h): return self #handle horizontal or vertical lines - for line in self._lines_list: + for line in self.lines: last_point = line[0] for x2, y2 in line[1:]: (x1, y1), last_point = last_point, (x2, y2) @@ -248,25 +209,6 @@ class Element(object): if in_between(x, x1, x2) and in_between(y, y1, y2): return self return None - def get_rotation(self): - """ - Get the rotation in degrees. - - Returns: - the rotation - """ - return self.rotation - - def set_rotation(self, rotation): - """ - Set the rotation in degrees. - - Args: - rotation: the rotation""" - if rotation not in POSSIBLE_ROTATIONS: - raise Exception('"%s" is not one of the possible rotations: (%s)'%(rotation, POSSIBLE_ROTATIONS)) - self.rotation = rotation - def mouse_over(self): pass diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py index 7176594460..5de38877c1 100644 --- a/grc/gui/FlowGraph.py +++ b/grc/gui/FlowGraph.py @@ -143,7 +143,6 @@ class FlowGraph(Element, _Flowgraph): #get the new block block = self.new_block(key) block.set_coordinate(coor) - block.set_rotation(0) block.get_param('id').set_value(id) Actions.ELEMENT_CREATE() return id @@ -363,8 +362,8 @@ class FlowGraph(Element, _Flowgraph): for selected_block in blocks: x, y = selected_block.get_coordinate() min_x, min_y = min(min_x, x), min(min_y, y) - x += selected_block.W - y += selected_block.H + x += selected_block.width + y += selected_block.height max_x, max_y = max(max_x, x), max(max_y, y) ctr_x, ctr_y = (max_x + min_x)/2, (max_y + min_y)/2 @@ -380,7 +379,7 @@ class FlowGraph(Element, _Flowgraph): for selected_block in blocks: x, y = selected_block.get_coordinate() - w, h = selected_block.W, selected_block.H + w, h = selected_block.width, selected_block.height selected_block.set_coordinate(transform(x, y, w, h)) return True @@ -747,6 +746,6 @@ class FlowGraph(Element, _Flowgraph): w, h = initial for block in self.blocks: x, y = block.get_coordinate() - w = max(w, x + block.W) - h = max(h, y + block.H) + w = max(w, x + block.width) + h = max(h, y + block.height) return w, h diff --git a/grc/gui/Port.py b/grc/gui/Port.py index 298b22e19f..24dde67a01 100644 --- a/grc/gui/Port.py +++ b/grc/gui/Port.py @@ -25,6 +25,7 @@ from gi.repository import Gtk, PangoCairo, Pango from . import Actions, Colors, Utils, Constants from .Element import Element +from ..core.Element import property_nop_write from ..core.Port import Port as _Port @@ -44,19 +45,19 @@ class Port(_Port, Element): self._bg_color = (0, 0, 0) self._line_width_factor = 1.0 - self._W = self.H = 0 + self._width = self.height = 0 self.connector_length = 0 self.label_layout = Gtk.DrawingArea().create_pango_layout('') self.label_layout.set_alignment(Pango.Alignment.CENTER) @property - def W(self): - return self._W if not self._label_hidden() else Constants.PORT_LABEL_HIDDEN_WIDTH + def width(self): + return self._width if not self._label_hidden() else Constants.PORT_LABEL_HIDDEN_WIDTH - @W.setter - def W(self, value): - self._W = value + @width.setter + def width(self, value): + self._width = value self.label_layout.set_width(value * Pango.SCALE) def _get_color(self): @@ -79,15 +80,15 @@ class Port(_Port, Element): self.clear() if self.is_horizontal(): - self.add_area(0, 0, self.W, self.H) + self.areas.append([0, 0, self.width, self.height]) elif self.is_vertical(): - self.add_area(0, 0, self.H, self.W) + self.areas.append([0, 0, self.height, self.width]) self._connector_coordinate = { - 0: (self.W, self.H / 2), - 90: (self.H / 2, 0), - 180: (0, self.H / 2), - 270: (self.H / 2, self.W) + 0: (self.width, self.height / 2), + 90: (self.height / 2, 0), + 180: (0, self.height / 2), + 270: (self.height / 2, self.width) }[self.get_connector_direction()] def create_labels(self): @@ -106,11 +107,11 @@ class Port(_Port, Element): )) label_width, label_height = self.label_layout.get_pixel_size() - self.W = 2 * Constants.PORT_LABEL_PADDING + label_width - self.H = 2 * Constants.PORT_LABEL_PADDING + label_height + self.width = 2 * Constants.PORT_LABEL_PADDING + label_width + self.height = 2 * Constants.PORT_LABEL_PADDING + label_height if self.get_type() == 'bus': - self.H += 2 * label_height - self.H += self.H % 2 # uneven height + self.height += 2 * label_height + self.height += self.height % 2 # uneven height def draw(self, widget, cr, border_color, bg_color): """ @@ -124,7 +125,7 @@ class Port(_Port, Element): if self.is_vertical(): cr.rotate(-math.pi / 2) - cr.translate(-self.W, 0) + cr.translate(-self.width, 0) cr.translate(0, Constants.PORT_LABEL_PADDING) PangoCairo.update_layout(cr, self.label_layout) @@ -150,27 +151,13 @@ class Port(_Port, Element): the direction in degrees """ if self.is_source: - return self.get_rotation() + return self.rotation elif self.is_sink: - return (self.get_rotation() + 180) % 360 + return (self.rotation + 180) % 360 - def get_rotation(self): - """ - Get the parent's rotation rather than self. - - Returns: - the parent's rotation - """ - return self.parent.get_rotation() - - def move(self, delta_coor): - """ - Move the parent rather than self. - - Args: - delta_corr: the (delta_x, delta_y) tuple - """ - self.parent.move(delta_coor) + @property_nop_write + def rotation(self): + return self.parent_block.rotation def rotate(self, direction): """ @@ -181,23 +168,22 @@ class Port(_Port, Element): """ self.parent.rotate(direction) - def set_highlighted(self, highlight): + def move(self, delta_coor): """ - Set the parent highlight rather than self. + Move the parent rather than self. Args: - highlight: true to enable highlighting + delta_corr: the (delta_x, delta_y) tuple """ - self.parent.set_highlighted(highlight) + self.parent.move(delta_coor) - def is_highlighted(self): - """ - Get the parent's is highlight rather than self. + @property + def highlighted(self): + return self.parent_block.highlighted - Returns: - the parent's highlighting status - """ - return self.parent.is_highlighted() + @highlighted.setter + def highlighted(self, value): + self.parent_block.highlighted = value def _label_hidden(self): """ |