commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 08/101: grc: gtk3: remove canvas size and e


From: git
Subject: [Commit-gnuradio] [gnuradio] 08/101: grc: gtk3: remove canvas size and enable zooming
Date: Thu, 16 Mar 2017 14:57:57 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch python3
in repository gnuradio.

commit 69da909690bb8bc2072cffb622ddf7bf2e971cce
Author: Sebastian Koslowski <address@hidden>
Date:   Tue May 31 17:35:10 2016 +0200

    grc: gtk3: remove canvas size and enable zooming
---
 grc/gui/ActionHandler.py   |  17 ++----
 grc/gui/Block.py           |  70 ++++------------------
 grc/gui/BlockTreeWindow.py |   2 +-
 grc/gui/Constants.py       |   5 +-
 grc/gui/DrawingArea.py     | 126 ++++++++++++++++++++++++++++----------
 grc/gui/FlowGraph.py       | 146 ++++++++++++++++++++++-----------------------
 grc/gui/MainWindow.py      |   4 +-
 grc/gui/NotebookPage.py    |  68 +++++++++------------
 grc/gui/PropsDialog.py     |   4 +-
 grc/gui/Utils.py           |  30 +---------
 10 files changed, 218 insertions(+), 254 deletions(-)

diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index 7dc37cc..de635b6 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -676,7 +676,7 @@ class ActionHandler:
         can_disable = any(block.get_state() != Constants.BLOCK_DISABLED
                           for block in selected_blocks)
         can_bypass_all = all(block.can_bypass() for block in selected_blocks) \
-                          and any (not block.get_bypassed() for block in 
selected_blocks)
+                         and any(not block.get_bypassed() for block in 
selected_blocks)
         Actions.BLOCK_ENABLE.set_sensitive(can_enable)
         Actions.BLOCK_DISABLE.set_sensitive(can_disable)
         Actions.BLOCK_BYPASS.set_sensitive(can_bypass_all)
@@ -687,21 +687,16 @@ class ActionHandler:
         Actions.BUSSIFY_SINKS.set_sensitive(bool(selected_blocks))
         Actions.RELOAD_BLOCKS.set_sensitive(True)
         Actions.FIND_BLOCKS.set_sensitive(True)
-        #set the exec and stop buttons
+
         self.update_exec_stop()
-        #saved status
+
         Actions.FLOW_GRAPH_SAVE.set_sensitive(not page.get_saved())
         main.update()
-        try: #set the size of the flow graph area (if changed)
-            new_size = (flow_graph.get_option('window_size') or
-                        self.platform.config.default_canvas_size)
-            if flow_graph.get_size() != tuple(new_size):
-                flow_graph.set_size(*new_size)
-        except: pass
-        #draw the flow graph
+
         flow_graph.update_selected()
         flow_graph.queue_draw()
-        return True #action was handled
+
+        return True  # action was handled
 
     def update_exec_stop(self):
         """
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 5e5c5c4..1b90cf6 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -27,8 +27,7 @@ from . import Actions, Colors, Utils
 
 from .Constants import (
     BLOCK_LABEL_PADDING, PORT_SPACING, PORT_SEPARATION, LABEL_SEPARATION,
-    PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS, BLOCK_FONT, PARAM_FONT,
-    BORDER_PROXIMITY_SENSITIVITY
+    PORT_BORDER_SEPARATION, POSSIBLE_ROTATIONS, BLOCK_FONT, PARAM_FONT
 )
 from . Element import Element
 from ..core.Param import num_to_str
@@ -64,22 +63,13 @@ class Block(Element, _Block):
         Returns:
             the coordinate tuple (x, y) or (0, 0) if failure
         """
-        try: #should evaluate to tuple
-            coor = eval(self.get_param('_coordinate').get_value())
-            x, y = map(int, coor)
-            fgW,fgH = self.get_parent().get_size()
-            if x <= 0:
-                x = 0
-            elif x >= fgW - BORDER_PROXIMITY_SENSITIVITY:
-                x = fgW - BORDER_PROXIMITY_SENSITIVITY
-            if y <= 0:
-                y = 0
-            elif y >= fgH - BORDER_PROXIMITY_SENSITIVITY:
-                y = fgH - BORDER_PROXIMITY_SENSITIVITY
-            return (x, y)
+        try:
+            coor = self.get_param('_coordinate').get_value()  # should 
evaluate to tuple
+            coor = tuple(int(x) for x in coor[1:-1].split(','))
         except:
