ayon-core/openpype/hosts/maya/api/menu.py
2023-03-29 14:46:41 +02:00

256 lines
6.9 KiB
Python

import os
import logging
from qtpy import QtWidgets, QtGui
import maya.utils
import maya.cmds as cmds
from openpype.settings import get_project_settings
from openpype.pipeline import legacy_io
from openpype.pipeline.workfile import BuildWorkfile
from openpype.tools.utils import host_tools
from openpype.hosts.maya.api import lib, lib_rendersettings
from .lib import get_main_window, IS_HEADLESS
from ..tools import show_look_assigner
from .workfile_template_builder import (
create_placeholder,
update_placeholder,
build_workfile_template,
update_workfile_template,
)
log = logging.getLogger(__name__)
MENU_NAME = "op_maya_menu"
def _get_menu(menu_name=None):
"""Return the menu instance if it currently exists in Maya"""
if menu_name is None:
menu_name = MENU_NAME
widgets = {w.objectName(): w for w in QtWidgets.QApplication.allWidgets()}
return widgets.get(menu_name)
def install():
if cmds.about(batch=True):
log.info("Skipping openpype.menu initialization in batch mode..")
return
def deferred():
pyblish_icon = host_tools.get_pyblish_icon()
parent_widget = get_main_window()
cmds.menu(
MENU_NAME,
label=legacy_io.Session["AVALON_LABEL"],
tearOff=True,
parent="MayaWindow"
)
# Create context menu
context_label = "{}, {}".format(
legacy_io.Session["AVALON_ASSET"],
legacy_io.Session["AVALON_TASK"]
)
cmds.menuItem(
"currentContext",
label=context_label,
parent=MENU_NAME,
enable=False
)
cmds.setParent("..", menu=True)
cmds.menuItem(divider=True)
# Create default items
cmds.menuItem(
"Create...",
command=lambda *args: host_tools.show_creator(parent=parent_widget)
)
cmds.menuItem(
"Load...",
command=lambda *args: host_tools.show_loader(
parent=parent_widget,
use_context=True
)
)
cmds.menuItem(
"Publish...",
command=lambda *args: host_tools.show_publish(
parent=parent_widget
),
image=pyblish_icon
)
cmds.menuItem(
"Manage...",
command=lambda *args: host_tools.show_scene_inventory(
parent=parent_widget
)
)
cmds.menuItem(
"Library...",
command=lambda *args: host_tools.show_library_loader(
parent=parent_widget
)
)
cmds.menuItem(divider=True)
cmds.menuItem(
"Work Files...",
command=lambda *args: host_tools.show_workfiles(
parent=parent_widget
),
)
cmds.menuItem(
"Set Frame Range",
command=lambda *args: lib.reset_frame_range()
)
cmds.menuItem(
"Set Resolution",
command=lambda *args: lib.reset_scene_resolution()
)
cmds.menuItem(
"Set Colorspace",
command=lambda *args: lib.set_colorspace(),
)
cmds.menuItem(
"Set Render Settings",
command=lambda *args: lib_rendersettings.RenderSettings().set_default_renderer_settings() # noqa
)
cmds.menuItem(divider=True, parent=MENU_NAME)
cmds.menuItem(
"Build First Workfile",
parent=MENU_NAME,
command=lambda *args: BuildWorkfile().process()
)
cmds.menuItem(
"Look assigner...",
command=lambda *args: show_look_assigner(
parent_widget
)
)
cmds.menuItem(
"Experimental tools...",
command=lambda *args: host_tools.show_experimental_tools_dialog(
parent_widget
)
)
builder_menu = cmds.menuItem(
"Template Builder",
subMenu=True,
tearOff=True,
parent=MENU_NAME
)
cmds.menuItem(
"Create Placeholder",
parent=builder_menu,
command=create_placeholder
)
cmds.menuItem(
"Update Placeholder",
parent=builder_menu,
command=update_placeholder
)
cmds.menuItem(
"Build Workfile from template",
parent=builder_menu,
command=build_workfile_template
)
cmds.menuItem(
"Update Workfile from template",
parent=builder_menu,
command=update_workfile_template
)
cmds.setParent(MENU_NAME, menu=True)
def add_scripts_menu():
try:
import scriptsmenu.launchformaya as launchformaya
except ImportError:
log.warning(
"Skipping studio.menu install, because "
"'scriptsmenu' module seems unavailable."
)
return
# load configuration of custom menu
project_settings = get_project_settings(os.getenv("AVALON_PROJECT"))
config = project_settings["maya"]["scriptsmenu"]["definition"]
_menu = project_settings["maya"]["scriptsmenu"]["name"]
if not config:
log.warning("Skipping studio menu, no definition found.")
return
# run the launcher for Maya menu
studio_menu = launchformaya.main(
title=_menu.title(),
objectName=_menu.title().lower().replace(" ", "_")
)
# apply configuration
studio_menu.build_from_configuration(studio_menu, config)
# Allow time for uninstallation to finish.
# We use Maya's executeDeferred instead of QTimer.singleShot
# so that it only gets called after Maya UI has initialized too.
# This is crucial with Maya 2020+ which initializes without UI
# first as a QCoreApplication
maya.utils.executeDeferred(deferred)
cmds.evalDeferred(add_scripts_menu, lowestPriority=True)
def uninstall():
menu = _get_menu()
if menu:
log.info("Attempting to uninstall ...")
try:
menu.deleteLater()
del menu
except Exception as e:
log.error(e)
def popup():
"""Pop-up the existing menu near the mouse cursor."""
menu = _get_menu()
cursor = QtGui.QCursor()
point = cursor.pos()
menu.exec_(point)
def update_menu_task_label():
"""Update the task label in Avalon menu to current session"""
if IS_HEADLESS:
return
object_name = "{}|currentContext".format(MENU_NAME)
if not cmds.menuItem(object_name, query=True, exists=True):
log.warning("Can't find menuItem: {}".format(object_name))
return
label = "{}, {}".format(
legacy_io.Session["AVALON_ASSET"],
legacy_io.Session["AVALON_TASK"]
)
cmds.menuItem(object_name, edit=True, label=label)