gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 5a3724d57396c4bb58e5475e37953d73ee108426
parent e3a231119128450b4b4aa526ed4ae281bb0f6cbc
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sun, 14 Jul 2024 02:13:52 +0200

more grid view work, basic item selection and drag&drop now working

Diffstat:
Msource/jucePluginEditorLib/CMakeLists.txt | 3+++
Msource/jucePluginEditorLib/patchmanager/grid.cpp | 164++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msource/jucePluginEditorLib/patchmanager/grid.h | 39+++++++++++++++++++++++++++++++++++----
Asource/jucePluginEditorLib/patchmanager/griditem.cpp | 33+++++++++++++++++++++++++++++++++
Asource/jucePluginEditorLib/patchmanager/griditem.h | 28++++++++++++++++++++++++++++
Asource/jucePluginEditorLib/patchmanager/griditemcontainer.cpp | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asource/jucePluginEditorLib/patchmanager/griditemcontainer.h | 27+++++++++++++++++++++++++++
Asource/jucePluginEditorLib/patchmanager/gridviewport.cpp | 37+++++++++++++++++++++++++++++++++++++
Asource/jucePluginEditorLib/patchmanager/gridviewport.h | 24++++++++++++++++++++++++
Msource/jucePluginEditorLib/patchmanager/list.cpp | 21+++++++++++++--------
Msource/jucePluginEditorLib/patchmanager/list.h | 2++
Msource/jucePluginEditorLib/patchmanager/listmodel.h | 27+++++++++++++++++++++++++++
Msource/jucePluginEditorLib/patchmanager/patchmanager.cpp | 15+++++++++------
13 files changed, 515 insertions(+), 28 deletions(-)

diff --git a/source/jucePluginEditorLib/CMakeLists.txt b/source/jucePluginEditorLib/CMakeLists.txt @@ -24,6 +24,9 @@ set(SOURCES_PM patchmanager/defaultskin.h patchmanager/editable.cpp patchmanager/editable.h patchmanager/grid.cpp patchmanager/grid.h + patchmanager/griditem.cpp patchmanager/griditem.h + patchmanager/griditemcontainer.cpp patchmanager/griditemcontainer.h + patchmanager/gridviewport.cpp patchmanager/gridviewport.h patchmanager/grouptreeitem.cpp patchmanager/grouptreeitem.h patchmanager/info.cpp patchmanager/info.h patchmanager/list.cpp patchmanager/list.h diff --git a/source/jucePluginEditorLib/patchmanager/grid.cpp b/source/jucePluginEditorLib/patchmanager/grid.cpp @@ -1,19 +1,152 @@ #include "grid.h" +#include "griditem.h" +#include "list.h" +#include "patchmanager.h" + +#include "../../juceUiLib/uiObjectStyle.h" +#include "../../juceUiLib/uiObject.h" +#include "../pluginEditor.h" + namespace jucePluginEditorLib::patchManager { - Grid::Grid(PatchManager& _pm) : ListModel(_pm) + Grid::Grid(PatchManager& _pm) : ListModel(_pm), m_viewport(*this), m_itemContainer(*this) + { + m_viewport.setScrollBarsShown(false, true); + m_viewport.setViewedComponent(&m_itemContainer, false); + + addAndMakeVisible(m_viewport); + + if (const auto& t = _pm.getTemplate("pm_listbox")) + t->apply(_pm.getEditor(), *this); + + List::applyStyleToViewport(_pm, m_viewport); + } + + void Grid::paint(juce::Graphics& g) + { + if(const auto c = findColor(juce::ListBox::backgroundColourId); c.getAlpha() > 0) + g.fillAll(c); + + Component::paint(g); + } + + void Grid::setVisibleItemRange(const std::pair<uint32_t, uint32_t>& _range) + { + const auto& start = _range.first; + const auto& end = start + _range.second; + + // move items not in range back to pool first + for(auto it = m_items.begin(); it != m_items.end();) + { + const auto index = it->first; + + if(index < start || index >= end) + { + m_itemPool.emplace_back(std::move(it->second)); + it = m_items.erase(it); + } + else + { + ++it; + } + } + + // now allocate new items or get them from pool for any item that we do not have yet + for(auto i=start; i<end; ++i) + { + auto it = m_items.find(i); + + if(it != m_items.end()) + continue; + + std::unique_ptr<GridItem> item; + + if(!m_itemPool.empty()) + { + item = std::move(m_itemPool.back()); + m_itemPool.pop_back(); + } + + if(!item) + item.reset(new GridItem(*this)); + + item->setItem(i, refreshComponentForRow(static_cast<int>(i), false, item->getItem())); + + if(item->getParentComponent() != &m_itemContainer) + m_itemContainer.addAndMakeVisible(item.get()); + + m_items.insert({i, std::move(item)}); + } + + const auto visibleRowCount = m_viewport.getVisibleRowCount(); + + for (const auto& it : m_items) + { + const auto index = it.first; + const auto& item = it.second; + + const auto x = index / visibleRowCount; + const auto y = index - x * visibleRowCount; + + item->setTopLeftPosition(static_cast<int>(m_itemWidth * x), static_cast<int>(m_itemHeight * y)); + item->setSize(m_itemWidth, m_itemHeight); + } + } + + void Grid::selectItem(uint32_t _index, bool _deselectOthers) + { + if(_deselectOthers) + { + if(m_selectedItems.size() == 1 && *m_selectedItems.begin() == _index) + return; + + m_selectedItems.clear(); + m_selectedItems.insert(_index); + } + else if(!m_selectedItems.insert(_index).second) + return; + + selectedRowsChanged(static_cast<int>(_index)); + repaint(); + } + + void Grid::deselectItem(const uint32_t _index) + { + if(!m_selectedItems.erase(_index)) + return; + + repaint(); + } + + GridItem* Grid::getItem(uint32_t _index) const + { + const auto it = m_items.find(_index); + return it == m_items.end() ? nullptr : it->second.get(); + } + + void Grid::resized() + { + updateViewportSize(); + } + + int Grid::getNeededColumnCount() { + const auto numItems = getNumRows(); + const auto itemsPerColumn = getVisibleRowCount(); + const auto columnCount = (numItems + itemsPerColumn - 1) / itemsPerColumn; + return columnCount; } - void Grid::mouseDown(const juce::MouseEvent& _e) + int Grid::getVisibleRowCount() const { - Component::mouseDown(_e); + return getHeight() / m_itemHeight; } - void Grid::mouseUp(const juce::MouseEvent& _e) + void Grid::updateViewportSize() { - Component::mouseUp(_e); + m_itemContainer.setSize(m_itemWidth * getNeededColumnCount(), getHeight()); + m_viewport.setSize(getWidth(), getHeight()); } juce::Colour Grid::findColor(const int _colorId) @@ -28,10 +161,13 @@ namespace jucePluginEditorLib::patchManager void Grid::onModelChanged() { + updateViewportSize(); + repaint(); } void Grid::redraw() { + repaint(); } void Grid::ensureVisible(int _row) @@ -41,22 +177,30 @@ namespace jucePluginEditorLib::patchManager int Grid::getSelectedEntry() const { - return -1; // TODO + if (m_selectedItems.empty()) + return -1; + + return static_cast<int>(*m_selectedItems.begin()); } juce::SparseSet<int> Grid::getSelectedEntries() const { - return {}; // TODO + return toSparseSet(m_selectedItems); } void Grid::deselectAll() { - // TODO + if(m_selectedItems.empty()) + return; + + m_selectedItems.clear(); + repaint(); } - void Grid::setSelectedEntries(const juce::SparseSet<int>&) + void Grid::setSelectedEntries(const juce::SparseSet<int>& _items) { - // TODO + m_selectedItems = toSet<uint32_t>(_items); + repaint(); } juce::Rectangle<int> Grid::getEntryPosition(int _row, bool _relativeToComponentTopLeft) diff --git a/source/jucePluginEditorLib/patchmanager/grid.h b/source/jucePluginEditorLib/patchmanager/grid.h @@ -1,20 +1,45 @@ #pragma once +#include "griditemcontainer.h" +#include "gridviewport.h" #include "listmodel.h" #include "juce_gui_basics/juce_gui_basics.h" namespace jucePluginEditorLib::patchManager { + class GridItem; + class Grid : public ListModel, public juce::Component { public: Grid(PatchManager& _pm); - void mouseDown(const juce::MouseEvent& _e) override; - void mouseUp(const juce::MouseEvent& _e) override; + void paint(juce::Graphics& g) override; + + int getItemWidth() const { return m_itemWidth; } + int getItemHeight() const { return m_itemHeight; } + + void setVisibleItemRange(const std::pair<uint32_t, uint32_t>& _range); + + const GridViewport& getViewport() const { return m_viewport; } + + bool isSelected(const uint32_t _index) + { + return m_selectedItems.find(_index) != m_selectedItems.end(); + } + + void selectItem(uint32_t _index, bool _deselectOthers); + void deselectItem(uint32_t _index); + GridItem* getItem(uint32_t _index) const; + private: + void resized() override; + int getNeededColumnCount(); + int getVisibleRowCount() const; + void updateViewportSize(); + public: // ListModel juce::Colour findColor(int _colorId) override; const juce::LookAndFeel& getStyle() const override; @@ -27,9 +52,15 @@ namespace jucePluginEditorLib::patchManager void setSelectedEntries(const juce::SparseSet<int>&) override; juce::Rectangle<int> getEntryPosition(int _row, bool _relativeToComponentTopLeft) override; + private: int m_itemHeight = 22; - int m_itemWidth = 100; + int m_itemWidth = 150; + + GridViewport m_viewport; + GridItemContainer m_itemContainer; - juce::Viewport m_viewport; + std::map<uint32_t, std::unique_ptr<GridItem>> m_items; + std::list<std::unique_ptr<GridItem>> m_itemPool; + std::set<uint32_t> m_selectedItems; }; } diff --git a/source/jucePluginEditorLib/patchmanager/griditem.cpp b/source/jucePluginEditorLib/patchmanager/griditem.cpp @@ -0,0 +1,33 @@ +#include "griditem.h" + +#include "grid.h" + +namespace jucePluginEditorLib::patchManager +{ + GridItem::GridItem(Grid& _grid) : m_grid(_grid) + { + setInterceptsMouseClicks(false, true); + } + + void GridItem::paint(juce::Graphics& _g) + { + if(m_index >= static_cast<uint32_t>(m_grid.getNumRows())) + return; + + _g.setColour(m_grid.findColour(juce::ListBox::backgroundColourId).withMultipliedBrightness(0.1f)); + _g.drawRect(0, 0, getWidth()-1, getHeight()-1); + + m_grid.paintListBoxItem(static_cast<int>(m_index), _g, getWidth(), getHeight(), m_grid.isSelected(m_index)); + + juce::Component::paint(_g); + } + + void GridItem::setItem(uint32_t _index, juce::Component* _component) + { + m_index = _index; + m_item = _component; + + if(m_item->getParentComponent() != this) + addAndMakeVisible(m_item); + } +} diff --git a/source/jucePluginEditorLib/patchmanager/griditem.h b/source/jucePluginEditorLib/patchmanager/griditem.h @@ -0,0 +1,28 @@ +#pragma once + +#include "juce_gui_basics/juce_gui_basics.h" + +namespace juce +{ + class Graphics; +} + +namespace jucePluginEditorLib::patchManager +{ + class Grid; + + class GridItem : public juce::Component + { + public: + GridItem(Grid& _grid); + + void paint(juce::Graphics& _g) override; + + void setItem(uint32_t _index, juce::Component* _component); + juce::Component* getItem() const { return m_item; } + private: + Grid& m_grid; + uint32_t m_index = ~0; + juce::Component* m_item = nullptr; + }; +} diff --git a/source/jucePluginEditorLib/patchmanager/griditemcontainer.cpp b/source/jucePluginEditorLib/patchmanager/griditemcontainer.cpp @@ -0,0 +1,123 @@ +#include "griditemcontainer.h" + +#include "grid.h" +#include "griditem.h" + +#include "dsp56kEmu/logging.h" + +namespace jucePluginEditorLib::patchManager +{ + GridItemContainer::GridItemContainer(Grid& _grid) : m_grid(_grid) + { + } + + void GridItemContainer::mouseDown(const juce::MouseEvent& _e) + { + Component::mouseDown(_e); + m_itemIndexMouseDown = mouseToItemIndex(_e); + } + + juce::ScaledImage GridItemContainer::createSnapshotOfRows(const juce::SparseSet<int>& _rows, int& _x, int& _y) const + { + juce::Rectangle<int> imageArea; + + const auto rows = Grid::toSet<uint32_t>(_rows); + for (const auto row : rows) + { + if (const auto* rowComp = m_grid.getItem(row)) + { + auto pos = m_grid.getLocalPoint(rowComp, juce::Point<int>()); + + imageArea = imageArea.getUnion ({ pos.x, pos.y, rowComp->getWidth(), rowComp->getHeight() }); + } + } + + imageArea = imageArea.getIntersection (getLocalBounds()); + _x = imageArea.getX(); + _y = imageArea.getY(); + + constexpr auto additionalScale = 2.0f; + const auto listScale = Component::getApproximateScaleFactorForComponent (this) * additionalScale; + juce::Image snapshot (juce::Image::ARGB, + juce::roundToInt (static_cast<float>(imageArea.getWidth()) * listScale), + juce::roundToInt (static_cast<float>(imageArea.getHeight()) * listScale), + true); + + for (const auto row : rows) + { + if (auto* rowComp = m_grid.getItem(row)) + { + juce::Graphics g (snapshot); + g.setOrigin ((getLocalPoint (rowComp, juce::Point<int>()) - imageArea.getPosition()) * additionalScale); + + const auto rowScale = Component::getApproximateScaleFactorForComponent (rowComp) * additionalScale; + + if (g.reduceClipRegion (rowComp->getLocalBounds() * rowScale)) + { + g.beginTransparencyLayer (0.6f); + g.addTransform (juce::AffineTransform::scale (rowScale)); + rowComp->paintEntireComponent (g, false); + g.endTransparencyLayer(); + } + } + } + + return { snapshot, additionalScale }; + } + + void GridItemContainer::mouseDrag(const juce::MouseEvent& _e) + { + m_itemIndexMouseDown = InvalidItem; + + const auto rows = m_grid.getSelectedEntries(); + + if(!rows.isEmpty()) + { + const auto dragDescription = m_grid.getDragSourceDescription(rows); + + if(!dragDescription.isVoid()) + { + if (auto* dragContainer = juce::DragAndDropContainer::findParentDragContainerFor (this)) + { + int x, y; + const auto dragImage = createSnapshotOfRows(rows, x, y); + + const auto p = juce::Point<int> (x, y) - _e.getEventRelativeTo (this).position.toInt(); + dragContainer->startDragging (dragDescription, this, dragImage, true, &p, &_e.source); + } + } + } + + Component::mouseDrag(_e); + } + + void GridItemContainer::mouseUp(const juce::MouseEvent& _e) + { + const auto i = mouseToItemIndex(_e); + + if(i == m_itemIndexMouseDown) + { + const auto cmd = _e.mods.isCommandDown(); + + if(m_grid.isSelected(i) && cmd) + { + m_grid.deselectItem(i); + } + else + { + m_grid.selectItem(i, !cmd); + m_grid.listBoxItemClicked(static_cast<int>(i), _e); + } + } + } + + uint32_t GridItemContainer::mouseToItemIndex(const juce::MouseEvent& _e) const + { + const auto rowsPerCol = m_grid.getViewport().getVisibleRowCount(); + + const auto col = _e.x / m_grid.getItemWidth(); + const auto row = _e.y / m_grid.getItemHeight(); + + return row + col * rowsPerCol; + } +} diff --git a/source/jucePluginEditorLib/patchmanager/griditemcontainer.h b/source/jucePluginEditorLib/patchmanager/griditemcontainer.h @@ -0,0 +1,27 @@ +#pragma once + +#include "juce_gui_basics/juce_gui_basics.h" + +namespace jucePluginEditorLib::patchManager +{ + class Grid; + + class GridItemContainer : public juce::Component + { + public: + static constexpr uint32_t InvalidItem = ~0; + + GridItemContainer(Grid& _grid); + + void mouseDown(const juce::MouseEvent& _e) override; + juce::ScaledImage createSnapshotOfRows(const juce::SparseSet<int>& _rows, int& _x, int& _y) const; + void mouseDrag(const juce::MouseEvent& _e) override; + void mouseUp(const juce::MouseEvent& _e) override; + + private: + uint32_t mouseToItemIndex(const juce::MouseEvent& _e) const; + + Grid& m_grid; + uint32_t m_itemIndexMouseDown = InvalidItem; + }; +} diff --git a/source/jucePluginEditorLib/patchmanager/gridviewport.cpp b/source/jucePluginEditorLib/patchmanager/gridviewport.cpp @@ -0,0 +1,37 @@ +#include "gridviewport.h" + +#include "grid.h" + +namespace jucePluginEditorLib::patchManager +{ + GridViewport::GridViewport(Grid& _grid) : m_grid(_grid) + { + } + + void GridViewport::visibleAreaChanged(const juce::Rectangle<int>& _area) + { + Viewport::visibleAreaChanged(_area); + + m_grid.setVisibleItemRange(getItemRangeFromArea(_area)); + } + + std::pair<int, int> GridViewport::getItemRangeFromArea(const juce::Rectangle<int>& _area) const + { + const auto xOffset = _area.getX(); + + const auto firstColumn = xOffset / m_grid.getItemWidth(); + const auto lastColumn = (xOffset + _area.getWidth() + m_grid.getItemWidth() - 1) / m_grid.getItemWidth(); + + const auto rowCount = _area.getHeight() / m_grid.getItemHeight(); + + const auto firstItem = firstColumn * rowCount; + const auto itemCount = (lastColumn - firstColumn) * rowCount + rowCount; + + return {firstItem, itemCount}; + } + + int GridViewport::getVisibleRowCount() const + { + return getViewArea().getHeight() / m_grid.getItemHeight(); + } +} diff --git a/source/jucePluginEditorLib/patchmanager/gridviewport.h b/source/jucePluginEditorLib/patchmanager/gridviewport.h @@ -0,0 +1,23 @@ +#pragma once + +#include "juce_gui_basics/juce_gui_basics.h" + +namespace jucePluginEditorLib::patchManager +{ + class Grid; + + class GridViewport : public juce::Viewport + { + public: + GridViewport(Grid& _grid); + + void visibleAreaChanged(const juce::Rectangle<int>& _area) override; + + std::pair<int, int> getItemRangeFromArea(const juce::Rectangle<int>& _area) const; + + int getVisibleRowCount() const; + + private: + Grid& m_grid; + }; +} +\ No newline at end of file diff --git a/source/jucePluginEditorLib/patchmanager/list.cpp b/source/jucePluginEditorLib/patchmanager/list.cpp @@ -21,20 +21,25 @@ namespace jucePluginEditorLib::patchManager if (const auto& t = _pm.getTemplate("pm_listbox")) t->apply(_pm.getEditor(), *this); + applyStyleToViewport(_pm, *getViewport()); + + setRowSelectedOnMouseDown(false); + } + + void List::applyStyleToViewport(const PatchManager& _pm, juce::Viewport& _viewport) + { if(const auto t = _pm.getTemplate("pm_scrollbar")) { - t->apply(_pm.getEditor(), getVerticalScrollBar()); - t->apply(_pm.getEditor(), getHorizontalScrollBar()); + t->apply(_pm.getEditor(), _viewport.getVerticalScrollBar()); + t->apply(_pm.getEditor(), _viewport.getHorizontalScrollBar()); } else { - getVerticalScrollBar().setColour(juce::ScrollBar::thumbColourId, juce::Colour(defaultSkin::colors::scrollbar)); - getVerticalScrollBar().setColour(juce::ScrollBar::trackColourId, juce::Colour(defaultSkin::colors::scrollbar)); - getHorizontalScrollBar().setColour(juce::ScrollBar::thumbColourId, juce::Colour(defaultSkin::colors::scrollbar)); - getHorizontalScrollBar().setColour(juce::ScrollBar::trackColourId, juce::Colour(defaultSkin::colors::scrollbar)); + _viewport.getVerticalScrollBar().setColour(juce::ScrollBar::thumbColourId, juce::Colour(defaultSkin::colors::scrollbar)); + _viewport.getVerticalScrollBar().setColour(juce::ScrollBar::trackColourId, juce::Colour(defaultSkin::colors::scrollbar)); + _viewport.getHorizontalScrollBar().setColour(juce::ScrollBar::thumbColourId, juce::Colour(defaultSkin::colors::scrollbar)); + _viewport.getHorizontalScrollBar().setColour(juce::ScrollBar::trackColourId, juce::Colour(defaultSkin::colors::scrollbar)); } - - setRowSelectedOnMouseDown(false); } juce::Colour List::findColor(const int _colorId) diff --git a/source/jucePluginEditorLib/patchmanager/list.h b/source/jucePluginEditorLib/patchmanager/list.h @@ -9,6 +9,8 @@ namespace jucePluginEditorLib::patchManager public: explicit List(PatchManager& _pm); + static void applyStyleToViewport(const PatchManager& _pm, juce::Viewport& _viewport); + private: // ListModel juce::Colour findColor(int _colorId) override; diff --git a/source/jucePluginEditorLib/patchmanager/listmodel.h b/source/jucePluginEditorLib/patchmanager/listmodel.h @@ -90,6 +90,33 @@ namespace jucePluginEditorLib::patchManager pluginLib::patchDB::SearchHandle getSearchHandle() const; + template<typename T> + static std::set<T> toSet(const juce::SparseSet<int>& _sparseSet) + { + std::set<T> result; + + const auto& ranges = _sparseSet.getRanges(); + + for (const auto& range : ranges) + { + for (int i = range.getStart(); i < range.getEnd(); ++i) + result.insert(static_cast<T>(i)); + } + return result; + } + + template<typename T> + static juce::SparseSet<int> toSparseSet(const std::set<T>& _set) + { + juce::SparseSet<int> result; + for (auto i : _set) + { + const auto ii = static_cast<int>(i); + result.addRange({ii, ii+1}); + } + return result; + } + // to be implemented in derived class virtual juce::Colour findColor(int _colorId) = 0; virtual const juce::LookAndFeel& getStyle() const = 0; diff --git a/source/jucePluginEditorLib/patchmanager/patchmanager.cpp b/source/jucePluginEditorLib/patchmanager/patchmanager.cpp @@ -18,8 +18,6 @@ #include "../../jucePluginLib/types.h" #include "../../jucePluginLib/clipboard.h" -#include "../../synthLib/os.h" - #include "dsp56kEmu/logging.h" #include "juce_gui_extra/misc/juce_ColourSelector.h" @@ -85,6 +83,11 @@ namespace jucePluginEditorLib::patchManager m_grid->setTopLeftPosition(m_list->getPosition()); m_grid->setSize(m_list->getWidth(), m_list->getHeight()); + m_grid->setLookAndFeel(&m_list->getLookAndFeel()); + m_grid->setColour(juce::ListBox::backgroundColourId, m_list->findColour(juce::ListBox::backgroundColourId)); + m_grid->setColour(juce::ListBox::textColourId, m_list->findColour(juce::ListBox::textColourId)); + m_grid->setColour(juce::ListBox::outlineColourId, m_list->findColour(juce::ListBox::outlineColourId)); + m_searchList = new SearchList(*m_list); m_searchList->setTopLeftPosition(m_list->getX(), m_list->getHeight() + g_padding); m_searchList->setSize(m_list->getWidth(), g_searchBarHeight); @@ -651,7 +654,7 @@ namespace jucePluginEditorLib::patchManager return false; if(getCurrentPart() == _part) - m_list->setSelectedPatches(std::set<pluginLib::patchDB::PatchKey>{}); + getListModel()->setSelectedPatches(std::set<pluginLib::patchDB::PatchKey>{}); return true; } @@ -850,7 +853,7 @@ namespace jucePluginEditorLib::patchManager void PatchManager::onSelectedItemsChanged() { // trees emit onSelectionChanged in destructor, be sure to guard it - if(!m_list) + if(!getListModel()) return; const auto selectedTags = m_selectedItems[m_treeTags]; @@ -859,7 +862,7 @@ namespace jucePluginEditorLib::patchManager { if(_item->getSearchHandle() != pluginLib::patchDB::g_invalidSearchHandle) { - m_list->setContent(_item->getSearchHandle()); + getListModel()->setContent(_item->getSearchHandle()); return true; } return false; @@ -877,7 +880,7 @@ namespace jucePluginEditorLib::patchManager pluginLib::patchDB::SearchRequest search = (*selectedTags.begin())->getSearchRequest(); for (const auto& selectedTag : selectedTags) search.tags.add(selectedTag->getSearchRequest().tags); - m_list->setContent(std::move(search)); + getListModel()->setContent(std::move(search)); return; } }