-            self.set_coordinate((0, 0))
-            return (0, 0)
+            coor = 0, 0
+            self.set_coordinate(coor)
+        return coor
 
     def set_coordinate(self, coor):
         """
@@ -94,41 +84,7 @@ class Block(Element, _Block):
                 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 bound_move_delta(self, delta_coor):
-        """
-        Limit potential moves from exceeding the bounds of the canvas
-
-        Args:
-            delta_coor: requested delta coordinate (dX, dY) to move
-
-        Returns:
-            The delta coordinate possible to move while keeping the block on 
the canvas
-            or the input (dX, dY) on failure
-        """
-        dX, dY = delta_coor
-
-        try:
-            fgW, fgH = self.get_parent().get_size()
-            x, y = map(int, eval(self.get_param("_coordinate").get_value()))
-            if self.is_horizontal():
-               sW, sH = self.W, self.H
-            else:
-               sW, sH = self.H, self.W
-
-            if x + dX < 0:
-                dX = -x
-            elif dX + x + sW >= fgW:
-                dX = fgW - x - sW
-            if y + dY < 0:
-                dY = -y
-            elif dY + y + sH >= fgH:
-               dY = fgH - y - sH
-        except:
-            pass
-
-        return ( dX, dY )
+        self.get_param('_coordinate').set_value(repr(coor))
 
     def get_rotation(self):
         """
@@ -138,11 +94,11 @@ class Block(Element, _Block):
             the rotation in degrees or 0 if failure
         """
         try: #should evaluate to dict
-            rotation = eval(self.get_param('_rotation').get_value())
-            return int(rotation)
+            rotation = int(self.get_param('_rotation').get_value())
         except:
-            self.set_rotation(POSSIBLE_ROTATIONS[0])
-            return POSSIBLE_ROTATIONS[0]
+            rotation = POSSIBLE_ROTATIONS[0]
+            self.set_rotation(rotation)
+        return rotation
 
     def set_rotation(self, rot):
         """
@@ -151,7 +107,7 @@ class Block(Element, _Block):
         Args:
             rot: the rotation in degrees
         """
-        self.get_param('_rotation').set_value(str(rot))
+        self.get_param('_rotation').set_value(repr(int(rot)))
 
     def create_shapes(self):
         """Update the block, parameters, and ports when a change occurs."""
diff --git a/grc/gui/BlockTreeWindow.py b/grc/gui/BlockTreeWindow.py
index e8de6e9..9a147bd 100644
--- a/grc/gui/BlockTreeWindow.py
+++ b/grc/gui/BlockTreeWindow.py
@@ -281,5 +281,5 @@ class BlockTreeWindow(Gtk.VBox):
         Handle the mouse button press.
         If a left double click is detected, call add selected block.
         """
-        if event.button == 1 and event.type == Gdk._2BUTTON_PRESS:
+        if event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
             self._add_selected_block()
diff --git a/grc/gui/Constants.py b/grc/gui/Constants.py
index 4ab644e..55739a7 100644
--- a/grc/gui/Constants.py
+++ b/grc/gui/Constants.py
@@ -86,11 +86,8 @@ CONNECTOR_ARROW_HEIGHT = 17
 # possible rotations in degrees
 POSSIBLE_ROTATIONS = (0, 90, 180, 270)
 
-# How close can the mouse get to the window border before mouse events are 
ignored.
-BORDER_PROXIMITY_SENSITIVITY = 50
-
 # How close the mouse can get to the edge of the visible window before 
scrolling is invoked.
-SCROLL_PROXIMITY_SENSITIVITY = 30
+SCROLL_PROXIMITY_SENSITIVITY = 50
 
 # When the window has to be scrolled, move it this distance in the required 
direction.
 SCROLL_DISTANCE = 15
diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py
index 2bce21f..d1e0e78 100644
--- a/grc/gui/DrawingArea.py
+++ b/grc/gui/DrawingArea.py
@@ -17,15 +17,10 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-import gi
-gi.require_version('Gtk', '3.0')
-from gi.repository import Gtk
-from gi.repository import Gdk
-from gi.repository import GObject
+from gi.repository import Gtk, Gdk, GObject
 
 
-from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT, DND_TARGETS
-import Colors
+from . import Constants, Colors
 
 
 class DrawingArea(Gtk.DrawingArea):
