Skip to content

Commit

Permalink
Merge pull request #3988 from Autodesk/barbalt/lights/EMSUSD-1518-inc…
Browse files Browse the repository at this point in the history
…lude-all

EMSUSD-1518 As an artist, I want the ability to determine whether a collection includes all objects by default or not
  • Loading branch information
seando-adsk authored Nov 20, 2024
2 parents 08d3ba6 + cccc766 commit eabf4ba
Show file tree
Hide file tree
Showing 11 changed files with 640 additions and 15 deletions.
27 changes: 27 additions & 0 deletions lib/mayaUsd/resources/ae/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,30 @@ foreach(_SUBDIR ${MAYAUSD_AE_TEMPLATES})
endforeach()

install(FILES __init__.py DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/${PROJECT_NAME})

# Install shared components

if(MAYA_APP_VERSION VERSION_GREATER_EQUAL 2023)
foreach(_SUBDIR ${MAYAUSD_AE_TEMPLATES})
install(FILES
${_SUBDIR}/lightCustomControl.py
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/ufe_ae/usd/nodes/${_SUBDIR}
)
endforeach()

set(MAYAUSD_SHARED_COMPONENTS usd-shared-components/src/python/usdSharedComponents)
install(FILES
${MAYAUSD_SHARED_COMPONENTS}/collection/__init__.py
${MAYAUSD_SHARED_COMPONENTS}/collection/widget.py
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/usd_shared_components/collection/
)

install(FILES
${MAYAUSD_SHARED_COMPONENTS}/common/__init__.py
${MAYAUSD_SHARED_COMPONENTS}/common/list.py
${MAYAUSD_SHARED_COMPONENTS}/common/persistentStorage.py
${MAYAUSD_SHARED_COMPONENTS}/common/resizable.py
${MAYAUSD_SHARED_COMPONENTS}/common/theme.py
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/python/usd_shared_components/common/
)
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Shared common components for USD plugins for 3dsMax and Maya
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from ..common.list import StringList
from ..common.resizable import Resizable

try:
from PySide6.QtWidgets import QWidget, QVBoxLayout
except ImportError:
from PySide2.QtWidgets import QWidget, QVBoxLayout # type: ignore

from pxr import Usd

class CollectionWidget(QWidget):
def __init__(self, collection: Usd.CollectionAPI = None, parent: QWidget = None):
super(CollectionWidget, self).__init__(parent)

self._collection: Usd.CollectionAPI = collection

includes = []
excludes = []
shouldIncludeAll = False

if self._collection is not None:
includeRootAttribute = self._collection.GetIncludeRootAttr()
if includeRootAttribute.IsAuthored():
shouldIncludeAll = self._collection.GetIncludeRootAttr().Get()

for p in self._collection.GetIncludesRel().GetTargets():
includes.append(p.pathString)
for p in self._collection.GetExcludesRel().GetTargets():
excludes.append(p.pathString)

self.mainLayout = QVBoxLayout(self)
self.mainLayout.setContentsMargins(0,0,0,0)

self._include = StringList( includes, "Include", "Include all", self)
self._include.cbIncludeAll.setChecked(shouldIncludeAll)
self._include.cbIncludeAll.stateChanged.connect(self.onIncludeAllToggle)
self._resizableInclude = Resizable(self._include, "USD_Light_Linking", "IncludeListHeight", self)

self.mainLayout.addWidget(self._resizableInclude)

self._exclude = StringList( excludes, "Exclude", "", self)
self._resizableExclude = Resizable(self._exclude, "USD_Light_Linking", "ExcludeListHeight", self)

self.mainLayout.addWidget(self._resizableExclude)
self.mainLayout.addStretch(1)

def onIncludeAllToggle(self):
self._collection.GetIncludeRootAttr().Set(self._include.cbIncludeAll.isChecked())
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Shared common components for USD plugins for 3dsMax and Maya
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from typing import Sequence, Union
from .theme import Theme

try:
from PySide6.QtCore import (
QModelIndex,
QPersistentModelIndex,
QSize,
QStringListModel,
Qt,
Signal,
)
from PySide6.QtGui import QPainter
from PySide6.QtWidgets import QStyleOptionViewItem, QStyledItemDelegate, QListView, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QCheckBox
except:
from PySide2.QtCore import (
QModelIndex,
QPersistentModelIndex,
QSize,
QStringListModel,
Qt,
Signal,
)
from PySide2.QtGui import QPainter # type: ignore
from PySide2.QtWidgets import QStyleOptionViewItem, QStyledItemDelegate, QListView, QLabel, QVBoxLayout, QHBoxLayout, QWidget, QCheckBox # type: ignore

class _StringList(QListView):
selectedItemsChanged = Signal()

class Delegate(QStyledItemDelegate):
def __init__(self, model: QStringListModel, parent=None):
super(_StringList.Delegate, self).__init__(parent)
self._model = model

def sizeHint(self, option: QStyleOptionViewItem, index: Union[QModelIndex, QPersistentModelIndex]):
s: int = Theme.instance().uiScaled(24)
return QSize(s, s)

def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: Union[QModelIndex, QPersistentModelIndex]):
s: str = self._model.data(index, Qt.DisplayRole)
Theme.instance().paintStringListEntry(painter, option.rect, s)

def __init__(self, items: Sequence[str] = [], parent=None):
super(_StringList, self).__init__(parent)
self._model = QStringListModel(items, self)
self.setModel(self._model)

self.setUniformItemSizes(True)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setTextElideMode(Qt.TextElideMode.ElideMiddle)
self.setSelectionBehavior(QListView.SelectRows)
self.setSelectionMode(QListView.MultiSelection)
self.setContentsMargins(0,0,0,0)

self.selectionModel().selectionChanged.connect(lambda: self.selectedItemsChanged.emit())

def drawFrame(self, painter: QPainter):
pass

@property
def items(self) -> Sequence[str]:
return self._model.stringList

@items.setter
def items(self, items: Sequence[str]):
self._model.setStringList(items)

@property
def selectedItems(self) -> Sequence[str]:
return [index.data(Qt.DisplayRole) for index in self.selectedIndexes()]


class StringList(QWidget):

def __init__(self, items: Sequence[str] = [], headerTitle: str = "", toggleTitle: str = "", parent=None):
super().__init__()
self.list = _StringList(items, self)

layout = QVBoxLayout(self)
LEFT_RIGHT_MARGINS = 2
layout.setContentsMargins(LEFT_RIGHT_MARGINS, 0, LEFT_RIGHT_MARGINS, 0)

headerWidget = QWidget(self)
headerLayout = QHBoxLayout(headerWidget)

titleLabel = QLabel(headerTitle, self)
headerLayout.addWidget(titleLabel)
headerLayout.addStretch(1)
headerLayout.setContentsMargins(0,0,0,0)

# only add the check box on the header if there's a label
if toggleTitle != None and toggleTitle != "":
self.cbIncludeAll = QCheckBox(toggleTitle, self)
self.cbIncludeAll.setCheckable(True)
headerLayout.addWidget(self.cbIncludeAll)

headerWidget.setLayout(headerLayout)

layout.addWidget(headerWidget)
layout.addWidget(self.list)

self.setLayout(layout)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
try:
from PySide6.QtCore import QSettings
except:
from PySide2.QtCore import QSettings # type: ignore


class PersistentStorage(object):
_instance = None

def __init__(self):
raise RuntimeError("Call instance() instead")

@classmethod
def instance(cls):
if cls._instance is None:
cls._instance = cls.__new__(cls)
return cls._instance

@classmethod
def injectInstance(cls, persistentStorage):
cls._instance = persistentStorage

def _settings(self) -> QSettings:
return QSettings("settings.ini", QSettings.IniFormat)

def set(self, group: str, key: str, value: object):
settings: QSettings = self._settings()
settings.beginGroup(group)
settings.setValue(key, value)
settings.endGroup()
settings.sync()

def get(self, group: str, key: str, default: object = None) -> object:
settings: QSettings = self._settings()
settings.beginGroup(group)
return settings.value(key, default, type=type(default))
Loading

0 comments on commit eabf4ba

Please sign in to comment.