Browse Source

Fix ModuleBrowser brand and tag list filtering.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
114cc58f05
3 changed files with 71 additions and 69 deletions
  1. +1
    -1
      plugin.mk
  2. +69
    -67
      src/app/ModuleBrowser.cpp
  3. +1
    -1
      src/app/ModuleWidget.cpp

+ 1
- 1
plugin.mk View File

@@ -24,7 +24,7 @@ ifdef ARCH_LIN
TARGET := plugin.so TARGET := plugin.so
RACK_USER_DIR ?= $(HOME)/.Rack RACK_USER_DIR ?= $(HOME)/.Rack
# Link to glibc 2.23 # Link to glibc 2.23
# FLAGS += -include $(RACK_DIR)/include/force_link_glibc_2.23.h
# FLAGS += -include force_link_glibc_2.23.h
endif endif


ifdef ARCH_MAC ifdef ARCH_MAC


+ 69
- 67
src/app/ModuleBrowser.cpp View File

@@ -52,6 +52,43 @@ static float modelScore(plugin::Model *model, const std::string &search) {
return score; return score;
} }


static bool isModelVisible(plugin::Model *model, bool favorites, const std::string &search, const std::string &brand, const std::string &tag) {
// Filter favorites
if (favorites) {
auto it = settings::favoriteModels.find(model);
if (it != settings::favoriteModels.end())
return false;
}

// Filter search query
if (search != "") {
float score = modelScore(model, search);
if (score <= 0.f)
return false;
}

// Filter brand
if (brand != "") {
if (model->plugin->brand != brand)
return false;
}

// Filter tag
if (tag != "") {
bool found = false;
for (const std::string &modelTag : model->tags) {
if (modelTag == tag) {
found = true;
break;
}
}
if (!found)
return false;
}

return true;
}



struct BrowserOverlay : widget::OpaqueWidget { struct BrowserOverlay : widget::OpaqueWidget {
void step() override { void step() override {
@@ -470,18 +507,14 @@ struct ModuleBrowser : widget::OpaqueWidget {
// Reset scroll position // Reset scroll position
modelScroll->offset = math::Vec(); modelScroll->offset = math::Vec();


// Show all or only favorites
// Filter ModelBoxes
for (Widget *w : modelContainer->children) { for (Widget *w : modelContainer->children) {
if (favorites) {
ModelBox *m = dynamic_cast<ModelBox*>(w);
auto it = settings::favoriteModels.find(m->model);
w->visible = (it != settings::favoriteModels.end());
}
else {
w->visible = true;
}
ModelBox *m = dynamic_cast<ModelBox*>(w);
assert(m);
m->visible = isModelVisible(m->model, favorites, search, brand, tag);
} }


// Sort ModelBoxes
if (search.empty()) { if (search.empty()) {
// Sort by plugin name and then module name // Sort by plugin name and then module name
modelContainer->children.sort([&](Widget *w1, Widget *w2) { modelContainer->children.sort([&](Widget *w1, Widget *w2) {
@@ -494,84 +527,46 @@ struct ModuleBrowser : widget::OpaqueWidget {
} }
else { else {
std::map<Widget*, float> scores; std::map<Widget*, float> scores;
// Compute scores and filter visibility
// Compute scores
for (Widget *w : modelContainer->children) { for (Widget *w : modelContainer->children) {
ModelBox *m = dynamic_cast<ModelBox*>(w); ModelBox *m = dynamic_cast<ModelBox*>(w);
assert(m); assert(m);
float score = 0.f;
if (m->visible) {
score = modelScore(m->model, search);
m->visible = (score > 0);
}
scores[m] = score;
if (!m->visible)
continue;
scores[m] = modelScore(m->model, search);;
} }
// Sort by score // Sort by score
modelContainer->children.sort([&](Widget *w1, Widget *w2) { modelContainer->children.sort([&](Widget *w1, Widget *w2) {
// If score was not computed, scores[w] returns 0, but this doesn't matter because those widgets aren't visible.
return scores[w1] > scores[w2]; return scores[w1] > scores[w2];
}); });
} }


// Filter ModelBoxes by brand
if (!brand.empty()) {
for (Widget *w : modelContainer->children) {
if (!w->visible)
continue;
ModelBox *m = dynamic_cast<ModelBox*>(w);
assert(m);
if (m->model->plugin->brand != brand)
m->visible = false;
}
}

// Filter ModelBoxes by tag
if (!tag.empty()) {
for (Widget *w : modelContainer->children) {
if (!w->visible)
continue;
ModelBox *m = dynamic_cast<ModelBox*>(w);
assert(m);
bool found = false;
for (const std::string &tag : m->model->tags) {
if (tag == this->tag) {
found = true;
break;
}
}
if (!found)
m->visible = false;
}
}

std::set<std::string> enabledBrands;
std::set<std::string> enabledTags;
// Filter the brand and tag lists


// Get list of enabled brands and tags for sidebar
// Get modules that would be filtered by just the favorites and search state
std::vector<plugin::Model*> filteredModels;
for (Widget *w : modelContainer->children) { for (Widget *w : modelContainer->children) {
ModelBox *m = dynamic_cast<ModelBox*>(w); ModelBox *m = dynamic_cast<ModelBox*>(w);
assert(m); assert(m);
if (!m->visible)
continue;
enabledBrands.insert(m->model->plugin->brand);
for (const std::string &tag : m->model->tags) {
enabledTags.insert(tag);
}
if (isModelVisible(m->model, favorites, search, "", ""))
filteredModels.push_back(m->model);
} }


// Count models
int modelsLen = 0;
for (Widget *w : modelContainer->children) {
if (w->visible)
modelsLen++;
}
modelLabel->text = string::f("Modules (%d)", modelsLen);
auto hasModel = [&](const std::string &brand, const std::string &tag) -> bool {
for (plugin::Model *model : filteredModels) {
if (isModelVisible(model, false, "", brand, tag))
return true;
}
return false;
};


// Enable brand and tag items that are available in visible ModelBoxes // Enable brand and tag items that are available in visible ModelBoxes
int brandsLen = 0; int brandsLen = 0;
for (Widget *w : sidebar->brandList->children) { for (Widget *w : sidebar->brandList->children) {
BrandItem *item = dynamic_cast<BrandItem*>(w); BrandItem *item = dynamic_cast<BrandItem*>(w);
assert(item); assert(item);
auto it = enabledBrands.find(item->text);
item->disabled = (it == enabledBrands.end());
item->disabled = !hasModel(item->text, tag);
if (!item->disabled) if (!item->disabled)
brandsLen++; brandsLen++;
} }
@@ -581,12 +576,19 @@ struct ModuleBrowser : widget::OpaqueWidget {
for (Widget *w : sidebar->tagList->children) { for (Widget *w : sidebar->tagList->children) {
TagItem *item = dynamic_cast<TagItem*>(w); TagItem *item = dynamic_cast<TagItem*>(w);
assert(item); assert(item);
auto it = enabledTags.find(item->text);
item->disabled = (it == enabledTags.end());
item->disabled = !hasModel(brand, item->text);
if (!item->disabled) if (!item->disabled)
tagsLen++; tagsLen++;
} }
sidebar->tagLabel->text = string::f("Tags (%d)", tagsLen); sidebar->tagLabel->text = string::f("Tags (%d)", tagsLen);

// Count models
int modelsLen = 0;
for (Widget *w : modelContainer->children) {
if (w->visible)
modelsLen++;
}
modelLabel->text = string::f("Modules (%d)", modelsLen);
} }


void clear() { void clear() {


+ 1
- 1
src/app/ModuleWidget.cpp View File

@@ -812,7 +812,7 @@ void ModuleWidget::createContextMenu() {
assert(model); assert(model);


ui::MenuLabel *modelLabel = new ui::MenuLabel; ui::MenuLabel *modelLabel = new ui::MenuLabel;
modelLabel->text = model->name;
modelLabel->text = model->plugin->brand + " " + model->name;
menu->addChild(modelLabel); menu->addChild(modelLabel);


ModulePluginItem *pluginItem = new ModulePluginItem; ModulePluginItem *pluginItem = new ModulePluginItem;


Loading…
Cancel
Save