Skip to content

Commit c4d9c79

Browse files
committed
wip menu refactor
1 parent 8d9a81f commit c4d9c79

File tree

6 files changed

+106
-64
lines changed

6 files changed

+106
-64
lines changed

NodeGraphQt/base/graph.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,21 +348,47 @@ def end_undo(self):
348348

349349
def context_menu(self):
350350
"""
351-
Returns the node graph root context menu object.
351+
Returns the main context menu from the node graph.
352352
353353
Returns:
354354
Menu: context menu object.
355355
"""
356-
return Menu(self._viewer, self._viewer.context_menu())
356+
return Menu(self._viewer, self._viewer.context_menus()['Main'])
357357

358-
def disable_context_menu(self, disabled=True):
358+
def get_context_menu(self, name='Main'):
359359
"""
360-
Disable/Enable node graph context menu.
360+
Returns the context menu specified by the name.
361+
362+
Menu types:
363+
"Main" - context menu from the node graph.
364+
"Node" - context menu from a Node.
365+
"Port" - context menu from a Port.
366+
367+
Args:
368+
name (str): menu name.
369+
370+
Returns:
371+
Menu: context menu object.
372+
"""
373+
menus = self._viewer.context_menus()
374+
if name not in menus:
375+
return
376+
return Menu(self._viewer, menus['Main'])
377+
378+
def disable_context_menu(self, disabled=True, name='Main'):
379+
"""
380+
Disable/Enable the main context menu from the node graph.
381+
382+
Menu types:
383+
"Main" - context menu from the node graph.
384+
"Node" - context menu from a Node.
385+
"Port" - context menu from a Port.
361386
362387
Args:
363388
disabled (bool): true to enable context menu.
389+
name (str): menu name. (default: Main)
364390
"""
365-
menu = self._viewer.context_menu()
391+
menu = self._viewer.context_menus()[name]
366392
menu.setDisabled(disabled)
367393
menu.setVisible(not disabled)
368394

NodeGraphQt/base/menu.py

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from distutils.version import LooseVersion
33

44
from NodeGraphQt import QtGui, QtCore, QtWidgets
5+
from NodeGraphQt.errors import NodeMenuError
56
from NodeGraphQt.widgets.stylesheet import STYLE_QMENU
67

78

@@ -31,6 +32,15 @@ def name(self):
3132
"""
3233
return self.qmenu.title()
3334

35+
def set_name(self, name):
36+
"""
37+
Set the name for the menu.
38+
39+
Args:
40+
name (str): label name.
41+
"""
42+
self.qmenu.setTitle(name)
43+
3444
def get_menu(self, name):
3545
"""
3646
Returns the child menu by name.
@@ -45,7 +55,7 @@ def get_menu(self, name):
4555
if action.menu() and action.menu().title() == name:
4656
return Menu(self.__viewer, action.menu())
4757

48-
def get_command(self, name):
58+
def get_action(self, name):
4959
"""
5060
Returns the child menu command by name.
5161
@@ -57,7 +67,7 @@ def get_command(self, name):
5767
"""
5868
for action in self.qmenu.actions():
5969
if not action.menu() and action.text() == name:
60-
return MenuCommand(self.__viewer, action)
70+
return MenuAction(self.__viewer, action)
6171

6272
def all_commands(self):
6373
"""
@@ -78,66 +88,68 @@ def get_actions(menu):
7888
child_actions = get_actions(self.qmenu)
7989
return [MenuCommand(self.__viewer, a) for a in child_actions]
8090

81-
def add_menu(self, name):
91+
def create_menu(self, name):
8292
"""
83-
Adds a child menu to the current menu.
93+
Create a child menu to the current menu.
8494
8595
Args:
8696
name (str): menu name.
8797
8898
Returns:
8999
NodeGraphQt.Menu: the appended menu item.
90100
"""
91-
menu = QtWidgets.QMenu(name, self.qmenu)
92-
menu.setStyleSheet(STYLE_QMENU)
101+
menu = QtWidgets.QMenu(name, self.__viewer)
93102
self.qmenu.addMenu(menu)
94103
return Menu(self.__viewer, menu)
95104

96-
def add_command(self, name, func=None, shortcut=None):
105+
def create_action(self, name):
97106
"""
98-
Adds a command to the menu.
107+
Create a command to the menu.
99108
100109
Args:
101-
name (str): command name.
102-
func (function): command function.
103-
shortcut (str): function shotcut key.
110+
name (NodeGraphQt.MenuCommand): menu command.
111+
104112
105-
Returns:
106-
NodeGraphQt.MenuCommand: the appended command.
107113
"""
108114
action = QtWidgets.QAction(name, self.__viewer)
109-
if LooseVersion(QtCore.qVersion()) >= LooseVersion('5.10'):
110-
action.setShortcutVisibleInContextMenu(True)
111-
if shortcut:
112-
action.setShortcut(shortcut)
113-
if func:
114-
action.triggered.connect(func)
115115
qaction = self.qmenu.addAction(action)
116-
return MenuCommand(self.__viewer, qaction)
116+
return MenuAction(self.__viewer, qaction)
117117

118-
def add_separator(self):
118+
def create_separator(self):
119119
"""
120-
Adds a separator to the menu.
120+
Create a separator to the menu.
121121
"""
122122
self.qmenu.addSeparator()
123123

124124

125-
class MenuCommand(object):
125+
class MenuAction(QtWidgets.QAction):
126126
"""
127127
base class for a menu command.
128128
"""
129129

130-
def __init__(self, viewer, qaction):
130+
#: signal emits when the action has triggered in the node graph.
131+
executed = QtCore.QSignal(object)
132+
133+
def __init__(self, parent=None, viewer=None, name=''):
134+
super(MenuAction, self).__init__(parent)
131135
self.__viewer = viewer
132-
self.__qaction = qaction
136+
if LooseVersion(QtCore.qVersion()) >= LooseVersion('5.10'):
137+
self.setShortcutVisibleInContextMenu(True)
138+
self.setText(name)
139+
self.triggered.connect(self._on_triggered)
133140

134141
def __repr__(self):
135142
cls_name = self.__class__.__name__
136143
return 'NodeGraphQt.{}(\'{}\')'.format(cls_name, self.name())
137144

138-
@property
139-
def qaction(self):
140-
return self.__qaction
145+
def _on_triggered(self):
146+
menu = self.menu()
147+
pos = self.mapToScene(menu.pos())
148+
149+
items = self.__viewer._items_near(pos)
150+
151+
152+
self.triggered.emit()
141153

142154
def name(self):
143155
"""
@@ -146,7 +158,16 @@ def name(self):
146158
Returns:
147159
str: label name.
148160
"""
149-
return self.qaction.text()
161+
return self.text()
162+
163+
def set_name(self, name):
164+
"""
165+
Set the name for the menu command.
166+
167+
Args:
168+
name (str): label name.
169+
"""
170+
self.setText(name)
150171

151172
def set_shortcut(self, shortcut=None):
152173
"""
@@ -157,9 +178,3 @@ def set_shortcut(self, shortcut=None):
157178
"""
158179
shortcut = shortcut or QtGui.QKeySequence()
159180
self.qaction.setShortcut(shortcut)
160-
161-
def run_command(self):
162-
"""
163-
execute the menu command.
164-
"""
165-
self.qaction.trigger()

NodeGraphQt/errors.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,6 @@
11
#!/usr/bin/python
22
# -*- coding: utf-8 -*-
3-
4-
5-
class NodePropertyError(Exception):
6-
pass
7-
8-
9-
class NodeWidgetError(Exception):
10-
pass
11-
12-
13-
class NodeRegistrationError(Exception):
14-
pass
15-
16-
17-
class PortRegistrationError(Exception):
18-
pass
3+
class NodePropertyError(Exception): pass
4+
class NodeWidgetError(Exception): pass
5+
class NodeRegistrationError(Exception): pass
6+
class PortRegistrationError(Exception): pass

NodeGraphQt/widgets/viewer.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ def __init__(self, parent=None):
7373
self.scene().addItem(self._SLICER_PIPE)
7474

7575
self._undo_stack = QtWidgets.QUndoStack(self)
76-
self._context_menu = QtWidgets.QMenu('main', self)
77-
self._context_menu.setStyleSheet(STYLE_QMENU)
7876
self._search_widget = TabSearchWidget(self)
7977
self._search_widget.search_submitted.connect(self._on_search_submitted)
8078

@@ -84,7 +82,13 @@ def __init__(self, parent=None):
8482
menu_bar.setNativeMenuBar(False)
8583
# shortcuts don't work with "setVisibility(False)".
8684
menu_bar.resize(0, 0)
87-
menu_bar.addMenu(self._context_menu)
85+
86+
self._context_menus = {}
87+
for name in ['Main', 'Node', 'Port']:
88+
menu = QtWidgets.QMenu(name, self)
89+
menu.setStyleSheet(STYLE_QMENU)
90+
self._context_menus[name] = menu
91+
menu_bar.addMenu(menu)
8892

8993
self.acyclic = True
9094
self.LMB_state = False
@@ -155,8 +159,17 @@ def resizeEvent(self, event):
155159

156160
def contextMenuEvent(self, event):
157161
self.RMB_state = False
158-
if self._context_menu.isEnabled():
159-
self._context_menu.exec_(event.globalPos())
162+
163+
pos = self.mapToScene(self._previous_pos)
164+
items = self._items_near(pos)
165+
ports = [i for i in items if isinstance(i, PortItem)]
166+
nodes = [i for i in items if isinstance(i, AbstractNodeItem)]
167+
if self._context_menus['Port'].isEnabled() and ports:
168+
self._context_menus['Port'].exec_(event.globalPos())
169+
elif self._context_menus['Node'].isEnabled() and nodes:
170+
self._context_menus['Node'].exec_(event.globalPos())
171+
elif self._context_menus['Main'].isEnabled():
172+
self._context_menus['Main'].exec_(event.globalPos())
160173
else:
161174
return super(NodeViewer, self).contextMenuEvent(event)
162175

@@ -591,8 +604,8 @@ def tab_search_toggle(self):
591604
self._search_widget.setVisible(state)
592605
self.clearFocus()
593606

594-
def context_menu(self):
595-
return self._context_menu
607+
def context_menus(self):
608+
return self._context_menus
596609

597610
def question_dialog(self, text, title='Node Graph'):
598611
dlg = QtWidgets.QMessageBox.question(

docs/_images/favicon.png

-741 Bytes
Loading

docs/_templates/localtoc.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{%- if display_toc %}
2-
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table of Contents FOO') }}</a></h3>
2+
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table of Contents') }}</a></h3>
33
{{ toc }}
44
{%- endif %}

0 commit comments

Comments
 (0)