Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prim Hierarchy Editor: Allow listing and setting the default prim #4

Closed
BigRoy opened this issue Nov 22, 2023 · 1 comment · Fixed by #21
Closed

Prim Hierarchy Editor: Allow listing and setting the default prim #4

BigRoy opened this issue Nov 22, 2023 · 1 comment · Fixed by #21
Assignees
Labels
enhancement New feature or request

Comments

@BigRoy
Copy link
Owner

BigRoy commented Nov 22, 2023

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:

prism_show_ref_var_dft

We might want to look into something similar.


Prism implements it as:

The scenegraph is a QTreeWidget with a QStyledItemDelegate assigned. The colored labels are drawn in the paintEvent of the QStyledItemDelegate using some QRect, QFont and QPen objects. The eye is a QToolButton, which was added using the setItemWidget on the QTreeWidgetItem object.

Responding to clicks on those labels like:

... the Reference Editor gets opened from a mouseClickEvent function on the Scenegraph widget, which checks if the mouseclick happened on the "REF" rect of the item under the cursor.

@BigRoy BigRoy added the enhancement New feature or request label Nov 22, 2023
@BigRoy
Copy link
Owner Author

BigRoy commented Nov 24, 2023

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:
image

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant