From 80d5450af95b5287f931a263474ffc9610728f7f Mon Sep 17 00:00:00 2001 From: Boondorl Date: Thu, 6 Mar 2025 19:41:40 -0500 Subject: [PATCH] Updated ZWidget ListView Added column support for consistent spacing between elements. Improved item adding functionality. Added Update and Remove item functionalities. Update ListView scrollbar on item add/remove. --- .../zwidget/widgets/listview/listview.h | 10 +- .../ZWidget/src/widgets/listview/listview.cpp | 92 ++++++++++++++++++- 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h index 2b150abc0..550cc07f9 100644 --- a/libraries/ZWidget/include/zwidget/widgets/listview/listview.h +++ b/libraries/ZWidget/include/zwidget/widgets/listview/listview.h @@ -12,7 +12,12 @@ class ListView : public Widget public: ListView(Widget* parent = nullptr); - void AddItem(const std::string& text); + void SetColumnWidths(const std::vector& widths); + void AddItem(const std::string& text, int index = -1, int column = 0); + void UpdateItem(const std::string& text, int index, int column = 0); + void RemoveItem(int index = -1); + size_t GetItemAmount() const { return items.size(); } + size_t GetColumnAmount() const { return columnwidths.size(); } int GetSelectedItem() const { return selectedItem; } void SetSelectedItem(int index); void ScrollToItem(int index); @@ -34,6 +39,7 @@ protected: Scrollbar* scrollbar = nullptr; - std::vector items; + std::vector> items; + std::vector columnwidths; int selectedItem = 0; }; diff --git a/libraries/ZWidget/src/widgets/listview/listview.cpp b/libraries/ZWidget/src/widgets/listview/listview.cpp index 717f95827..a8dd066d0 100644 --- a/libraries/ZWidget/src/widgets/listview/listview.cpp +++ b/libraries/ZWidget/src/widgets/listview/listview.cpp @@ -8,11 +8,90 @@ ListView::ListView(Widget* parent) : Widget(parent) scrollbar = new Scrollbar(this); scrollbar->FuncScroll = [=]() { OnScrollbarScroll(); }; + + SetColumnWidths({ 0.0 }); } -void ListView::AddItem(const std::string& text) +void ListView::SetColumnWidths(const std::vector& widths) { - items.push_back(text); + columnwidths = widths; + + bool updated = false; + const size_t newWidth = columnwidths.size(); + for (std::vector& column : items) + { + while (column.size() < newWidth) + { + updated = true; + column.push_back(""); + } + while (column.size() > newWidth) + { + updated = true; + column.erase(column.end()); + } + } + + if (updated) + Update(); +} + +void ListView::AddItem(const std::string& text, int index, int column) +{ + if (column < 0 || column >= columnwidths.size()) + return; + + std::vector newEntry; + for (size_t i = 0u; i < columnwidths.size(); ++i) + newEntry.push_back(""); + + newEntry[column] = text; + if (index >= 0) + { + if (index >= items.size()) + { + newEntry[column] = ""; + while (items.size() < index) + items.push_back(newEntry); + + newEntry[column] = text; + items.push_back(newEntry); + } + else + { + items.insert(items.begin() + index, newEntry); + } + } + else + { + items.push_back(newEntry); + } + scrollbar->SetRanges(GetHeight(), items.size() * 20.0); + Update(); +} + +void ListView::UpdateItem(const std::string& text, int index, int column) +{ + if (index < 0 || index >= items.size() || column < 0 || column >= columnwidths.size()) + return; + + items[index][column] = text; + Update(); +} + +void ListView::RemoveItem(int index) +{ + if (!items.size() || index >= items.size()) + return; + + if (index < 0) + index = items.size() - 1; + + if (selectedItem == index) + SetSelectedItem(0); + + items.erase(items.begin() + index); + scrollbar->SetRanges(GetHeight(), items.size() * 20.0); Update(); } @@ -68,7 +147,7 @@ void ListView::OnPaint(Canvas* canvas) double h = 20.0; int index = 0; - for (const std::string& item : items) + for (const std::vector& item : items) { double itemY = y; if (itemY + h >= 0.0 && itemY < GetHeight()) @@ -77,7 +156,12 @@ void ListView::OnPaint(Canvas* canvas) { canvas->fillRect(Rect::xywh(x - 2.0, itemY, w, h), Colorf::fromRgba8(100, 100, 100)); } - canvas->drawText(Point(x, y + 15.0), Colorf::fromRgba8(255, 255, 255), item); + double cx = x; + for (size_t entry = 0u; entry < item.size(); ++entry) + { + canvas->drawText(Point(cx, y + 15.0), Colorf::fromRgba8(255, 255, 255), item[entry]); + cx += columnwidths[entry]; + } } y += h; index++;