Source code for mosaic.widgets.container_list

from qtpy.QtCore import Qt, QRect
from qtpy.QtGui import QColor, QFont, QFontMetrics
from qtpy.QtWidgets import (
    QFrame,
    QVBoxLayout,
    QLabel,
    QListWidget,
    QSizePolicy,
    QApplication,
    QListWidgetItem,
    QStyledItemDelegate,
    QStyleOptionViewItem,
)
import qtawesome as qta


[docs] class ContainerListWidget(QFrame):
[docs] def __init__(self, title: str = None, border: bool = True): super().__init__() self.setFrameStyle(QFrame.Shape.NoFrame) layout = QVBoxLayout(self) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self.title = title app = QApplication.instance() app.paletteChanged.connect(self.updateStyleSheet) if self.title is not None: self.setSizePolicy( QSizePolicy.Policy.MinimumExpanding, QSizePolicy.Policy.Expanding ) title_label = QLabel(self.title) title_label.setStyleSheet( """ QLabel { font-weight: 600; font-size: 14px; padding-left: 8px; padding-top: 8px; border: 0px solid transparent; } """ ) layout.addWidget(title_label) self.list_widget = QListWidget() self.list_widget.setFrameStyle(QFrame.Shape.NoFrame) self.list_widget.setHorizontalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff ) self.list_widget.setItemDelegate(MetadataItemDelegate(self.list_widget)) self.list_widget.setStyleSheet( """ QScrollBar:vertical { border: none; background: transparent; width: 8px; margin: 4px 0px; } QScrollBar::handle:vertical { background: rgba(209, 213, 219, 0.5); border-radius: 4px; min-height: 24px; } QScrollBar::handle:vertical:hover { background: rgba(209, 213, 219, 0.8); } QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0px; } QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { background: none; } QLineEdit { background-color: rgba(99, 102, 241, 1.0); border: none; padding: 4px 0px; } """ ) layout.addWidget(self.list_widget) if border: self.updateStyleSheet()
def updateStyleSheet(self): return self.setStyleSheet( """ QFrame { background-color: transparent; border: none; border-bottom: 1px solid #6b7280; } """ ) def __getattr__(self, name): return getattr(self.list_widget, name)
[docs] class StyledListWidgetItem(QListWidgetItem):
[docs] def __init__(self, text, visible=True, metadata=None, parent=None, editable=False): """ Create a styled list widget item with type-specific icons. Parameters ---------- text : str The display text for the item visible : bool Whether the item is visible metadata : dict Additional metadata for the item parent : QWidget Parent widget """ super().__init__(text, parent) self.visible = visible self.metadata = metadata or {} # Deactivate metadata label rendering _ = self.metadata.pop("metadata_text", None) self.visible_color = QColor(99, 102, 241) self.invisible_color = QColor(128, 128, 128) if editable: self.setFlags(self.flags() | Qt.ItemFlag.ItemIsEditable) self._update_icon(visible)
def _update_icon(self, visible): """Update the item icon based on type and visibility.""" self.visible = visible item_type = self.metadata.get("item_type") if item_type == "cluster": icon_name = "mdi.scatter-plot" elif item_type == "parametric": icon_name = "mdi.function" elif item_type == "mesh": icon_name = "mdi.triangle-outline" elif item_type == "trajectory": icon_name = "mdi.chart-line-variant" else: icon_name = "mdi.shape-outline" color = self.visible_color if visible else self.invisible_color icon = qta.icon(icon_name, color=color, scale_factor=0.7) self.setIcon(icon) def set_visible(self, visible): if visible != self.visible: self._update_visibility_icon(visible) if not visible: self.setForeground(self.invisible_color)
class MetadataItemDelegate(QStyledItemDelegate): def __init__(self, parent=None): super().__init__(parent) def paint(self, painter, option, index): original_rect = QRect(option.rect) list_widget = self.parent() item = list_widget.item(index.row()) if not isinstance(item, StyledListWidgetItem): return super().paint(painter, option, index) metadata_text = item.metadata.get("metadata_text", "") metadata_font = QFont(painter.font()) metadata_font.setPointSize(8) fm = QFontMetrics(metadata_font) metadata_width = min(fm.horizontalAdvance(metadata_text), 55) modified_option = QStyleOptionViewItem(option) modified_option.rect.setWidth(option.rect.width() - metadata_width) super().paint(painter, modified_option, index) painter.save() metadata_font = QFont(painter.font()) metadata_font.setPointSize(8) painter.setFont(metadata_font) painter.setPen(QColor(107, 114, 128)) metadata_rect = QRect( original_rect.right() - metadata_width, original_rect.top(), metadata_width, original_rect.height(), ) painter.drawText( metadata_rect, int(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter), metadata_text, ) painter.restore()