@@ -42,11 +37,16 @@ class DrawingArea(Gtk.DrawingArea):
         Args:
             main_window: the main_window containing all flow graphs
         """
+        Gtk.DrawingArea.__init__(self)
+
+        self._flow_graph = flow_graph
+
+        self.zoom_factor = 1.0
         self.ctrl_mask = False
         self.mod1_mask = False
-        self._flow_graph = flow_graph
-        GObject.GObject.__init__(self)
-        self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
+        self.button_state = [False] * 10
+
+        # self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT)
         self.connect('realize', self._handle_window_realize)
         self.connect('draw', self.draw)
         self.connect('motion-notify-event', self._handle_mouse_motion)
@@ -54,24 +54,28 @@ class DrawingArea(Gtk.DrawingArea):
         self.connect('button-release-event', self._handle_mouse_button_release)
         self.connect('scroll-event', self._handle_mouse_scroll)
         self.add_events(
-            Gdk.EventMask.BUTTON_PRESS_MASK | \
-            Gdk.EventMask.POINTER_MOTION_MASK | \
-            Gdk.EventMask.BUTTON_RELEASE_MASK | \
-            Gdk.EventMask.LEAVE_NOTIFY_MASK | \
-            Gdk.EventMask.ENTER_NOTIFY_MASK #| \
+            Gdk.EventMask.BUTTON_PRESS_MASK |
+            Gdk.EventMask.POINTER_MOTION_MASK |
+            Gdk.EventMask.BUTTON_RELEASE_MASK |
+            Gdk.EventMask.SCROLL_MASK |
+            Gdk.EventMask.LEAVE_NOTIFY_MASK |
+            Gdk.EventMask.ENTER_NOTIFY_MASK
             #Gdk.EventMask.FOCUS_CHANGE_MASK
         )
-        #setup drag and drop
+
+        # setup drag and drop
         self.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY)
         self.connect('drag-data-received', self._handle_drag_data_received)
         self.drag_dest_set_target_list(None)
         self.drag_dest_add_text_targets()
-        #setup the focus flag
+
+        # setup the focus flag
         self._focus_flag = False
         self.get_focus_flag = lambda: self._focus_flag
         def _handle_notify_event(widget, event, focus_flag): self._focus_flag 
= focus_flag
         self.connect('leave-notify-event', _handle_notify_event, False)
         self.connect('enter-notify-event', _handle_notify_event, True)
+        # todo: fix
 #        self.set_flags(Gtk.CAN_FOCUS)  # self.set_can_focus(True)
 #        self.connect('focus-out-event', self._handle_focus_lost_event)
 
@@ -86,10 +90,21 @@ class DrawingArea(Gtk.DrawingArea):
 
     def _handle_mouse_scroll(self, widget, event):
         if event.get_state() & Gdk.ModifierType.SHIFT_MASK:
-           if event.direction == Gdk.ScrollDirection.UP:
-               event.direction = Gdk.ScrollDirection.LEFT
-           else:
-               event.direction = Gdk.ScrollDirection.RIGHT
+            if event.direction == Gdk.ScrollDirection.UP:
+                event.direction = Gdk.ScrollDirection.LEFT
+            else:
+                event.direction = Gdk.ScrollDirection.RIGHT
+
+        elif event.get_state() & Gdk.ModifierType.CONTROL_MASK:
+            change = 1.2 if event.direction == Gdk.ScrollDirection.UP else 
1/1.2
+            zoom_factor = min(max(self.zoom_factor * change, 0.1), 5.0)
+
+            if zoom_factor != self.zoom_factor:
+                self.zoom_factor = zoom_factor
+                self.queue_draw()
+            return True
+
+        return False
 
     def _handle_mouse_button_press(self, widget, event):
         """
@@ -98,14 +113,18 @@ class DrawingArea(Gtk.DrawingArea):
         self.grab_focus()
         self.ctrl_mask = event.get_state() & Gdk.ModifierType.CONTROL_MASK
         self.mod1_mask = event.get_state() & Gdk.ModifierType.MOD1_MASK
-        if event.button == 1: self._flow_graph.handle_mouse_selector_press(
-            double_click=(event.type == Gdk.EventType._2BUTTON_PRESS),
-            coordinate=(event.x, event.y),
-        )
-        if event.button == 3: self._flow_graph.handle_mouse_context_press(
-            coordinate=(event.x, event.y),
-            event=event,
-        )
+        self.button_state[event.button] = True
+
+        if event.button == 1:
+            self._flow_graph.handle_mouse_selector_press(
+                double_click=(event.type == Gdk.EventType._2BUTTON_PRESS),
+                coordinate=self._translate_event_coords(event),
+            )
+        elif event.button == 3:
+            self._flow_graph.handle_mouse_context_press(
+                coordinate=self._translate_event_coords(event),
+                event=event,
+            )
 
     def _handle_mouse_button_release(self, widget, event):
         """
@@ -113,9 +132,11 @@ class DrawingArea(Gtk.DrawingArea):
         """
         self.ctrl_mask = event.get_state() & Gdk.ModifierType.CONTROL_MASK
         self.mod1_mask = event.get_state() & Gdk.ModifierType.MOD1_MASK
-        if event.button == 1: self._flow_graph.handle_mouse_selector_release(
-            coordinate=(event.x, event.y),
-        )
+        self.button_state[event.button] = False
+        if event.button == 1:
+            self._flow_graph.handle_mouse_selector_release(
+                coordinate=self._translate_event_coords(event),
+            )
 
     def _handle_mouse_motion(self, widget, event):
         """
@@ -123,20 +144,59 @@ class DrawingArea(Gtk.DrawingArea):
         """
         self.ctrl_mask = event.get_state() & Gdk.ModifierType.CONTROL_MASK
         self.mod1_mask = event.get_state() & Gdk.ModifierType.MOD1_MASK
+
+        if self.button_state[1]:
+            self._auto_scroll(event)
+
         self._flow_graph.handle_mouse_motion(
-            coordinate=(event.x, event.y),
+            coordinate=self._translate_event_coords(event),
+            button1_pressed=self.button_state[1]
         )
 
+    def _auto_scroll(self, event):
+        x, y = event.x, event.y
+        scrollbox = self.get_parent().get_parent()
+
+        w, h = self._flow_graph.get_max_coords(initial=(x, y))
+        self.set_size_request(w + 100, h + 100)
+
+        def scroll(pos, adj):
+            """scroll if we moved near the border"""
+            adj_val = adj.get_value()
+            adj_len = adj.get_page_size()
+            if pos - adj_val > adj_len - 
Constants.SCROLL_PROXIMITY_SENSITIVITY:
+                adj.set_value(adj_val + Constants.SCROLL_DISTANCE)
+                adj.emit('changed')
+            elif pos - adj_val < Constants.SCROLL_PROXIMITY_SENSITIVITY:
+                adj.set_value(adj_val - Constants.SCROLL_DISTANCE)
+                adj.emit('changed')
+
+        scroll(x, scrollbox.get_hadjustment())
+        scroll(y, scrollbox.get_vadjustment())
+
     def _handle_window_realize(self, widget):
         """
         Called when the window is realized.
         Update the flowgraph, which calls new pixmap.
         """
         self._flow_graph.update()
+        w, h = self._flow_graph.get_max_coords()
+        self.set_size_request(w + 100, h + 100)
 
     def draw(self, widget, cr):
+        width = widget.get_allocated_width()
+        height = widget.get_allocated_height()
+        cr.set_source_rgb(*Colors.FLOWGRAPH_BACKGROUND_COLOR)
+        cr.rectangle(0, 0, width, height)
+
+        cr.scale(self.zoom_factor, self.zoom_factor)
+        cr.fill()
+
         self._flow_graph.draw(widget, cr)
 
+    def _translate_event_coords(self, event):
+        return event.x / self.zoom_factor, event.y / self.zoom_factor
+
     def _handle_focus_lost_event(self, widget, event):
         # don't clear selection while context menu is active
         if not self._flow_graph.get_context_menu().flags() & Gtk.VISIBLE:
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index c3ea677..802c54f 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -76,9 +76,10 @@ class FlowGraph(Element, _Flowgraph):
         Returns:
             a unique id
         """
+        block_ids = set(b.get_id() for b in self.blocks)
         for index in count():
             block_id = '{}_{}'.format(base_id, index)
-            if block_id not in (b.get_id() for b in self.blocks):
+            if block_id not in block_ids:
                 break
         return block_id
 
@@ -128,7 +129,7 @@ class FlowGraph(Element, _Flowgraph):
     def queue_draw(self): self.get_drawing_area().queue_draw()
     def get_size(self): return self.get_drawing_area().get_size_request()
     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_scroll_pane(self): return 
self.drawing_area.get_parent().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)
@@ -146,8 +147,8 @@ class FlowGraph(Element, _Flowgraph):
         h_adj = self.get_scroll_pane().get_hadjustment()
         v_adj = self.get_scroll_pane().get_vadjustment()
         if coor is None: coor = (
-            int(random.uniform(.25, .75)*h_adj.page_size + h_adj.get_value()),
-            int(random.uniform(.25, .75)*v_adj.page_size + v_adj.get_value()),
+            int(random.uniform(.25, .75)*h_adj.get_page_size() + 
h_adj.get_value()),
+            int(random.uniform(.25, .75)*v_adj.get_page_size() + 
v_adj.get_value()),
         )
         #get the new block
         block = self.new_block(key)
@@ -169,7 +170,8 @@ class FlowGraph(Element, _Flowgraph):
         """
         #get selected blocks
         blocks = self.get_selected_blocks()
