From 0dd158155c074113ec1cc6a3de7ecdd2be7d65e8 Mon Sep 17 00:00:00 2001
From: Sebastian Koslowski <koslowski@kit.edu>
Date: Tue, 19 Aug 2014 17:02:33 +0200
Subject: grc: snap-to-grid (WIP)

---
 grc/gui/Block.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'grc/gui/Block.py')

diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 0afb351647..589ed34de1 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -43,6 +43,8 @@ class Block(Element):
         Block contructor.
         Add graphics related params to the block.
         """
+        self.W = 0
+        self.H = 0
         #add the position param
         self.get_params().append(self.get_parent().get_parent().Param(
             block=self,
@@ -85,6 +87,9 @@ class Block(Element):
                 y = 0
             elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
                 y = fgH - BORDER_PROXIMITY_SENSITIVITY
+            offset_x, offset_y = (0, self.H/2) if self.is_horizontal() else (self.H/2, 0)
+            x = Utils.align_to_grid(x + offset_x) - offset_x
+            y = Utils.align_to_grid(y + offset_y) - offset_y
             return (x, y)
         except:
             self.set_coordinate((0, 0))
@@ -179,8 +184,7 @@ class Block(Element):
                 self.label_height + 2 * BLOCK_LABEL_PADDING
             ] +
             [  # ports
-                2 * PORT_BORDER_SEPARATION +
-                sum([port.H + PORT_SEPARATION for port in ports if not port.get_hide()]) - PORT_SEPARATION
+                PORT_SEPARATION * len(filter(lambda p: not p.get_hide(), ports))
                 for ports in (self.get_sources_gui(), self.get_sinks_gui())
             ] +
             [  # bus ports only
-- 
cgit v1.2.3


From 8886123e78485e5c3d1edccaa35ce591e43dbbe5 Mon Sep 17 00:00:00 2001
From: Sebastian Koslowski <koslowski@kit.edu>
Date: Wed, 20 Aug 2014 17:55:15 +0200
Subject: grc: toggle action and mod1 modifier for snap-to-grid

---
 grc/gui/ActionHandler.py |  5 ++++-
 grc/gui/Actions.py       |  5 +++++
 grc/gui/Bars.py          |  1 +
 grc/gui/Block.py         | 10 +++++++---
 grc/gui/DrawingArea.py   |  4 ++++
 grc/gui/FlowGraph.py     |  4 +++-
 6 files changed, 24 insertions(+), 5 deletions(-)

(limited to 'grc/gui/Block.py')

diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index b68fa60a26..dcc3c846eb 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -118,7 +118,7 @@ class ActionHandler:
                 Actions.TYPES_WINDOW_DISPLAY, Actions.TOGGLE_BLOCKS_WINDOW,
                 Actions.TOGGLE_REPORTS_WINDOW, Actions.TOGGLE_HIDE_DISABLED_BLOCKS,
                 Actions.TOOLS_RUN_FDESIGN, Actions.TOGGLE_SCROLL_LOCK, Actions.CLEAR_REPORTS,
-                Actions.TOGGLE_AUTO_HIDE_PORT_LABELS
+                Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, Actions.TOGGLE_SNAP_TO_GRID
             ): action.set_sensitive(True)
             if ParseXML.xml_failures:
                 Messages.send_xml_errors_if_any(ParseXML.xml_failures)
@@ -139,6 +139,7 @@ class ActionHandler:
                 Actions.TOGGLE_BLOCKS_WINDOW,
                 Actions.TOGGLE_AUTO_HIDE_PORT_LABELS,
                 Actions.TOGGLE_SCROLL_LOCK,
+                Actions.TOGGLE_SNAP_TO_GRID
             ): action.load_from_preferences()
         elif action == Actions.APPLICATION_QUIT:
             if self.main_window.close_pages():
@@ -389,6 +390,8 @@ class ActionHandler:
         elif action == Actions.TOGGLE_AUTO_HIDE_PORT_LABELS:
             action.save_to_preferences()
             self.main_window.get_flow_graph().create_shapes()
+        elif action == Actions.TOGGLE_SNAP_TO_GRID:
+            action.save_to_preferences()
         ##################################################
         # Param Modifications
         ##################################################
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index f4191a41fb..50ee456e76 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -247,6 +247,11 @@ BLOCK_DISABLE = Action(
     stock_id=gtk.STOCK_DISCONNECT,
     keypresses=(gtk.keysyms.d, NO_MODS_MASK),
 )
+TOGGLE_SNAP_TO_GRID = ToggleAction(
+    label='_Snap to grid',
+    tooltip='Snap blocks to a grid for an easier connection alignment',
+    preference_name='snap_to_grid'
+)
 TOGGLE_HIDE_DISABLED_BLOCKS = ToggleAction(
     label='Hide _disabled blocks',
     tooltip='Toggle visibility of disabled blocks and connections',
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index 8dae0f6981..6ddaa4ab21 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -99,6 +99,7 @@ MENU_BAR_LIST = (
         None,
         Actions.TOGGLE_HIDE_DISABLED_BLOCKS,
         Actions.TOGGLE_AUTO_HIDE_PORT_LABELS,
+        Actions.TOGGLE_SNAP_TO_GRID,
         None,
         Actions.ERRORS_WINDOW_DISPLAY,
         Actions.FIND_BLOCKS,
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 589ed34de1..a80b3d00eb 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -26,6 +26,7 @@ from Constants import \
     BLOCK_LABEL_PADDING, \
     PORT_SEPARATION, LABEL_SEPARATION, \
     PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS
+import Actions
 import pygtk
 pygtk.require('2.0')
 import gtk
@@ -87,9 +88,6 @@ class Block(Element):
                 y = 0
             elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
                 y = fgH - BORDER_PROXIMITY_SENSITIVITY
-            offset_x, offset_y = (0, self.H/2) if self.is_horizontal() else (self.H/2, 0)
-            x = Utils.align_to_grid(x + offset_x) - offset_x
-            y = Utils.align_to_grid(y + offset_y) - offset_y
             return (x, y)
         except:
             self.set_coordinate((0, 0))
@@ -102,6 +100,12 @@ class Block(Element):
         Args:
             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)
+            coor = (
+                Utils.align_to_grid(coor[0] + offset_x) - offset_x,
+                Utils.align_to_grid(coor[1] + offset_y) - offset_y
+            )
         self.get_param('_coordinate').set_value(str(coor))
 
     def get_rotation(self):
diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py
index 448948e7f4..d22a2c6d5f 100644
--- a/grc/gui/DrawingArea.py
+++ b/grc/gui/DrawingArea.py
@@ -37,6 +37,7 @@ class DrawingArea(gtk.DrawingArea):
             main_window: the main_window containing all flow graphs
         """
         self.ctrl_mask = False
