From 7271caccc92b6ebed5e44b60df99d42749ea16e1 Mon Sep 17 00:00:00 2001 From: Mizaki Date: Fri, 10 May 2024 17:14:39 +0100 Subject: [PATCH] Size combobox dropdown with extra space for move item arrows. Add same sizeHint as QComboBox for unified height --- comictaggerlib/ui/customwidgets.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/comictaggerlib/ui/customwidgets.py b/comictaggerlib/ui/customwidgets.py index 27adff1..681b96b 100644 --- a/comictaggerlib/ui/customwidgets.py +++ b/comictaggerlib/ui/customwidgets.py @@ -7,7 +7,7 @@ from sys import platform from typing import Any from PyQt5 import QtGui, QtWidgets -from PyQt5.QtCore import QEvent, QModelIndex, QPoint, QRect, Qt, pyqtSignal +from PyQt5.QtCore import QEvent, QModelIndex, QPoint, QRect, QSize, Qt, pyqtSignal from comicapi.utils import StrEnum from comictaggerlib.graphics import graphics_path @@ -192,9 +192,9 @@ class ReadStyleItemDelegate(QtWidgets.QStyledItemDelegate): painter.restore() - def _button_up_rect(self, rect: QRect = QRect(10, 1, 12, 12)) -> QRect: + def _button_up_rect(self, rect: QRect) -> QRect: return QRect( - rect.right() - (self.button_width * 2) - (self.button_padding * 2), + self.combobox.view().width() - (self.button_width * 2) - (self.button_padding * 2), rect.top() + (rect.height() - self.button_width) // 2, self.button_width, self.button_width, @@ -202,7 +202,7 @@ class ReadStyleItemDelegate(QtWidgets.QStyledItemDelegate): def _button_down_rect(self, rect: QRect = QRect(10, 1, 12, 12)) -> QRect: return QRect( - rect.right() - self.button_padding - self.button_width, + self.combobox.view().width() - self.button_padding - self.button_width, rect.top() + (rect.height() - self.button_width) // 2, self.button_width, self.button_width, @@ -250,15 +250,23 @@ class ReadStyleItemDelegate(QtWidgets.QStyledItemDelegate): item_rect = view.visualRect(index) button_up_rect = self._button_up_rect(item_rect) button_down_rect = self._button_down_rect(item_rect) + checked = index.data(Qt.CheckStateRole) - if button_up_rect.contains(event.pos()): + if checked == Qt.Checked and button_up_rect.contains(event.pos()): QtWidgets.QToolTip.showText(event.globalPos(), self.up_help, self.combobox, QRect(), 3000) - elif button_down_rect.contains(event.pos()): + elif checked == Qt.Checked and button_down_rect.contains(event.pos()): QtWidgets.QToolTip.showText(event.globalPos(), self.down_help, self.combobox, QRect(), 3000) else: QtWidgets.QToolTip.showText(event.globalPos(), self.item_help, self.combobox, QRect(), 3000) return True + def sizeHint(self, option: QtWidgets.QStyleOptionViewItem, index: QModelIndex) -> QSize: + # Reimpliment standard combobox sizeHint. Only height is used by view, width is ignored + menu_option = QtWidgets.QStyleOptionMenuItem() + return self.combobox.style().sizeFromContents( + QtWidgets.QStyle.ContentsType.CT_MenuItem, menu_option, option.rect.size(), self.combobox + ) + # Multiselect combobox from: https://gis.stackexchange.com/a/351152 (with custom changes) class CheckableOrderComboBox(QtWidgets.QComboBox): @@ -340,6 +348,13 @@ class CheckableOrderComboBox(QtWidgets.QComboBox): if self.count() == 1: self.model().item(0).setCheckState(Qt.CheckState.Checked) + # Add room for "move" arrows + text_width = self.fontMetrics().width(text) + checkbox_width = 40 + total_width = text_width + checkbox_width + (self.itemDelegate().button_width * 2) + if total_width > self.view().minimumWidth(): + self.view().setMinimumWidth(total_width) + def moveItem(self, index: int, up: bool = False, row: int | None = None) -> None: """'Move' an item. Really swap the data and titles around on the two items""" if row is None: