class ActionTreeWindow(PulseWindow): """ A standalone window that contains an ActionTreeWidget and an ActionPaletteWidget. """ OBJECT_NAME = 'pulseActionTreeWindow' PREFERRED_SIZE = QtCore.QSize(400, 300) STARTING_SIZE = QtCore.QSize(400, 300) MINIMUM_SIZE = QtCore.QSize(400, 300) WINDOW_MODULE = 'pulse.views.actiontree' def __init__(self, parent=None): super(ActionTreeWindow, self).__init__(parent=parent) self.setWindowTitle('Pulse Action Tree') layout = QtWidgets.QVBoxLayout(self) self.setLayout(layout) self.actionTree = ActionTreeWidget(self) layout.addWidget(self.actionTree) self.actionPalette = ActionPaletteWidget(self) layout.addWidget(self.actionPalette) layout.setStretch(layout.indexOf(self.actionTree), 2) layout.setStretch(layout.indexOf(self.actionPalette), 1)
def data(self, index, role=QtCore.Qt.DisplayRole): if not index.isValid(): return step = self.stepForIndex(index) if not step: return if role == QtCore.Qt.DisplayRole: return step.getDisplayName() elif role == QtCore.Qt.EditRole: return step.name elif role == QtCore.Qt.DecorationRole: iconFile = step.getIconFile() if iconFile: return QtGui.QIcon(iconFile) elif role == QtCore.Qt.SizeHintRole: return QtCore.QSize(0, 20) elif role == QtCore.Qt.ForegroundRole: color = step.getColor() if color: return QtGui.QColor(*[c * 255 for c in color])
def setupUi(self, parent): self.setupDefaultFormUi(parent) hlayout = QtWidgets.QHBoxLayout(parent) hlayout.setSpacing(4) self.listWidget = QtWidgets.QListWidget(parent) self.listWidget.setSortingEnabled(True) self.listWidget.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) self.listWidget.setSelectionMode( QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) self.listWidget.itemSelectionChanged.connect( self.onItemSelectionChanged) hlayout.addWidget(self.listWidget) self.pickButton = QtWidgets.QPushButton(parent) self.pickButton.setIcon(viewutils.getIcon("select.png")) self.pickButton.setFixedSize(QtCore.QSize(20, 20)) self.pickButton.clicked.connect(self.setFromSelection) hlayout.addWidget(self.pickButton) hlayout.setAlignment(self.pickButton, QtCore.Qt.AlignTop) self.setDefaultFormLayout(hlayout) if self._isValueTypeValid(self.attrValue): self._setFormValue(self.attrValue)
def data(self, column, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if isinstance(self.buildItem, pulse.BuildGroup): return '{0} ({1})'.format(self.buildItem.getDisplayName(), self.buildItem.getChildCount()) elif isinstance(self.buildItem, pulse.BatchBuildAction): return '{0} (x{1})'.format(self.buildItem.getDisplayName(), self.buildItem.getActionCount()) else: return self.buildItem.getDisplayName() elif role == QtCore.Qt.EditRole: return self.buildItem.getDisplayName() elif role == QtCore.Qt.DecorationRole: iconFile = self.buildItem.getIconFile() if iconFile: return QtGui.QIcon(iconFile) elif role == QtCore.Qt.SizeHintRole: return QtCore.QSize(0, 20) elif role == QtCore.Qt.ForegroundRole: color = self.buildItem.getColor() if color: return QtGui.QColor(*[c * 255 for c in color])
def setupVariantsUi(self, parent, layout): # variant header variantHeader = QtWidgets.QFrame(parent) variantHeader.setStyleSheet( ".QFrame{ background-color: rgb(255, 255, 255, 15); border-radius: 2px }" ) layout.addWidget(variantHeader) variantHeaderLayout = QtWidgets.QHBoxLayout(variantHeader) variantHeaderLayout.setContentsMargins(10, 4, 4, 4) variantHeaderLayout.setSpacing(4) self.variantsLabel = QtWidgets.QLabel(variantHeader) self.variantsLabel.setText("Variants: ") variantHeaderLayout.addWidget(self.variantsLabel) spacer = QtWidgets.QSpacerItem(20, 4, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) layout.addItem(spacer) # add variant button addVariantBtn = QtWidgets.QPushButton(variantHeader) addVariantBtn.setText('+') addVariantBtn.setFixedSize(QtCore.QSize(20, 20)) addVariantBtn.clicked.connect(self.addVariant) variantHeaderLayout.addWidget(addVariantBtn) # variant list layout self.variantListLayout = QtWidgets.QVBoxLayout(parent) self.variantListLayout.setContentsMargins(0, 0, 0, 0) self.variantListLayout.setSpacing(4) layout.addLayout(self.variantListLayout)
def createAttrForm(self, actionData, attr, parent): isVariant = False # duck type of actionProxy if hasattr(actionData, 'isVariantAttr'): isVariant = actionData.isVariantAttr(attr['name']) if isVariant: attrForm = BatchAttrForm.createForm(self.index, attr, parent=parent) else: attrForm = ActionAttrForm.createForm(self.index, attr, self.variantIndex, parent=parent) attrForm.isBatchForm = isVariant # add toggle variant button to label layout toggleVariantBtn = QtWidgets.QPushButton(parent) toggleVariantBtn.setCheckable(True) toggleVariantBtn.setText("·") toggleVariantBtn.setFixedSize(QtCore.QSize(14, 20)) attrForm.labelLayout.insertWidget(0, toggleVariantBtn) attrForm.labelLayout.setAlignment(toggleVariantBtn, QtCore.Qt.AlignTop) toggleVariantBtn.clicked.connect( partial(self.toggleIsVariantAttr, attr['name'])) attrForm.toggleVariantBtn = toggleVariantBtn return attrForm
def setupDefaultFormUi(self, parent): """ Optional UI setup that builds a standardized layout. Includes a form layout and a label with the attributes name. Should be called at the start of setupUi if desired. """ self.formLayout = QtWidgets.QFormLayout(parent) # margin that will give us some visible area of # the frame that can change color based on valid state self.formLayout.setMargin(2) self.formLayout.setFieldGrowthPolicy( QtWidgets.QFormLayout.ExpandingFieldsGrow) self.formLayout.setLabelAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTop | QtCore.Qt.AlignTrailing) self.formLayout.setHorizontalSpacing(10) # attribute name self.labelLayout = QtWidgets.QHBoxLayout(parent) self.label = QtWidgets.QLabel(parent) self.label.setMinimumSize( QtCore.QSize(self.LABEL_WIDTH, self.LABEL_HEIGHT)) self.label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignTop) # add some space above the label so it lines up self.label.setMargin(2) self.label.setText(pulse.names.toTitle(self.attr['name'])) self.labelLayout.addWidget(self.label) self.formLayout.setLayout(0, QtWidgets.QFormLayout.LabelRole, self.labelLayout)
class BlueprintEditorWindow(PulseWindow): OBJECT_NAME = 'pulseBlueprintEditorWindow' PREFERRED_SIZE = QtCore.QSize(400, 300) STARTING_SIZE = QtCore.QSize(400, 300) MINIMUM_SIZE = QtCore.QSize(400, 300) WINDOW_MODULE = 'pulse.views.blueprinteditor' def __init__(self, parent=None): super(BlueprintEditorWindow, self).__init__(parent=parent) self.setWindowTitle('Pulse Blueprint Editor') layout = QtWidgets.QVBoxLayout(self) self.setLayout(layout) widget = BlueprintEditorWidget(self) layout.addWidget(widget)
def setupUi(self, parent): super(BatchActionForm, self).setupUi(parent) # add action conversion button to header convertToActionBtn = QtWidgets.QPushButton(parent) convertToActionBtn.setIcon( viewutils.getIcon("convertBatchToAction.png")) convertToActionBtn.setFixedSize(QtCore.QSize(18, 18)) convertToActionBtn.clicked.connect(self.convertToActionClicked.emit) self.headerLayout.addWidget(convertToActionBtn)
def createControlShapeButton(text, shapeData): btn = QtWidgets.QPushButton(parent) btn.setStatusTip("Create a new control") if 'icon' in shapeData: btn.setIcon(getIcon("controls/" + shapeData["icon"])) btn.setIconSize(QtCore.QSize(32, 32)) else: btn.setText(text) btn.clicked.connect( cmd(pulse.controlshapes.createControlsForSelected, shapeData)) return btn
class QuickNameWindow(PulseWindow): OBJECT_NAME = 'pulseQuickNameWindow' PREFERRED_SIZE = QtCore.QSize(400, 300) STARTING_SIZE = QtCore.QSize(400, 300) MINIMUM_SIZE = QtCore.QSize(400, 300) WINDOW_MODULE = 'pulse.views.quickname' def __init__(self, parent=None): super(QuickNameWindow, self).__init__(parent=parent) self.setWindowTitle('Quick Name Editor') layout = QtWidgets.QVBoxLayout(self) layout.setMargin(0) self.setLayout(layout) widget = QuickNameWidget(self) layout.addWidget(widget)
class CopyPastMatrixWindow(PulseWindow): OBJECT_NAME = 'pulseCopyPasteMatrixWindow' PREFERRED_SIZE = QtCore.QSize(220, 160) STARTING_SIZE = QtCore.QSize(220, 160) MINIMUM_SIZE = QtCore.QSize(220, 160) REQUIRED_PLUGINS = [] WINDOW_MODULE = 'pulse.views.utilviews' def __init__(self, parent=None): super(CopyPastMatrixWindow, self).__init__(parent=parent) self.setWindowTitle('Copy Paste Matrix') layout = QtWidgets.QVBoxLayout(self) self.setLayout(layout) widget = CopyPastMatrixWidget(self) layout.addWidget(widget)
def setupVariantsUi(self, parent): viewutils.clearLayout(self.variantLayout) self.variantsLabel.setText("Variants: {0}".format( len(self.buildItem.variantValues))) for i, variant in enumerate(self.buildItem.variantValues): if i > 0: # divider line dividerLine = QtWidgets.QFrame(parent) dividerLine.setStyleSheet( ".QFrame{ background-color: rgb(0, 0, 0, 15); border-radius: 2px }" ) dividerLine.setMinimumHeight(2) self.variantLayout.addWidget(dividerLine) variantHLayout = QtWidgets.QHBoxLayout(parent) # remove variant button removeVariantBtn = QtWidgets.QPushButton(parent) removeVariantBtn.setText('x') removeVariantBtn.setFixedSize(QtCore.QSize(20, 20)) removeVariantBtn.clicked.connect( partial(self.removeVariantAtIndex, i)) variantHLayout.addWidget(removeVariantBtn) # create attr form for all variant attributes variantVLayout = QtWidgets.QVBoxLayout(parent) variantVLayout.setSpacing(0) variantHLayout.addLayout(variantVLayout) if self.buildItem.variantAttributes: for attr in self.buildItem.actionClass.config['attrs']: if attr['name'] not in self.buildItem.variantAttributes: continue attrValue = variant[attr['name']] # context = variant attrForm = ActionAttrForm.createForm(attr, attrValue, parent=parent) attrForm.valueChanged.connect( partial(self.attrValueChanged, variant, attrForm)) variantVLayout.addWidget(attrForm) else: noAttrsLabel = QtWidgets.QLabel(parent) noAttrsLabel.setText("No variant attributes") noAttrsLabel.setMinimumHeight(24) noAttrsLabel.setContentsMargins(10, 0, 0, 0) noAttrsLabel.setEnabled(False) variantVLayout.addWidget(noAttrsLabel) self.variantLayout.addLayout(variantHLayout)
def setupContentUi(self, parent): """ Build the content ui for this BatchBuildAction. Creates ui to manage the array of variant attributes. """ # constants main layout self.constantsLayout = QtWidgets.QVBoxLayout(parent) self.constantsLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addLayout(self.constantsLayout) spacer = QtWidgets.QSpacerItem(20, 4, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.mainLayout.addItem(spacer) # variant header variantHeader = QtWidgets.QFrame(parent) variantHeader.setStyleSheet( ".QFrame{ background-color: rgb(255, 255, 255, 15); border-radius: 2px }" ) self.mainLayout.addWidget(variantHeader) variantHeaderLayout = QtWidgets.QHBoxLayout(variantHeader) variantHeaderLayout.setContentsMargins(10, 4, 4, 4) variantHeaderLayout.setSpacing(4) self.variantsLabel = QtWidgets.QLabel(variantHeader) self.variantsLabel.setText("Variants: {0}".format( len(self.buildItem.variantValues))) variantHeaderLayout.addWidget(self.variantsLabel) spacer = QtWidgets.QSpacerItem(20, 4, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.mainLayout.addItem(spacer) # add variant button addVariantBtn = QtWidgets.QPushButton(variantHeader) addVariantBtn.setText('+') addVariantBtn.setFixedSize(QtCore.QSize(20, 20)) addVariantBtn.clicked.connect(self.addVariant) variantHeaderLayout.addWidget(addVariantBtn) # variant list main layout self.variantLayout = QtWidgets.QVBoxLayout(parent) self.variantLayout.setContentsMargins(0, 0, 0, 0) self.variantLayout.setSpacing(4) self.mainLayout.addLayout(self.variantLayout) self.setupConstantsUi(parent) self.setupVariantsUi(parent)
def setupUi(self, parent): hlayout = QtWidgets.QHBoxLayout(parent) hlayout.setContentsMargins(2, 2, 2, 2) pickButton = QtWidgets.QPushButton(parent) pickButton.setIcon(viewutils.getIcon("select.png")) pickButton.setFixedSize(QtCore.QSize(20, 20)) pickButton.clicked.connect(self.setFromSelection) hlayout.addWidget(pickButton) hlayout.setAlignment(pickButton, QtCore.Qt.AlignTop) # body spacer spacer = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) hlayout.addItem(spacer)
def createVariantActionDataForm(self, variantIndex, parent): """ Create a widget that wraps a BuildActionDataForm widget for use in the variants list. Adds a button to remove the variant. """ dataForm = BuildActionDataForm(self.index, variantIndex, parent=parent) # add remove variant button removeVariantBtn = QtWidgets.QPushButton(parent) removeVariantBtn.setText('x') removeVariantBtn.setFixedSize(QtCore.QSize(20, 20)) removeVariantBtn.clicked.connect( partial(self.removeVariantAtIndex, variantIndex)) dataForm.layout.insertWidget(0, removeVariantBtn) return dataForm
class PulseEditorWindow(PulseWindow): """ An all-in-one window that contains all pulse editors. """ OBJECT_NAME = 'pulseEditorWindow' STARTING_SIZE = QtCore.QSize(400, 600) PREFERRED_SIZE = QtCore.QSize(400, 600) MINIMUM_SIZE = QtCore.QSize(400, 600) WINDOW_MODULE = 'pulse.views.pulseeditor' mainTabIndex = optionVarProperty('pulse.editor.mainTabIndex', 0) actionsTabIndex = optionVarProperty('pulse.editor.actionsTabIndex', 0) def setMainTabIndex(self, index): self.mainTabIndex = index def setActionsTabIndex(self, index): self.actionsTabIndex = index def __init__(self, parent=None): super(PulseEditorWindow, self).__init__(parent=parent) self.setWindowTitle('Pulse') pulse.loadBuiltinActions() self.setupUi(self) self.mainTabWidget.setCurrentIndex(self.mainTabIndex) self.actionsTabWidget.setCurrentIndex(self.actionsTabIndex) # connect signals self.mainTabWidget.currentChanged.connect(self.setMainTabIndex) self.actionsTabWidget.currentChanged.connect(self.setActionsTabIndex) def setupUi(self, parent): layout = QtWidgets.QVBoxLayout(parent) layout.setMargin(0) self.setLayout(layout) buildToolbar = BuildToolbarWidget(parent) layout.addWidget(buildToolbar) # main tab widget (Config / Design / Actions) tabWidget = QtWidgets.QTabWidget(parent) # config tab configTab = BlueprintEditorWidget(parent) tabWidget.addTab(configTab, "Config") # design tab designTab = DesignViewWidget(parent) tabWidget.addTab(designTab, "Design") # actions tab actionsTab = QtWidgets.QWidget(parent) actionsLayout = QtWidgets.QVBoxLayout(actionsTab) actionsSplitter = QtWidgets.QSplitter(parent) actionsSplitter.setOrientation(QtCore.Qt.Orientation.Vertical) actionsLayout.addWidget(actionsSplitter) actionTree = ActionTreeWidget(actionsTab) actionTree.layout().setMargin(0) actionsSplitter.addWidget(actionTree) # actions tab widget (Palette / Editor) actionsTabWidget = QtWidgets.QTabWidget(parent) actionsSplitter.addWidget(actionsTabWidget) actionPalette = ActionPaletteWidget(actionsTab) actionPalette.layout().setMargin(0) actionsTabWidget.addTab(actionPalette, "Palette") actionEditor = ActionEditorWidget(actionsTab) actionEditor.layout().setMargin(0) actionsTabWidget.addTab(actionEditor, "Editor") tabWidget.addTab(actionsTab, "Actions") layout.addWidget(tabWidget) self.mainTabWidget = tabWidget self.actionsTabWidget = actionsTabWidget
def setupConstantsUi(self, parent): viewutils.clearLayout(self.constantsLayout) # create attr form all constant attributes for attr in self.buildItem.actionClass.config['attrs']: isConstant = (attr['name'] in self.buildItem.constantValues) # make an HBox with a button to toggle variant state attrHLayout = QtWidgets.QHBoxLayout(parent) attrHLayout.setSpacing(10) attrHLayout.setMargin(0) self.constantsLayout.addLayout(attrHLayout) if isConstant: # constant value, make an attr form attrValue = self.buildItem.constantValues[attr['name']] context = self.buildItem.constantValues attrForm = ActionAttrForm.createForm(attr, attrValue, parent=parent) attrForm.valueChanged.connect( partial(self.attrValueChanged, context, attrForm)) attrHLayout.addWidget(attrForm) else: # variant value, check for batch editor, or just display a label attrLabel = QtWidgets.QLabel(parent) # extra 2 to account for the left-side frame padding that occurs in the ActionAttrForm attrLabel.setFixedSize( QtCore.QSize(ActionAttrForm.LABEL_WIDTH + 2, ActionAttrForm.LABEL_HEIGHT)) attrLabel.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignTop) attrLabel.setMargin(2) attrLabel.setText(pulse.names.toTitle(attr['name'])) attrLabel.setEnabled(False) attrHLayout.addWidget(attrLabel) if BatchAttrForm.doesFormExist(attr): batchEditor = BatchAttrForm.createForm(self.buildItem, attr, parent=parent) batchEditor.valuesChanged.connect( self.batchEditorValuesChanged) attrHLayout.addWidget(batchEditor) else: spacer = QtWidgets.QSpacerItem( 24, 24, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) attrHLayout.addItem(spacer) # not a constant value, add a line with button to make it constant # button to toggle variant toggleVariantBtn = QtWidgets.QPushButton(parent) toggleVariantBtn.setText("v") toggleVariantBtn.setFixedSize(QtCore.QSize(20, 20)) toggleVariantBtn.setCheckable(True) toggleVariantBtn.setChecked(not isConstant) attrHLayout.addWidget(toggleVariantBtn) attrHLayout.setAlignment(toggleVariantBtn, QtCore.Qt.AlignTop) toggleVariantBtn.clicked.connect( partial(self.setIsVariantAttr, attr['name'], isConstant))
class PulseEditorWindow(PulseWindow): """ An all-in-one window that contains all pulse editors. """ OBJECT_NAME = 'pulseEditorWindow' STARTING_SIZE = QtCore.QSize(400, 600) PREFERRED_SIZE = QtCore.QSize(400, 600) MINIMUM_SIZE = QtCore.QSize(400, 600) WINDOW_MODULE = 'pulse.views.pulseeditor' mainTabIndex = optionVarProperty('pulse.editor.mainTabIndex', 0) actionsTabIndex = optionVarProperty('pulse.editor.actionsTabIndex', 0) def setMainTabIndex(self, index): self.mainTabIndex = index def setActionsTabIndex(self, index): self.actionsTabIndex = index def __init__(self, parent=None): super(PulseEditorWindow, self).__init__(parent=parent) self.setWindowTitle('Pulse') pulse.loadBuiltinActions() self.blueprintModel = BlueprintUIModel.getDefaultModel() self.setupUi(self) self.setupMenuBar(self) self.mainTabWidget.setCurrentIndex(self.mainTabIndex) self.actionsTabWidget.setCurrentIndex(self.actionsTabIndex) # connect signals self.mainTabWidget.currentChanged.connect(self.setMainTabIndex) self.actionsTabWidget.currentChanged.connect(self.setActionsTabIndex) def setupUi(self, parent): layout = QtWidgets.QVBoxLayout(parent) layout.setMargin(0) self.setLayout(layout) buildToolbar = BuildToolbarWidget(parent) layout.addWidget(buildToolbar) # main tab widget (Manage / Design / Actions) tabWidget = QtWidgets.QTabWidget(parent) # manage tab manageTab = ManageWidget(parent) tabWidget.addTab(manageTab, "Manage") # design tab designTab = DesignViewWidget(parent) tabWidget.addTab(designTab, "Design") # actions tab actionsTab = QtWidgets.QWidget(parent) actionsLayout = QtWidgets.QVBoxLayout(actionsTab) actionsSplitter = QtWidgets.QSplitter(parent) actionsSplitter.setOrientation(QtCore.Qt.Orientation.Vertical) actionsLayout.addWidget(actionsSplitter) actionTree = ActionTreeWidget(actionsTab) actionTree.layout().setMargin(0) actionsSplitter.addWidget(actionTree) # actions tab widget (Palette / Editor) actionsTabWidget = QtWidgets.QTabWidget(parent) actionsSplitter.addWidget(actionsTabWidget) actionPalette = ActionPaletteWidget(actionsTab) actionPalette.layout().setMargin(0) actionsTabWidget.addTab(actionPalette, "Palette") actionEditor = ActionEditorWidget(actionsTab) actionEditor.layout().setMargin(0) actionsTabWidget.addTab(actionEditor, "Editor") tabWidget.addTab(actionsTab, "Actions") layout.addWidget(tabWidget) self.mainTabWidget = tabWidget self.actionsTabWidget = actionsTabWidget def setupMenuBar(self, parent): self.menuBar = QtWidgets.QMenuBar(parent) self.layout().setMenuBar(self.menuBar) fileMenu = self.menuBar.addMenu("Blueprint") autosaveCheck = QtWidgets.QAction("Auto Save", parent) autosaveCheck.setCheckable(True) autosaveCheck.setChecked(self.blueprintModel.autoSave) autosaveCheck.toggled.connect(self.blueprintModel.setAutoSave) autosaveCheck.setStatusTip( "Automatically save Blueprint files when a scene is saved") fileMenu.addAction(autosaveCheck) autoloadCheck = QtWidgets.QAction("Auto Load", parent) autoloadCheck.setCheckable(True) autoloadCheck.setChecked(self.blueprintModel.autoLoad) autoloadCheck.toggled.connect(self.blueprintModel.setAutoLoad) autoloadCheck.setStatusTip( "Automatically load Blueprint files when a scene is opened") fileMenu.addAction(autoloadCheck) saveAction = QtWidgets.QAction("Save", parent) saveAction.setStatusTip( "Save the Blueprint as a yaml file associated with the current maya scene file" ) saveAction.triggered.connect(self.blueprintModel.save) fileMenu.addAction(saveAction) reloadAction = QtWidgets.QAction("Reload", parent) reloadAction.setStatusTip( "Reload the Blueprint from the yaml file associated with the current maya scene file" ) reloadAction.triggered.connect(self.blueprintModel.load) fileMenu.addAction(reloadAction) fileMenu.addSeparator() reloadAction = QtWidgets.QAction("Clear", parent) reloadAction.setStatusTip( "Delete all actions and reset the Blueprint.") reloadAction.triggered.connect(self.blueprintModel.initializeBlueprint) fileMenu.addAction(reloadAction) reloadAction = QtWidgets.QAction("Create Default Actions", parent) reloadAction.setStatusTip( "Reset the Blueprint to the default set of actions.") reloadAction.triggered.connect( self.blueprintModel.initializeBlueprintToDefaultActions) fileMenu.addAction(reloadAction) fileMenu.addSeparator() debugPrintAction = QtWidgets.QAction("Debug Print YAML", parent) debugPrintAction.triggered.connect(self.debugPrintSerialized) fileMenu.addAction(debugPrintAction) def debugPrintSerialized(self): print(self.blueprintModel, self.blueprintModel.blueprint) print(self.blueprintModel.getBlueprintFilepath()) print(self.blueprintModel.blueprint.dumpYaml())
class PulseWindow(MayaQWidgetDockableMixin, QtWidgets.QWidget): """ A base class for any standalone window in the Pulse UI. Integrates the Maya builtin dockable mixin, and prevents multiple instances of the window. """ OBJECT_NAME = None PREFERRED_SIZE = QtCore.QSize(200, 400) STARTING_SIZE = QtCore.QSize(200, 400) MINIMUM_SIZE = QtCore.QSize(200, 400) # the name of the module in which this window class can be found # used to build the UI_SCRIPT and CLOSE_SCRIPT WINDOW_MODULE = None # a string of python code to run when the workspace control is shown UI_SCRIPT = 'from {module} import {cls}\n{cls}.createWindow(restore=True)' # a string of python code to run when the workspace control is closed CLOSE_SCRIPT = 'from {module} import {cls}\n{cls}.windowClosed()' REQUIRED_PLUGINS = ['pulse'] # reference to singleton instance INSTANCE = None @classmethod def createWindow(cls, restore=False): if restore: parent = mui.MQtUtil.getCurrentParent() # create instance if it doesn't exists if not cls.INSTANCE: # load required plugins if cls.REQUIRED_PLUGINS: for plugin in cls.REQUIRED_PLUGINS: pm.loadPlugin(plugin, quiet=True) cls.INSTANCE = cls() if restore: mixinPtr = mui.MQtUtil.findControl(cls.INSTANCE.objectName()) mui.MQtUtil.addWidgetToMayaLayout(long(mixinPtr), long(parent)) else: uiScript = cls.UI_SCRIPT.format(module=cls.WINDOW_MODULE, cls=cls.__name__) closeScript = cls.CLOSE_SCRIPT.format(module=cls.WINDOW_MODULE, cls=cls.__name__) cls.INSTANCE.show(dockable=True, uiScript=uiScript, closeCallback=closeScript, requiredPlugin=cls.REQUIRED_PLUGINS) return cls.INSTANCE @classmethod def destroyWindow(cls): if cls.windowExists(): cls.hideWindow() cmds.deleteUI(cls.getWorkspaceControlName(), control=True) @classmethod def showWindow(cls): if cls.windowExists(): cmds.workspaceControl(cls.getWorkspaceControlName(), e=True, vis=True) else: cls.createWindow() @classmethod def hideWindow(cls): """ Close the window, if it exists """ if cls.windowExists(): cmds.workspaceControl(cls.getWorkspaceControlName(), e=True, vis=False) @classmethod def toggleWindow(cls): if cls.windowVisible(): cls.hideWindow() else: cls.showWindow() @classmethod def windowClosed(cls): cls.INSTANCE = None @classmethod def windowExists(cls): """ Return True if an instance of this window exists """ return cmds.workspaceControl(cls.getWorkspaceControlName(), q=True, ex=True) @classmethod def windowVisible(cls): return cls.windowExists() and cmds.workspaceControl( cls.getWorkspaceControlName(), q=True, vis=True) @classmethod def getWorkspaceControlName(cls): return cls.OBJECT_NAME + 'WorkspaceControl' def __init__(self, parent=None): super(PulseWindow, self).__init__(parent=parent) self.setObjectName(self.OBJECT_NAME) self.preferredSize = self.PREFERRED_SIZE self.resize(dpiScale(self.STARTING_SIZE)) def setSizeHint(self, size): self.preferredSize = size def sizeHint(self): return self.preferredSize def minimumSizeHint(self): return self.MINIMUM_SIZE