Skip to content

Commit 4dff870

Browse files
authored
Merge pull request #4052 from Autodesk/barbalt/dev/EMSUSD-1902
EMSUSD-1902 EMSUSD-1918 Fix minimum size and mouse scroll issue
2 parents c238975 + 001aa1c commit 4dff870

31 files changed

+309
-143
lines changed

lib/mayaUsd/resources/ae/CMakeLists.txt

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,14 @@ if(MAYA_APP_VERSION VERSION_GREATER_EQUAL 2023)
7272
)
7373

7474
set(LIB_ICONS
75-
${MAYAUSD_SHARED_COMPONENTS}/icons/dark/menu
75+
${MAYAUSD_SHARED_COMPONENTS}/icons/dark/add
7676
${MAYAUSD_SHARED_COMPONENTS}/icons/dark/delete
77+
${MAYAUSD_SHARED_COMPONENTS}/icons/dark/menu
78+
${MAYAUSD_SHARED_COMPONENTS}/icons/dark/selector
79+
${MAYAUSD_SHARED_COMPONENTS}/icons/dark/warning
7780
)
7881
foreach(ICON_BASE ${LIB_ICONS})
79-
# The _100.png files need to be installed without the _100. This is the
80-
# base icon name that is used. Maya will automatically choose the _150/_200
81-
# image if neeeded.
82-
install(FILES "${ICON_BASE}_100.png"
83-
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python/usd_shared_components/icons/dark"
84-
RENAME "${ICON_BASE}.png"
85-
)
86-
install(FILES "${ICON_BASE}_150.png" "${ICON_BASE}_200.png"
82+
install(FILES "${ICON_BASE}.svg"
8783
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/python/usd_shared_components/icons/dark"
8884
)
8985
endforeach()

lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/expressionWidget.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from .expressionRulesMenu import ExpressionMenu
22
from ..common.menuButton import MenuButton
3+
from ..common.theme import Theme
34

45
try:
56
from PySide6.QtCore import QEvent, Qt # type: ignore
@@ -16,27 +17,34 @@ def __init__(self, collection: Usd.CollectionAPI, parent: QWidget, expressionCha
1617
self._collection = collection
1718
self._expressionCallback = expressionChangedCallback
1819

19-
self._expressionText = QTextEdit(self)
20-
self._expressionText.setContentsMargins(0,0,0,0)
21-
self._expressionText.setLineWrapMode(QTextEdit.LineWrapMode.WidgetWidth)
22-
self._expressionText.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
23-
self._expressionText.setPlaceholderText("Type an expression here...")
20+
mainLayout = QVBoxLayout(self)
21+
margin: int = Theme.instance().uiScaled(2)
22+
mainLayout.setSpacing(margin)
2423

2524
self._expressionMenu = ExpressionMenu(collection, self)
2625
menuButton = MenuButton(self._expressionMenu, self)
2726

2827
menuWidget = QWidget(self)
2928
menuLayout = QHBoxLayout(menuWidget)
29+
30+
margins = menuLayout.contentsMargins()
31+
margins.setRight(0)
32+
menuLayout.setContentsMargins(margins)
33+
3034
menuLayout.addStretch(1)
3135
menuLayout.addWidget(menuButton)
36+
menuWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
37+
38+
self._expressionText = QTextEdit(self)
39+
self._expressionText.setLineWrapMode(QTextEdit.LineWrapMode.WidgetWidth)
40+
self._expressionText.setMinimumHeight(Theme.instance().uiScaled(80))
41+
self._expressionText.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
42+
self._expressionText.setPlaceholderText("Type an expression here...")
43+
44+
mainLayout.addWidget(menuWidget, 0)
45+
mainLayout.addWidget(self._expressionText, 1)
3246

33-
mainLayout = QVBoxLayout(self)
34-
mainLayout.setContentsMargins(0,0,0,0)
35-
mainLayout.addWidget(menuWidget)
36-
mainLayout.addWidget(self._expressionText)
37-
3847
self._expressionText.installEventFilter(self)
39-
self.setLayout(mainLayout)
4048
self.update()
4149

4250
def update(self):
@@ -71,4 +79,4 @@ def eventFilter(self, obj, event):
7179
elif event.type() == QEvent.FocusOut:
7280
self.submitExpression()
7381

74-
return super().eventFilter(obj, event)
82+
return super().eventFilter(obj, event)

lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/includeExcludeWidget.py

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@
1010
try:
1111
from PySide6.QtCore import QEvent, QObject, Qt # type: ignore
1212
from PySide6.QtWidgets import QFrame, QHBoxLayout, QVBoxLayout, QLineEdit, QMenu, QSizePolicy, QToolButton, QWidget # type: ignore
13-
from PySide6.QtGui import QAction # type: ignore
1413
except ImportError:
1514
from PySide2.QtCore import QEvent, QObject, Qt # type: ignore
1615
from PySide2.QtWidgets import QFrame, QHBoxLayout, QVBoxLayout, QLineEdit, QMenu, QSizePolicy, QToolButton, QWidget # type: ignore
17-
from PySide2.QtGui import QAction # type: ignore
1816

1917
from pxr import Usd, Sdf
2018

2119
# TODO: support I8N
2220
kSearchPlaceHolder = "Search..."
2321

24-
2522
class IncludeExcludeWidget(QWidget):
2623
def __init__(
2724
self,
@@ -34,15 +31,13 @@ def __init__(
3431
self._prim: Usd.Prim = prim
3532
self._updatingUI = False
3633

37-
includeExcludeLayout = QVBoxLayout(self)
38-
39-
includeExcludeLayout.setContentsMargins(0, 0, 0, 0)
34+
mainLayout = QVBoxLayout(self)
35+
mainLayout.setContentsMargins(0, 0, 0, 0)
4036

4137
self._expressionMenu = ExpressionMenu(self._collection, self)
4238
menuButton = MenuButton(self._expressionMenu, self)
4339

4440
self._filterWidget = QLineEdit()
45-
self._filterWidget.setContentsMargins(0, 0, 0, 0)
4641
self._filterWidget.setSizePolicy(
4742
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed
4843
)
@@ -53,33 +48,30 @@ def __init__(
5348
separator.setFrameShape(QFrame.VLine)
5449

5550
headerWidget = QWidget(self)
56-
headerWidget.setContentsMargins(0, 0, 0, 0)
5751
headerLayout = QHBoxLayout(headerWidget)
5852

59-
headerLayout.setContentsMargins(0, 2, 2, 0)
60-
6153
if Host.instance().canPick:
6254
addBtn = QToolButton(headerWidget)
63-
addBtn.setToolTip("Add prims to Include or Exclude")
55+
addBtn.setToolTip("Add Objects to the Include/Exclude list")
6456
addBtn.setIcon(Theme.instance().icon("add"))
6557
addBtn.setPopupMode(QToolButton.InstantPopup)
6658
addBtnMenu = QMenu(addBtn)
67-
addBtnMenu.addAction("Add prims to Include", self.onAddToIncludePrimClicked)
68-
addBtnMenu.addAction("Add prims to Exclude", self.onAddToExcludePrimClicked)
59+
addBtnMenu.addAction("Include Objects...", self.onAddToIncludePrimClicked)
60+
addBtnMenu.addAction("Exclude Objects...", self.onAddToExcludePrimClicked)
6961
addBtn.setMenu(addBtnMenu)
7062
headerLayout.addWidget(addBtn)
7163

7264
self._deleteBtn = QToolButton(headerWidget)
73-
self._deleteBtn.setToolTip("Remove selected prims from Include or Exclude")
65+
self._deleteBtn.setToolTip("Remove Selected Objects from Include/Exclude list")
7466
self._deleteBtn.setIcon(Theme.instance().icon("delete"))
7567
self._deleteBtn.setPopupMode(QToolButton.InstantPopup)
7668
self._deleteBtnMenu = QMenu(self._deleteBtn)
77-
self._deleteBtnActionFromIncludes = QAction("Remove selected prims from Include", self._deleteBtnMenu)
78-
self._deleteBtnActionFromIncludes.triggered.connect(self.onRemoveSelectionFromInclude)
79-
self._deleteBtnMenu.addAction(self._deleteBtnActionFromIncludes)
80-
self._deleteBtnActionFromExcludes = QAction("Remove selected prims from Exclude", self._deleteBtnMenu)
81-
self._deleteBtnActionFromExcludes.triggered.connect(self.onRemoveSelectionFromExclude)
82-
self._deleteBtnMenu.addAction(self._deleteBtnActionFromExcludes)
69+
self._deleteBtnActionFromIncludes = self._deleteBtnMenu.addAction(
70+
"Remove Selected Objects from Include", self.onRemoveSelectionFromInclude
71+
)
72+
self._deleteBtnActionFromExcludes = self._deleteBtnMenu.addAction(
73+
"Remove Selected Objects from Exclude", self.onRemoveSelectionFromExclude
74+
)
8375
self._deleteBtn.setMenu(self._deleteBtnMenu)
8476
headerLayout.addWidget(self._deleteBtn)
8577

@@ -88,7 +80,7 @@ def __init__(
8880
headerLayout.addWidget(self._filterWidget)
8981
headerLayout.addWidget(separator)
9082
headerLayout.addWidget(menuButton)
91-
includeExcludeLayout.addWidget(headerWidget)
83+
mainLayout.addWidget(headerWidget)
9284

9385
self._include = StringList([], "Include", "Include all", self)
9486
self._include.cbIncludeAll.stateChanged.connect(self.onIncludeAllToggle)
@@ -97,29 +89,32 @@ def __init__(
9789
"USD_Light_Linking",
9890
"IncludeListHeight",
9991
self,
100-
defaultSize=80,
92+
defaultSize=Theme.instance().uiScaled(80),
10193
)
102-
includeExcludeLayout.addWidget(self._resizableInclude)
94+
self._resizableInclude.minContentSize = Theme.instance().uiScaled(44)
95+
mainLayout.addWidget(self._resizableInclude)
10396

10497
self._exclude = StringList([], "Exclude", "", self)
10598
self._resizableExclude = Resizable(
10699
self._exclude,
107100
"USD_Light_Linking",
108101
"ExcludeListHeight",
109102
self,
110-
defaultSize=80,
103+
defaultSize=Theme.instance().uiScaled(80),
111104
)
112-
includeExcludeLayout.addWidget(self._resizableExclude)
105+
self._resizableExclude.minContentSize = Theme.instance().uiScaled(44)
106+
mainLayout.addWidget(self._resizableExclude)
113107

114108
self._include.list.selectionChanged.connect(self.onListSelectionChanged)
115109
self._exclude.list.selectionChanged.connect(self.onListSelectionChanged)
116110

117111
self._filterWidget.textChanged.connect(self._include.list._model.setFilter)
118112
self._filterWidget.textChanged.connect(self._exclude.list._model.setFilter)
119-
EventFilter(self._include.list, self)
120-
EventFilter(self._exclude.list, self)
121113

122-
self.setLayout(includeExcludeLayout)
114+
if Host.instance().canDrop:
115+
EventFilter(self._include.list, self)
116+
EventFilter(self._exclude.list, self)
117+
123118
self.updateUI()
124119
self.onListSelectionChanged()
125120

@@ -140,8 +135,8 @@ def update(self):
140135

141136
self._include.list.items = includes
142137
self._exclude.list.items = excludes
143-
self._include.list.update_placeholder()
144-
self._exclude.list.update_placeholder()
138+
self._include.list.updatePlaceholder()
139+
self._exclude.list.updatePlaceholder()
145140

146141
def getIncludedItems(self):
147142
return self._include.list.items()
@@ -156,6 +151,7 @@ def setIncludeAll(self, value: bool):
156151
self._include.cbIncludeAll.setChecked(value)
157152

158153
def updateUI(self):
154+
159155
if self._updatingUI:
160156
return
161157

@@ -180,22 +176,22 @@ def updateUI(self):
180176
self._updatingUI = False
181177

182178
def onAddToIncludePrimClicked(self):
183-
prims: Sequence[Usd.Prim] = Host.instance().pick(self._prim.GetStage())
184-
if prims is None:
179+
pickedItems: Sequence[Usd.Prim] = Host.instance().pick(self._prim.GetStage(), dialogTitle="Add Include Objects")
180+
if pickedItems is None:
185181
return
186182
self._updatingUI = True
187-
for prim in prims:
188-
self._collection.GetIncludesRel().AddTarget(prim.GetPath())
183+
for item in pickedItems:
184+
self._collection.GetIncludesRel().AddTarget(item.GetPath())
189185
self._updatingUI = False
190186
self.updateUI()
191187

192188
def onAddToExcludePrimClicked(self):
193-
prims: Sequence[Usd.Prim] = Host.instance().pick(self._prim.GetStage())
194-
if prims is None:
189+
pickedItems: Sequence[Usd.Prim] = Host.instance().pick(self._prim.GetStage(), dialogTitle="Add Exclude Objects")
190+
if pickedItems is None:
195191
return
196192
self._updatingUI = True
197-
for prim in prims:
198-
self._collection.GetExcludesRel().AddTarget(prim.GetPath())
193+
for item in pickedItems:
194+
self._collection.GetExcludesRel().AddTarget(item.GetPath())
199195
self._updatingUI = False
200196
self.updateUI()
201197

@@ -206,7 +202,6 @@ def onRemoveSelectionFromInclude(self):
206202
self._updatingUI = False
207203
self.updateUI()
208204
self.onListSelectionChanged()
209-
self._include.list.update_placeholder()
210205

211206
def onRemoveSelectionFromExclude(self):
212207
self._updatingUI = True
@@ -215,7 +210,6 @@ def onRemoveSelectionFromExclude(self):
215210
self._updatingUI = False
216211
self.updateUI()
217212
self.onListSelectionChanged()
218-
self._exclude.list.update_placeholder()
219213

220214
def onListSelectionChanged(self):
221215
includesSelected = self._include.list.hasSelectedItems
@@ -233,16 +227,16 @@ def onListSelectionChanged(self):
233227

234228
if includesSelected and excludeSelected:
235229
self._deleteBtn.setToolTip(
236-
"Remove selected prims from Include or Exclude..."
230+
"Remove Selected Objects from Include/Exclude list"
237231
)
238232
self._deleteBtn.setPopupMode(QToolButton.InstantPopup)
239233
self._deleteBtn.setStyleSheet("")
240234
else:
241235
if includesSelected:
242-
self._deleteBtn.setToolTip("Remove selected prims from Include")
236+
self._deleteBtn.setToolTip("Remove Selected Objects from Include")
243237
self._deleteBtn.pressed.connect(self.onRemoveSelectionFromInclude)
244238
elif excludeSelected:
245-
self._deleteBtn.setToolTip("Remove selected prims from Exclude")
239+
self._deleteBtn.setToolTip("Remove Selected Objects from Exclude")
246240
self._deleteBtn.pressed.connect(self.onRemoveSelectionFromExclude)
247241
self._deleteBtn.setPopupMode(QToolButton.DelayedPopup)
248242
self._deleteBtn.setStyleSheet(

lib/mayaUsd/resources/ae/usd-shared-components/src/python/usdSharedComponents/collection/widget.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
11
from .includeExcludeWidget import IncludeExcludeWidget
22
from .expressionWidget import ExpressionWidget
3+
from ..common.theme import Theme
34

45
try:
5-
from PySide6.QtCore import Slot # type: ignore
6-
from PySide6.QtGui import QIcon # type: ignore
7-
from PySide6.QtWidgets import QWidget, QTabWidget, QVBoxLayout # type: ignore
6+
from PySide6.QtCore import QEvent, QObject, Qt, Slot # type: ignore
7+
from PySide6.QtGui import QIcon, QWheelEvent # type: ignore
8+
from PySide6.QtWidgets import QTabBar, QTabWidget, QVBoxLayout, QWidget # type: ignore
89
except ImportError:
9-
from PySide2.QtCore import Slot # type: ignore
10-
from PySide2.QtGui import QIcon # type: ignore
11-
from PySide2.QtWidgets import QWidget, QTabWidget, QVBoxLayout # type: ignore
10+
from PySide2.QtCore import QEvent, QObject, Qt, Slot # type: ignore
11+
from PySide2.QtGui import QIcon, QWheelEvent # type: ignore
12+
from PySide2.QtWidgets import QTabBar, QTabWidget, QVBoxLayout, QWidget # type: ignore
1213

1314
from pxr import Usd, Tf
1415

1516

17+
class NonScrollingTabBar(QTabBar):
18+
"""A QTabBar that does not switch tabs when the mouse wheel is used."""
19+
20+
def __init__(self, parent: QWidget = None):
21+
super(NonScrollingTabBar, self).__init__(parent)
22+
23+
def wheelEvent(self, event: QWheelEvent):
24+
# Ignore the event. This cannot be done using an event filter as the
25+
# event needs to be properly ignored to 'bubble up' the parent chain.
26+
event.ignore()
27+
1628
class CollectionWidget(QWidget):
1729

1830
def __init__(
@@ -39,18 +51,30 @@ def __init__(
3951
Usd.Notice.ObjectsChanged, self.onObjectsChanged, self._prim.GetStage()
4052
)
4153

54+
self._tabWidget = None
55+
4256
# only create tab when usd version is greater then 23.11
4357
if Usd.GetVersion() >= (0, 23, 11):
44-
tabWidget = QTabWidget()
45-
tabWidget.currentChanged.connect(self.onTabChanged)
58+
self._tabWidget = QTabWidget()
59+
self._tabWidget.setTabBar(NonScrollingTabBar(self._tabWidget))
60+
self._tabWidget.currentChanged.connect(self.onTabChanged)
61+
self._tabWidget.setDocumentMode(True)
4662

4763
self._expressionWidget = ExpressionWidget(
48-
collection, tabWidget, self.onExpressionChanged
64+
collection, self._tabWidget, self.onExpressionChanged
65+
)
66+
self._tabWidget.addTab(
67+
self._includeExcludeWidget, QIcon(), "Include/Exclude"
4968
)
50-
tabWidget.addTab(self._includeExcludeWidget, QIcon(), "Include/Exclude")
51-
tabWidget.addTab(self._expressionWidget, QIcon(), "Expression")
69+
self._tabWidget.addTab(self._expressionWidget, QIcon(), "Expression")
70+
71+
offset: int = Theme.instance().uiScaled(4)
72+
self._includeExcludeWidget.setContentsMargins(0, offset, 0, 0)
73+
self._expressionWidget.setContentsMargins(0, offset, 0, 0)
5274

53-
mainLayout.addWidget(tabWidget)
75+
self._tabWidget.tabBar().setExpanding(True)
76+
self._tabWidget.tabBar().setCursor(Qt.ArrowCursor)
77+
mainLayout.addWidget(self._tabWidget)
5478
else:
5579
mainLayout.addWidget(self._includeExcludeWidget)
5680

0 commit comments

Comments
 (0)