Implemented support for multi-select and selection limit in ListScene widget

This commit is contained in:
Nav
2023-03-23 19:20:50 +00:00
parent a1da8dc004
commit 6c2527b7f4
2 changed files with 31 additions and 9 deletions

View File

@@ -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);
}

View File

@@ -4,6 +4,7 @@
#include <QGraphicsView>
#include <QMargins>
#include <vector>
#include <list>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsSceneWheelEvent>
#include <QGraphicsSceneContextMenuEvent>
@@ -28,13 +29,14 @@ namespace Bloom::Widgets
);
void refreshGeometry();
void setSelectionLimit(std::uint8_t selectionLimit);
void setItems(const std::vector<ListItem*>& items);
void addListItem(ListItem* item);
void sortItems();
void setEnabled(bool enabled);
signals:
void selectionChanged(ListItem* selectedItem);
void selectionChanged(const std::list<ListItem*>& selectedItems);
void itemClicked(ListItem* item);
void itemDoubleClicked(ListItem* item);
void itemContextMenu(ListItem* item, QPoint sourcePosition);
@@ -48,7 +50,8 @@ namespace Bloom::Widgets
std::vector<ListItem*> listItems;
QGraphicsView* const parent;
bool enabled = false;
ListItem* selectedItem = nullptr;
std::list<ListItem*> selectedItems;
std::uint8_t selectionLimit = 1;
QWidget* viewport() const {
const auto views = this->views();