Merge pull request #3172 from quadproduction/106-add-a-gizmo-menu-definition-to-openpype-nuke-settings

This commit is contained in:
Milan Kolar 2022-06-07 11:42:59 +01:00 committed by GitHub
commit 122513fcad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 313 additions and 2 deletions

View file

@ -0,0 +1,86 @@
import os
import re
import nuke
from openpype.api import Logger
log = Logger.get_logger(__name__)
class GizmoMenu():
def __init__(self, title, icon=None):
self.toolbar = self._create_toolbar_menu(
title,
icon=icon
)
self._script_actions = []
def _create_toolbar_menu(self, name, icon=None):
nuke_node_menu = nuke.menu("Nodes")
return nuke_node_menu.addMenu(
name,
icon=icon
)
def _make_menu_path(self, path, icon=None):
parent = self.toolbar
for folder in re.split(r"/|\\", path):
if not folder:
continue
existing_menu = parent.findItem(folder)
if existing_menu:
parent = existing_menu
else:
parent = parent.addMenu(folder, icon=icon)
return parent
def build_from_configuration(self, configuration):
for menu in configuration:
# Construct parent path else parent is toolbar
parent = self.toolbar
gizmo_toolbar_path = menu.get("gizmo_toolbar_path")
if gizmo_toolbar_path:
parent = self._make_menu_path(gizmo_toolbar_path)
for item in menu["sub_gizmo_list"]:
assert isinstance(item, dict), "Configuration is wrong!"
if not item.get("title"):
continue
item_type = item.get("sourcetype")
if item_type == ("python" or "file"):
parent.addCommand(
item["title"],
command=str(item["command"]),
icon=item.get("icon"),
shortcut=item.get("hotkey")
)
# add separator
# Special behavior for separators
elif item_type == "separator":
parent.addSeparator()
# add submenu
# items should hold a collection of submenu items (dict)
elif item_type == "menu":
# assert "items" in item, "Menu is missing 'items' key"
parent.addMenu(
item['title'],
icon=item.get('icon')
)
def add_gizmo_path(self, gizmo_paths):
for gizmo_path in gizmo_paths:
if os.path.isdir(gizmo_path):
for folder in os.listdir(gizmo_path):
if os.path.isdir(os.path.join(gizmo_path, folder)):
nuke.pluginAddPath(os.path.join(gizmo_path, folder))
nuke.pluginAddPath(gizmo_path)
else:
log.warning("This path doesn't exist: {}".format(gizmo_path))

View file

@ -30,6 +30,8 @@ from openpype.pipeline import (
legacy_io, legacy_io,
) )
from . import gizmo_menu
from .workio import ( from .workio import (
save_file, save_file,
open_file open_file
@ -2498,6 +2500,70 @@ def recreate_instance(origin_node, avalon_data=None):
return new_node return new_node
def add_scripts_gizmo():
# load configuration of custom menu
project_settings = get_project_settings(os.getenv("AVALON_PROJECT"))
platform_name = platform.system().lower()
for gizmo_settings in project_settings["nuke"]["gizmo"]:
gizmo_list_definition = gizmo_settings["gizmo_definition"]
toolbar_name = gizmo_settings["toolbar_menu_name"]
# gizmo_toolbar_path = gizmo_settings["gizmo_toolbar_path"]
gizmo_source_dir = gizmo_settings.get(
"gizmo_source_dir", {}).get(platform_name)
toolbar_icon_path = gizmo_settings.get(
"toolbar_icon_path", {}).get(platform_name)
if not gizmo_source_dir:
log.debug("Skipping studio gizmo `{}`, "
"no gizmo path found.".format(toolbar_name)
)
return
if not gizmo_list_definition:
log.debug("Skipping studio gizmo `{}`, "
"no definition found.".format(toolbar_name)
)
return
if toolbar_icon_path:
try:
toolbar_icon_path = toolbar_icon_path.format(**os.environ)
except KeyError as e:
log.error(
"This environment variable doesn't exist: {}".format(e)
)
existing_gizmo_path = []
for source_dir in gizmo_source_dir:
try:
resolve_source_dir = source_dir.format(**os.environ)
except KeyError as e:
log.error(
"This environment variable doesn't exist: {}".format(e)
)
continue
if not os.path.exists(resolve_source_dir):
log.warning(
"The source of gizmo `{}` does not exists".format(
resolve_source_dir
)
)
continue
existing_gizmo_path.append(resolve_source_dir)
# run the launcher for Nuke toolbar
toolbar_menu = gizmo_menu.GizmoMenu(
title=toolbar_name,
icon=toolbar_icon_path
)
# apply configuration
toolbar_menu.add_gizmo_path(existing_gizmo_path)
toolbar_menu.build_from_configuration(gizmo_list_definition)
class NukeDirmap(HostDirmap): class NukeDirmap(HostDirmap):
def __init__(self, host_name, project_settings, sync_module, file_name): def __init__(self, host_name, project_settings, sync_module, file_name):
""" """

View file

@ -8,7 +8,8 @@ from openpype.hosts.nuke.api.lib import (
on_script_load, on_script_load,
check_inventory_versions, check_inventory_versions,
WorkfileSettings, WorkfileSettings,
dirmap_file_name_filter dirmap_file_name_filter,
add_scripts_gizmo
) )
from openpype.settings import get_project_settings from openpype.settings import get_project_settings
@ -59,3 +60,5 @@ def add_scripts_menu():
add_scripts_menu() add_scripts_menu()
add_scripts_gizmo()

View file

@ -290,5 +290,29 @@
} }
] ]
}, },
"gizmo": [
{
"toolbar_menu_name": "OpenPype Gizmo",
"gizmo_path": {
"windows": [],
"darwin": [],
"linux": []
},
"toolbar_icon_path": {},
"gizmo_definition": [
{
"gizmo_toolbar_path": "/path/to/menu",
"sub_gizmo_list": [
{
"sourcetype": "python",
"title": "Gizmo Note",
"command": "nuke.nodes.StickyNote(label='You can create your own toolbar menu in the Nuke GizmoMenu of OpenPype')",
"shortcut": ""
}
]
}
]
}
],
"filters": {} "filters": {}
} }