-        if not blocks: return None
+        if not blocks:
+            return None
         #calc x and y min
         x_min, y_min = blocks[0].get_coordinate()
         for block in blocks:
@@ -281,7 +283,8 @@ class FlowGraph(Element, _Flowgraph):
         """
         changed = False
         for selected_block in self.get_selected_blocks():
-            if selected_block.set_enabled(enable): changed = True
+            if selected_block.set_enabled(enable):
+                changed = True
         return changed
 
     def bypass_selected(self):
@@ -295,7 +298,8 @@ class FlowGraph(Element, _Flowgraph):
         """
         changed = False
         for selected_block in self.get_selected_blocks():
-            if selected_block.set_bypassed(): changed = True
+            if selected_block.set_bypassed():
+                changed = True
         return changed
 
     def move_selected(self, delta_coordinate):
@@ -306,9 +310,6 @@ class FlowGraph(Element, _Flowgraph):
             delta_coordinate: the change in coordinates
         """
         for selected_block in self.get_selected_blocks():
-            delta_coordinate = 
selected_block.bound_move_delta(delta_coordinate)
-
-        for selected_block in self.get_selected_blocks():
             selected_block.move(delta_coordinate)
             self.element_moved = True
 
@@ -401,26 +402,18 @@ class FlowGraph(Element, _Flowgraph):
         """
         Draw the background and grid if enabled.
         """
-
-        cr.set_source_rgb(*Colors.FLOWGRAPH_BACKGROUND_COLOR)
-        cr.rectangle(0, 0, *self.get_size())
-        cr.fill()
-
         # draw comments first
         if Actions.TOGGLE_SHOW_BLOCK_COMMENTS.get_active():
             for block in self.blocks:
                 if block.get_enabled():
                     # block.draw_comment(widget, cr)
                     pass
-        #draw multi select rectangle
+        # draw multi select rectangle
         if self.mouse_pressed and (not self.get_selected_elements() or 
self.get_ctrl_mask()):
-            #coordinates
             x1, y1 = self.press_coor
             x2, y2 = self.get_coordinate()
-            #calculate top-left coordinate and width/height
             x, y = int(min(x1, x2)), int(min(y1, y2))
             w, h = int(abs(x1 - x2)), int(abs(y1 - y2))
-            #draw
             cr.set_source_rgb(*Colors.HIGHLIGHT_COLOR)
             cr.rectangle(x, y, w, h)
             cr.fill()
@@ -428,7 +421,7 @@ class FlowGraph(Element, _Flowgraph):
             cr.rectangle(x, y, w, h)
             cr.stroke()
 
-        #draw blocks on top of connections
+        # draw blocks on top of connections
         hide_disabled_blocks = Actions.TOGGLE_HIDE_DISABLED_BLOCKS.get_active()
         hide_variables = Actions.TOGGLE_HIDE_VARIABLES.get_active()
         blocks = sorted(self.blocks, key=methodcaller('get_enabled'))
@@ -439,7 +432,8 @@ class FlowGraph(Element, _Flowgraph):
             if hide_variables and (element.is_variable or element.is_import):
                 continue  # skip hidden disabled blocks and connections
             element.draw(widget, cr)
-        #draw selected blocks on top of selected connections
+
+        # draw selected blocks on top of selected connections
         for selected_element in self.get_selected_connections() + 
self.get_selected_blocks():
             selected_element.draw(widget, cr)
 
@@ -666,7 +660,7 @@ class FlowGraph(Element, _Flowgraph):
             self.mouse_pressed = True
             self.update_selected_elements()
             self.mouse_pressed = False
-        self._context_menu.popup(None, None, None, event.button, event.time)
+        self._context_menu.popup(None, None, None, None, event.button, 
event.time)
 
     def handle_mouse_selector_press(self, double_click, coordinate):
         """
@@ -677,11 +671,12 @@ class FlowGraph(Element, _Flowgraph):
         """
         self.press_coor = coordinate
         self.set_coordinate(coordinate)
-        self.time = 0
         self.mouse_pressed = True
-        if double_click: self.unselect()
+
+        if double_click:
+            self.unselect()
         self.update_selected_elements()
-        #double click detected, bring up params dialog if possible
+
         if double_click and self.get_selected_block():
             self.mouse_pressed = False
             Actions.BLOCK_PARAM_MODIFY()
@@ -693,69 +688,70 @@ class FlowGraph(Element, _Flowgraph):
         And update the selected flowgraph elements.
         """
         self.set_coordinate(coordinate)
-        self.time = 0
         self.mouse_pressed = False
         if self.element_moved:
             Actions.BLOCK_MOVE()
             self.element_moved = False
         self.update_selected_elements()
 
-    def handle_mouse_motion(self, coordinate):
+    def handle_mouse_motion(self, coordinate, button1_pressed):
         """
         The mouse has moved, respond to mouse dragging or notify elements
         Move a selected element to the new coordinate.
         Auto-scroll the scroll bars at the boundaries.
         """
-        #to perform a movement, the mouse must be pressed
+        # to perform a movement, the mouse must be pressed
         # (no longer checking pending events via Gtk.events_pending() - always 
true in Windows)
-        if not self.mouse_pressed:
-            # only continue if mouse-over stuff is enabled (just the auto-hide 
port label stuff for now)
-            if not Actions.TOGGLE_AUTO_HIDE_PORT_LABELS.get_active(): return
-            redraw = False
-            for element in reversed(self.get_elements()):
-                over_element = element.what_is_selected(coordinate)
-                if not over_element: continue
-                if over_element != self.element_under_mouse:  # over sth new
-                    if self.element_under_mouse:
-                        redraw |= self.element_under_mouse.mouse_out() or False
-                    self.element_under_mouse = over_element
-                    redraw |= over_element.mouse_over() or False
-                break
-            else:
+        if not button1_pressed:
+            self._handle_mouse_motion_move(coordinate)
+        else:
+            self._handle_mouse_motion_drag(coordinate)
+
+    def _handle_mouse_motion_move(self, coordinate):
+        # only continue if mouse-over stuff is enabled (just the auto-hide 
port label stuff for now)
+        if not Actions.TOGGLE_AUTO_HIDE_PORT_LABELS.get_active():
+            return
+        redraw = False
+        for element in reversed(self.get_elements()):
+            over_element = element.what_is_selected(coordinate)
+            if not over_element:
+                continue
+            if over_element != self.element_under_mouse:  # over sth new
                 if self.element_under_mouse:
                     redraw |= self.element_under_mouse.mouse_out() or False
-                    self.element_under_mouse = None
-            if redraw:
-                #self.create_labels()
-                self.create_shapes()
-                self.queue_draw()
+                self.element_under_mouse = over_element
+                redraw |= over_element.mouse_over() or False
+            break
         else:
-            #perform auto-scrolling
-            width, height = self.get_size()
-            x, y = coordinate
-            h_adj = self.get_scroll_pane().get_hadjustment()
-            v_adj = self.get_scroll_pane().get_vadjustment()
-            for pos, length, adj, adj_val, adj_len in (
-                (x, width, h_adj, h_adj.get_value(), h_adj.page_size),
-                (y, height, v_adj, v_adj.get_value(), v_adj.page_size),
-            ):
-                #scroll if we moved near the border
-                if pos-adj_val > adj_len-SCROLL_PROXIMITY_SENSITIVITY and 
adj_val+SCROLL_DISTANCE < length-adj_len:
-                    adj.set_value(adj_val+SCROLL_DISTANCE)
-                    adj.emit('changed')
-                elif pos-adj_val < SCROLL_PROXIMITY_SENSITIVITY:
-                    adj.set_value(adj_val-SCROLL_DISTANCE)
-                    adj.emit('changed')
-            #remove the connection if selected in drag event
-            if len(self.get_selected_elements()) == 1 and 
self.get_selected_element().is_connection:
-                Actions.ELEMENT_DELETE()
-            #move the selected elements and record the new coordinate
-            if not self.get_ctrl_mask():
-                X, Y = self.get_coordinate()
-                dX, dY = int(x - X), int(y - Y)
-                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
+            if self.element_under_mouse:
+                redraw |= self.element_under_mouse.mouse_out() or False
+                self.element_under_mouse = None
+        if redraw:
+            # self.create_labels()
+            self.create_shapes()
             self.queue_draw()
+
+    def _handle_mouse_motion_drag(self, coordinate):
+        # remove the connection if selected in drag event
+        if len(self.get_selected_elements()) == 1 and 
self.get_selected_element().is_connection:
+            Actions.ELEMENT_DELETE()
+
+        # move the selected elements and record the new coordinate
+        x, y = coordinate
+        if not self.get_ctrl_mask():
+            X, Y = self.get_coordinate()
+            dX, dY = int(x - X), int(y - Y)
+            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
+        self.queue_draw()
+
+    def get_max_coords(self, initial=(0, 0)):
+        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)
+        return w, h
diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py
index 751e0d9..126a9af 100644
--- a/grc/gui/MainWindow.py
+++ b/grc/gui/MainWindow.py
@@ -241,14 +241,14 @@ class MainWindow(Gtk.Window):
                 file_path=file_path,
             )
             if file_path: Messages.send_end_load()
-        except Exception, e: #return on failure
+        except Exception as e: #return on failure
             Messages.send_fail_load(e)
             if isinstance(e, KeyError) and str(e) == "'options'":
                 # This error is unrecoverable, so crash gracefully
                 exit(-1)
             return
         #add this page to the notebook
-        self.notebook.append_page(page, page.get_tab())
+        self.notebook.append_page(page, page.tab)
         self.notebook.set_tab_reorderable(page, True)
         #only show if blank or manual
         if not file_path or show: self._set_page(page)
diff --git a/grc/gui/NotebookPage.py b/grc/gui/NotebookPage.py
index 9a76897..e15617a 100644
--- a/grc/gui/NotebookPage.py
+++ b/grc/gui/NotebookPage.py
@@ -17,17 +17,15 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
-import gi
-gi.require_version('Gtk', '3.0')
-from gi.repository import Gtk
-from gi.repository import GObject
-
-import Actions
-from StateCache import StateCache
-from Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT
-from DrawingArea import DrawingArea
 import os
 
+from gi.repository import Gtk, Gdk, GObject
+
+from . import Actions
+from .StateCache import StateCache
+from .Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT
+from .DrawingArea import DrawingArea
+
 
 class NotebookPage(Gtk.HBox):
     """A page in the notebook."""
@@ -40,49 +38,46 @@ class NotebookPage(Gtk.HBox):
             main_window: main window
             file_path: path to a flow graph file
         """
+        Gtk.HBox.__init__(self)
+
+        self.main_window = main_window
         self._flow_graph = flow_graph
         self.process = None
-        #import the file
-        self.main_window = main_window
+
+        # import the file
         self.file_path = file_path
         initial_state = flow_graph.get_parent().parse_flow_graph(file_path)
+        self.get_flow_graph().import_data(initial_state)
         self.state_cache = StateCache(initial_state)
         self.saved = True
-        #import the data to the flow graph
-        self.get_flow_graph().import_data(initial_state)
-        #initialize page gui
-        GObject.GObject.__init__(self)
-        self.show()
-        #tab box to hold label and close button
-        self.tab = Gtk.HBox(homogeneous=False, spacing=0)
-        #setup tab label
+
+        # tab box to hold label and close button
         self.label = Gtk.Label()
-        self.tab.pack_start(self.label, False, False, 0)
-        #setup button image
         image = Gtk.Image()
         image.set_from_stock('gtk-close', Gtk.IconSize.MENU)
-        #setup image box
         image_box = Gtk.HBox(homogeneous=False, spacing=0)
         image_box.pack_start(image, True, False, 0)
-        #setup the button
         button = Gtk.Button()
         button.connect("clicked", self._handle_button)
         button.set_relief(Gtk.ReliefStyle.NONE)
         button.add(image_box)
-        #button size
-        #w, h = Gtk.icon_size_lookup_for_settings(button.get_settings(), 
Gtk.IconSize.MENU)
-        #button.set_size_request(w+6, h+6)
-        self.tab.pack_start(button, False, False, 0)
-        self.tab.show_all()
-        #setup scroll window and drawing area
+
+        tab = self.tab = Gtk.HBox(homogeneous=False, spacing=0)
+        tab.pack_start(self.label, False, False, 0)
+        tab.pack_start(button, False, False, 0)
+        tab.show_all()
+
+        # setup scroll window and drawing area
+        self.drawing_area = DrawingArea(self.get_flow_graph())
+
         self.scrolled_window = Gtk.ScrolledWindow()
         self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, 
MIN_WINDOW_HEIGHT)
-        self.scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, 
Gtk.PolicyType.AUTOMATIC)
+        self.scrolled_window.set_policy(Gtk.PolicyType.ALWAYS, 
Gtk.PolicyType.ALWAYS)
         self.scrolled_window.connect('key-press-event', 
self._handle_scroll_window_key_press)
-        self.drawing_area = DrawingArea(self.get_flow_graph())
         self.scrolled_window.add_with_viewport(self.drawing_area)
         self.pack_start(self.scrolled_window, True, True, 0)
-        #inject drawing area into flow graph
+
+        # inject drawing area into flow graph
         self.get_flow_graph().drawing_area = self.drawing_area
         self.show_all()
 
@@ -125,15 +120,6 @@ class NotebookPage(Gtk.HBox):
         """
         self.label.set_markup(markup)
 
