Skip to content

Commit 90e3317

Browse files
committed
Redirected click to use hook
1 parent 0e27293 commit 90e3317

3 files changed

Lines changed: 105 additions & 1 deletion

File tree

hooks/tree_node_clicked.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""Hook to call whenever a publish tree node is clicked (Qt tree item).
2+
3+
`.tk_multi_publish2` related wordings and phrases used:
4+
5+
- "tree node", or "node" for short:
6+
7+
- An instance of a subclass of
8+
`.tk_multi_publish2.publish_tree_widget.tree_node_base.TreeNodeBase`
9+
10+
- Which itself subclasses `.QTreeWidgetItem`
11+
12+
- "widget" of the node
13+
14+
- Behaves like a delegate, but not actually using the Qt delegate system
15+
from model/view architecture
16+
17+
- An instance of a subclass of
18+
`.tk_multi_publish2.publish_tree_widget.custom_widget_base.CustomWidgetBase`
19+
20+
- Which itself subclasses `.QFrame`
21+
22+
- Publish "api" associated with the node, if any:
23+
24+
- `.tk_multi_publish2.api.item.PublishItem` for a `.TreeNodeItem`
25+
- `.tk_multi_publish2.api.task.PublishTask` for a `.TreeNodeTask`
26+
- otherwise `None`, i.e. for `.TreeNodeContext` and `.TreeNodeSummary`
27+
28+
"""
29+
30+
from typing import TypeVar, Union
31+
import sgtk
32+
from sgtk.platform.qt import QtCore, QtGui
33+
34+
HookBaseClass = sgtk.get_hook_baseclass()
35+
36+
TreeNode = TypeVar("TreeNode", bound=QtGui.QTreeWidgetItem)
37+
CustomTreeWidget = TypeVar("CustomTreeWidget", bound=QtGui.QFrame)
38+
API = Union[TypeVar("PublishItem"), TypeVar("PublishTask"), None]
39+
40+
41+
class TreeNodeClicked(HookBaseClass):
42+
@staticmethod
43+
def flipped_state(check_state: QtCore.Qt.CheckState) -> QtCore.Qt.CheckState:
44+
"""Flips a unchecked state to checked and any other state to unchecked."""
45+
return (
46+
QtCore.Qt.Checked
47+
if check_state == QtCore.Qt.Unchecked
48+
else QtCore.Qt.Unchecked
49+
)
50+
51+
def single(
52+
self,
53+
node: TreeNode,
54+
widget: CustomTreeWidget,
55+
api: API,
56+
buttons: QtCore.Qt.MouseButtons,
57+
modifiers: QtCore.Qt.KeyboardModifiers,
58+
): # type: (...) -> None
59+
"""Single click callback on a `.TreeNodeBase` (a `.QtGui.QTreeWidgetItem`)."""
60+
61+
def double(
62+
self,
63+
node: TreeNode,
64+
widget: CustomTreeWidget,
65+
api: API,
66+
buttons: QtCore.Qt.MouseButtons,
67+
modifiers: QtCore.Qt.KeyboardModifiers,
68+
): # type: (...) -> None
69+
"""Double click callback on a `.TreeNodeBase` (a `.QtGui.QTreeWidgetItem`)."""
70+
if buttons == QtCore.Qt.LeftButton:
71+
# Ensure expansion states are correctly updated
72+
node.setExpanded(node.isExpanded())

info.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ configuration:
4848
identification, publish display name, image sequence paths, etc."
4949
default_value: "{self}/path_info.py"
5050

51+
tree_node_clicked:
52+
type: hook
53+
default_value: "{self}/tree_node_clicked.py"
54+
description:
55+
"Actions to take for clicking on a tree node (an instance of subclass
56+
of TreeNodeBase). The methods 'single' and 'double' are called
57+
respectively for single and double clicks."
58+
5159
thumbnail_generator:
5260
type: hook
5361
description:

python/tk_multi_publish2/publish_tree_widget/publish_tree_widget.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ def __init__(self, parent):
6363
self._summary_node.setHidden(True)
6464

6565
# forward double clicks on items to the items themselves
66-
self.itemDoubleClicked.connect(lambda i, c: i.double_clicked(c))
66+
self.itemDoubleClicked.connect(self._click_slot_factory("double"))
67+
self.itemClicked.connect(self._click_slot_factory("single"))
6768

6869
# Capture the native expand toggles and update the button state.
6970
self.itemExpanded.connect(self.on_item_expand_state_change)
@@ -559,6 +560,29 @@ def mouseMoveEvent(self, event):
559560
# bubble up all events that aren't drag select related
560561
super().mouseMoveEvent(event)
561562

563+
def _click_slot_factory(self, method_name):
564+
"""Create a slot to call the given hook method on click.
565+
566+
i.e. for both single and double clicks::
567+
568+
self.itemClicked.connect(self._click_slot_factory("single"))
569+
self.itemDoubleClicked.connect(self._click_slot_factory("double"))
570+
571+
"""
572+
573+
@QtCore.Slot(QtGui.QTreeWidgetItem, int)
574+
def _on_click_slot(tree_node: QtGui.QTreeWidgetItem, column: int) -> None:
575+
kwargs = {
576+
"node": tree_node,
577+
"widget": self.itemWidget(tree_node, column),
578+
"api": tree_node.get_publish_instance(),
579+
"buttons": QtGui.QApplication.mouseButtons(),
580+
"modifiers": QtGui.QApplication.keyboardModifiers(),
581+
}
582+
self._bundle.execute_hook_method("tree_node_clicked", method_name, **kwargs)
583+
584+
return _on_click_slot
585+
562586

563587
def _init_item_r(parent_item):
564588

0 commit comments

Comments
 (0)