diff options
author | Sebastian Koslowski <koslowski@kit.edu> | 2016-04-18 18:11:52 +0200 |
---|---|---|
committer | Seth Hitefield <sdhitefield@gmail.com> | 2016-05-24 13:02:23 -0400 |
commit | 5352dfd80fd238256da7bbd5efd15c154f3f5a14 (patch) | |
tree | 2221b54d0b7f7b42bd7f6e3fa521a6c9e8ded401 | |
parent | e66cfa31ff52b95a9c3df27c8a1f3b02bef6db3d (diff) |
gtk3: add flowgraph draw code and other gtk3 fixes (WIP)
-rw-r--r-- | grc/core/Platform.py | 7 | ||||
-rw-r--r-- | grc/gui/ActionHandler.py | 9 | ||||
-rw-r--r-- | grc/gui/Actions.py | 21 | ||||
-rw-r--r-- | grc/gui/Bars.py | 4 | ||||
-rw-r--r-- | grc/gui/Block.py | 91 | ||||
-rw-r--r-- | grc/gui/Colors.py | 25 | ||||
-rw-r--r-- | grc/gui/Connection.py | 29 | ||||
-rw-r--r-- | grc/gui/DrawingArea.py | 57 | ||||
-rw-r--r-- | grc/gui/Element.py | 26 | ||||
-rw-r--r-- | grc/gui/FlowGraph.py | 29 | ||||
-rw-r--r-- | grc/gui/MainWindow.py | 28 | ||||
-rw-r--r-- | grc/gui/NotebookPage.py | 16 | ||||
-rw-r--r-- | grc/gui/Port.py | 63 | ||||
-rw-r--r-- | grc/gui/VariableEditor.py | 95 |
14 files changed, 230 insertions, 270 deletions
diff --git a/grc/core/Platform.py b/grc/core/Platform.py index dfb60ee6a5..82d91ddb72 100644 --- a/grc/core/Platform.py +++ b/grc/core/Platform.py @@ -219,10 +219,9 @@ class Platform(Element): color = n.find('color') or '' try: - import gi # ugly but handy - from gi.repository import Gdk - Gdk.color_parse(color) - except (ValueError, ImportError): + chars_per_color = 2 if len(color) > 4 else 1 + tuple(int(color[o:o + 2], 16) / 255.0 for o in range(1, 3 * chars_per_color, chars_per_color)) + except ValueError: if color: # no color is okay, default set in GUI print >> sys.stderr, 'Warning: Can\'t parse color code "{}" for domain "{}" '.format(color, key) color = None diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py index 96f7080c40..e25fa19030 100644 --- a/grc/gui/ActionHandler.py +++ b/grc/gui/ActionHandler.py @@ -84,9 +84,8 @@ class ActionHandler: # prevent key event stealing while the search box is active # .has_focus() only in newer versions 2.17+? # .is_focus() seems to work, but exactly the same - if self.main_window.btwin.search_entry.flags() & Gtk.HAS_FOCUS: + if self.main_window.btwin.search_entry.has_focus(): return False - if not self.get_focus_flag(): return False return Actions.handle_key_press(event) def _quit(self, window, event): @@ -447,9 +446,9 @@ class ActionHandler: action.save_to_preferences() elif action == Actions.TOGGLE_FLOW_GRAPH_VAR_EDITOR_SIDEBAR: if self.init: - md = gtk.MessageDialog(main, - gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, - gtk.BUTTONS_CLOSE, "Moving the variable editor requires a restart of GRC.") + md = Gtk.MessageDialog(main, + Gtk.DIALOG_DESTROY_WITH_PARENT, Gtk.MESSAGE_INFO, + Gtk.BUTTONS_CLOSE, "Moving the variable editor requires a restart of GRC.") md.run() md.destroy() action.save_to_preferences() diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py index b2745c995a..d0e114293f 100644 --- a/grc/gui/Actions.py +++ b/grc/gui/Actions.py @@ -27,6 +27,7 @@ import Preferences NO_MODS_MASK = 0 + ######################################################################## # Actions API ######################################################################## @@ -48,7 +49,7 @@ def handle_key_press(event): """ _used_mods_mask = reduce(lambda x, y: x | y, [mod_mask for keyval, mod_mask in _actions_keypress_dict], NO_MODS_MASK) # extract the key value and the consumed modifiers - keyval, egroup, level, consumed = _keymap.translate_keyboard_state( + _unused, keyval, egroup, level, consumed = _keymap.translate_keyboard_state( event.hardware_keycode, event.get_state(), event.group) # get the modifier mask and ignore irrelevant modifiers mod_mask = event.get_state() & ~consumed & _used_mods_mask @@ -261,32 +262,32 @@ BLOCK_ROTATE_CW = Action( BLOCK_VALIGN_TOP = Action( label='Vertical Align Top', tooltip='Align tops of selected blocks', - keypresses=(gtk.keysyms.t, gtk.gdk.SHIFT_MASK), + keypresses=(Gdk.KEY_t, Gdk.ModifierType.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), + keypresses=(Gdk.KEY_m, Gdk.ModifierType.SHIFT_MASK), ) BLOCK_VALIGN_BOTTOM = Action( label='Vertical Align Bottom', tooltip='Align bottoms of selected blocks', - keypresses=(gtk.keysyms.b, gtk.gdk.SHIFT_MASK), + keypresses=(Gdk.KEY_b, Gdk.ModifierType.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), + keypresses=(Gdk.KEY_l, Gdk.ModifierType.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), + keypresses=(Gdk.KEY_c, Gdk.ModifierType.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), + keypresses=(Gdk.KEY_r, Gdk.ModifierType.SHIFT_MASK), ) BLOCK_ALIGNMENTS = [ BLOCK_VALIGN_TOP, @@ -341,9 +342,9 @@ TOGGLE_HIDE_VARIABLES = ToggleAction( TOGGLE_FLOW_GRAPH_VAR_EDITOR = ToggleAction( label='Show _Variable Editor', tooltip='Show the variable editor. Modify variables and imports in this flow graph', - stock_id=gtk.STOCK_EDIT, + stock_id=Gtk.STOCK_EDIT, default=True, - keypresses=(gtk.keysyms.e, gtk.gdk.CONTROL_MASK), + keypresses=(Gdk.KEY_e, Gdk.ModifierType.CONTROL_MASK), preference_name='variable_editor_visable', ) TOGGLE_FLOW_GRAPH_VAR_EDITOR_SIDEBAR = ToggleAction( @@ -407,7 +408,7 @@ ERRORS_WINDOW_DISPLAY = Action( TOGGLE_CONSOLE_WINDOW = ToggleAction( label='Show _Console Panel', tooltip='Toggle visibility of the console', - keypresses=(Gdk.KEY_c, Gdk.ModifierType.CONTROL_MASK), + keypresses=(Gdk.KEY_r, Gdk.ModifierType.CONTROL_MASK), preference_name='console_window_visible' ) TOGGLE_BLOCKS_WINDOW = ToggleAction( diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py index 2d0709309c..c8631aa298 100644 --- a/grc/gui/Bars.py +++ b/grc/gui/Bars.py @@ -61,6 +61,7 @@ TOOLBAR_LIST = ( Actions.OPEN_HIER, ) + # The list of actions and categories for the menu bar. MENU_BAR_LIST = ( (Gtk.Action(name='File', label='_File'), [ @@ -88,7 +89,7 @@ MENU_BAR_LIST = ( None, Actions.BLOCK_ROTATE_CCW, Actions.BLOCK_ROTATE_CW, - (gtk.Action('Align', '_Align', None, None), Actions.BLOCK_ALIGNMENTS), + (Gtk.Action('Align', '_Align', None, None), Actions.BLOCK_ALIGNMENTS), None, Actions.BLOCK_ENABLE, Actions.BLOCK_DISABLE, @@ -140,6 +141,7 @@ MENU_BAR_LIST = ( ]), ) + # The list of actions for the context menu. CONTEXT_MENU_LIST = [ Actions.BLOCK_CUT, diff --git a/grc/gui/Block.py b/grc/gui/Block.py index 64c9e022b5..d16c9d01c6 100644 --- a/grc/gui/Block.py +++ b/grc/gui/Block.py @@ -17,10 +17,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ +import math import gi gi.require_version('Gtk', '3.0') -from gi.repository import Gtk -from gi.repository import Pango +gi.require_version('PangoCairo', '1.0') +from gi.repository import Gtk, Pango, PangoCairo from . import Actions, Colors, Utils @@ -89,7 +90,9 @@ class Block(Element, _Block): )) Element.__init__(self) self._comment_pixmap = None + self._bg_color = Colors.BLOCK_ENABLED_COLOR self.has_busses = [False, False] # source, sink + self.layouts = [] def get_coordinate(self): """ @@ -196,14 +199,14 @@ class Block(Element, _Block): def create_labels(self): """Create the labels for the signal block.""" Element.create_labels(self) - self._bg_color = self.is_dummy_block and Colors.MISSING_BLOCK_BACKGROUND_COLOR or \ - self.get_bypassed() and Colors.BLOCK_BYPASSED_COLOR or \ - self.get_enabled() and Colors.BLOCK_ENABLED_COLOR or Colors.BLOCK_DISABLED_COLOR - - layouts = list() + self._bg_color = Colors.MISSING_BLOCK_BACKGROUND_COLOR if self.is_dummy_block else \ + Colors.BLOCK_BYPASSED_COLOR if self.get_bypassed() else \ + Colors.BLOCK_ENABLED_COLOR if self.get_enabled() else \ + Colors.BLOCK_DISABLED_COLOR + del self.layouts[:] #create the main layout layout = Gtk.DrawingArea().create_pango_layout('') - layouts.append(layout) + self.layouts.append(layout) layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self, font=BLOCK_FONT)) self.label_width, self.label_height = layout.get_pixel_size() #display the params @@ -217,30 +220,11 @@ class Block(Element, _Block): layout = Gtk.DrawingArea().create_pango_layout('') layout.set_spacing(LABEL_SEPARATION*Pango.SCALE) layout.set_markup('\n'.join(markups)) - layouts.append(layout) + self.layouts.append(layout) w, h = layout.get_pixel_size() self.label_width = max(w, self.label_width) self.label_height += h + LABEL_SEPARATION - width = self.label_width - height = self.label_height - #setup the pixmap - pixmap = self.get_parent().new_pixmap(width, height) - gc = pixmap.new_gc() - gc.set_foreground(self._bg_color) - pixmap.draw_rectangle(gc, True, 0, 0, width, height) - #draw the layouts - h_off = 0 - for i,layout in enumerate(layouts): - w,h = layout.get_pixel_size() - if i == 0: w_off = (width-w)/2 - else: w_off = 0 - pixmap.draw_layout(gc, w_off, h_off, layout) - h_off = h + h_off + LABEL_SEPARATION - #create vertical and horizontal pixmaps - self.horizontal_label = pixmap - if self.is_vertical(): - self.vertical_label = self.get_parent().new_pixmap(height, width) - Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label) + #calculate width and height needed W = self.label_width + 2 * BLOCK_LABEL_PADDING @@ -301,29 +285,50 @@ class Block(Element, _Block): else: self._comment_pixmap = None - def draw(self, gc, window): + def draw(self, widget, cr): """ Draw the signal block with label and inputs/outputs. - - Args: - gc: the graphics context - window: the gtk window to draw on """ # draw ports for port in self.get_ports_gui(): - port.draw(gc, window) + port.draw(widget, cr) # draw main block - x, y = self.get_coordinate() - Element.draw( - self, gc, window, bg_color=self._bg_color, - border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or - self.is_dummy_block and Colors.MISSING_BLOCK_BORDER_COLOR or Colors.BORDER_COLOR, + border_color = ( + Colors.HIGHLIGHT_COLOR if self.is_highlighted() else + Colors.MISSING_BLOCK_BORDER_COLOR if self.is_dummy_block else + Colors.BORDER_COLOR ) - #draw label image + Element.draw(self, widget, cr, border_color, self._bg_color) + x, y = self.get_coordinate() + # create the image surface + width = self.label_width + height = self.label_height + cr.set_source_rgb(*self._bg_color) + cr.save() if self.is_horizontal(): - window.draw_drawable(gc, self.horizontal_label, 0, 0, x+BLOCK_LABEL_PADDING, y+(self.H-self.label_height)/2, -1, -1) + cr.translate(x + BLOCK_LABEL_PADDING, y + (self.H - self.label_height) / 2) elif self.is_vertical(): - window.draw_drawable(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1) + cr.translate(x + (self.H - self.label_height) / 2, y + BLOCK_LABEL_PADDING) + cr.rotate(-90 * math.pi / 180.) + cr.translate(-width, 0) + + # cr.rectangle(0, 0, width, height) + # cr.fill() + + # draw the layouts + h_off = 0 + for i, layout in enumerate(self.layouts): + w, h = layout.get_pixel_size() + if i == 0: + w_off = (width - w) / 2 + else: + w_off = 0 + cr.translate(w_off, h_off) + PangoCairo.update_layout(cr, layout) + PangoCairo.show_layout(cr, layout) + cr.translate(-w_off, -h_off) + h_off = h + h_off + LABEL_SEPARATION + cr.restore() def what_is_selected(self, coor, coor_m=None): """ diff --git a/grc/gui/Colors.py b/grc/gui/Colors.py index 2c5c73017e..686b378c38 100644 --- a/grc/gui/Colors.py +++ b/grc/gui/Colors.py @@ -16,26 +16,30 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ + try: import gi gi.require_version('Gtk', '3.0') - from gi.repository import Gtk from gi.repository import Gdk + # Not gtk3? + #COLORMAP = Gdk.colormap_get_system() #create all of the colors + #def get_color(color_code): return _COLORMAP.alloc_color(color_code, True, True) + def get_color(color_code): - color = Gdk.RGBA() - color.parse(color_code) - return color + chars_per_color = 2 if len(color_code) > 4 else 1 + offsets = range(1, 3 * chars_per_color + 1, chars_per_color) + return tuple(int(color_code[o:o + 2], 16) / 255.0 for o in offsets) HIGHLIGHT_COLOR = get_color('#00FFFF') BORDER_COLOR = get_color('#444444') # Missing blocks stuff MISSING_BLOCK_BACKGROUND_COLOR = get_color('#FFF2F2') - MISSING_BLOCK_BORDER_COLOR = get_color('red') + MISSING_BLOCK_BORDER_COLOR = get_color('#FF0000') # Param entry boxes - PARAM_ENTRY_TEXT_COLOR = get_color('black') + PARAM_ENTRY_TEXT_COLOR = get_color('#000000') ENTRYENUM_CUSTOM_COLOR = get_color('#EEEEEE') # Flow graph color constants @@ -49,12 +53,9 @@ try: BLOCK_BYPASSED_COLOR = get_color('#F4FF81') # Connection color constants - CONNECTION_ENABLED_COLOR = get_color('black') + CONNECTION_ENABLED_COLOR = get_color('#000000') CONNECTION_DISABLED_COLOR = get_color('#BBBBBB') - CONNECTION_ERROR_COLOR = get_color('red') + CONNECTION_ERROR_COLOR = get_color('#FF0000') except Exception as e: - print 'Unable to import Colors' - - -DEFAULT_DOMAIN_COLOR_CODE = '#777777' + print 'Unable to import Colors', e diff --git a/grc/gui/Connection.py b/grc/gui/Connection.py index 356a55d83b..46414c94c8 100644 --- a/grc/gui/Connection.py +++ b/grc/gui/Connection.py @@ -91,10 +91,10 @@ class Connection(Element, _Connection): ] source_domain = self.get_source().get_domain() sink_domain = self.get_sink().get_domain() - self.line_attributes[0] = 2 if source_domain != sink_domain else 0 - self.line_attributes[1] = Gdk.LINE_DOUBLE_DASH \ - if not source_domain == sink_domain == GR_MESSAGE_DOMAIN \ - else Gdk.LINE_ON_OFF_DASH + # self.line_attributes[0] = 2 if source_domain != sink_domain else 0 + # self.line_attributes[1] = Gdk.LINE_DOUBLE_DASH \ + # if not source_domain == sink_domain == GR_MESSAGE_DOMAIN \ + # else Gdk.LINE_ON_OFF_DASH get_domain_color = lambda d: Colors.get_color(( self.get_parent().get_parent().domains.get(d, {}) ).get('color') or Colors.DEFAULT_DOMAIN_COLOR_CODE) @@ -147,13 +147,9 @@ class Connection(Element, _Connection): self.add_line((x1, y1), points[0]) self.add_line((x2, y2), points[0]) - def draw(self, gc, window): + def draw(self, widget, cr): """ Draw the connection. - - Args: - gc: the graphics context - window: the gtk window to draw on """ sink = self.get_sink() source = self.get_source() @@ -175,11 +171,12 @@ class Connection(Element, _Connection): Colors.CONNECTION_DISABLED_COLOR if not self.get_enabled() else color ) - Element.draw(self, gc, window, mod_color(self._color), mod_color(self._bg_color)) + Element.draw(self, widget, cr, mod_color(self._color), mod_color(self._bg_color)) # draw arrow on sink port - try: - gc.set_foreground(mod_color(self._arrow_color)) - gc.set_line_attributes(0, Gdk.LINE_SOLID, Gdk.CAP_BUTT, Gdk.JOIN_MITER) - window.draw_polygon(gc, True, self._arrow) - except: - pass + cr.set_source_rgb(*self._arrow_color) + # TODO: gc.set_line_attributes(0, Gdk.LINE_SOLID, Gdk.CAP_BUTT, Gdk.JOIN_MITER) + cr.move_to(*self._arrow[0]) + cr.line_to(*self._arrow[1]) + cr.line_to(*self._arrow[2]) + cr.close_path() + cr.fill() diff --git a/grc/gui/DrawingArea.py b/grc/gui/DrawingArea.py index f91fb2a3de..2bce21fa6d 100644 --- a/grc/gui/DrawingArea.py +++ b/grc/gui/DrawingArea.py @@ -48,8 +48,7 @@ class DrawingArea(Gtk.DrawingArea): GObject.GObject.__init__(self) self.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT) self.connect('realize', self._handle_window_realize) - self.connect('configure-event', self._handle_window_configure) - self.connect('expose-event', self._handle_window_expose) + self.connect('draw', self.draw) self.connect('motion-notify-event', self._handle_mouse_motion) self.connect('button-press-event', self._handle_mouse_button_press) self.connect('button-release-event', self._handle_mouse_button_release) @@ -59,35 +58,22 @@ class DrawingArea(Gtk.DrawingArea): Gdk.EventMask.POINTER_MOTION_MASK | \ Gdk.EventMask.BUTTON_RELEASE_MASK | \ Gdk.EventMask.LEAVE_NOTIFY_MASK | \ - Gdk.EventMask.ENTER_NOTIFY_MASK | \ - Gdk.EventMask.FOCUS_CHANGE_MASK + Gdk.EventMask.ENTER_NOTIFY_MASK #| \ + #Gdk.EventMask.FOCUS_CHANGE_MASK ) #setup drag and drop - self.drag_dest_set(Gtk.DestDefaults.ALL, DND_TARGETS, Gdk.DragAction.COPY) + 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 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) - self.set_flags(Gtk.CAN_FOCUS) # self.set_can_focus(True) - self.connect('focus-out-event', self._handle_focus_lost_event) - - def new_pixmap(self, width, height): - return Gdk.Pixmap(self.window, width, height, -1) - - def get_screenshot(self, transparent_bg=False): - pixmap = self._pixmap - W, H = pixmap.get_size() - pixbuf = GdkPixbuf.Pixbuf(GdkPixbuf.Colorspace.RGB, 0, 8, W, H) - pixbuf.fill(0xFF + Colors.FLOWGRAPH_BACKGROUND_COLOR.pixel << 8) - pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, W-1, H-1) - if transparent_bg: - bgc = Colors.FLOWGRAPH_BACKGROUND_COLOR - pixbuf = pixbuf.add_alpha(True, bgc.red, bgc.green, bgc.blue) - return pixbuf - +# self.set_flags(Gtk.CAN_FOCUS) # self.set_can_focus(True) +# self.connect('focus-out-event', self._handle_focus_lost_event) ########################################################################## ## Handlers @@ -96,7 +82,7 @@ class DrawingArea(Gtk.DrawingArea): """ Handle a drag and drop by adding a block at the given coordinate. """ - self._flow_graph.add_new_block(selection_data.data, (x, y)) + self._flow_graph.add_new_block(selection_data.get_text(), (x, y)) def _handle_mouse_scroll(self, widget, event): if event.get_state() & Gdk.ModifierType.SHIFT_MASK: @@ -113,7 +99,7 @@ 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_press( - double_click=(event.type == Gdk._2BUTTON_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( @@ -148,27 +134,8 @@ class DrawingArea(Gtk.DrawingArea): """ self._flow_graph.update() - def _handle_window_configure(self, widget, event): - """ - Called when the window is resized. - Create a new pixmap for background buffer. - """ - self._pixmap = self.new_pixmap(*self.get_size_request()) - - def _handle_window_expose(self, widget, event): - """ - Called when window is exposed, or queue_draw is called. - Double buffering: draw to pixmap, then draw pixmap to window. - """ - gc = self.window.new_gc() - self._flow_graph.draw(gc, self._pixmap) - self.window.draw_drawable(gc, self._pixmap, 0, 0, 0, 0, -1, -1) - # draw a light grey line on the bottom and right end of the canvas. - # this is useful when the theme uses the same panel bg color as the canvas - W, H = self._pixmap.get_size() - gc.set_foreground(Colors.FLOWGRAPH_EDGE_COLOR) - self.window.draw_line(gc, 0, H-1, W, H-1) - self.window.draw_line(gc, W-1, 0, W-1, H) + def draw(self, widget, cr): + self._flow_graph.draw(widget, cr) def _handle_focus_lost_event(self, widget, event): # don't clear selection while context menu is active diff --git a/grc/gui/Element.py b/grc/gui/Element.py index 3f6017def7..30c0f5dba7 100644 --- a/grc/gui/Element.py +++ b/grc/gui/Element.py @@ -90,29 +90,33 @@ class Element(object): self.clear() for child in self.get_children(): child.create_shapes() - def draw(self, gc, window, border_color, bg_color): + def draw(self, widget, cr, border_color, bg_color): """ Draw in the given window. Args: - gc: the graphics context - window: the gtk window to draw on + widget: + cr: border_color: the color for lines and rectangle borders bg_color: the color for the inside of the rectangle """ X, Y = self.get_coordinate() - gc.set_line_attributes(*self.line_attributes) + # TODO: gc.set_line_attributes(*self.line_attributes) for (rX, rY), (W, H) in self._areas_list: aX = X + rX aY = Y + rY - gc.set_foreground(bg_color) - window.draw_rectangle(gc, True, aX, aY, W, H) - gc.set_foreground(border_color) - window.draw_rectangle(gc, False, aX, aY, W, H) + cr.set_source_rgb(*bg_color) + cr.rectangle(aX, aY, W, H) + cr.fill() + cr.set_source_rgb(*border_color) + cr.rectangle(aX, aY, W, H) + cr.stroke() + for (x1, y1), (x2, y2) in self._lines_list: - gc.set_foreground(border_color) - gc.set_background(bg_color) - window.draw_line(gc, X+x1, Y+y1, X+x2, Y+y2) + cr.set_source_rgb(*border_color) + cr.move_to(X + x1, Y + y1) + cr.line_to(X + x2, Y + y2) + cr.stroke() def rotate(self, rotation): """ diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py index f7af93fe8e..c3ea6770c1 100644 --- a/grc/gui/FlowGraph.py +++ b/grc/gui/FlowGraph.py @@ -397,23 +397,21 @@ class FlowGraph(Element, _Flowgraph): changed = True return changed - def draw(self, gc, window): + def draw(self, widget, cr): """ Draw the background and grid if enabled. - Draw all of the elements in this flow graph onto the pixmap. - Draw the pixmap to the drawable window of this flow graph. """ - W,H = self.get_size() - #draw the background - gc.set_foreground(Colors.FLOWGRAPH_BACKGROUND_COLOR) - window.draw_rectangle(gc, True, 0, 0, W, H) + 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(gc, window) + # block.draw_comment(widget, cr) + pass #draw multi select rectangle if self.mouse_pressed and (not self.get_selected_elements() or self.get_ctrl_mask()): #coordinates @@ -423,10 +421,13 @@ class FlowGraph(Element, _Flowgraph): x, y = int(min(x1, x2)), int(min(y1, y2)) w, h = int(abs(x1 - x2)), int(abs(y1 - y2)) #draw - gc.set_foreground(Colors.HIGHLIGHT_COLOR) - window.draw_rectangle(gc, True, x, y, w, h) - gc.set_foreground(Colors.BORDER_COLOR) - window.draw_rectangle(gc, False, x, y, w, h) + cr.set_source_rgb(*Colors.HIGHLIGHT_COLOR) + cr.rectangle(x, y, w, h) + cr.fill() + cr.set_source_rgb(*Colors.BORDER_COLOR) + cr.rectangle(x, y, w, h) + cr.stroke() + #draw blocks on top of connections hide_disabled_blocks = Actions.TOGGLE_HIDE_DISABLED_BLOCKS.get_active() hide_variables = Actions.TOGGLE_HIDE_VARIABLES.get_active() @@ -437,10 +438,10 @@ class FlowGraph(Element, _Flowgraph): continue # skip hidden disabled blocks and connections if hide_variables and (element.is_variable or element.is_import): continue # skip hidden disabled blocks and connections - element.draw(gc, window) + element.draw(widget, cr) #draw selected blocks on top of selected connections for selected_element in self.get_selected_connections() + self.get_selected_blocks(): - selected_element.draw(gc, window) + selected_element.draw(widget, cr) def update_selected(self): """ diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py index 649b8b29c5..95a5c89867 100644 --- a/grc/gui/MainWindow.py +++ b/grc/gui/MainWindow.py @@ -36,6 +36,7 @@ from .NotebookPage import NotebookPage from ..core import Messages + MAIN_WINDOW_TITLE_TMPL = """\ #if not $saved *#slurp @@ -104,8 +105,8 @@ class MainWindow(Gtk.Window): vbox.pack_start(self.tool_bar, False, False, 0) # Main parent container for the different panels - self.container = Gtk.HPaned() - vbox.pack_start(self.container) + self.main = Gtk.HPaned() #(orientation=Gtk.Orientation.HORIZONTAL) + vbox.pack_start(self.main, True, True, 0) # Create the notebook self.notebook = Gtk.Notebook() @@ -127,9 +128,9 @@ class MainWindow(Gtk.Window): self.vars = VariableEditor(platform, self.get_flow_graph) # Figure out which place to put the variable editor - self.left = Gtk.VPaned() - self.right = Gtk.VPaned() - self.left_subpanel = Gtk.HPaned() + self.left = Gtk.VPaned() #orientation=Gtk.Orientation.VERTICAL) + self.right = Gtk.VPaned() #orientation=Gtk.Orientation.VERTICAL) + self.left_subpanel = Gtk.HPaned() #orientation=Gtk.Orientation.HORIZONTAL) self.variable_panel_sidebar = Preferences.variable_editor_sidebar() if self.variable_panel_sidebar: @@ -147,12 +148,12 @@ class MainWindow(Gtk.Window): # Create the right panel self.right.pack1(self.btwin) - self.container.pack1(self.left) - self.container.pack2(self.right, False) + self.main.pack1(self.left) + self.main.pack2(self.right, False) # Load preferences and show the main window self.resize(*Preferences.main_window_size()) - self.container.set_position(Preferences.blocks_window_position()) + self.main.set_position(Preferences.blocks_window_position()) self.left.set_position(Preferences.console_window_position()) if self.variable_panel_sidebar: self.right.set_position(Preferences.variable_editor_position(sidebar=True)) @@ -276,9 +277,7 @@ class MainWindow(Gtk.Window): return #add this page to the notebook self.notebook.append_page(page, page.get_tab()) - try: self.notebook.set_tab_reorderable(page, True) - except: pass #gtk too old - self.notebook.set_tab_label_packing(page, False, False, Gtk.PACK_START) + self.notebook.set_tab_reorderable(page, True) #only show if blank or manual if not file_path or show: self._set_page(page) @@ -303,7 +302,7 @@ class MainWindow(Gtk.Window): Preferences.file_open(open_file) Preferences.main_window_size(self.get_size()) Preferences.console_window_position(self.left.get_position()) - Preferences.blocks_window_position(self.container.get_position()) + Preferences.blocks_window_position(self.main.get_position()) if self.variable_panel_sidebar: Preferences.variable_editor_position(self.right.get_position(), sidebar=True) else: @@ -405,14 +404,11 @@ class MainWindow(Gtk.Window): Returns: the selected flow graph """ - return None - # TODO: Issues with flowgraphs - #return self.get_page().get_flow_graph() + return self.get_page().get_flow_graph() def get_focus_flag(self): """ Get the focus flag from the current page. - Returns: the focus flag """ diff --git a/grc/gui/NotebookPage.py b/grc/gui/NotebookPage.py index 3f49cd0223..9a76897fe6 100644 --- a/grc/gui/NotebookPage.py +++ b/grc/gui/NotebookPage.py @@ -54,7 +54,7 @@ class NotebookPage(Gtk.HBox): GObject.GObject.__init__(self) self.show() #tab box to hold label and close button - self.tab = Gtk.HBox(False, 0) + self.tab = Gtk.HBox(homogeneous=False, spacing=0) #setup tab label self.label = Gtk.Label() self.tab.pack_start(self.label, False, False, 0) @@ -62,7 +62,7 @@ class NotebookPage(Gtk.HBox): image = Gtk.Image() image.set_from_stock('gtk-close', Gtk.IconSize.MENU) #setup image box - image_box = Gtk.HBox(False, 0) + image_box = Gtk.HBox(homogeneous=False, spacing=0) image_box.pack_start(image, True, False, 0) #setup the button button = Gtk.Button() @@ -79,20 +79,18 @@ class NotebookPage(Gtk.HBox): 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.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.get_drawing_area()) + 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 - #self.get_flow_graph().drawing_area = self.get_drawing_area() + self.get_flow_graph().drawing_area = self.drawing_area self.show_all() - def get_drawing_area(self): return self.drawing_area - def _handle_scroll_window_key_press(self, widget, event): """forward Ctrl-PgUp/Down to NotebookPage (switch fg instead of horiz. scroll""" is_ctrl_pg = ( - event.state & gtk.gdk.CONTROL_MASK and - event.keyval in (gtk.keysyms.Page_Up, gtk.keysyms.Page_Down) + event.state & Gdk.ModifierType.CONTROL_MASK and + event.keyval in (Gdk.KEY_Page_Up, Gdk.KEY_Page_Down) ) if is_ctrl_pg: return self.get_parent().event(event) diff --git a/grc/gui/Port.py b/grc/gui/Port.py index 02cef5d04b..eb15f6c788 100644 --- a/grc/gui/Port.py +++ b/grc/gui/Port.py @@ -17,9 +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 math import gi gi.require_version('Gtk', '3.0') -from gi.repository import Gtk +from gi.repository import Gtk, PangoCairo from . import Actions, Colors, Utils from .Constants import ( @@ -45,15 +46,19 @@ class Port(_Port, Element): """ _Port.__init__(self, block, n, dir) Element.__init__(self) - self.W = self.H = self.w = self.h = 0 + self.W = self.w = self.h = 0 + self.H = 20 # todo: fix self._connector_coordinate = (0, 0) self._connector_length = 0 self._hovering = True self._force_label_unhidden = False + self.layout = Gtk.DrawingArea().create_pango_layout('') + self._bg_color = Colors.get_color(self.get_color()) def create_shapes(self): """Create new areas and labels for the port.""" Element.create_shapes(self) + self._bg_color = Colors.get_color(self.get_color()) if self.get_hide(): return # this port is hidden, no need to create shapes if self.get_domain() == GR_MESSAGE_DOMAIN: @@ -112,50 +117,34 @@ class Port(_Port, Element): def create_labels(self): """Create the labels for the socket.""" - Element.create_labels(self) - self._bg_color = Colors.get_color(self.get_color()) - # create the layout - layout = Gtk.DrawingArea().create_pango_layout('') - layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self, font=PORT_FONT)) - self.w, self.h = layout.get_pixel_size() - self.W = 2 * PORT_LABEL_PADDING + self.w - self.H = 2 * PORT_LABEL_PADDING + self.h * ( - 3 if self.get_type() == 'bus' else 1) - self.H += self.H % 2 - # create the pixmap - pixmap = self.get_parent().get_parent().new_pixmap(self.w, self.h) - gc = pixmap.new_gc() - gc.set_foreground(self._bg_color) - pixmap.draw_rectangle(gc, True, 0, 0, self.w, self.h) - pixmap.draw_layout(gc, 0, 0, layout) - # create vertical and horizontal pixmaps - self.horizontal_label = pixmap - if self.is_vertical(): - self.vertical_label = self.get_parent().get_parent().new_pixmap(self.h, self.w) - Utils.rotate_pixmap(gc, self.horizontal_label, self.vertical_label) - - def draw(self, gc, window): + self.layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self, font=PORT_FONT)) + + def draw(self, widget, cr): """ Draw the socket with a label. - - Args: - gc: the graphics context - window: the gtk window to draw on """ - Element.draw( - self, gc, window, bg_color=self._bg_color, - border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or - self.get_parent().is_dummy_block and Colors.MISSING_BLOCK_BORDER_COLOR or - Colors.BORDER_COLOR, + border_color = ( + Colors.HIGHLIGHT_COLOR if self.is_highlighted() else + Colors.MISSING_BLOCK_BORDER_COLOR if self.get_parent().is_dummy_block else + Colors.BORDER_COLOR ) + Element.draw(self, widget, cr, border_color, self._bg_color) + if not self._areas_list or self._label_hidden(): return # this port is either hidden (no areas) or folded (no label) X, Y = self.get_coordinate() - (x, y), (w, h) = self._areas_list[0] # use the first area's sizes to place the labels + (x, y), _ = self._areas_list[0] + cr.set_source_rgb(*self._bg_color) + cr.save() if self.is_horizontal(): - window.draw_drawable(gc, self.horizontal_label, 0, 0, x+X+(self.W-self.w)/2, y+Y+(self.H-self.h)/2, -1, -1) + cr.translate(x + X + (self.W - self.w) / 2, y + Y + (self.H - self.h) / 2) elif self.is_vertical(): - window.draw_drawable(gc, self.vertical_label, 0, 0, x+X+(self.H-self.h)/2, y+Y+(self.W-self.w)/2, -1, -1) + cr.translate(x + X + (self.H - self.h) / 2, y + Y + (self.W - self.w) / 2) + cr.rotate(-90 * math.pi / 180.) + cr.translate(-self.w, 0) + PangoCairo.update_layout(cr, self.layout) + PangoCairo.show_layout(cr, self.layout) + cr.restore() def get_connector_coordinate(self): """ diff --git a/grc/gui/VariableEditor.py b/grc/gui/VariableEditor.py index 7721f3bda6..8729762928 100644 --- a/grc/gui/VariableEditor.py +++ b/grc/gui/VariableEditor.py @@ -1,5 +1,5 @@ """ -Copyright 2015 Free Software Foundation, Inc. +Copyright 2015, 2016 Free Software Foundation, Inc. This file is part of GNU Radio GNU Radio Companion is free software; you can redistribute it and/or @@ -19,10 +19,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA from operator import attrgetter -import pygtk -pygtk.require('2.0') -import gtk -import gobject +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject from . import Actions from . import Preferences @@ -32,34 +33,34 @@ BLOCK_INDEX = 0 ID_INDEX = 1 -class VariableEditorContextMenu(gtk.Menu): +class VariableEditorContextMenu(Gtk.Menu): """ A simple context menu for our variable editor """ def __init__(self, var_edit): - gtk.Menu.__init__(self) + Gtk.Menu.__init__(self) - self.imports = gtk.MenuItem("Add _Import") + self.imports = Gtk.MenuItem("Add _Import") self.imports.connect('activate', var_edit.handle_action, var_edit.ADD_IMPORT) self.add(self.imports) - self.variables = gtk.MenuItem("Add _Variable") + self.variables = Gtk.MenuItem("Add _Variable") self.variables.connect('activate', var_edit.handle_action, var_edit.ADD_VARIABLE) self.add(self.variables) - self.add(gtk.SeparatorMenuItem()) + self.add(Gtk.SeparatorMenuItem()) - self.enable = gtk.MenuItem("_Enable") + self.enable = Gtk.MenuItem("_Enable") self.enable.connect('activate', var_edit.handle_action, var_edit.ENABLE_BLOCK) - self.disable = gtk.MenuItem("_Disable") + self.disable = Gtk.MenuItem("_Disable") self.disable.connect('activate', var_edit.handle_action, var_edit.DISABLE_BLOCK) self.add(self.enable) self.add(self.disable) - self.add(gtk.SeparatorMenuItem()) + self.add(Gtk.SeparatorMenuItem()) - self.delete = gtk.MenuItem("_Delete") + self.delete = Gtk.MenuItem("_Delete") self.delete.connect('activate', var_edit.handle_action, var_edit.DELETE_BLOCK) self.add(self.delete) - self.add(gtk.SeparatorMenuItem()) + self.add(Gtk.SeparatorMenuItem()) - self.properties = gtk.MenuItem("_Properties...") + self.properties = Gtk.MenuItem("_Properties...") self.properties.connect('activate', var_edit.handle_action, var_edit.OPEN_PROPERTIES) self.add(self.properties) self.show_all() @@ -71,7 +72,7 @@ class VariableEditorContextMenu(gtk.Menu): self.disable.set_sensitive(selected and enabled) -class VariableEditor(gtk.VBox): +class VariableEditor(Gtk.VBox): # Actions that are handled by the editor ADD_IMPORT = 0 @@ -83,7 +84,7 @@ class VariableEditor(gtk.VBox): DISABLE_BLOCK = 6 def __init__(self, platform, get_flow_graph): - gtk.VBox.__init__(self) + Gtk.VBox.__init__(self) self.platform = platform self.get_flow_graph = get_flow_graph self._block = None @@ -91,14 +92,14 @@ class VariableEditor(gtk.VBox): # Only use the model to store the block reference and name. # Generate everything else dynamically - self.treestore = gtk.TreeStore(gobject.TYPE_PYOBJECT, # Block reference - gobject.TYPE_STRING) # Category and block name - self.treeview = gtk.TreeView(self.treestore) + self.treestore = Gtk.TreeStore(GObject.TYPE_PYOBJECT, # Block reference + GObject.TYPE_STRING) # Category and block name + self.treeview = Gtk.TreeView(self.treestore) self.treeview.set_enable_search(False) self.treeview.set_search_column(-1) #self.treeview.set_enable_search(True) #self.treeview.set_search_column(ID_INDEX) - self.treeview.get_selection().set_mode('single') + self.treeview.get_selection().set_mode(Gtk.SelectionMode.SINGLE) self.treeview.set_headers_visible(True) self.treeview.connect('button-press-event', self._handle_mouse_button_press) self.treeview.connect('button-release-event', self._handle_mouse_button_release) @@ -106,67 +107,67 @@ class VariableEditor(gtk.VBox): self.treeview.connect('key-press-event', self._handle_key_button_press) # Block Name or Category - self.id_cell = gtk.CellRendererText() + self.id_cell = Gtk.CellRendererText() self.id_cell.connect('edited', self._handle_name_edited_cb) - id_column = gtk.TreeViewColumn("Id", self.id_cell, text=ID_INDEX) + id_column = Gtk.TreeViewColumn("Id", self.id_cell, text=ID_INDEX) id_column.set_name("id") id_column.set_resizable(True) id_column.set_max_width(300) id_column.set_min_width(80) id_column.set_fixed_width(100) - id_column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + id_column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) id_column.set_cell_data_func(self.id_cell, self.set_properties) self.id_column = id_column self.treeview.append_column(id_column) - self.treestore.set_sort_column_id(ID_INDEX, gtk.SORT_ASCENDING) + self.treestore.set_sort_column_id(ID_INDEX, Gtk.SortType.ASCENDING) # For forcing resize self._col_width = 0 # Block Value - self.value_cell = gtk.CellRendererText() + self.value_cell = Gtk.CellRendererText() self.value_cell.connect('edited', self._handle_value_edited_cb) - value_column = gtk.TreeViewColumn("Value", self.value_cell) + value_column = Gtk.TreeViewColumn("Value", self.value_cell) value_column.set_name("value") value_column.set_resizable(False) value_column.set_expand(True) value_column.set_min_width(100) - value_column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) + value_column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) value_column.set_cell_data_func(self.value_cell, self.set_value) self.value_column = value_column self.treeview.append_column(value_column) # Block Actions (Add, Remove) - self.action_cell = gtk.CellRendererPixbuf() + self.action_cell = Gtk.CellRendererPixbuf() value_column.pack_start(self.action_cell, False) value_column.set_cell_data_func(self.action_cell, self.set_icon) # Make the scrolled window to hold the tree view - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolled_window = Gtk.ScrolledWindow() + scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolled_window.add_with_viewport(self.treeview) scrolled_window.set_size_request(DEFAULT_BLOCKS_WINDOW_WIDTH, -1) - self.pack_start(scrolled_window) + self.pack_start(scrolled_window, True, True, 0) # Context menus self._context_menu = VariableEditorContextMenu(self) self._confirm_delete = Preferences.variable_editor_confirm_delete() # Sets cell contents - def set_icon(self, col, cell, model, iter): + def set_icon(self, col, cell, model, iter, data): block = model.get_value(iter, BLOCK_INDEX) if block: - pb = self.treeview.render_icon(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU, None) + pb = self.treeview.render_icon(Gtk.STOCK_CLOSE, 16, None) else: - pb = self.treeview.render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_MENU, None) + pb = self.treeview.render_icon(Gtk.STOCK_ADD, 16, None) cell.set_property('pixbuf', pb) - def set_value(self, col, cell, model, iter): + def set_value(self, col, cell, model, iter, data): sp = cell.set_property block = model.get_value(iter, BLOCK_INDEX) # Set the default properties for this column first. # Some set in set_properties() may be overridden (editable for advanced variable blocks) - self.set_properties(col, cell, model, iter) + self.set_properties(col, cell, model, iter, data) # Set defaults value = None @@ -198,7 +199,7 @@ class VariableEditor(gtk.VBox): # Always set the text value. sp('text', value) - def set_properties(self, col, cell, model, iter): + def set_properties(self, col, cell, model, iter, data): sp = cell.set_property block = model.get_value(iter, BLOCK_INDEX) # Set defaults @@ -268,13 +269,13 @@ class VariableEditor(gtk.VBox): elif key == self.DELETE_CONFIRM: if self._confirm_delete: # Create a context menu to confirm the delete operation - confirmation_menu = gtk.Menu() + confirmation_menu = Gtk.Menu() block_id = self._block.get_param('id').get_value().replace("_", "__") - confirm = gtk.MenuItem("Delete {}".format(block_id)) + confirm = Gtk.MenuItem("Delete {}".format(block_id)) confirm.connect('activate', self.handle_action, self.DELETE_BLOCK) confirmation_menu.add(confirm) confirmation_menu.show_all() - confirmation_menu.popup(None, None, None, event.button, event.time) + confirmation_menu.popup(None, None, None, None, event.button, event.time) else: self.handle_action(None, self.DELETE_BLOCK, None) elif key == self.ENABLE_BLOCK: @@ -302,12 +303,12 @@ class VariableEditor(gtk.VBox): if event.button == 1 and col.get_name() == "value": # Make sure this has a block (not the import/variable rows) - if self._block and event.type == gtk.gdk._2BUTTON_PRESS: + if self._block and event.type == Gdk.EventType._2BUTTON_PRESS: # Open the advanced dialog if it is a gui variable if self._block.get_key() not in ("variable", "import"): self.handle_action(None, self.OPEN_PROPERTIES, event=event) return True - if event.type == gtk.gdk.BUTTON_PRESS: + if event.type == Gdk.EventType.BUTTON_PRESS: # User is adding/removing blocks # Make sure this is the action cell (Add/Remove Icons) if path[2] > col.cell_get_position(self.action_cell)[0]: @@ -320,15 +321,15 @@ class VariableEditor(gtk.VBox): else: self.handle_action(None, self.DELETE_CONFIRM, event=event) return True - elif event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + elif event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS: if self._block: self._context_menu.update_sensitive(True, enabled=self._block.get_enabled()) else: self._context_menu.update_sensitive(False) - self._context_menu.popup(None, None, None, event.button, event.time) + self._context_menu.popup(None, None, None, None, event.button, event.time) # Null handler. Stops the treeview from handling double click events. - if event.type == gtk.gdk._2BUTTON_PRESS: + if event.type == Gdk.EventType._2BUTTON_PRESS: return True return False |