+        self.mod1_mask = False
         self._flow_graph = flow_graph
         gtk.DrawingArea.__init__(self)
         self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
@@ -88,6 +89,7 @@ class DrawingArea(gtk.DrawingArea):
         """
         self.grab_focus()
         self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
+        self.mod1_mask = event.state & gtk.gdk.MOD1_MASK
         if event.button == 1: self._flow_graph.handle_mouse_selector_press(
             double_click=(event.type == gtk.gdk._2BUTTON_PRESS),
             coordinate=(event.x, event.y),
@@ -102,6 +104,7 @@ class DrawingArea(gtk.DrawingArea):
         Forward button release information to the flow graph.
         """
         self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
+        self.mod1_mask = event.state & gtk.gdk.MOD1_MASK
         if event.button == 1: self._flow_graph.handle_mouse_selector_release(
             coordinate=(event.x, event.y),
         )
@@ -111,6 +114,7 @@ class DrawingArea(gtk.DrawingArea):
         Forward mouse motion information to the flow graph.
         """
         self.ctrl_mask = event.state & gtk.gdk.CONTROL_MASK
+        self.mod1_mask = event.state & gtk.gdk.MOD1_MASK
         self._flow_graph.handle_mouse_motion(
             coordinate=(event.x, event.y),
         )
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index 4d2b1b6dd3..31017a9923 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -84,6 +84,7 @@ class FlowGraph(Element):
     def set_size(self, *args): self.get_drawing_area().set_size_request(*args)
     def get_scroll_pane(self): return self.drawing_area.get_parent()
     def get_ctrl_mask(self): return self.drawing_area.ctrl_mask
+    def get_mod1_mask(self): return self.drawing_area.mod1_mask
     def new_pixmap(self, *args): return self.get_drawing_area().new_pixmap(*args)
 
     def add_new_block(self, key, coor=None):
@@ -597,7 +598,8 @@ class FlowGraph(Element):
             if not self.get_ctrl_mask():
                 X, Y = self.get_coordinate()
                 dX, dY = int(x - X), int(y - Y)
-                if abs(dX) >= Utils.CANVAS_GRID_SIZE or abs(dY) >= Utils.CANVAS_GRID_SIZE:
+                active = Actions.TOGGLE_SNAP_TO_GRID.get_active() or self.get_mod1_mask()
+                if not active or abs(dX) >= Utils.CANVAS_GRID_SIZE or abs(dY) >= Utils.CANVAS_GRID_SIZE:
                     self.move_selected((dX, dY))
                     self.set_coordinate((x, y))
             #queue draw for animation
-- 
cgit v1.2.3


From 00709699b217bc6b6b866ffad6d9a8c1e9497ae8 Mon Sep 17 00:00:00 2001
From: Sebastian Koslowski <koslowski@kit.edu>
Date: Wed, 20 Aug 2014 17:55:40 +0200
Subject: grc: fix block height

---
 grc/gui/Block.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'grc/gui/Block.py')

diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index a80b3d00eb..0ae624f94f 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -183,13 +183,17 @@ class Block(Element):
             Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label)
         #calculate width and height needed
         self.W = self.label_width + 2*BLOCK_LABEL_PADDING
+        def get_min_height_for_ports():
+            visible_ports = filter(lambda p: not p.get_hide(), ports)
+            H = 2*PORT_BORDER_SEPARATION + len(visible_ports) * PORT_SEPARATION
+            if visible_ports: H -= ports[0].H
+            return H
         self.H = max(*(
             [  # labels
                 self.label_height + 2 * BLOCK_LABEL_PADDING
             ] +
             [  # ports
-                PORT_SEPARATION * len(filter(lambda p: not p.get_hide(), ports))
-                for ports in (self.get_sources_gui(), self.get_sinks_gui())
+                get_min_height_for_ports() for ports in (self.get_sources_gui(), self.get_sinks_gui())
             ] +
             [  # bus ports only
                 4 * PORT_BORDER_SEPARATION +
-- 
cgit v1.2.3