diff options
-rw-r--r-- | grc/gui/ActionHandler.py | 10 | ||||
-rw-r--r-- | grc/gui/Actions.py | 39 | ||||
-rw-r--r-- | grc/gui/Bars.py | 1 | ||||
-rw-r--r-- | grc/gui/FlowGraph.py | 41 |
4 files changed, 91 insertions, 0 deletions
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py index 077786d4b4..1d8167491a 100644 --- a/grc/gui/ActionHandler.py +++ b/grc/gui/ActionHandler.py @@ -324,6 +324,12 @@ class ActionHandler: elif action == Actions.BLOCK_MOVE: self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) self.get_page().set_saved(False) + + elif action in Actions.BLOCK_ALIGNMENTS: + if self.get_flow_graph().align_selected(action): + self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data()) + self.get_page().set_saved(False) + elif action == Actions.BLOCK_ROTATE_CCW: if self.get_flow_graph().rotate_selected(90): self.get_flow_graph().update() @@ -607,6 +613,10 @@ class ActionHandler: Actions.BLOCK_PARAM_MODIFY.set_sensitive(bool(selected_block)) Actions.BLOCK_ROTATE_CCW.set_sensitive(bool(selected_blocks)) Actions.BLOCK_ROTATE_CW.set_sensitive(bool(selected_blocks)) + #update alignment options + for act in Actions.BLOCK_ALIGNMENTS: + if act: + act.set_sensitive(len(selected_blocks) > 1) #update cut/copy/paste Actions.BLOCK_CUT.set_sensitive(bool(selected_blocks)) Actions.BLOCK_COPY.set_sensitive(bool(selected_blocks)) diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py index 354e536a82..484d4f3301 100644 --- a/grc/gui/Actions.py +++ b/grc/gui/Actions.py @@ -253,6 +253,45 @@ BLOCK_ROTATE_CW = Action( stock_id=gtk.STOCK_GO_FORWARD, keypresses=(gtk.keysyms.Right, NO_MODS_MASK), ) +BLOCK_VALIGN_TOP = Action( + label='Vertical Align Top', + tooltip='Align tops of selected blocks', + keypresses=(gtk.keysyms.t, gtk.gdk.SHIFT_MASK), +) +BLOCK_VALIGN_MIDDLE = Action( + label='Vertical Align Middle', + tooltip='Align centers of selected blocks vertically', + keypresses=(gtk.keysyms.m, gtk.gdk.SHIFT_MASK), +) +BLOCK_VALIGN_BOTTOM = Action( + label='Vertical Align Bottom', + tooltip='Align bottoms of selected blocks', + keypresses=(gtk.keysyms.b, gtk.gdk.SHIFT_MASK), +) +BLOCK_HALIGN_LEFT = Action( + label='Horizontal Align Left', + tooltip='Align left edges of blocks selected blocks', + keypresses=(gtk.keysyms.l, gtk.gdk.SHIFT_MASK), +) +BLOCK_HALIGN_CENTER = Action( + label='Horizontal Align Center', + tooltip='Align centers of selected blocks horizontally', + keypresses=(gtk.keysyms.c, gtk.gdk.SHIFT_MASK), +) +BLOCK_HALIGN_RIGHT = Action( + label='Horizontal Align Right', + tooltip='Align right edges of selected blocks', + keypresses=(gtk.keysyms.r, gtk.gdk.SHIFT_MASK), +) +BLOCK_ALIGNMENTS = [ + BLOCK_VALIGN_TOP, + BLOCK_VALIGN_MIDDLE, + BLOCK_VALIGN_BOTTOM, + None, + BLOCK_HALIGN_LEFT, + BLOCK_HALIGN_CENTER, + BLOCK_HALIGN_RIGHT, +] BLOCK_PARAM_MODIFY = Action( label='_Properties', tooltip='Modify params for the selected block', diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py index cb101111cd..b758f3c444 100644 --- a/grc/gui/Bars.py +++ b/grc/gui/Bars.py @@ -86,6 +86,7 @@ MENU_BAR_LIST = ( None, Actions.BLOCK_ROTATE_CCW, Actions.BLOCK_ROTATE_CW, + (gtk.Action('Align', '_Align', None, None), Actions.BLOCK_ALIGNMENTS), None, Actions.BLOCK_ENABLE, Actions.BLOCK_DISABLE, diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py index 357f87c894..9c6bd8f169 100644 --- a/grc/gui/FlowGraph.py +++ b/grc/gui/FlowGraph.py @@ -312,6 +312,47 @@ class FlowGraph(Element, _Flowgraph): selected_block.move(delta_coordinate) self.element_moved = True + def align_selected(self, calling_action=None): + """ + Align the selected blocks. + + Args: + calling_action: the action initiating the alignment + + Returns: + True if changed, otherwise False + """ + blocks = self.get_selected_blocks() + if calling_action is None or not blocks: + return False + + # compute common boundary of selected objects + min_x, min_y = max_x, max_y = blocks[0].get_coordinate() + 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 + 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 + + # align the blocks as requested + transform = { + Actions.BLOCK_VALIGN_TOP: lambda x, y, w, h: (x, min_y), + Actions.BLOCK_VALIGN_MIDDLE: lambda x, y, w, h: (x, ctr_y - h/2), + Actions.BLOCK_VALIGN_BOTTOM: lambda x, y, w, h: (x, max_y - h), + Actions.BLOCK_HALIGN_LEFT: lambda x, y, w, h: (min_x, y), + Actions.BLOCK_HALIGN_CENTER: lambda x, y, w, h: (ctr_x-w/2, y), + Actions.BLOCK_HALIGN_RIGHT: lambda x, y, w, h: (max_x - w, y), + }.get(calling_action, lambda *args: args) + + for selected_block in blocks: + x, y = selected_block.get_coordinate() + w, h = selected_block.W, selected_block.H + selected_block.set_coordinate(transform(x, y, w, h)) + + return True + def rotate_selected(self, rotation): """ Rotate the selected blocks by multiples of 90 degrees. |