From 6c2527b7f4e87d82813180f20461e8e9c98e1087 Mon Sep 17 00:00:00 2001 From: Nav Date: Thu, 23 Mar 2023 19:20:50 +0000 Subject: [PATCH] Implemented support for multi-select and selection limit in ListScene widget --- .../Widgets/ListView/ListScene.cpp | 33 +++++++++++++++---- .../Widgets/ListView/ListScene.hpp | 7 ++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.cpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.cpp index 6b46ab09..64d1cd55 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.cpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.cpp @@ -19,6 +19,10 @@ namespace Bloom::Widgets this->setItems(std::move(items)); } + void ListScene::setSelectionLimit(std::uint8_t selectionLimit) { + this->selectionLimit = selectionLimit; + } + void ListScene::refreshGeometry() { const auto* viewport = this->viewport(); const auto viewportWidth = viewport != nullptr ? viewport->width() : 0; @@ -90,10 +94,26 @@ namespace Bloom::Widgets void ListScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) { const auto button = mouseEvent->button(); - if (this->selectedItem != nullptr) { - this->selectedItem->selected = false; - this->selectedItem->update(); - this->selectedItem = nullptr; + const auto selectedItemCount = this->selectedItems.size(); + if (selectedItemCount > 0) { + const auto ctrlModifierEnabled = (mouseEvent->modifiers() & Qt::ControlModifier) != 0; + if (!ctrlModifierEnabled || selectedItemCount >= this->selectionLimit) { + const auto itemsToRemove = ctrlModifierEnabled + ? selectedItemCount - this->selectionLimit + 1 + : selectedItemCount; + + auto itemIt = this->selectedItems.begin(); + while ( + itemIt != this->selectedItems.end() + && (selectedItemCount - this->selectedItems.size()) < itemsToRemove + ) { + auto& item = *itemIt; + item->selected = false; + item->update(); + + this->selectedItems.erase(itemIt++); + } + } } const auto mousePosition = mouseEvent->buttonDownScenePos(button); @@ -108,12 +128,11 @@ namespace Bloom::Widgets return; } - this->selectedItem = clickedListItem; - + this->selectedItems.push_back(clickedListItem); clickedListItem->selected = true; clickedListItem->update(); - emit this->selectionChanged(this->selectedItem); + emit this->selectionChanged(this->selectedItems); emit this->itemClicked(clickedListItem); } diff --git a/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.hpp b/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.hpp index f96cfab0..37e967ab 100644 --- a/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.hpp +++ b/src/Insight/UserInterfaces/InsightWindow/Widgets/ListView/ListScene.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -28,13 +29,14 @@ namespace Bloom::Widgets ); void refreshGeometry(); + void setSelectionLimit(std::uint8_t selectionLimit); void setItems(const std::vector& items); void addListItem(ListItem* item); void sortItems(); void setEnabled(bool enabled); signals: - void selectionChanged(ListItem* selectedItem); + void selectionChanged(const std::list& selectedItems); void itemClicked(ListItem* item); void itemDoubleClicked(ListItem* item); void itemContextMenu(ListItem* item, QPoint sourcePosition); @@ -48,7 +50,8 @@ namespace Bloom::Widgets std::vector listItems; QGraphicsView* const parent; bool enabled = false; - ListItem* selectedItem = nullptr; + std::list selectedItems; + std::uint8_t selectionLimit = 1; QWidget* viewport() const { const auto views = this->views();