1320 lines
43 KiB
Python
1320 lines
43 KiB
Python
|
"""
|
||
|
|
||
|
License:
|
||
|
This collection of code named GS CurveTools is a property of George Sladkovsky (Yehor Sladkovskyi)
|
||
|
and can not be copied or distributed without his written permission.
|
||
|
|
||
|
GS CurveTools v1.3.1 Studio
|
||
|
Copyright 2023, George Sladkovsky (Yehor Sladkovskyi)
|
||
|
All Rights Reserved
|
||
|
|
||
|
Autodesk Maya is a property of Autodesk, Inc.
|
||
|
|
||
|
Social Media and Contact Links:
|
||
|
|
||
|
Discord Server: https://discord.gg/f4DH6HQ
|
||
|
Online Store: https://sladkovsky3d.artstation.com/store
|
||
|
Online Documentation: https://gs-curvetools.readthedocs.io/
|
||
|
Twitch Channel: https://www.twitch.tv/videonomad
|
||
|
YouTube Channel: https://www.youtube.com/c/GeorgeSladkovsky
|
||
|
ArtStation Portfolio: https://www.artstation.com/sladkovsky3d
|
||
|
Contact Email: george.sladkovsky@gmail.com
|
||
|
|
||
|
"""
|
||
|
|
||
|
import re
|
||
|
from functools import partial as pa
|
||
|
from imp import reload
|
||
|
|
||
|
import maya.cmds as mc
|
||
|
import maya.OpenMayaUI as omui
|
||
|
from PySide2 import QtCore, QtGui, QtWidgets
|
||
|
from shiboken2 import wrapInstance
|
||
|
|
||
|
from . import style, tooltips, utils
|
||
|
|
||
|
TOOLTIPS_DICT = tooltips.processTooltips()
|
||
|
|
||
|
reload(utils)
|
||
|
reload(style)
|
||
|
reload(tooltips)
|
||
|
|
||
|
# Holds the names and pointers to all controls
|
||
|
try:
|
||
|
bool(WIDGETS) # type: ignore # pylint: disable=used-before-assignment
|
||
|
except BaseException:
|
||
|
WIDGETS = {}
|
||
|
|
||
|
|
||
|
def getUniqueName(name):
|
||
|
from ..main import MAIN_WINDOW_NAME
|
||
|
return (MAIN_WINDOW_NAME + "_" + name)
|
||
|
|
||
|
|
||
|
def wrapControl(name):
|
||
|
name = omui.MQtUtil.findControl(name)
|
||
|
return wrapInstance(int(name), QtWidgets.QWidget)
|
||
|
|
||
|
|
||
|
def separator():
|
||
|
name = omui.MQtUtil.findControl(mc.separator(st='in'))
|
||
|
return wrapInstance(int(name), QtWidgets.QWidget)
|
||
|
|
||
|
# Layouts
|
||
|
|
||
|
|
||
|
class Layout(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, parent, objName='', spacing=2,
|
||
|
margin=0, margins=[0, 0, 0, 0], vis=True):
|
||
|
super(Layout, self).__init__()
|
||
|
if objName:
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
self.__parent = parent
|
||
|
self.__spacing = spacing
|
||
|
self.__margin = margin
|
||
|
self.__margins = margins
|
||
|
self.__visibility = vis
|
||
|
|
||
|
def __enter__(self):
|
||
|
layout = QtWidgets.QVBoxLayout(self)
|
||
|
layout.setContentsMargins(*self.__margins)
|
||
|
layout.setMargin(self.__margin)
|
||
|
layout.setSpacing(self.__spacing)
|
||
|
layout.addWidget(self)
|
||
|
self.setVisible(self.__visibility)
|
||
|
return self
|
||
|
|
||
|
def __exit__(self, *_):
|
||
|
self.__parent.addWidget(self)
|
||
|
|
||
|
|
||
|
class Row(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, parent, objName='', spacing=2, margins=[0, 0, 0, 0]):
|
||
|
super(Row, self).__init__()
|
||
|
if objName:
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.__parent = parent
|
||
|
self.__spacing = spacing
|
||
|
self.__margins = margins
|
||
|
|
||
|
def __enter__(self):
|
||
|
row = QtWidgets.QHBoxLayout(self)
|
||
|
row.setSpacing(self.__spacing)
|
||
|
row.setContentsMargins(*self.__margins)
|
||
|
return self
|
||
|
|
||
|
def __exit__(self, *_):
|
||
|
self.__parent.addWidget(self)
|
||
|
|
||
|
|
||
|
class Column(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, parent, objName='', spacing=2, margins=[0, 0, 0, 0]):
|
||
|
super(Column, self).__init__()
|
||
|
if objName:
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
self.__parent = parent
|
||
|
self.__spacing = spacing
|
||
|
self.__margins = margins
|
||
|
|
||
|
def __enter__(self):
|
||
|
layout = QtWidgets.QVBoxLayout(self)
|
||
|
layout.setSpacing(self.__spacing)
|
||
|
layout.setContentsMargins(*self.__margins)
|
||
|
return self
|
||
|
|
||
|
def __exit__(self, *_):
|
||
|
self.__parent.addWidget(self)
|
||
|
|
||
|
|
||
|
class Frame(QtWidgets.QFrame):
|
||
|
|
||
|
def __init__(self, parent, objName='', label=None, spacing=2, margins=[0, 0, 0, 0]):
|
||
|
super(Frame, self).__init__()
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.setAutoFillBackground(True)
|
||
|
self.setGeometry(0, 0, 0, 0)
|
||
|
|
||
|
self.mainParent = parent
|
||
|
self.frameSpacing = style.scale(spacing)
|
||
|
self.frameMargins = style.scale(margins)
|
||
|
self.frameLabel = label
|
||
|
|
||
|
self.mainLayout = QtWidgets.QVBoxLayout(self)
|
||
|
self.mainLayout.setSpacing(self.frameSpacing)
|
||
|
self.mainLayout.setContentsMargins(0, 0, 0, 0)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def eventFilter(self, object, event):
|
||
|
if object is not self.frameButton and event.type() == QtCore.QEvent.ToolTip:
|
||
|
self.enableTooltip(False)
|
||
|
elif object is self.frameButton and event.type() == QtCore.QEvent.ToolTip:
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
return super(Frame, self).eventFilter(object, event)
|
||
|
|
||
|
def __enter__(self):
|
||
|
# Layout Button
|
||
|
self.frameButton = Button(self.layout())
|
||
|
if self.frameLabel:
|
||
|
self.frameButton.setLabel(self.frameLabel)
|
||
|
self.setCollapsible(True)
|
||
|
self.frameButton.clicked.connect(pa(self.toggleCollapsed))
|
||
|
|
||
|
# Main Frame for Contents
|
||
|
self.frameWidget = QtWidgets.QWidget()
|
||
|
self.frameWidget.setContentsMargins(*self.frameMargins)
|
||
|
self.frameLayout = QtWidgets.QVBoxLayout(self.frameWidget)
|
||
|
self.frameLayout.setSpacing(self.frameSpacing)
|
||
|
self.frameLayout.setContentsMargins(*self.frameMargins)
|
||
|
self.frameWidget.installEventFilter(self)
|
||
|
self.frameButton.installEventFilter(self)
|
||
|
|
||
|
self.frameWidget.setHidden(True)
|
||
|
self.layout().addWidget(self.frameWidget)
|
||
|
return self
|
||
|
|
||
|
def __exit__(self, *_):
|
||
|
self.mainParent.addWidget(self)
|
||
|
|
||
|
def getFrameLayout(self):
|
||
|
return self.frameLayout
|
||
|
|
||
|
def setCollapsed(self, hidden=False):
|
||
|
self.frameWidget.setHidden(hidden)
|
||
|
self.frameButton.setChecked(not hidden)
|
||
|
|
||
|
def toggleCollapsed(self):
|
||
|
palette = QtGui.QPalette()
|
||
|
if self.frameWidget.isVisible():
|
||
|
self.setFrameStyle(self.NoFrame)
|
||
|
color = QtGui.QColor(0, 0, 0, 0)
|
||
|
palette.setColor(QtGui.QPalette.Background, color)
|
||
|
self.setPalette(palette)
|
||
|
self.frameWidget.setHidden(True)
|
||
|
self.frameButton.setChecked(False)
|
||
|
else:
|
||
|
self.setFrameStyle(self.Panel | self.Sunken)
|
||
|
color = QtGui.QColor(0, 0, 0, 30)
|
||
|
palette.setColor(QtGui.QPalette.Background, color)
|
||
|
self.setPalette(palette)
|
||
|
self.frameWidget.setHidden(False)
|
||
|
self.frameButton.setChecked(True)
|
||
|
|
||
|
def setCollapsible(self, collapsible):
|
||
|
if collapsible:
|
||
|
self.frameButton.setButtonStyle('frame-button')
|
||
|
self.frameButton.setCheckable(True)
|
||
|
self.frameButton.setChecked(False)
|
||
|
self.frameButton.blockSignals(False)
|
||
|
else:
|
||
|
self.frameButton.setButtonStyle('frame-button-not-collapsible')
|
||
|
self.setCollapsed(False)
|
||
|
self.frameButton.setCheckable(False)
|
||
|
self.frameButton.setChecked(False)
|
||
|
self.frameButton.blockSignals(True)
|
||
|
|
||
|
# Menu Items:
|
||
|
|
||
|
|
||
|
class Menu:
|
||
|
|
||
|
def __init__(self, label, parent, tearable=True, collapsible=False):
|
||
|
self.label = label
|
||
|
self.parent = parent
|
||
|
self.tearable = tearable
|
||
|
self.collapsible = collapsible
|
||
|
|
||
|
def __enter__(self):
|
||
|
self.menu = QtWidgets.QMenu(self.label)
|
||
|
self.menu.setToolTipsVisible(True)
|
||
|
self.menu.setTearOffEnabled(self.tearable)
|
||
|
self.menu.setSeparatorsCollapsible(self.collapsible)
|
||
|
return self.menu
|
||
|
|
||
|
def __exit__(self, *_):
|
||
|
self.parent.addMenu(self.menu)
|
||
|
|
||
|
|
||
|
class ActionGroup:
|
||
|
|
||
|
def __init__(self, objName, parent):
|
||
|
self.objName = objName
|
||
|
self.parent = parent
|
||
|
|
||
|
def __enter__(self):
|
||
|
self.group = QtWidgets.QActionGroup(self.parent)
|
||
|
if self.objName:
|
||
|
self.group.setObjectName(getUniqueName(self.objName))
|
||
|
WIDGETS[self.objName] = self.group
|
||
|
return self.group
|
||
|
|
||
|
def __exit__(self, *_):
|
||
|
pass
|
||
|
|
||
|
|
||
|
class MenuItem(QtWidgets.QAction):
|
||
|
|
||
|
def __init__(self, objName, label, parent, checkable=False, checked=False, collection=None):
|
||
|
super(MenuItem, self).__init__(label, parent)
|
||
|
self.objName = objName
|
||
|
self.setCheckable(checkable)
|
||
|
if checked:
|
||
|
self.setChecked(checked)
|
||
|
if self.objName:
|
||
|
self.setObjectName(getUniqueName(self.objName))
|
||
|
WIDGETS[self.objName] = self
|
||
|
if collection:
|
||
|
self.setActionGroup(collection)
|
||
|
parent.addAction(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
|
||
|
def mayaSlider(slider, objName='', layout=None): # TODO: Need to refactor these function to use one class for wrapping
|
||
|
slider = wrapInstance(int(omui.MQtUtil.findControl(slider)), QtWidgets.QWidget)
|
||
|
if objName:
|
||
|
slider.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = slider
|
||
|
if layout:
|
||
|
layout.addWidget(slider)
|
||
|
return slider
|
||
|
|
||
|
|
||
|
# Buttons
|
||
|
|
||
|
class Button(QtWidgets.QPushButton): # Maybe change back to the mode without inheritance
|
||
|
""" Creates a normal button """
|
||
|
markingPixmap = QtGui.QPixmap(utils.getFolder.icons() + 'marking.png')
|
||
|
modPixmap = QtGui.QPixmap(utils.getFolder.icons() + 'mod.png')
|
||
|
resetPixmap = QtGui.QPixmap(utils.getFolder.icons() + 'reset.png')
|
||
|
|
||
|
def __init__(self, layout=None, objName=''):
|
||
|
super(Button, self).__init__()
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
self.buttonStyle = ''
|
||
|
self.buttonState = 0
|
||
|
self.buttonLabels = None
|
||
|
|
||
|
if layout:
|
||
|
layout.addWidget(self)
|
||
|
|
||
|
self.setButtonStyle()
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def setLabel(self, text, margins=[0, 0, 0, 0], lineHeight=80):
|
||
|
text = self._formatText(text, lineHeight=lineHeight)
|
||
|
|
||
|
self.label = QtWidgets.QLabel(text, self)
|
||
|
|
||
|
self.label.setAlignment(QtCore.Qt.AlignCenter)
|
||
|
self.label.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
|
||
|
|
||
|
layout = QtWidgets.QHBoxLayout(self)
|
||
|
layout.setContentsMargins(*style.scale(margins))
|
||
|
layout.addWidget(self.label)
|
||
|
self.setLabelStyle()
|
||
|
|
||
|
def setLabelStyle(self, labelStyle='normal'):
|
||
|
self.font = QtGui.QFont('Roboto')
|
||
|
self.label.setFont(self.font)
|
||
|
if labelStyle == 'normal':
|
||
|
self.setFontSize(11)
|
||
|
elif labelStyle == 'small':
|
||
|
self.setFontSize(10, False)
|
||
|
|
||
|
def setButtonStyle(self, buttonStyle='normal'):
|
||
|
if buttonStyle == 'normal':
|
||
|
self.setStyleSheet(style.buttonNormal)
|
||
|
self.buttonStyle = 'normal'
|
||
|
elif buttonStyle == 'active-orange':
|
||
|
self.setStyleSheet(style.buttonActiveOrange)
|
||
|
self.buttonStyle = 'active-orange'
|
||
|
elif buttonStyle == 'active-blue':
|
||
|
self.setStyleSheet(style.buttonActiveBlue)
|
||
|
self.buttonStyle = 'active-blue'
|
||
|
elif buttonStyle == 'active-white':
|
||
|
self.setStyleSheet(style.buttonActiveWhite)
|
||
|
self.buttonStyle = 'active-white'
|
||
|
elif buttonStyle == 'small':
|
||
|
self.setStyleSheet(style.smallNormal)
|
||
|
self.buttonStyle = 'small'
|
||
|
elif buttonStyle == 'small-filled':
|
||
|
self.setStyleSheet(style.smallFilled)
|
||
|
self.buttonStyle = 'small-filled'
|
||
|
elif buttonStyle == 'small-no-border':
|
||
|
self.setStyleSheet(style.smallNoBorder)
|
||
|
self.buttonStyle = 'small-no-border'
|
||
|
elif buttonStyle == 'slider-label':
|
||
|
self.setStyleSheet(style.sliderLabel)
|
||
|
self.buttonStyle = 'slider-label'
|
||
|
elif buttonStyle == 'icon':
|
||
|
self.setStyleSheet(style.buttonIcon)
|
||
|
self.buttonStyle = 'icon-button'
|
||
|
elif buttonStyle == 'frame-button':
|
||
|
self.setStyleSheet(style.frameButton)
|
||
|
self.buttonStyle = 'frame-button'
|
||
|
elif buttonStyle == 'frame-button-not-collapsible':
|
||
|
self.setStyleSheet(style.frameButtonNotCollapsable)
|
||
|
self.buttonStyle = 'frame-button-not-collapsible'
|
||
|
elif buttonStyle == 'small-compound-top-left':
|
||
|
self.setStyleSheet(style.smallCompoundTopLeft)
|
||
|
self.buttonStyle = 'small-compound-top-left'
|
||
|
elif buttonStyle == 'small-compound-top-right':
|
||
|
self.setStyleSheet(style.smallCompoundTopRight)
|
||
|
self.buttonStyle = 'small-compound-top-right'
|
||
|
elif buttonStyle == 'small-filled-compound-bottom':
|
||
|
self.setStyleSheet(style.smallFilledCompoundBottom)
|
||
|
self.buttonStyle = 'small-filled-compound-bottom'
|
||
|
|
||
|
def setIcon(self, icoType):
|
||
|
iconMod = self.modPixmap
|
||
|
iconMarking = self.markingPixmap
|
||
|
self.modLabelMod = QtWidgets.QLabel(self)
|
||
|
self.modLabelMarking = QtWidgets.QLabel(self)
|
||
|
|
||
|
mult = 7
|
||
|
iconMod = iconMod.scaled(style.scale(mult), style.scale(mult), QtCore.Qt.KeepAspectRatio)
|
||
|
self.modLabelMod.setContentsMargins(*style.scale([2, 2, 0, 0]))
|
||
|
self.modLabelMod.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
|
||
|
self.modLabelMod.setPixmap(iconMod)
|
||
|
self.modLabelMod.setVisible(False)
|
||
|
|
||
|
iconMarking = iconMarking.scaled(style.scale(mult), style.scale(mult), QtCore.Qt.KeepAspectRatio)
|
||
|
self.modLabelMarking.setContentsMargins(*style.scale([2, 2, 0, 0]))
|
||
|
self.modLabelMarking.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
|
||
|
self.modLabelMarking.setPixmap(iconMarking)
|
||
|
self.modLabelMarking.setVisible(False)
|
||
|
|
||
|
if icoType == 'marking-top':
|
||
|
self.modLabelMarking.setVisible(True)
|
||
|
elif icoType == 'marking-bottom':
|
||
|
self.modLabelMarking.setVisible(True)
|
||
|
self.modLabelMarking.move(*style.scale([0, 16]))
|
||
|
elif icoType == 'mod-top':
|
||
|
self.modLabelMod.setVisible(True)
|
||
|
elif icoType == 'mod-bottom':
|
||
|
self.modLabelMod.setVisible(True)
|
||
|
self.modLabelMod.move(*style.scale([0, 17]))
|
||
|
elif icoType == 'both':
|
||
|
self.modLabelMod.setVisible(True)
|
||
|
self.modLabelMarking.setVisible(True)
|
||
|
self.modLabelMarking.move(*style.scale([1, 13]))
|
||
|
elif icoType == 'reset':
|
||
|
iconReset = self.resetPixmap
|
||
|
iconReset = iconReset.scaled(style.scale(11), style.scale(11), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||
|
super(Button, self).setIcon(iconReset)
|
||
|
else:
|
||
|
self.modLabelMod.setVisible(False)
|
||
|
self.modLabelMarking.setVisible(False)
|
||
|
|
||
|
def changeIcon(self, icoType):
|
||
|
if icoType == 'marking':
|
||
|
self.modLabel.setPixmap(self.markingPixmap)
|
||
|
elif icoType == 'mod-top':
|
||
|
self.modLabel.setPixmap(self.modPixmap)
|
||
|
else:
|
||
|
self.modLabel.setPixmap(self.markingModPixmap)
|
||
|
|
||
|
def setIconVisible(self, vis=True):
|
||
|
self.modLabel.setVisible(vis)
|
||
|
|
||
|
def setFontSize(self, size, bold=True):
|
||
|
font = self.label.font()
|
||
|
font.setPixelSize(style.scale(size))
|
||
|
if bold:
|
||
|
font.setBold(bold)
|
||
|
self.label.setFont(font)
|
||
|
|
||
|
def setLabelOffset(self, offsetX, offsetY, width=None, height=None):
|
||
|
if not width:
|
||
|
width = self.label.geometry().width()
|
||
|
if not height:
|
||
|
height = self.label.geometry().height()
|
||
|
rect = QtCore.QRect(offsetX, offsetY, width, height)
|
||
|
self.label.setFrameRect(rect)
|
||
|
|
||
|
def setWidthHeight(self, w=None, h=None):
|
||
|
if w:
|
||
|
self.setFixedWidth(style.scale(w))
|
||
|
if h:
|
||
|
self.setFixedHeight(style.scale(h))
|
||
|
|
||
|
def changeText(self, *_):
|
||
|
rect = self.rect().width()
|
||
|
_min = style.scale(75)
|
||
|
_max = style.scale(115)
|
||
|
if rect < _min and self.buttonState != 0:
|
||
|
text = self._formatText(self.buttonLabels[0])
|
||
|
self.label.setText(text)
|
||
|
self.buttonState = 0
|
||
|
elif _min <= rect < _max and self.buttonState != 1:
|
||
|
text = self._formatText(self.buttonLabels[1])
|
||
|
self.label.setText(text)
|
||
|
self.buttonState = 1
|
||
|
elif rect >= _max and self.buttonState != 2 and len(self.buttonLabels) > 2:
|
||
|
text = self._formatText(self.buttonLabels[2])
|
||
|
self.label.setText(text)
|
||
|
self.buttonState = 2
|
||
|
|
||
|
def setValue(self, value):
|
||
|
if self.isCheckable():
|
||
|
self.setChecked(bool(value))
|
||
|
|
||
|
def addParent(self, parent, stretch=0):
|
||
|
parent.addWidget(self, stretch)
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def _formatText(self, text, lineHeight=80):
|
||
|
if lineHeight == 100:
|
||
|
return text
|
||
|
if isinstance(text, list):
|
||
|
self.resizeEvent = self.changeText
|
||
|
self.buttonLabels = text
|
||
|
text = text[0]
|
||
|
text = '<p style="line-height:{1}%;">{0}</p>'.format(text, lineHeight)
|
||
|
return text
|
||
|
|
||
|
|
||
|
class IconCheckButton(QtWidgets.QPushButton):
|
||
|
|
||
|
def __init__(self, parent, objName=''):
|
||
|
super(IconCheckButton, self).__init__()
|
||
|
self.setContentsMargins(0, 0, 0, 0)
|
||
|
self.setStyleSheet(style.buttonIcon)
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
WIDGETS[objName] = self
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
self.setCheckable(True)
|
||
|
self.clicked.connect(self.toggleIcon)
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def setChecked(self, checked):
|
||
|
super(IconCheckButton, self).setChecked(checked)
|
||
|
self.toggleIcon()
|
||
|
|
||
|
def setIcons(self, checked, unchecked):
|
||
|
self.icons = [checked, unchecked]
|
||
|
self.switchToIcon(0)
|
||
|
|
||
|
def switchToIcon(self, iconId):
|
||
|
icon = QtGui.QIcon(self.icons[iconId])
|
||
|
self.setIcon(icon)
|
||
|
|
||
|
def setIconWidthHeight(self, w, h):
|
||
|
self.setFixedSize(QtCore.QSize(style.scale(w), style.scale(h)))
|
||
|
self.setIconSize(QtCore.QSize(style.scale(w), style.scale(h)))
|
||
|
|
||
|
def toggleIcon(self):
|
||
|
if self.isChecked():
|
||
|
self.switchToIcon(0)
|
||
|
else:
|
||
|
self.switchToIcon(1)
|
||
|
|
||
|
# Layers
|
||
|
|
||
|
|
||
|
class Layer(QtWidgets.QPushButton):
|
||
|
|
||
|
LAYERS = 20
|
||
|
|
||
|
def __init__(self, objName=None, layout=None):
|
||
|
super(Layer, self).__init__()
|
||
|
|
||
|
self.buttonStyle = 'empty'
|
||
|
|
||
|
self.setMinimumSize(1, 1)
|
||
|
self.setStyle()
|
||
|
|
||
|
self.setCheckable(True)
|
||
|
|
||
|
self.setAcceptDrops(True)
|
||
|
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
if layout:
|
||
|
layout.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def setLabel(self, label):
|
||
|
self.buttonLabel = QtWidgets.QLabel(label, self)
|
||
|
self.buttonLabel.setStyleSheet(style.layerLabel)
|
||
|
self.buttonLabel.setAlignment(QtCore.Qt.AlignCenter)
|
||
|
self.buttonLabel.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
|
||
|
buttonLayout = QtWidgets.QHBoxLayout(self)
|
||
|
buttonLayout.setContentsMargins(0, 0, 0, 0)
|
||
|
buttonLayout.addWidget(self.buttonLabel)
|
||
|
|
||
|
def changeLabel(self, text):
|
||
|
self.buttonLabel.setText(text)
|
||
|
|
||
|
def setNumberOfLayers(self, num):
|
||
|
Layer.LAYERS = num
|
||
|
|
||
|
# Set custom styles
|
||
|
def setStyle(self, buttonStyle='empty'):
|
||
|
if self.buttonStyle == 'custom':
|
||
|
return 0
|
||
|
if buttonStyle == self.buttonStyle:
|
||
|
return
|
||
|
if buttonStyle == 'empty':
|
||
|
self.setStyleSheet(style.layer('rgba(0,0,0,0)'))
|
||
|
self.buttonStyle = 'empty'
|
||
|
elif buttonStyle == 'active':
|
||
|
self.setStyleSheet(style.layer('#db9456'))
|
||
|
self.buttonStyle = 'active'
|
||
|
elif buttonStyle == 'hidden':
|
||
|
self.setStyleSheet(style.layer('#a1a1a1'))
|
||
|
self.buttonStyle = 'hidden'
|
||
|
elif buttonStyle == 'curve':
|
||
|
self.setStyleSheet(style.layer('#5285a6'))
|
||
|
self.buttonStyle = 'curve'
|
||
|
elif buttonStyle == 'geo':
|
||
|
self.setStyleSheet(style.layer('#25934e'))
|
||
|
self.buttonStyle = 'geo'
|
||
|
elif buttonStyle == 'edit':
|
||
|
self.setStyleSheet(style.layer('\
|
||
|
qlineargradient(\
|
||
|
x1: 0, y1: 0, x2: 1, y2: 1,\
|
||
|
stop: 0 #db9456, stop: 0.499 #db9456, stop: 0.501 red,stop: 1 red\
|
||
|
);'))
|
||
|
self.buttonStyle = 'edit'
|
||
|
|
||
|
def colorize(self, isColorized):
|
||
|
if isColorized:
|
||
|
self.buttonStyle = 'custom'
|
||
|
else:
|
||
|
self.buttonStyle = 'empty'
|
||
|
|
||
|
def setLayout(self, layout):
|
||
|
layout.addWidget(self)
|
||
|
|
||
|
def mousePressEvent(self, event):
|
||
|
super(Layer, self).mousePressEvent(event)
|
||
|
if event.button() == QtCore.Qt.MiddleButton:
|
||
|
drag = QtGui.QDrag(self)
|
||
|
mimeData = QtCore.QMimeData()
|
||
|
mimeData.setText(self.objectName())
|
||
|
drag.setMimeData(mimeData)
|
||
|
drag.exec_()
|
||
|
|
||
|
def dragEnterEvent(self, event):
|
||
|
super(Layer, self).dragEnterEvent(event)
|
||
|
if event.proposedAction() != QtCore.Qt.MoveAction:
|
||
|
return
|
||
|
if event.source().__class__ != Layer:
|
||
|
return
|
||
|
event.acceptProposedAction()
|
||
|
|
||
|
def dropEvent(self, event):
|
||
|
super(Layer, self).dropEvent(event)
|
||
|
if event.proposedAction() != QtCore.Qt.MoveAction:
|
||
|
return
|
||
|
source = event.source()
|
||
|
if source != self and source.__class__ == Layer:
|
||
|
from .. import core
|
||
|
core.moveLayers(event.mimeData().text(), self.objectName())
|
||
|
event.acceptProposedAction()
|
||
|
|
||
|
# Sliders
|
||
|
|
||
|
|
||
|
class MayaSlider:
|
||
|
|
||
|
""" Just a simple wrapper of normal Maya sliders """
|
||
|
|
||
|
def __init__(self, slider, objName='', layout=None):
|
||
|
self.slider = wrapInstance(int(omui.MQtUtil.findControl(slider)), QtWidgets.QWidget)
|
||
|
if objName:
|
||
|
self.slider.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self.slider
|
||
|
if layout:
|
||
|
layout.addWidget(self.slider)
|
||
|
|
||
|
|
||
|
class ControlSlider(QtWidgets.QWidget):
|
||
|
|
||
|
linkIconTop = QtGui.QPixmap(utils.getFolder.icons() + 'marking.png')
|
||
|
linkIconBottom = QtGui.QPixmap(utils.getFolder.icons() + 'link_bottom.png')
|
||
|
|
||
|
def __init__(self, parent=None, objName='', typ='int'):
|
||
|
super(ControlSlider, self).__init__()
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.attributeName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.minimum = self.fieldMinimum = 0
|
||
|
self.maximum = self.fieldMaximum = 0
|
||
|
|
||
|
self.typ = typ
|
||
|
|
||
|
self.layout = QtWidgets.QHBoxLayout(self)
|
||
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||
|
|
||
|
self.button = Button(self.layout)
|
||
|
self.button.setButtonStyle('slider-label')
|
||
|
self.button.setCheckable(True)
|
||
|
self.button.setAutoFillBackground(True)
|
||
|
|
||
|
if self.typ == 'int': # Possibly replace with native sliders for better functionality
|
||
|
m_slider = mc.intSliderGrp(cw=[(1, 45), (2, 1)], adj=2, f=1)
|
||
|
else:
|
||
|
m_slider = mc.floatSliderGrp(cw=[(1, 45), (2, 1)], adj=2, f=1)
|
||
|
|
||
|
self.slider = wrapInstance(int(omui.MQtUtil.findControl(m_slider)), QtWidgets.QWidget)
|
||
|
self.layout.addWidget(self.slider)
|
||
|
|
||
|
self.m_slider = self.slider.objectName()
|
||
|
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.button.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.button.setToolTip('')
|
||
|
|
||
|
def setLabel(self, label):
|
||
|
self.button.setLabel(label)
|
||
|
self.button.label.setAlignment(QtCore.Qt.AlignRight)
|
||
|
self.button.setFixedWidth(style.scale(55))
|
||
|
|
||
|
def setLabelWidth(self, width):
|
||
|
self.button.setFixedWidth(style.scale(width))
|
||
|
|
||
|
def setValue(self, value):
|
||
|
if self.typ == 'int':
|
||
|
mc.intSliderGrp(self.m_slider, e=1, v=value)
|
||
|
else:
|
||
|
mc.floatSliderGrp(self.m_slider, e=1, v=value)
|
||
|
|
||
|
def getValue(self):
|
||
|
if self.typ == 'int':
|
||
|
return mc.intSliderGrp(self.m_slider, q=1, v=1)
|
||
|
else:
|
||
|
return mc.floatSliderGrp(self.m_slider, q=1, v=1)
|
||
|
|
||
|
def setDragCommand(self, cmd):
|
||
|
self.dragCommand = cmd
|
||
|
if self.typ == 'int':
|
||
|
mc.intSliderGrp(self.m_slider, e=1, dc=self.dragCommand)
|
||
|
else:
|
||
|
mc.floatSliderGrp(self.m_slider, e=1, dc=self.dragCommand)
|
||
|
|
||
|
def setReleaseCommand(self, cmd):
|
||
|
def releaseCommand(*_):
|
||
|
self.dragCommand()
|
||
|
cmd()
|
||
|
if self.typ == 'int':
|
||
|
mc.intSliderGrp(self.m_slider, e=1, cc=releaseCommand)
|
||
|
else:
|
||
|
mc.floatSliderGrp(self.m_slider, e=1, cc=releaseCommand)
|
||
|
|
||
|
def getAttributeName(self):
|
||
|
return self.attributeName
|
||
|
|
||
|
def setMinMax(self, minimum, maximum):
|
||
|
self.minimum = minimum
|
||
|
self.maximum = maximum
|
||
|
if self.typ == 'int':
|
||
|
mc.intSliderGrp(self.m_slider, e=1,
|
||
|
min=self.minimum, max=self.maximum,
|
||
|
fmn=self.minimum, fmx=self.maximum)
|
||
|
else:
|
||
|
mc.floatSliderGrp(self.m_slider, e=1,
|
||
|
min=self.minimum, max=self.maximum,
|
||
|
fmn=self.minimum, fmx=self.maximum)
|
||
|
|
||
|
def setFieldMinMax(self, minimum, maximum):
|
||
|
self.fieldMinimum = minimum
|
||
|
self.fieldMaximum = maximum
|
||
|
if self.typ == 'int':
|
||
|
mc.intSliderGrp(self.m_slider, e=1, fmn=self.fieldMinimum, fmx=self.fieldMaximum)
|
||
|
else:
|
||
|
mc.floatSliderGrp(self.m_slider, e=1, fmn=self.fieldMinimum, fmx=self.fieldMaximum)
|
||
|
|
||
|
def setPrecision(self, precision):
|
||
|
if self.typ != 'int':
|
||
|
mc.floatSliderGrp(self.m_slider, e=1, pre=precision)
|
||
|
|
||
|
def setStep(self, step):
|
||
|
if self.typ != 'int':
|
||
|
mc.floatSliderGrp(self.m_slider, e=1, s=step)
|
||
|
|
||
|
def resetMinMax(self):
|
||
|
if self.typ == 'int':
|
||
|
mc.intSliderGrp(self.m_slider, e=1,
|
||
|
fmn=self.fieldMinimum, fmx=self.fieldMaximum,
|
||
|
min=self.minimum, max=self.maximum)
|
||
|
else:
|
||
|
mc.floatSliderGrp(self.m_slider, e=1,
|
||
|
fmn=self.fieldMinimum, fmx=self.fieldMaximum,
|
||
|
min=self.minimum, max=self.maximum)
|
||
|
|
||
|
# Falloff curve graph
|
||
|
|
||
|
|
||
|
class FallOffCurve(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, parent, objName='', attr=True):
|
||
|
super(FallOffCurve, self).__init__()
|
||
|
self.objName = objName
|
||
|
self.attr = attr
|
||
|
self.layout = QtWidgets.QVBoxLayout(self)
|
||
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||
|
if self.objName:
|
||
|
self.setObjectName(getUniqueName(self.objName))
|
||
|
WIDGETS[self.objName] = self
|
||
|
if self.attr:
|
||
|
self.m_graph = mc.falloffCurveAttr(ccw=5, stg=0, h=220, hlc=[0.68, 0.68, 0.68])
|
||
|
else:
|
||
|
self.m_graph = mc.falloffCurve(ccw=5, stg=0, h=220, hlc=[0.68, 0.68, 0.68])
|
||
|
self.graph = wrapInstance(int(omui.MQtUtil.findControl(self.m_graph)), QtWidgets.QWidget)
|
||
|
self.graph.setStyleSheet('*{background-color:rgba(0,0,0,0);}')
|
||
|
self.layout.addWidget(self.graph)
|
||
|
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
def connectGraph(self, path):
|
||
|
if self.attr:
|
||
|
mc.falloffCurveAttr(self.m_graph, e=1, at=path)
|
||
|
else:
|
||
|
mc.falloffCurve(self.m_graph, e=1, at=path)
|
||
|
|
||
|
def changeCommand(self, command):
|
||
|
if self.attr:
|
||
|
mc.falloffCurveAttr(self.m_graph, e=1, cc=command)
|
||
|
else:
|
||
|
mc.falloffCurve(self.m_graph, e=1, cc=command)
|
||
|
|
||
|
def getGraph(self):
|
||
|
if self.attr:
|
||
|
return mc.falloffCurveAttr(self.m_graph, q=1, asString=1)
|
||
|
else:
|
||
|
return mc.falloffCurve(self.m_graph, q=1, asString=1)
|
||
|
|
||
|
def setGraph(self, string):
|
||
|
if self.attr:
|
||
|
mc.falloffCurveAttr(self.m_graph, e=1, asString=string)
|
||
|
else:
|
||
|
mc.falloffCurve(self.m_graph, e=1, asString=string)
|
||
|
|
||
|
def resetGraph(self, custom=None):
|
||
|
defaults = r"0, 0.5, 0.333, 0.5, 0.667, 0.5, 1, 0.5"
|
||
|
if custom:
|
||
|
defaults = custom
|
||
|
if self.attr:
|
||
|
mc.falloffCurveAttr(self.m_graph, e=1, asString=defaults)
|
||
|
else:
|
||
|
mc.falloffCurve(self.m_graph, e=1, asString=defaults)
|
||
|
|
||
|
# Color picker button
|
||
|
|
||
|
|
||
|
class ColorPicker(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, objName='', parent=None):
|
||
|
super(ColorPicker, self).__init__()
|
||
|
|
||
|
self.layout = QtWidgets.QVBoxLayout(self)
|
||
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.m_colorSlider = mc.colorSliderGrp(objName, rgb=[.5, .5, .5])
|
||
|
|
||
|
origSlider = wrapInstance(int(omui.MQtUtil.findControl(self.m_colorSlider)), QtWidgets.QWidget)
|
||
|
self.components = origSlider.children()
|
||
|
self.colorRect = self.components[1]
|
||
|
self.layout.addWidget(self.colorRect)
|
||
|
origSlider.setVisible(False)
|
||
|
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def addParent(self, parent, stretch=0):
|
||
|
parent.addWidget(self, stretch)
|
||
|
|
||
|
def connectCommand(self, command):
|
||
|
mc.colorSliderGrp(self.m_colorSlider, e=1, cc=command)
|
||
|
|
||
|
def connectDragCommand(self, command):
|
||
|
mc.colorSliderGrp(self.m_colorSlider, e=1, dc=command)
|
||
|
|
||
|
def resetColors(self):
|
||
|
mc.colorSliderGrp(self.m_colorSlider, e=1, rgb=[0, 0, 0])
|
||
|
|
||
|
def setRGBColors(self, clr=[0, 0, 0]):
|
||
|
mc.colorSliderGrp(self.m_colorSlider, e=1, rgb=clr)
|
||
|
|
||
|
def getRGBColors(self):
|
||
|
return mc.colorSliderGrp(self.m_colorSlider, q=1, rgb=1)
|
||
|
|
||
|
def setHSVColors(self, clr=[0, 0, 0]):
|
||
|
mc.colorSliderGrp(self.m_colorSlider, e=1, hsv=clr)
|
||
|
|
||
|
def getHSVColors(self):
|
||
|
return mc.colorSliderGrp(self.m_colorSlider, q=1, hsv=1)
|
||
|
|
||
|
# Layer selection drop-down menu
|
||
|
|
||
|
|
||
|
class LayerSelector(QtWidgets.QComboBox):
|
||
|
|
||
|
def __init__(self, objName, parent):
|
||
|
super(LayerSelector, self).__init__()
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
symbols = []
|
||
|
for c in range(ord('a'), ord('j') + 1):
|
||
|
symbols.append(chr(c).capitalize())
|
||
|
numbers = [str(i) for i in range(10)]
|
||
|
numbers2 = [str(i) for i in range(20, 40)]
|
||
|
numbers3 = [str(i) for i in range(40, 80)]
|
||
|
|
||
|
self.setContentsMargins(0, 0, 0, 0)
|
||
|
self.addItems(numbers + symbols + numbers2 + numbers3)
|
||
|
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def setCurrentIndex(self, index):
|
||
|
# Disabling programmatic signal
|
||
|
self.blockSignals(True)
|
||
|
super(LayerSelector, self).setCurrentIndex(index)
|
||
|
self.blockSignals(False)
|
||
|
|
||
|
def updateLayerList(self):
|
||
|
self.blockSignals(True)
|
||
|
from .. import core
|
||
|
if core.getOption('layerNumbersOnly'):
|
||
|
for i in range(10, 20):
|
||
|
self.removeItem(i)
|
||
|
self.insertItem(i, str(i))
|
||
|
else:
|
||
|
letters = [chr(c).capitalize() for c in range(ord('a'), ord('j') + 1)]
|
||
|
for i in range(10, 20):
|
||
|
self.removeItem(i)
|
||
|
self.insertItem(i, str(letters[i - 10]))
|
||
|
self.blockSignals(False)
|
||
|
|
||
|
def wheelEvent(self, event):
|
||
|
super(LayerSelector, self).wheelEvent(event)
|
||
|
|
||
|
|
||
|
class LayerCollectionWidget(QtWidgets.QComboBox):
|
||
|
|
||
|
def __init__(self, objName, parent=None):
|
||
|
super(LayerCollectionWidget, self).__init__()
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
self.setContentsMargins(0, 0, 0, 0)
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def clear(self):
|
||
|
super(LayerCollectionWidget, self).clear()
|
||
|
self.addItem("Main")
|
||
|
|
||
|
|
||
|
# Line edit input field
|
||
|
|
||
|
|
||
|
class LineEdit(QtWidgets.QLineEdit):
|
||
|
|
||
|
def __init__(self, objName, parent=None):
|
||
|
super(LineEdit, self).__init__()
|
||
|
|
||
|
self.autoFormat = False
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.setContentsMargins(0, 0, 0, 0)
|
||
|
|
||
|
self.editingFinished.connect(self.formatText)
|
||
|
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def setAutoFormat(self, shouldFormat):
|
||
|
self.autoFormat = shouldFormat
|
||
|
|
||
|
@utils.deferred
|
||
|
def formatText(self):
|
||
|
if self.autoFormat:
|
||
|
newName = self.text()
|
||
|
if newName:
|
||
|
if newName[0].isdigit():
|
||
|
newName = newName[1:]
|
||
|
self.setText(re.sub(r"[^0-9a-zA-Z]+", "_", newName))
|
||
|
|
||
|
# Single float field
|
||
|
|
||
|
|
||
|
class FloatField(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, objName, parent=None, attrName=''):
|
||
|
super(FloatField, self).__init__()
|
||
|
|
||
|
self.layout = QtWidgets.QVBoxLayout(self)
|
||
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||
|
|
||
|
self.objName = ''
|
||
|
if objName:
|
||
|
self.objName = objName
|
||
|
if not attrName:
|
||
|
self.attributeName = objName
|
||
|
else:
|
||
|
self.attributeName = attrName
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.floatField = mc.floatField(min=-10, max=10, pre=1, step=0.25, v=0)
|
||
|
|
||
|
wrappedField = wrapInstance(int(omui.MQtUtil.findControl(self.floatField)), QtWidgets.QWidget)
|
||
|
self.layout.addWidget(wrappedField)
|
||
|
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.enableTooltip(mc.optionVar(q="GSCT_enableTooltips"))
|
||
|
|
||
|
def enableTooltip(self, enable):
|
||
|
if enable and self.objName in TOOLTIPS_DICT:
|
||
|
self.setToolTip(TOOLTIPS_DICT[self.objName])
|
||
|
else:
|
||
|
self.setToolTip('')
|
||
|
|
||
|
def setDragCommand(self, cmd):
|
||
|
self.dragCommand = cmd
|
||
|
mc.floatField(self.floatField, e=1, dc=cmd)
|
||
|
|
||
|
def setReleaseCommand(self, cmd):
|
||
|
def releaseCommand(*_):
|
||
|
self.dragCommand()
|
||
|
cmd()
|
||
|
mc.floatField(self.floatField, e=1, cc=releaseCommand)
|
||
|
|
||
|
def getAttributeName(self):
|
||
|
return self.attributeName
|
||
|
|
||
|
def getValue(self):
|
||
|
return mc.floatField(self.floatField, q=1, v=1)
|
||
|
|
||
|
def setRange(self, minimum, maximum):
|
||
|
mc.floatField(self.floatField, e=1, min=minimum, max=maximum)
|
||
|
|
||
|
def setPrecision(self, pre):
|
||
|
mc.floatField(self.floatField, e=1, pre=pre)
|
||
|
|
||
|
def setStep(self, step):
|
||
|
mc.floatField(self.floatField, e=1, step=step)
|
||
|
|
||
|
def setValue(self, value):
|
||
|
mc.floatField(self.floatField, e=1, v=value)
|
||
|
|
||
|
|
||
|
class IntField(QtWidgets.QWidget):
|
||
|
|
||
|
def __init__(self, objName, parent):
|
||
|
super(IntField, self).__init__()
|
||
|
|
||
|
self.layout = QtWidgets.QVBoxLayout(self)
|
||
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||
|
if objName:
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
|
||
|
self.intField = mc.intField(min=-10, max=10, step=1, v=0)
|
||
|
|
||
|
wrappedField = wrapInstance(int(omui.MQtUtil.findControl(self.intField)), QtWidgets.QWidget)
|
||
|
self.layout.addWidget(wrappedField)
|
||
|
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
def setRange(self, minimum, maximum):
|
||
|
mc.intField(self.intField, e=1, min=minimum, max=maximum)
|
||
|
|
||
|
def setStep(self, step):
|
||
|
mc.intField(self.intField, e=1, step=step)
|
||
|
|
||
|
def setValue(self, value):
|
||
|
mc.intField(self.intField, e=1, v=value)
|
||
|
|
||
|
# Label
|
||
|
|
||
|
|
||
|
class Label(QtWidgets.QLabel):
|
||
|
|
||
|
def __init__(self, parent=None, objName=None, margins=[0, 0, 0, 0]):
|
||
|
super(Label, self).__init__()
|
||
|
|
||
|
if objName:
|
||
|
self.setObjectName(getUniqueName(objName))
|
||
|
WIDGETS[objName] = self
|
||
|
self.layout = QtWidgets.QHBoxLayout(self)
|
||
|
self.setContentsMargins(*style.scale(margins))
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
def addParent(self, parent, stretch=0):
|
||
|
parent.addWidget(self, stretch)
|
||
|
|
||
|
def setLabel(self, text, lineHeight=100):
|
||
|
text = self.__formatText(text, lineHeight=lineHeight)
|
||
|
|
||
|
self.setText(text)
|
||
|
|
||
|
self.setAlignment(QtCore.Qt.AlignCenter)
|
||
|
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
|
||
|
|
||
|
self.setLabelStyle()
|
||
|
|
||
|
def setLabelStyle(self, labelStyle='normal'):
|
||
|
self.font = QtGui.QFont('Roboto')
|
||
|
self.setFont(self.font)
|
||
|
if labelStyle == 'normal':
|
||
|
self.setFontSize(11)
|
||
|
elif labelStyle == 'small':
|
||
|
self.setFontSize(10, False)
|
||
|
|
||
|
def setFontSize(self, size, bold=True):
|
||
|
font = self.font
|
||
|
font.setPixelSize(style.scale(size))
|
||
|
if bold:
|
||
|
font.setBold(bold)
|
||
|
self.setFont(font)
|
||
|
|
||
|
def __formatText(self, text, lineHeight=80):
|
||
|
if lineHeight == 100:
|
||
|
return text
|
||
|
if isinstance(text, list):
|
||
|
self.resizeEvent = self.changeText
|
||
|
self.buttonLabels = text
|
||
|
text = text[0]
|
||
|
text = '<p style="line-height:{1}%;">{0}</p>'.format(text, lineHeight)
|
||
|
return text
|
||
|
|
||
|
|
||
|
class UVStandardItem(QtGui.QStandardItem):
|
||
|
|
||
|
def __init__(self, grpName='', crvName='', fontSize=12, setBold=False, color=[128, 128, 128, 255]):
|
||
|
super(UVStandardItem, self).__init__()
|
||
|
|
||
|
self.fnt = QtGui.QFont('Open Sans')
|
||
|
self.fnt.setBold(setBold)
|
||
|
self.fnt.setPixelSize(style.scale(fontSize))
|
||
|
self.curveName = crvName
|
||
|
self.groupName = grpName
|
||
|
|
||
|
self.setEditable(False)
|
||
|
clr = QtGui.QColor(*color)
|
||
|
self.setForeground(clr)
|
||
|
self.setFont(self.fnt)
|
||
|
self.setText(self.groupName)
|
||
|
|
||
|
def setBold(self, bold=True):
|
||
|
self.fnt.setBold(bold)
|
||
|
self.setFont(self.fnt)
|
||
|
|
||
|
|
||
|
class UVItemList(QtWidgets.QTreeView):
|
||
|
|
||
|
signal_mouseReleased = QtCore.Signal()
|
||
|
signal_keyPressed = QtCore.Signal()
|
||
|
|
||
|
def __init__(self, parent=None):
|
||
|
super(UVItemList, self).__init__()
|
||
|
|
||
|
self.layout = QtWidgets.QHBoxLayout(self)
|
||
|
if parent:
|
||
|
parent.addWidget(self)
|
||
|
|
||
|
self.treeModel = QtGui.QStandardItemModel()
|
||
|
self.rootNode = self.treeModel.invisibleRootItem()
|
||
|
|
||
|
self.itemList = []
|
||
|
|
||
|
self.setModel(self.treeModel)
|
||
|
self.setHeaderHidden(True)
|
||
|
self.setAnimated(True)
|
||
|
self.setIndentation(style.scale(8))
|
||
|
self.setSelectionMode(self.ExtendedSelection)
|
||
|
|
||
|
def mouseReleaseEvent(self, event):
|
||
|
super(UVItemList, self).mouseReleaseEvent(event)
|
||
|
self.expandSelection()
|
||
|
self.signal_mouseReleased.emit()
|
||
|
|
||
|
def keyPressEvent(self, event):
|
||
|
super(UVItemList, self).keyPressEvent(event)
|
||
|
self.signal_keyPressed.emit()
|
||
|
|
||
|
def getSelection(self):
|
||
|
selectedItems = self.selectedIndexes()
|
||
|
selectedCurves = []
|
||
|
for i in selectedItems:
|
||
|
model = i.model()
|
||
|
item = model.itemFromIndex(i)
|
||
|
selectedCurves.append(item.curveName)
|
||
|
return selectedCurves
|
||
|
|
||
|
def getItemList(self):
|
||
|
return self.itemList
|
||
|
|
||
|
def expandSelection(self):
|
||
|
indexes = self.selectedIndexes()
|
||
|
for index in indexes:
|
||
|
model = index.model()
|
||
|
item = model.itemFromIndex(index)
|
||
|
if item.hasChildren():
|
||
|
for row in range(item.rowCount()):
|
||
|
self.selectionModel().select(
|
||
|
self.treeModel.index(row, 0, index),
|
||
|
self.selectionModel().Select
|
||
|
)
|
||
|
|
||
|
def selectItems(self, items):
|
||
|
if not items:
|
||
|
return
|
||
|
if not isinstance(items, list):
|
||
|
items = [items]
|
||
|
for item in items:
|
||
|
index = item.index()
|
||
|
self.selectionModel().select(
|
||
|
index,
|
||
|
self.selectionModel().Toggle
|
||
|
)
|
||
|
|
||
|
def clearItemList(self):
|
||
|
self.rootNode.removeRows(0, self.treeModel.rowCount())
|
||
|
|
||
|
def updateItemList(self, inputDict):
|
||
|
self.itemList *= 0
|
||
|
self.clearItemList()
|
||
|
for key in inputDict:
|
||
|
parent = mc.listRelatives(key, p=1, pa=1)
|
||
|
rootItem = UVStandardItem(crvName=key, grpName=parent[0])
|
||
|
self.itemList.append(rootItem)
|
||
|
self.rootNode.appendRow(rootItem)
|
||
|
if inputDict[key]:
|
||
|
rootItem.setBold()
|
||
|
for item in inputDict[key]:
|
||
|
if (mc.attributeQuery('gsmessage', n=item, ex=1) and
|
||
|
mc.connectionInfo(item + '.gsmessage', isSource=1)):
|
||
|
continue
|
||
|
parent = mc.listRelatives(item, p=1, pa=1)
|
||
|
subItem = UVStandardItem(crvName=item, grpName=parent[0])
|
||
|
self.itemList.append(subItem)
|
||
|
rootItem.appendRow(subItem)
|
||
|
self.expandAll()
|
||
|
self.selectAll()
|