Closed BigRoy closed 10 months ago
Here's a quick prototype mimicking somewhat what Prism does with a styled delegate:
from qtpy import QtCore, QtGui, QtWidgets
class Delegate(QtWidgets.QStyledItemDelegate):
"""Draws rounded rects 'tags' to the right hand side of the widget.
The tags to be drawn should be returned by index's data via the
BlockTagsRole on this class. The returned data should be a list
with dicts defining each tag:
{
"text": "text", # text value in the block
"background-color": "#FFFFFF", # background color
"color": "#FF9999" # text color
}
"""
RectDataRole = QtCore.Qt.UserRole + 1001
def paint(self, painter, option, index):
super(Delegate, self).paint(painter, option, index)
if index.column() != 0:
return
# For the first column we want to paint in the state
# of default prim, variants and references/payloads
rect = QtCore.QRect(option.rect)
corner_radius = 5
padding_topbottom = 2
padding_sides = 4
width = 30
painter.setRenderHint(QtGui.QPainter.Antialiasing)
blocks = [
{"text": "REF", "background-color": "#333355"},
{"text": "VAR", "background-color": "#335533"},
{"text": "DFT", "background-color": "#553333"},
]
block_rects = []
for i, block_data in enumerate(blocks):
text = block_data.get("text", "")
background_color = QtGui.QColor(block_data.get("background-color", "#FF9999"))
text_color = QtGui.QColor(block_data.get("color", "#FFFFFF"))
painter.setPen(text_color)
# Calculate left by computing offset from right hand side (align right)
i = i + 1
right = rect.right()
left = right - (width * i) - (2 * i * padding_sides) + padding_sides
block_rect = QtCore.QRect(left, rect.top() + padding_topbottom, width, rect.height() - padding_topbottom * 2)
# Draw the block rect
path = QtGui.QPainterPath()
path.addRoundedRect(block_rect, corner_radius, corner_radius)
painter.fillPath(path, background_color)
# Draw text in the block - vertically centered
point = block_rect.topLeft()
point.setY(point.y() + block_rect.height() * 0.5)
painter.drawText(block_rect, QtCore.Qt.AlignCenter, text)
block_rects.append(block_rect)
# This is a bit of a hack, we store the created QRect on the
# item so that on the view we can respond to clicks on these blocks
# easily
model = index.model()
model.setData(index, block_rects, self.RectDataRole)
class View(QtWidgets.QListView):
def mousePressEvent(self, event):
point = event.position().toPoint()
index = self.indexAt(point)
rects = index.data(Delegate.RectDataRole) or []
for rect in rects:
if rect.contains(point):
print(rect)
delegate = Delegate()
view = View()
model = QtGui.QStandardItemModel()
for value in ["Cube", "Sphere", "Cone"]:
item = QtGui.QStandardItem()
item.setText(value)
model.appendRow(item)
view.setModel(model)
view.setItemDelegate(delegate)
view.show()
view.setStyleSheet("QListView::item { padding: 5px; }")
Which in Maya generates this:
Where the little labels are clickable to report that they were clicked. I guess even if a bit of a hack we could start by using something along these lines.
We should expose the functionality to set the default prim.
There maybe also be reasons to set the default prim per layer (e.g. see here) so we might want to expose that as well however being able to set the USD stage's root layer default prim would be the first goal.
Prism Editor has a similar feature which displays it nicely:
We might want to look into something similar.
Prism implements it as:
Responding to clicks on those labels like: