diff --git a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/expressionRulesMenu.py b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/expressionRulesMenu.py index 0d4fd9941..d4d6fdf34 100644 --- a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/expressionRulesMenu.py +++ b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/expressionRulesMenu.py @@ -9,15 +9,28 @@ from pxr import Usd +# TODO: support I8N EXPAND_PRIMS_MENU_OPTION = "Expand Prims" EXPAND_PRIMS_PROPERTIES_MENU_OPTION = "Expand Prims and Properties" EXPLICIT_ONLY_MENU_OPTION = "Explicit Only" +kIncludeExcludeLabel = "Include/Exclude" +kRemoveAllLabel = "Remove All" class ExpressionMenu(QMenu): def __init__(self, data: CollectionData, parent: QWidget): super(ExpressionMenu, self).__init__(parent) self._collData = data + # Note: this is necessary to avoid the separator not show up. + self.setSeparatorsCollapsible(False) + + self._incExSeparator = self.addSection(kIncludeExcludeLabel) + self._removeAllAction = QAction(kRemoveAllLabel, self) + self.addActions([self._incExSeparator, self._removeAllAction]) + + self._removeAllAction.triggered.connect(self._onRemoveAll) + + self._collData.dataChanged.connect(self._onDataChanged) expansionRulesMenu = QMenu("Expansion Rules", self) self.expandPrimsAction = QAction(EXPAND_PRIMS_MENU_OPTION, expansionRulesMenu, checkable=True) self.expandPrimsPropertiesAction = QAction(EXPAND_PRIMS_PROPERTIES_MENU_OPTION, expansionRulesMenu, checkable=True) @@ -28,11 +41,10 @@ def __init__(self, data: CollectionData, parent: QWidget): actionGroup.setExclusive(True) for action in expansionRulesMenu.actions(): actionGroup.addAction(action) - - self.triggered.connect(self.onExpressionSelected) - self._collData.dataChanged.connect(self._onDataChanged) self.addMenu(expansionRulesMenu) + actionGroup.triggered.connect(self.onExpressionSelected) + self._onDataChanged() def _onDataChanged(self): @@ -44,6 +56,9 @@ def _onDataChanged(self): elif usdExpansionRule == Usd.Tokens.explicitOnly: self.explicitOnlyAction.setChecked(True) + def _onRemoveAll(self): + self._collData.removeAllIncludeExclude() + def onExpressionSelected(self, menuOption): if menuOption == self.expandPrimsAction: self._collData.setExpansionRule(Usd.Tokens.expandPrims) diff --git a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/includeExcludeWidget.py b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/includeExcludeWidget.py index c6fa0f081..dd2dbe7a4 100644 --- a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/includeExcludeWidget.py +++ b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/includeExcludeWidget.py @@ -132,14 +132,14 @@ def onAddToIncludePrimClicked(self): stage = self._collData.getStage() if not stage: return - items = Host.instance().pick(stage, ADD_INCLUDE_OBJECTS_TITLE) + items = Host.instance().pick(stage, dialogTitle=ADD_INCLUDE_OBJECTS_TITLE) self._collData.getIncludeData().addStrings(items) def onAddToExcludePrimClicked(self): stage = self._collData.getStage() if not stage: return - items = Host.instance().pick(stage, ADD_EXCLUDE_OBJECTS_TITLE) + items = Host.instance().pick(stage, dialogTitle=ADD_EXCLUDE_OBJECTS_TITLE) self._collData.getExcludeData().addStrings(items) def onRemoveSelectionFromInclude(self): diff --git a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/filteredStringListView.py b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/filteredStringListView.py index 21e00eb58..edea5fe95 100644 --- a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/filteredStringListView.py +++ b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/filteredStringListView.py @@ -17,6 +17,7 @@ ) from PySide6.QtGui import QPainter, QPaintEvent, QFont # type: ignore from PySide6.QtWidgets import ( # type: ignore + QLabel, QListView, QStyledItemDelegate, QStyleOptionViewItem @@ -33,7 +34,7 @@ Signal, ) from PySide2.QtGui import QPainter, QPaintEvent, QFont # type: ignore - from PySide2.QtWidgets import QListView, QStyledItemDelegate, QStyleOptionViewItem # type: ignore + from PySide2.QtWidgets import QLabel, QListView, QStyledItemDelegate, QStyleOptionViewItem # type: ignore NO_OBJECTS_FOUND_LABEL = "No objects found" @@ -81,6 +82,16 @@ def __init__(self, data: StringListData, headerTitle: str = "", parent=None): self.setSelectionMode(QListView.SelectionMode.ExtendedSelection) self.setContentsMargins(1, 0, 1, 1) + self.placeholder_label = QLabel(self) + self.placeholder_label.setAlignment(Qt.AlignmentFlag.AlignCenter) + palette = self.placeholder_label.palette() + palette.setColor( + self.placeholder_label.foregroundRole(), + Theme.instance().palette.colorPlaceHolderText, + ) + self.placeholder_label.setPalette(palette) + self.placeholder_label.hide() + self.setCursor(Qt.ArrowCursor) DragAndDropEventFilter(self, data) @@ -107,6 +118,15 @@ def paintEvent(self, event: QPaintEvent): self._paintPlaceHolder(DRAG_OBJECTS_HERE_LABEL) elif Host.instance().canPick: self._paintPlaceHolder(PICK_OBJECTS_LABEL) + else: + self.placeholder_label.hide() + else: + self.placeholder_label.hide() + + def _paintPlaceHolder(self, placeHolderText): + self.placeholder_label.setText(placeHolderText) + self.placeholder_label.setGeometry(self.viewport().geometry()) + self.placeholder_label.show() def selectedItems(self) -> Sequence[str]: return [str(index.data(Qt.DisplayRole)) for index in self.selectedIndexes()] @@ -114,12 +134,6 @@ def selectedItems(self) -> Sequence[str]: def hasSelectedItems(self) -> bool: return bool(self.selectionModel().hasSelection()) - def _paintPlaceHolder(self, placeHolderText): - painter = QPainter(self.viewport()) - theme = Theme.instance() - painter.setPen(theme.palette.colorPlaceHolderText) - painter.drawText(self.rect(), Qt.AlignCenter, placeHolderText) - class DragAndDropEventFilter(QObject): def __init__(self, widget, data: StringListData): super().__init__(widget) diff --git a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/theme.py b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/theme.py index a423e4f77..380ef8499 100644 --- a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/theme.py +++ b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/common/theme.py @@ -49,9 +49,9 @@ class Palette(object): def __init__(self): super(Theme.Palette, self) self.colorResizeBorderActive: QColor = QColor(0x5285a6) - self.colorPlaceHolderText = QColor(128, 128, 128) - pal = QPallette = QPalette() + pal = QPalette() + self.colorPlaceHolderText = pal.color(QPalette.ColorRole.WindowText) self.colorPlaceHolderText.setAlphaF(0.7) diff --git a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/data/collectionData.py b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/data/collectionData.py index ba113322a..61a477bb6 100644 --- a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/data/collectionData.py +++ b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/data/collectionData.py @@ -46,6 +46,12 @@ def getExcludeData(self) -> StringListData: Returns the excluded items string list. ''' return None + + def removeAllIncludeExclude(self): + ''' + Remove all included and excluded items. + ''' + pass # Expression diff --git a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/usdData/usdCollectionData.py b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/usdData/usdCollectionData.py index de61a300e..387912529 100644 --- a/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/usdData/usdCollectionData.py +++ b/lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/usdData/usdCollectionData.py @@ -74,7 +74,7 @@ def includesAll(self) -> bool: if not self._collection: return False includeRootAttribute = self._collection.GetIncludeRootAttr() - return includeRootAttribute.Get() + return bool(includeRootAttribute.Get()) def setIncludeAll(self, state: bool): ''' @@ -99,6 +99,13 @@ def getExcludeData(self) -> CollectionStringListData: ''' return self._excludes + def removeAllIncludeExclude(self): + ''' + Remove all included and excluded items. + By design, we author a block collection opinion. + ''' + self._collection.BlockCollection() + # Expression def getExpansionRule(self): @@ -143,7 +150,6 @@ def setMembershipExpression(self, textExpression: AnyStr): if usdExpressionAttr != None: usdExpression = usdExpressionAttr.GetText() - textExpression = self._expressionText.toPlainText() if usdExpression != textExpression: # assign default value if text is empty if textExpression == "": @@ -151,6 +157,3 @@ def setMembershipExpression(self, textExpression: AnyStr): else: self._collection.CreateMembershipExpressionAttr(Sdf.PathExpression(textExpression)) - if self._expressionCallback != None: - self._expressionCallback() - diff --git a/lib/mayaUsd/resources/ae/usdschemabase/lightCustomControl.py b/lib/mayaUsd/resources/ae/usdschemabase/lightCustomControl.py index 9dd6d70fe..619208d89 100644 --- a/lib/mayaUsd/resources/ae/usdschemabase/lightCustomControl.py +++ b/lib/mayaUsd/resources/ae/usdschemabase/lightCustomControl.py @@ -10,7 +10,7 @@ class MayaHost(Host): def __init__(self): pass - def pick(self, stage: Usd.Stage) -> Sequence[Usd.Prim]: + def pick(self, stage: Usd.Stage, *, dialogTitle: str = "") -> Sequence[Usd.Prim]: return [] # nothing to do yet