Source code for bgdev.tools.toolbar.tabs.maya.main

# pylint: disable=invalid-name
"""Maya toolbar override.

:created: 14/10/2018
:author: Benoit GIELLY <benoit.gielly@gmail.com>
"""
from __future__ import absolute_import

import logging
import os

from PySide2 import QtCore, QtWidgets
from maya import OpenMayaUI, cmds
import shiboken2

from ... import cfg, main

LOG = logging.getLogger(__name__)


[docs]def show(*args, **kwargs): """Show the widget within a maya workspaceControl.""" dock = kwargs.pop("dock", True) floating = kwargs.get("floating") if not dock: kwargs["floating"] = floating if floating is not None else True # show the widget window = Toolbar() window.dock(*args, **kwargs) return window
class Toolbar(main.BaseToolbar): """Create a script launcher window.""" DCC_TABS_FOLDER = os.path.dirname(__file__) def __init__(self, parent=None): parent = parent or maya_window() super(Toolbar, self).__init__(parent=parent) self.dock_title = "Launcher" self.dock_area = "left" def dock(self, title=None, area=None, floating=False): """Launch in a dock.""" dock_widget( self, title=title or self.dock_title or self.windowTitle(), area=area or self.dock_area, floating=floating, ) @staticmethod def repeatable(callback): """Make the command repeatable. Note: In Maya, the `repeatLast` command can only run MEL code which makes the passed python callback unusable. To make it work, we have to use the `config` module to run the callback as a global variable, accessible in the Maya main scope. Args: callback (function): Method executed by the button. """ mel_callback = "import {0};{0}.COMMAND_CALLBACK()".format(cfg.__name__) try: # the callback can error even though mel.eval-ing it works... cmds.repeatLast(addCommand='python("{0}")'.format(mel_callback)) except BaseException: pass
[docs]def maya_window(): """Return the MayaWindow if in Maya else None.""" for each in QtWidgets.QApplication.topLevelWidgets(): if each.objectName() == "MayaWindow": return each return None
[docs]def to_qwidget(ctrl): """Convert a Maya widget to a PySide2 QWidget. Args: ctrl (str): Name of the maya widget as a string. Returns: QtWidgets.QWidget: QWidget instance object of the given widget. """ for method in ["findControl", "findLayout", "findMenuItem"]: ptr = getattr(OpenMayaUI.MQtUtil, method)(ctrl) if ptr: return shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget) return None
[docs]def dock_widget(widget, title="DockWindow", area="right", floating=False): """Dock the given widget properly for both M2016 and 2017+.""" # convert widget to Qt if needed if not issubclass(widget.__class__, QtCore.QObject): widget = to_qwidget(widget) # make sure our widget has a name name = widget.objectName() if not name: name, num = title + "_mainWindow", 1 while cmds.control(name, exists=True): name = title + "_mainWindow" + str(num) num += 1 widget.setObjectName(title + "_mainWindow") # if `floating` is True, return with `widget.show()` if floating is True: if not widget.windowTitle(): widget.setWindowTitle(title) widget.show() return widget # make sure the workspaceControl doesn't exist yet control = name + "_WorkspaceControl" if cmds.control(control, exists=True): cmds.deleteUI(control) # create workspaceControl (only works with Maya 2017+) flags = {"dockToControl": ["ToolBox", "right"]} if area == "right": # If the ChannelBox is not visible, fallback on the AttributeEditor. _control = "ChannelBoxLayerEditor" if not cmds.workspaceControl(_control, query=True, visible=True): _control = "AttributeEditor" flags = {"tabToControl": [_control, -1]} control = cmds.workspaceControl(control) cmds.workspaceControl(control, edit=True, label=title, r=True, **flags) # Convert workspace to Qt and add the widget into its layout. workspace = to_qwidget(control) layout = workspace.layout() layout.addWidget(widget) return widget
[docs]def get_workspaces(**kwargs): """Get Maya workspaces (WIP).""" docking_workspaces = [ "Maya Classic", "Modeling - Standard", "Modeling - Expert", "UV Editing", "Rigging", "Animation", "MASH", "Motion Graphics", "Bifrost Fluids", ] current = cmds.workspaceLayoutManager(query=True, current=True) workspace = kwargs.pop("workspace", current) return workspace, docking_workspaces