mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
added better options for multiselection combobox
This commit is contained in:
parent
6f37ae40f6
commit
fa0bb79692
1 changed files with 104 additions and 40 deletions
|
|
@ -10,6 +10,10 @@ from ayon_core.tools.utils.constants import (
|
|||
ITEM_IS_USER_TRISTATE,
|
||||
)
|
||||
|
||||
CUSTOM_ITEM_TYPE = 0
|
||||
STANDARD_ITEM_TYPE = 1
|
||||
SEPARATOR_ITEM_TYPE = 2
|
||||
|
||||
|
||||
class CustomPaintDelegate(QtWidgets.QStyledItemDelegate):
|
||||
"""Delegate showing status name and short name."""
|
||||
|
|
@ -22,6 +26,7 @@ class CustomPaintDelegate(QtWidgets.QStyledItemDelegate):
|
|||
short_text_role,
|
||||
text_color_role,
|
||||
icon_role,
|
||||
item_type_role=None,
|
||||
parent=None
|
||||
):
|
||||
super().__init__(parent)
|
||||
|
|
@ -29,8 +34,24 @@ class CustomPaintDelegate(QtWidgets.QStyledItemDelegate):
|
|||
self._text_color_role = text_color_role
|
||||
self._short_text_role = short_text_role
|
||||
self._icon_role = icon_role
|
||||
self._item_type_role = item_type_role
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
item_type = None
|
||||
if self._item_type_role is not None:
|
||||
item_type = index.data(self._item_type_role)
|
||||
|
||||
if item_type is None:
|
||||
item_type = CUSTOM_ITEM_TYPE
|
||||
|
||||
if item_type == STANDARD_ITEM_TYPE:
|
||||
super().paint(painter, option, index)
|
||||
return
|
||||
|
||||
elif item_type == SEPARATOR_ITEM_TYPE:
|
||||
self._paint_separator(painter, option, index)
|
||||
return
|
||||
|
||||
if option.widget:
|
||||
style = option.widget.style()
|
||||
else:
|
||||
|
|
@ -158,6 +179,29 @@ class CustomPaintDelegate(QtWidgets.QStyledItemDelegate):
|
|||
|
||||
painter.restore()
|
||||
|
||||
def _paint_separator(self, painter, option, index):
|
||||
painter.save()
|
||||
painter.setClipRect(option.rect)
|
||||
|
||||
style = option.widget.style()
|
||||
style.drawPrimitive(
|
||||
QtWidgets.QCommonStyle.PE_PanelItemViewItem,
|
||||
option,
|
||||
painter,
|
||||
option.widget
|
||||
)
|
||||
|
||||
pen = painter.pen()
|
||||
pen.setWidth(2)
|
||||
painter.setPen(pen)
|
||||
mid_y = (option.rect.top() + option.rect.bottom()) * 0.5
|
||||
painter.drawLine(
|
||||
QtCore.QPointF(option.rect.left(), mid_y),
|
||||
QtCore.QPointF(option.rect.right(), mid_y)
|
||||
)
|
||||
|
||||
painter.restore()
|
||||
|
||||
def _get_index_name(self, index):
|
||||
return index.data(self._text_role)
|
||||
|
||||
|
|
@ -198,11 +242,12 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
name_role,
|
||||
short_name_role,
|
||||
text_role,
|
||||
short_text_role,
|
||||
text_color_role,
|
||||
icon_role,
|
||||
value_role=None,
|
||||
item_type_role=None,
|
||||
model=None,
|
||||
placeholder=None,
|
||||
parent=None,
|
||||
|
|
@ -218,21 +263,23 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
|
|||
self.setView(combo_view)
|
||||
|
||||
item_delegate = CustomPaintDelegate(
|
||||
name_role,
|
||||
short_name_role,
|
||||
text_color_role,
|
||||
icon_role,
|
||||
text_role=text_role,
|
||||
short_text_role=short_text_role,
|
||||
text_color_role=text_color_role,
|
||||
icon_role=icon_role,
|
||||
item_type_role=item_type_role,
|
||||
parent=combo_view,
|
||||
)
|
||||
combo_view.setItemDelegateForColumn(0, item_delegate)
|
||||
|
||||
if value_role is None:
|
||||
value_role = name_role
|
||||
value_role = text_role
|
||||
|
||||
self._combo_view = combo_view
|
||||
self._item_delegate = item_delegate
|
||||
self._value_role = value_role
|
||||
self._name_role = name_role
|
||||
self._short_name_role = short_name_role
|
||||
self._text_role = text_role
|
||||
self._short_text_role = short_text_role
|
||||
self._text_color_role = text_color_role
|
||||
self._icon_role = icon_role
|
||||
|
||||
|
|
@ -307,40 +354,18 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
|
|||
state = checkstate_int_to_enum(
|
||||
current_index.data(QtCore.Qt.CheckStateRole)
|
||||
)
|
||||
|
||||
new_state = None
|
||||
|
||||
if event.type() == QtCore.QEvent.MouseButtonRelease:
|
||||
if (
|
||||
self._block_mouse_release_timer.isActive()
|
||||
or not current_index.isValid()
|
||||
or not self.view().isVisible()
|
||||
or not self.view().rect().contains(event.pos())
|
||||
or not index_flags & QtCore.Qt.ItemIsSelectable
|
||||
or not index_flags & QtCore.Qt.ItemIsEnabled
|
||||
or not index_flags & QtCore.Qt.ItemIsUserCheckable
|
||||
):
|
||||
return
|
||||
|
||||
if state == QtCore.Qt.Checked:
|
||||
new_state = UNCHECKED_INT
|
||||
else:
|
||||
new_state = CHECKED_INT
|
||||
new_state = self._mouse_released_event_handle(
|
||||
event, current_index, index_flags, state
|
||||
)
|
||||
|
||||
elif event.type() == QtCore.QEvent.KeyPress:
|
||||
# TODO: handle QtCore.Qt.Key_Enter, Key_Return?
|
||||
if event.key() == QtCore.Qt.Key_Space:
|
||||
if (
|
||||
index_flags & QtCore.Qt.ItemIsUserCheckable
|
||||
and index_flags & ITEM_IS_USER_TRISTATE
|
||||
):
|
||||
new_state = (checkstate_enum_to_int(state) + 1) % 3
|
||||
|
||||
elif index_flags & QtCore.Qt.ItemIsUserCheckable:
|
||||
# toggle the current items check state
|
||||
if state != QtCore.Qt.Checked:
|
||||
new_state = CHECKED_INT
|
||||
else:
|
||||
new_state = UNCHECKED_INT
|
||||
new_state = self._key_press_event_handler(
|
||||
event, current_index, index_flags, state
|
||||
)
|
||||
|
||||
if new_state is not None:
|
||||
model.setData(current_index, new_state, QtCore.Qt.CheckStateRole)
|
||||
|
|
@ -421,7 +446,7 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
|
|||
|
||||
icon = index.data(self._icon_role)
|
||||
# TODO handle this case
|
||||
if icon.isNull():
|
||||
if icon is None or icon.isNull():
|
||||
continue
|
||||
|
||||
icon_rect = QtCore.QRect(content_rect)
|
||||
|
|
@ -519,4 +544,43 @@ class CustomPaintMultiselectComboBox(QtWidgets.QComboBox):
|
|||
if event.key() in self.ignored_keys:
|
||||
return event.ignore()
|
||||
|
||||
return super().keyPressEvent(event)
|
||||
return super().keyPressEvent(event)
|
||||
|
||||
def _mouse_released_event_handle(
|
||||
self, event, current_index, index_flags, state
|
||||
):
|
||||
if (
|
||||
self._block_mouse_release_timer.isActive()
|
||||
or not current_index.isValid()
|
||||
or not self.view().isVisible()
|
||||
or not self.view().rect().contains(event.pos())
|
||||
or not index_flags & QtCore.Qt.ItemIsSelectable
|
||||
or not index_flags & QtCore.Qt.ItemIsEnabled
|
||||
or not index_flags & QtCore.Qt.ItemIsUserCheckable
|
||||
):
|
||||
return None
|
||||
|
||||
if state == QtCore.Qt.Checked:
|
||||
return UNCHECKED_INT
|
||||
return CHECKED_INT
|
||||
|
||||
|
||||
def _key_press_event_handler(
|
||||
self, event, current_index, index_flags, state
|
||||
):
|
||||
# TODO: handle QtCore.Qt.Key_Enter, Key_Return?
|
||||
if event.key() != QtCore.Qt.Key_Space:
|
||||
return None
|
||||
|
||||
if (
|
||||
index_flags & QtCore.Qt.ItemIsUserCheckable
|
||||
and index_flags & ITEM_IS_USER_TRISTATE
|
||||
):
|
||||
return (checkstate_enum_to_int(state) + 1) % 3
|
||||
|
||||
if index_flags & QtCore.Qt.ItemIsUserCheckable:
|
||||
# toggle the current items check state
|
||||
if state != QtCore.Qt.Checked:
|
||||
return CHECKED_INT
|
||||
return UNCHECKED_INT
|
||||
return None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue