# coding:utf-8 from typing import List, Union from PySide6.QtCore import Qt, QModelIndex, Property from PySide6.QtGui import QPainter from PySide6.QtWidgets import QStyleOptionViewItem, QListView, QListView, QListWidget, QWidget from .scroll_bar import SmoothScrollDelegate from .table_view import TableItemDelegate from ...common.style_sheet import FluentStyleSheet, themeColor from ...common.color import autoFallbackThemeColor class ListItemDelegate(TableItemDelegate): """ List item delegate """ def __init__(self, parent: QListView): super().__init__(parent) def _drawBackground(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex): painter.drawRoundedRect(option.rect, 5, 5) def _drawIndicator(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex): y, h = option.rect.y(), option.rect.height() ph = round(0.35*h if self.pressedRow == index.row() else 0.257*h) painter.setBrush(autoFallbackThemeColor(self.lightCheckedColor, self.darkCheckedColor)) painter.drawRoundedRect(0, ph + y, 3, h - 2*ph, 1.5, 1.5) class ListBase: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.delegate = ListItemDelegate(self) self.scrollDelegate = SmoothScrollDelegate(self) self._isSelectRightClickedRow = False FluentStyleSheet.LIST_VIEW.apply(self) self.setItemDelegate(self.delegate) self.setMouseTracking(True) self.entered.connect(lambda i: self._setHoverRow(i.row())) self.pressed.connect(lambda i: self._setPressedRow(i.row())) def _setHoverRow(self, row: int): """ set hovered row """ self.delegate.setHoverRow(row) self.viewport().update() def _setPressedRow(self, row: int): """ set pressed row """ if self.selectionMode() == QListView.SelectionMode.NoSelection: return self.delegate.setPressedRow(row) self.viewport().update() def _setSelectedRows(self, indexes: List[QModelIndex]): if self.selectionMode() == QListView.SelectionMode.NoSelection: return self.delegate.setSelectedRows(indexes) self.viewport().update() def leaveEvent(self, e): QListView.leaveEvent(self, e) self._setHoverRow(-1) def resizeEvent(self, e): QListView.resizeEvent(self, e) self.viewport().update() def keyPressEvent(self, e): QListView.keyPressEvent(self, e) self.updateSelectedRows() def mousePressEvent(self, e): if e.button() == Qt.LeftButton or self._isSelectRightClickedRow: return QListView.mousePressEvent(self, e) index = self.indexAt(e.pos()) if index.isValid(): self._setPressedRow(index.row()) QWidget.mousePressEvent(self, e) def mouseReleaseEvent(self, e): QListView.mouseReleaseEvent(self, e) self.updateSelectedRows() if self.indexAt(e.pos()).row() < 0 or e.button() == Qt.RightButton: self._setPressedRow(-1) def setItemDelegate(self, delegate: ListItemDelegate): self.delegate = delegate super().setItemDelegate(delegate) def clearSelection(self): QListView.clearSelection(self) self.updateSelectedRows() def setCurrentIndex(self, index: QModelIndex): QListView.setCurrentIndex(self, index) self.updateSelectedRows() def updateSelectedRows(self): self._setSelectedRows(self.selectedIndexes()) def setCheckedColor(self, light, dark): """ set the color in checked status Parameters ---------- light, dark: str | QColor | Qt.GlobalColor color in light/dark theme mode """ self.delegate.setCheckedColor(light, dark) class ListWidget(ListBase, QListWidget): """ List widget """ def __init__(self, parent=None): super().__init__(parent) def setCurrentItem(self, item, command=None): self.setCurrentRow(self.row(item), command) def setCurrentRow(self, row: int, command=None): if not command: super().setCurrentRow(row) else: super().setCurrentRow(row, command) self.updateSelectedRows() def isSelectRightClickedRow(self): return self._isSelectRightClickedRow def setSelectRightClickedRow(self, isSelect: bool): self._isSelectRightClickedRow = isSelect selectRightClickedRow = Property(bool, isSelectRightClickedRow, setSelectRightClickedRow) class ListView(ListBase, QListView): """ List view """ def __init__(self, parent=None): super().__init__(parent) def isSelectRightClickedRow(self): return self._isSelectRightClickedRow def setSelectRightClickedRow(self, isSelect: bool): self._isSelectRightClickedRow = isSelect selectRightClickedRow = Property(bool, isSelectRightClickedRow, setSelectRightClickedRow)