summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Koslowski <koslowski@kit.edu>2016-07-13 10:31:12 +0200
committerSebastian Koslowski <koslowski@kit.edu>2016-07-13 16:35:50 +0200
commitcf71e261f1438d51adf857fd8b926cfdda0a51ab (patch)
treefe854f31fd090d910daee74b0043744362918edb
parent11c4f515b250ccdef366da222c10d16229f5d347 (diff)
grc: gtk3: update gui element class
-rw-r--r--grc/core/Element.py7
-rw-r--r--grc/core/FlowGraph.py7
-rw-r--r--grc/gui/Block.py46
-rw-r--r--grc/gui/Connection.py32
-rw-r--r--grc/gui/Element.py94
-rw-r--r--grc/gui/FlowGraph.py11
-rw-r--r--grc/gui/Port.py80
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):
"""