-    def get_tab(self):
-        """
-        Get the gtk widget for this page's tab.
-
-        Returns:
-            gtk widget
-        """
-        return self.tab
-
     def get_proc(self):
         """
         Get the subprocess for the flow graph.
diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py
index ca41abc..d6b6494 100644
--- a/grc/gui/PropsDialog.py
+++ b/grc/gui/PropsDialog.py
@@ -87,7 +87,9 @@ class PropsDialog(Gtk.Dialog):
             self._code_text_display = code_view = SimpleTextDisplay()
             code_view.set_wrap_mode(Gtk.WrapMode.NONE)
             code_view.get_buffer().create_tag('b', weight=Pango.Weight.BOLD)
-            code_view.override_font(Pango.FontDescription('monospace %d' % 
Constants.FONT_SIZE))
+            code_view.set_monospace(True)
+            # todo: set font size in non-deprecated way
+            # code_view.override_font(Pango.FontDescription('monospace %d' % 
Constants.FONT_SIZE))
             code_box = Gtk.ScrolledWindow()
             code_box.set_policy(Gtk.PolicyType.AUTOMATIC, 
Gtk.PolicyType.AUTOMATIC)
             code_box.add_with_viewport(self._code_text_display)
diff --git a/grc/gui/Utils.py b/grc/gui/Utils.py
index e5d69bc..311b37f 100644
--- a/grc/gui/Utils.py
+++ b/grc/gui/Utils.py
@@ -19,36 +19,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA  02110-1301, USA
 
 import gi
 gi.require_version('Gtk', '3.0')
-from gi.repository import Gtk
-from gi.repository import Gdk
-from gi.repository import GdkPixbuf
-from gi.repository import GObject
 from gi.repository import GLib
 
-from Constants import POSSIBLE_ROTATIONS, CANVAS_GRID_SIZE
-
-
-def rotate_pixmap(gc, src_pixmap, dst_pixmap, 
angle=GdkPixbuf.PixbufRotation.COUNTERCLOCKWISE):
-    """
-    Load the destination pixmap with a rotated version of the source pixmap.
-    The source pixmap will be loaded into a pixbuf, rotated, and drawn to the 
destination pixmap.
-    The pixbuf is a client-side drawable, where a pixmap is a server-side 
drawable.
-
-    Args:
-        gc: the graphics context
-        src_pixmap: the source pixmap
-        dst_pixmap: the destination pixmap
-        angle: the angle to rotate by
-    """
-    width, height = src_pixmap.get_size()
-    pixbuf = GdkPixbuf.Pixbuf(
-        colorspace=GdkPixbuf.Colorspace.RGB,
-        has_alpha=False, bits_per_sample=8,
-        width=width, height=height,
-    )
-    pixbuf.get_from_drawable(src_pixmap, src_pixmap.get_colormap(), 0, 0, 0, 
0, -1, -1)
-    pixbuf = pixbuf.rotate_simple(angle)
-    dst_pixmap.draw_pixbuf(gc, pixbuf, 0, 0, 0, 0)
+from .Constants import POSSIBLE_ROTATIONS, CANVAS_GRID_SIZE
 
 
 def get_rotated_coordinate(coor, rotation):
@@ -97,7 +70,6 @@ def encode(value):
     Older versions of glib seg fault if the last byte starts a multi-byte
     character.
     """
-
     valid_utf8 = value.decode('utf-8', errors='replace').encode('utf-8')
     return GLib.markup_escape_text(valid_utf8)
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]