From 2e58cd2e1a1a1dd23e0bc59bc1cbc414fa6d1ec9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 30 May 2023 21:44:26 +0800 Subject: [PATCH] move the custom popup menu to nuke/startup and add the frame setting to Openpype tool menu --- openpype/hosts/nuke/api/lib.py | 32 --------- openpype/hosts/nuke/api/pipeline.py | 5 -- .../nuke/startup}/custom_popup.py | 71 ++++++++++++++----- .../defaults/project_settings/nuke.json | 7 ++ 4 files changed, 61 insertions(+), 54 deletions(-) rename openpype/{widgets => hosts/nuke/startup}/custom_popup.py (65%) diff --git a/openpype/hosts/nuke/api/lib.py b/openpype/hosts/nuke/api/lib.py index 94a0ff15ad..59a63d1373 100644 --- a/openpype/hosts/nuke/api/lib.py +++ b/openpype/hosts/nuke/api/lib.py @@ -2358,38 +2358,6 @@ class WorkfileSettings(object): # add colorspace menu item self.set_colorspace() - def reset_frame_range_read_nodes(self): - from openpype.widgets import custom_popup - parent = get_main_window() - dialog = custom_popup.CustomScriptDialog(parent=parent) - dialog.setWindowTitle("Frame Range") - dialog.set_name("Frame Range: ") - dialog.set_line_edit("%s - %s" % (nuke.root().firstFrame(), - nuke.root().lastFrame())) - frame = dialog.widgets["line_edit"] - selection = dialog.widgets["selection"] - dialog.on_clicked.connect( - lambda: set_frame_range(frame, selection) - ) - - def set_frame_range(frame, selection): - frame_range = frame.text() - selected = selection.isChecked() - if not nuke.allNodes("Read"): - return - for read_node in nuke.allNodes("Read"): - if selected: - if not nuke.selectedNodes(): - return - if read_node in nuke.selectedNodes(): - read_node["frame_mode"].setValue("start_at") - read_node["frame"].setValue(frame_range) - else: - read_node["frame_mode"].setValue("start_at") - read_node["frame"].setValue(frame_range) - dialog.show() - - return False def set_favorites(self): from .utils import set_context_favorites diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index 33e25d3c81..75b0f80d21 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -286,11 +286,6 @@ def _install_menu(): lambda: WorkfileSettings().set_context_settings() ) - menu.addSeparator() - menu.addCommand( - "Set Frame Range(Read Node)", - lambda: WorkfileSettings().reset_frame_range_read_nodes() - ) menu.addSeparator() menu.addCommand( "Build Workfile", diff --git a/openpype/widgets/custom_popup.py b/openpype/hosts/nuke/startup/custom_popup.py similarity index 65% rename from openpype/widgets/custom_popup.py rename to openpype/hosts/nuke/startup/custom_popup.py index be4b0c32d5..c85577133c 100644 --- a/openpype/widgets/custom_popup.py +++ b/openpype/hosts/nuke/startup/custom_popup.py @@ -1,9 +1,26 @@ import sys import contextlib - +import re +import nuke from PySide2 import QtCore, QtWidgets +def get_main_window(): + """Acquire Nuke's main window""" + main_window = None + if main_window is None: + + top_widgets = QtWidgets.QApplication.topLevelWidgets() + name = "Foundry::UI::DockMainWindow" + for widget in top_widgets: + if ( + widget.inherits("QMainWindow") + and widget.metaObject().className() == name + ): + main_window = widget + break + return main_window + class CustomScriptDialog(QtWidgets.QDialog): """A Popup that moves itself to bottom right of screen on show event. @@ -14,6 +31,9 @@ class CustomScriptDialog(QtWidgets.QDialog): on_clicked = QtCore.Signal() on_line_changed = QtCore.Signal(str) + context = None + + def __init__(self, parent=None, *args, **kwargs): super(CustomScriptDialog, self).__init__(parent=parent, @@ -23,23 +43,25 @@ class CustomScriptDialog(QtWidgets.QDialog): # Layout layout = QtWidgets.QVBoxLayout(self) - line_layout = QtWidgets.QHBoxLayout() - line_layout.setContentsMargins(10, 5, 10, 10) + frame_layout = QtWidgets.QHBoxLayout() + frame_layout.setContentsMargins(10, 5, 10, 10) selection_layout = QtWidgets.QHBoxLayout() selection_layout.setContentsMargins(10, 5, 10, 10) button_layout = QtWidgets.QHBoxLayout() button_layout.setContentsMargins(10, 5, 10, 10) # Increase spacing slightly for readability - line_layout.setSpacing(10) + frame_layout.setSpacing(10) button_layout.setSpacing(10) - name = QtWidgets.QLabel("") + name = QtWidgets.QLabel("Frame Range: ") name.setStyleSheet(""" QLabel { font-size: 12px; } """) - line_edit = QtWidgets.QLineEdit("") + line_edit = QtWidgets.QLineEdit( + "%s-%s" % (nuke.root().firstFrame(), + nuke.root().lastFrame())) selection_name = QtWidgets.QLabel("Use Selection") selection_name.setStyleSheet(""" QLabel { @@ -54,13 +76,13 @@ class CustomScriptDialog(QtWidgets.QDialog): cancel.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum) - line_layout.addWidget(name) - line_layout.addWidget(line_edit) + frame_layout.addWidget(name) + frame_layout.addWidget(line_edit) selection_layout.addWidget(selection_name) selection_layout.addWidget(has_selection) button_layout.addWidget(button) button_layout.addWidget(cancel) - layout.addLayout(line_layout) + layout.addLayout(frame_layout) layout.addLayout(selection_layout) layout.addLayout(button_layout) # Default size @@ -73,7 +95,6 @@ class CustomScriptDialog(QtWidgets.QDialog): "button": button, "cancel": cancel } - # Signals has_selection.toggled.connect(self.emit_click_with_state) line_edit.textChanged.connect(self.on_line_edit_changed) @@ -115,18 +136,34 @@ class CustomScriptDialog(QtWidgets.QDialog): Raises the parent (if any) """ + frame_range = self.widgets['line_edit'].text() + selected = self.widgets["selection"].isChecked() + pattern = r"^(?P-?[0-9]+)(?:(?:-+)(?P-?[0-9]+))?$" + match = re.match(pattern, frame_range) + frame_start = int(match.group("start")) + frame_end = int(match.group("end")) + if not nuke.allNodes("Read"): + return + for read_node in nuke.allNodes("Read"): + if selected: + if not nuke.selectedNodes(): + return + if read_node in nuke.selectedNodes(): + read_node["frame_mode"].setValue("start_at") + read_node["frame"].setValue(frame_range) + read_node["first"].setValue(frame_start) + read_node["last"].setValue(frame_end) + else: + read_node["frame_mode"].setValue("start_at") + read_node["frame"].setValue(frame_range) + read_node["first"].setValue(frame_start) + read_node["last"].setValue(frame_end) - parent = self.parent() self.close() - # Trigger the signal - self.on_clicked.emit() - - if parent: - parent.raise_() + return False def showEvent(self, event): - # Position popup based on contents on show event return super(CustomScriptDialog, self).showEvent(event) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index f01bdf7d50..287d13e5c9 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -222,6 +222,13 @@ "title": "OpenPype Docs", "command": "import webbrowser;webbrowser.open(url='https://openpype.io/docs/artist_hosts_nuke_tut')", "tooltip": "Open the OpenPype Nuke user doc page" + }, + { + "type": "action", + "sourcetype": "python", + "title": "Set Frame Range(Read Node)", + "command": "from openpype.hosts.nuke.startup import custom_popup;from openpype.hosts.nuke.startup.custom_popup import get_main_window;custom_popup.CustomScriptDialog(parent=get_main_window()).show();", + "tooltip": "Set Frame Range for Read Node(s)" } ] },