┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/kitemviews/kitemlistcontroller.cpp
diff options
context:
space:
mode:
authorAkseli Lahtinen <[email protected]>2025-06-20 00:15:31 +0300
committerAkseli Lahtinen <[email protected]>2025-06-20 00:15:31 +0300
commitc1e71289082ec7416ac19c822393ea70f63d1b75 (patch)
tree58e43ee607af7c6586235417d1056d7df5e8838b /src/kitemviews/kitemlistcontroller.cpp
parentb1d46a3cbd6dd70a6ec7e31d2d11056a5f5c6d91 (diff)
New selection effects
This adds a new selection effect that is similar to what we have in QtQuick file item views. There are also changes to some usability: Instead of only the icon and text being the clickable area in icon and details mode, the whole selection is now the clickable area. Otherwise the usability should stay the same, it's mostly a visual change. See also: https://invent.kde.org/teams/vdg/issues/-/issues/94
Diffstat (limited to 'src/kitemviews/kitemlistcontroller.cpp')
-rw-r--r--src/kitemviews/kitemlistcontroller.cpp39
1 files changed, 25 insertions, 14 deletions
diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
index cd60c3a41..fdde48abc 100644
--- a/src/kitemviews/kitemlistcontroller.cpp
+++ b/src/kitemviews/kitemlistcontroller.cpp
@@ -675,6 +675,10 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent *event, con
return false;
}
+ for (KItemListWidget *widget : m_view->visibleItemListWidgets()) {
+ widget->setPressed(false);
+ }
+
if (m_view->m_tapAndHoldIndicator->isActive()) {
m_view->m_tapAndHoldIndicator->setActive(false);
}
@@ -990,7 +994,7 @@ bool KItemListController::hoverMoveEvent(QGraphicsSceneHoverEvent *event, const
// we also unhover any old expansion toggle hovers, in case the mouse movement from expansion toggle to icon+text is too fast (i.e. newHoveredWidget is never null between the transition)
unhoverOldExpansionWidget();
- const bool isOverIconAndText = newHoveredWidget->iconRect().contains(mappedPos) || newHoveredWidget->textRect().contains(mappedPos);
+ const bool isOverIconAndText = newHoveredWidget->selectionRectCore().contains(mappedPos);
const bool hasMultipleSelection = m_selectionManager->selectedItems().count() > 1;
if (hasMultipleSelection && !isOverIconAndText) {
@@ -1029,6 +1033,7 @@ bool KItemListController::hoverLeaveEvent(QGraphicsSceneHoverEvent *event, const
const auto widgets = m_view->visibleItemListWidgets();
for (KItemListWidget *widget : widgets) {
+ widget->setPressed(false);
if (widget->isHovered()) {
widget->setHovered(false);
Q_EMIT itemUnhovered(widget->index());
@@ -1365,9 +1370,8 @@ void KItemListController::slotRubberBandChanged()
const QRectF widgetRect = m_view->itemRect(index);
if (widgetRect.intersects(rubberBandRect)) {
// Select the full row intersecting with the rubberband rectangle
- const QRectF selectionRect = widget->selectionRect().translated(widgetRect.topLeft());
- const QRectF iconRect = widget->iconRect().translated(widgetRect.topLeft());
- if (selectionRect.intersects(rubberBandRect) || iconRect.intersects(rubberBandRect)) {
+ const QRectF selectionRect = widget->selectionRectFull().translated(widgetRect.topLeft());
+ if (selectionRect.intersects(rubberBandRect)) {
selectedItems.insert(index);
}
}
@@ -1467,7 +1471,7 @@ KItemListWidget *KItemListController::widgetForPos(const QPointF &pos) const
const auto widgets = m_view->visibleItemListWidgets();
for (KItemListWidget *widget : widgets) {
const QPointF mappedPos = widget->mapFromItem(m_view, pos);
- if (widget->contains(mappedPos) || widget->selectionRect().contains(mappedPos)) {
+ if (widget->contains(mappedPos)) {
return widget;
}
}
@@ -1486,7 +1490,7 @@ KItemListWidget *KItemListController::widgetForDropPos(const QPointF &pos) const
const auto widgets = m_view->visibleItemListWidgets();
for (KItemListWidget *widget : widgets) {
const QPointF mappedPos = widget->mapFromItem(m_view, pos);
- if (widget->contains(mappedPos)) {
+ if (widget->selectionRectCore().contains(mappedPos)) {
return widget;
}
}
@@ -1641,6 +1645,7 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
// simplify the overall logic and possibilities both for users and devs.
const bool leftClick = buttons & Qt::LeftButton;
const bool rightClick = buttons & Qt::RightButton;
+ const bool singleClickActivation = m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick);
// The previous selection is cleared if either
// 1. The selection mode is SingleSelection, or
@@ -1661,11 +1666,11 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
if (selectedItemsCount > 1 && m_pressedIndex.has_value()) {
const auto row = m_view->m_visibleItems.value(m_pressedIndex.value());
const auto mappedPos = row->mapFromItem(m_view, pos);
- if (pressedItemAlreadySelected || row->iconRect().contains(mappedPos) || row->textRect().contains(mappedPos)) {
+ if (row->selectionRectCore().contains(mappedPos)) {
// we are indeed inside the text/icon rect, keep m_pressedIndex what it is
// and short-circuit for single-click activation (it will then propagate to onRelease and activate the item)
// or we just keep going for double-click activation
- if (m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced) {
+ if (singleClickActivation || m_singleClickActivationEnforced) {
if (!pressedItemAlreadySelected) {
// An unselected item was clicked directly while deselecting multiple other items so we mark it "current".
m_selectionManager->setCurrentItem(m_pressedIndex.value());
@@ -1676,6 +1681,9 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
m_selectionManager->setSelected(m_pressedIndex.value(), 1, KItemListSelectionManager::Toggle);
}
}
+ if (leftClick) {
+ row->setPressed(true);
+ }
return true; // event handled, don't create rubber band
}
} else {
@@ -1723,11 +1731,16 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
if (m_pressedIndex.has_value()) {
// The hover highlight area of an item is being pressed.
const auto row = m_view->m_visibleItems.value(m_pressedIndex.value()); // anything outside of row.contains() will be the empty region of the row rect
- const bool hitTargetIsRowEmptyRegion = !row->contains(row->mapFromItem(m_view, pos));
+
+ const bool hitTargetIsRowEmptyRegion = !row->selectionRectCore().contains(row->mapFromItem(m_view, pos));
// again, when this method returns false, a rubberBand selection is created as the event is not consumed;
// createRubberBand here tells us whether to return true or false.
bool createRubberBand = (hitTargetIsRowEmptyRegion && m_selectionManager->selectedItems().isEmpty());
+ if (leftClick) {
+ row->setPressed(true);
+ }
+
if (rightClick && hitTargetIsRowEmptyRegion) {
// We have a right click outside the icon and text rect but within the hover highlight area.
// We don't want items to get selected through this, so we return now.
@@ -1741,8 +1754,7 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
break;
case SingleSelection:
- if (!leftClick || shiftOrControlPressed
- || (!m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) && !m_singleClickActivationEnforced)) {
+ if (!leftClick || shiftOrControlPressed || (!singleClickActivation && !m_singleClickActivationEnforced)) {
m_selectionManager->setSelected(m_pressedIndex.value());
}
break;
@@ -1755,7 +1767,7 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
// We rule out the latter, if the item is not clicked directly and was unselected previously.
const auto row = m_view->m_visibleItems.value(m_pressedIndex.value());
const auto mappedPos = row->mapFromItem(m_view, pos);
- if (!row->iconRect().contains(mappedPos) && !row->textRect().contains(mappedPos) && !pressedItemAlreadySelected) {
+ if (!row->selectionRectCore().contains(mappedPos)) {
createRubberBand = true;
} else {
m_selectionManager->setSelected(m_pressedIndex.value(), 1, KItemListSelectionManager::Toggle);
@@ -1765,8 +1777,7 @@ bool KItemListController::onPress(const QPointF &pos, const Qt::KeyboardModifier
}
} else if (!shiftPressed || !m_selectionManager->isAnchoredSelectionActive()) {
// Select the pressed item and start a new anchored selection
- if (!leftClick || shiftOrControlPressed
- || (!m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) && !m_singleClickActivationEnforced)) {
+ if (!leftClick || shiftOrControlPressed || (!singleClickActivation && !m_singleClickActivationEnforced)) {
m_selectionManager->setSelected(m_pressedIndex.value(), 1, KItemListSelectionManager::Select);
}
m_selectionManager->beginAnchoredSelection(m_pressedIndex.value());