224 lines
6.3 KiB
Python
224 lines
6.3 KiB
Python
from maya import OpenMayaUI as omui
|
|
from maya import cmds
|
|
|
|
from ngSkinTools2.api.log import getLogger
|
|
from ngSkinTools2.api.pyside import QtCore, QtGui, QtWidgets, QWidget, wrap_instance
|
|
from ngSkinTools2.api.session import session
|
|
from ngSkinTools2.ui.options import config
|
|
|
|
from .. import cleanup, signal, version
|
|
from ..observableValue import ObservableValue
|
|
from . import (
|
|
aboutwindow,
|
|
dialogs,
|
|
hotkeys_setup,
|
|
qt,
|
|
tabLayerEffects,
|
|
tabMirror,
|
|
tabPaint,
|
|
tabSetWeights,
|
|
tabTools,
|
|
targetui,
|
|
updatewindow,
|
|
)
|
|
from .layout import scale_multiplier
|
|
|
|
log = getLogger("main window")
|
|
|
|
|
|
def get_image_path(file_name):
|
|
import os
|
|
|
|
for i in os.getenv("XBMLANGPATH", "").split(os.path.pathsep):
|
|
result = os.path.join(i, file_name)
|
|
if os.path.isfile(result):
|
|
return result
|
|
|
|
return file_name
|
|
|
|
|
|
def build_menu(parent, actions):
|
|
menu = QtWidgets.QMenuBar(parent=parent)
|
|
|
|
def top_level_menu(label):
|
|
sub_item = menu.addMenu(label)
|
|
sub_item.setSeparatorsCollapsible(False)
|
|
sub_item.setTearOffEnabled(True)
|
|
return sub_item
|
|
|
|
sub = top_level_menu("File")
|
|
sub.addSeparator().setText("Import/Export")
|
|
sub.addAction(actions.importFile)
|
|
sub.addAction(actions.exportFile)
|
|
|
|
sub = top_level_menu("Layers")
|
|
sub.addSeparator().setText("Layer actions")
|
|
sub.addAction(actions.initialize)
|
|
sub.addAction(actions.import_v1)
|
|
actions.addLayersActions(sub)
|
|
sub.addSeparator().setText("Copy")
|
|
sub.addAction(actions.transfer)
|
|
|
|
sub = top_level_menu("Tools")
|
|
sub.addAction(actions.add_influences)
|
|
sub.addAction(actions.toolsAssignFromClosestJoint)
|
|
sub.addSeparator()
|
|
sub.addAction(actions.transfer)
|
|
sub.addSeparator()
|
|
sub.addAction(actions.toolsDeleteCustomNodesOnSelection)
|
|
sub.addAction(actions.toolsDeleteCustomNodes)
|
|
|
|
sub = top_level_menu("View")
|
|
sub.addAction(actions.show_used_influences_only)
|
|
|
|
sub = top_level_menu("Help")
|
|
sub.addAction(actions.documentation.user_guide)
|
|
sub.addAction(actions.documentation.api_root)
|
|
sub.addAction(actions.documentation.changelog)
|
|
sub.addAction(actions.documentation.contact)
|
|
sub.addSeparator()
|
|
sub.addAction(actions.check_for_updates)
|
|
sub.addAction("About...").triggered.connect(lambda: aboutwindow.show(parent))
|
|
|
|
return menu
|
|
|
|
|
|
def build_rmb_menu_layers(view, actions):
|
|
view.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
|
|
actions.addLayersActions(view)
|
|
|
|
|
|
class MainWindowOptions:
|
|
current_tab = ObservableValue(0)
|
|
|
|
|
|
def build_ui(parent):
|
|
"""
|
|
:type parent: QWidget
|
|
"""
|
|
options = MainWindowOptions()
|
|
window = QtWidgets.QWidget(parent)
|
|
|
|
session.addQtWidgetReference(window)
|
|
|
|
from ngSkinTools2.ui.actions import Actions
|
|
|
|
actions = Actions(parent=window, session=session)
|
|
|
|
tabs = QtWidgets.QTabWidget(window)
|
|
|
|
tabs.addTab(tabPaint.build_ui(tabs, actions), "Paint")
|
|
tabs.addTab(tabSetWeights.build_ui(tabs), "Set Weights")
|
|
tabs.addTab(tabMirror.build_ui(tabs), "Mirror")
|
|
tabs.addTab(tabLayerEffects.build_ui(), "Effects")
|
|
tabs.addTab(tabTools.build_ui(actions, session), "Tools")
|
|
|
|
@signal.on(options.current_tab.changed)
|
|
def set_current_tab():
|
|
tabs.setCurrentIndex(options.current_tab())
|
|
|
|
layers_toolbar = QtWidgets.QToolBar()
|
|
layers_toolbar.addAction(actions.addLayer)
|
|
layers_toolbar.setOrientation(QtCore.Qt.Vertical)
|
|
|
|
spacing_h = 5
|
|
spacing_v = 5
|
|
|
|
layers_row = targetui.build_target_ui(window, actions, session)
|
|
|
|
split = QtWidgets.QSplitter(orientation=QtCore.Qt.Vertical, parent=window)
|
|
split.addWidget(layers_row)
|
|
split.addWidget(tabs)
|
|
split.setStretchFactor(0, 2)
|
|
split.setStretchFactor(1, 3)
|
|
split.setContentsMargins(spacing_h, spacing_v, spacing_h, spacing_v)
|
|
|
|
def build_icon_label():
|
|
w = QWidget()
|
|
w.setStyleSheet("background-color: #dcce87;color: #373737;")
|
|
l = QtWidgets.QHBoxLayout()
|
|
icon = QtWidgets.QLabel()
|
|
icon.setPixmap(QtGui.QIcon(":/error.png").pixmap(16 * scale_multiplier, 16 * scale_multiplier))
|
|
icon.setFixedSize(16 * scale_multiplier, 16 * scale_multiplier)
|
|
text = QtWidgets.QLabel("<placeholder>")
|
|
text.setWordWrap(True)
|
|
text.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
|
|
|
|
l.addWidget(icon)
|
|
l.addWidget(text)
|
|
w.setContentsMargins(0, 0, 0, 0)
|
|
w.setLayout(l)
|
|
|
|
return w, text.setText
|
|
|
|
layout = QtWidgets.QVBoxLayout(window)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
layout.addWidget(build_menu(window, actions))
|
|
layout.addWidget(split)
|
|
|
|
window.setLayout(layout)
|
|
|
|
hotkeys_setup.install_hotkeys()
|
|
|
|
dialogs.promptsParent = window
|
|
|
|
if config.checkForUpdatesAtStartup():
|
|
updatewindow.silent_check_and_show_if_available(qt.mainWindow)
|
|
|
|
return window, options
|
|
|
|
|
|
DOCK_NAME = 'ngSkinTools2_mainWindow'
|
|
|
|
|
|
def workspace_control_permanent_script():
|
|
from ngSkinTools2 import workspace_control_main_window
|
|
|
|
return "import {f.__module__}; {f.__module__}.{f.__name__}()".format(f=workspace_control_main_window)
|
|
|
|
|
|
# noinspection PyShadowingBuiltins
|
|
def open():
|
|
"""
|
|
opens main window
|
|
"""
|
|
|
|
if not cmds.workspaceControl(DOCK_NAME, q=True, exists=True):
|
|
# build UI script in type-safe manner
|
|
|
|
cmds.workspaceControl(
|
|
DOCK_NAME,
|
|
retain=False,
|
|
floating=True,
|
|
# ttc=["AttributeEditor",-1],
|
|
uiScript=workspace_control_permanent_script(),
|
|
)
|
|
|
|
# bring tab to front
|
|
cmds.evalDeferred(lambda *args: cmds.workspaceControl(DOCK_NAME, e=True, r=True))
|
|
|
|
def close():
|
|
from maya import cmds
|
|
|
|
# noinspection PyBroadException
|
|
try:
|
|
cmds.deleteUI(DOCK_NAME)
|
|
except:
|
|
pass
|
|
pass
|
|
|
|
cleanup.registerCleanupHandler(close)
|
|
|
|
|
|
def resume_in_workspace_control():
|
|
"""
|
|
this method is responsible for resuming workspace control when Maya is building/restoring UI as part of it's
|
|
workspace management cycle (open UI for the first time, restart maya, change workspace, etc)
|
|
"""
|
|
|
|
cmds.workspaceControl(DOCK_NAME, e=True, label="ngSkinTools " + version.pluginVersion())
|
|
widget = wrap_instance(omui.MQtUtil.findControl(DOCK_NAME), QtWidgets.QWidget)
|
|
|
|
ui, _ = build_ui(widget)
|
|
widget.layout().addWidget(ui)
|