def build_workspace_control_ui(shotgun_panel_name): """ Embeds a Shotgun app panel into the calling Maya workspace control. This function will be called in two cases: - When the workspace control is being created by Maya command workspaceControl; - When the workspace control is being restored from a workspace control state created by Maya when this workspace control was previously closed and deleted. .. note:: This function is only for Maya 2017 and later. :param shotgun_panel_name: Name of the Qt widget at the root of a Shotgun app panel. """ import maya.api.OpenMaya import maya.utils from maya.OpenMayaUI import MQtUtil # In the context of this function, we know that we are running in Maya 2017 and later # with the newer versions of PySide and shiboken. from PySide2 import QtWidgets from shiboken2 import wrapInstance # Retrieve the calling Maya workspace control. ptr = MQtUtil.getCurrentParent() workspace_control = wrapInstance(long(ptr), QtWidgets.QWidget) # Search for the Shotgun app panel widget. for widget in QtWidgets.QApplication.allWidgets(): if widget.objectName() == shotgun_panel_name: # Reparent the Shotgun app panel widget under Maya workspace control. widget.setParent(workspace_control) # Add the Shotgun app panel widget to the Maya workspace control layout. workspace_control.layout().addWidget(widget) # Install an event filter on Maya workspace control to monitor # its close event in order to reparent the Shotgun app panel widget # under Maya main window for later use. panel_util.install_event_filter_by_widget(workspace_control, shotgun_panel_name) break else: msg = "Shotgun: Cannot restore %s: Shotgun app panel not found" % shotgun_panel_name fct = maya.api.OpenMaya.MGlobal.displayError maya.utils.executeInMainThreadWithResult(fct, msg)
def build_workspace_control_ui(shotgun_panel_name): """ Embeds a Shotgun app panel into the calling Maya workspace control. This function will be called in two cases: - When the workspace control is being created by Maya command workspaceControl; - When the workspace control is being restored from a workspace control state created by Maya when this workspace control was previously closed and deleted. .. note:: This function is only for Maya 2017 and later. :param shotgun_panel_name: Name of the Qt widget at the root of a Shotgun app panel. """ from maya.OpenMayaUI import MQtUtil # In the context of this function, we know that we are running in Maya 2017 and later # with the newer versions of PySide and shiboken. from PySide2 import QtWidgets from shiboken2 import wrapInstance import sgtk.platform # Retrieve the Maya engine. engine = sgtk.platform.current_engine() # Retrieve the calling Maya workspace control. ptr = MQtUtil.getCurrentParent() workspace_control = wrapInstance(long(ptr), QtWidgets.QWidget) # Search for the Shotgun app panel widget. for widget in QtWidgets.QApplication.allWidgets(): if widget.objectName() == shotgun_panel_name: maya_panel_name = workspace_control.objectName() engine.logger.debug( "Reparenting Shotgun app panel %s under Maya workspace panel %s.", shotgun_panel_name, maya_panel_name, ) # When possible, give a minimum width to the workspace control; # otherwise, it will use the width of the currently displayed tab. # Note that we did not use the workspace control "initialWidth" and "minimumWidth" # to set the minimum width to the initial width since these values are not # properly saved by Maya 2017 in its layout preference files. # This minimum width behaviour is consistent with Maya standard panels. size_hint = widget.sizeHint() if size_hint.isValid(): # Use the widget recommended width as the workspace control minimum width. minimum_width = size_hint.width() engine.logger.debug( "Setting Maya workspace panel %s minimum width to %s.", maya_panel_name, minimum_width, ) workspace_control.setMinimumWidth(minimum_width) else: # The widget has no recommended size. engine.logger.debug( "Cannot set Maya workspace panel %s minimum width.", maya_panel_name ) # Reparent the Shotgun app panel widget under Maya workspace control. widget.setParent(workspace_control) # Add the Shotgun app panel widget to the Maya workspace control layout. workspace_control.layout().addWidget(widget) # Install an event filter on Maya workspace control to monitor # its close event in order to reparent the Shotgun app panel widget # under Maya main window for later use. engine.logger.debug( "Installing a close event filter on Maya workspace panel %s.", maya_panel_name, ) panel_util.install_event_filter_by_widget( workspace_control, shotgun_panel_name ) # Delete any leftover workspace control state to avoid a spurious deletion # of our workspace control when the user switches to another workspace and back. if cmds.workspaceControlState(maya_panel_name, exists=True): # Once Maya will have completed its UI update and be idle, # delete the leftover workspace control state. engine.logger.debug( "Deleting leftover Maya workspace control state %s.", maya_panel_name, ) maya.utils.executeDeferred( cmds.workspaceControlState, maya_panel_name, remove=True ) break else: # The Shotgun app panel widget was not found and needs to be recreated. # Search for the Shotgun app panel that needs to be restored # among the panels registered with the engine. for panel_id in engine.panels: # The name of the Qt widget at the root of the Shotgun app panel # was constructed by prepending to the panel unique identifier. if shotgun_panel_name.endswith(panel_id): # Once Maya will have completed its UI update and be idle, # recreate and dock the Shotgun app panel. maya.utils.executeDeferred(engine.panels[panel_id]["callback"]) break else: # The Shotgun app panel that needs to be restored is not in the context configuration. engine.logger.error( "Cannot restore %s: Shotgun app panel not found. " "Make sure the app is in the context configuration. ", shotgun_panel_name, )
def build_workspace_control_ui(shotgun_panel_name): """ Embeds a Shotgun app panel into the calling Maya workspace control. This function will be called in two cases: - When the workspace control is being created by Maya command workspaceControl; - When the workspace control is being restored from a workspace control state created by Maya when this workspace control was previously closed and deleted. .. note:: This function is only for Maya 2017 and later. :param shotgun_panel_name: Name of the Qt widget at the root of a Shotgun app panel. """ from maya.OpenMayaUI import MQtUtil # In the context of this function, we know that we are running in Maya 2017 and later # with the newer versions of PySide and shiboken. from PySide2 import QtWidgets from shiboken2 import wrapInstance import sgtk.platform # Retrieve the Maya engine. engine = sgtk.platform.current_engine() # Retrieve the calling Maya workspace control. ptr = MQtUtil.getCurrentParent() workspace_control = wrapInstance(long(ptr), QtWidgets.QWidget) # Search for the Shotgun app panel widget. for widget in QtWidgets.QApplication.allWidgets(): if widget.objectName() == shotgun_panel_name: maya_panel_name = workspace_control.objectName() engine.logger.debug("Reparenting Shotgun app panel %s under Maya workspace panel %s.", shotgun_panel_name, maya_panel_name) # When possible, give a minimum width to the workspace control; # otherwise, it will use the width of the currently displayed tab. # Note that we did not use the workspace control "initialWidth" and "minimumWidth" # to set the minimum width to the initial width since these values are not # properly saved by Maya 2017 in its layout preference files. # This minimum width behaviour is consistent with Maya standard panels. size_hint = widget.sizeHint() if size_hint.isValid(): # Use the widget recommended width as the workspace control minimum width. minimum_width = size_hint.width() engine.logger.debug("Setting Maya workspace panel %s minimum width to %s.", maya_panel_name, minimum_width) workspace_control.setMinimumWidth(minimum_width) else: # The widget has no recommended size. engine.logger.debug("Cannot set Maya workspace panel %s minimum width.", maya_panel_name) # Reparent the Shotgun app panel widget under Maya workspace control. widget.setParent(workspace_control) # Add the Shotgun app panel widget to the Maya workspace control layout. workspace_control.layout().addWidget(widget) # Install an event filter on Maya workspace control to monitor # its close event in order to reparent the Shotgun app panel widget # under Maya main window for later use. engine.logger.debug("Installing a close event filter on Maya workspace panel %s.", maya_panel_name) panel_util.install_event_filter_by_widget(workspace_control, shotgun_panel_name) # Delete any leftover workspace control state to avoid a spurious deletion # of our workspace control when the user switches to another workspace and back. if cmds.workspaceControlState(maya_panel_name, exists=True): # Once Maya will have completed its UI update and be idle, # delete the leftover workspace control state. engine.logger.debug("Deleting leftover Maya workspace control state %s.", maya_panel_name) maya.utils.executeDeferred(cmds.workspaceControlState, maya_panel_name, remove=True) break else: # The Shotgun app panel widget was not found and needs to be recreated. # Search for the Shotgun app panel that needs to be restored # among the panels registered with the engine. for panel_id in engine.panels: # The name of the Qt widget at the root of the Shotgun app panel # was constructed by prepending to the panel unique identifier. if shotgun_panel_name.endswith(panel_id): # Once Maya will have completed its UI update and be idle, # recreate and dock the Shotgun app panel. maya.utils.executeDeferred(engine.panels[panel_id]["callback"]) break else: # The Shotgun app panel that needs to be restored is not in the context configuration. engine.logger.error("Cannot restore %s: Shotgun app panel not found. " \ "Make sure the app is in the context configuration. ", shotgun_panel_name)