View file

@ -83,6 +83,10 @@
"type": "schema", "type": "schema",
"name": "schema_scriptsmenu" "name": "schema_scriptsmenu"
}, },
{
"type": "schema",
"name": "schema_nuke_scriptsgizmo"
},
{ {
"type": "dict", "type": "dict",
"collapsible": true, "collapsible": true,

View file

@ -0,0 +1,124 @@
{
"type": "list",
"key": "gizmo",
"label": "Gizmo Menu",
"is_group": true,
"use_label_wrap": true,
"object_type": {
"type": "dict",
"children": [
{
"type": "text",
"key": "toolbar_menu_name",
"label": "Toolbar Menu Name"
},
{
"type": "path",
"key": "gizmo_source_dir",
"label": "Gizmo directory path",
"multipath": true,
"multiplatform": true
},
{
"type": "collapsible-wrap",
"label": "Options",
"collapsible": true,
"collapsed": true,
"children": [
{
"type": "path",
"key": "toolbar_icon_path",
"label": "Toolbar Icon Path",
"multipath": false,
"multiplatform": true
},
{
"type": "splitter"
},
{
"type": "list",
"key": "gizmo_definition",
"label": "Gizmo definitions",
"use_label_wrap": true,
"object_type": {
"type": "dict",
"children": [
{
"type": "text",
"key": "gizmo_toolbar_path",
"label": "Gizmo Menu Path"
},
{
"type": "list",
"key": "sub_gizmo_list",
"label": "Sub Gizmo List",
"use_label_wrap": true,
"object_type": {
"type": "dict-conditional",
"enum_key": "sourcetype",
"enum_label": "Type of usage",
"enum_children": [
{
"key": "python",
"label": "Python",
"children": [
{
"type": "text",
"key": "title",
"label": "Title"
},
{
"type": "text",
"key": "command",
"label": "Python command"
},
{
"type": "text",
"key": "shortcut",
"label": "Hotkey"
}
]
},
{
"key": "file",
"label": "File",
"children": [
{
"type": "text",
"key": "title",
"label": "Title"
},
{
"type": "text",
"key": "file_name",
"label": "Gizmo file name"
},
{
"type": "text",
"key": "shortcut",
"label": "Hotkey"
}
]
},
{
"key": "separator",
"label": "Separator",
"children": [
{
"type": "text",
"key": "gizmo_toolbar_path",
"label": "Toolbar path"
}
]
}
]
}
}
]
}
}
]
}
]
}
}

View file

@ -12,3 +12,7 @@ You can add your custom tools menu into Nuke by extending definitions in **Nuke
This is still work in progress. Menu definition will be handled more friendly with widgets and not This is still work in progress. Menu definition will be handled more friendly with widgets and not
raw json. raw json.
::: :::
## Gizmo Menu
You can add your custom toolbar menu into Nuke by setting your gizmo path and extending definitions in **Nuke -> Gizmo Menu**.
![Custom menu definition](assets/nuke-admin_gizmomenu.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB