From 1023247941e51bdc5ab9987cb2ae2d4beaa04687 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 26 Aug 2021 19:57:58 -0400 Subject: [PATCH] Add Model::appendContextMenu(). Display Model context menu in ModelBox of module browser. --- include/plugin/Model.hpp | 8 ++++ include/system.hpp | 2 + src/app/Browser.cpp | 7 ++- src/app/ModuleWidget.cpp | 92 +------------------------------------- src/plugin/Model.cpp | 95 ++++++++++++++++++++++++++++++++++++++++ src/system.cpp | 6 +++ 6 files changed, 118 insertions(+), 92 deletions(-) diff --git a/include/plugin/Model.hpp b/include/plugin/Model.hpp index 030b9aff..b40bc8be 100644 --- a/include/plugin/Model.hpp +++ b/include/plugin/Model.hpp @@ -10,6 +10,11 @@ namespace rack { +namespace ui { +struct Menu; +} // namespace app + + namespace app { struct ModuleWidget; } // namespace app @@ -65,6 +70,9 @@ struct Model { std::string getFullName(); std::string getFactoryPresetDirectory(); std::string getUserPresetDirectory(); + /** Returns the module or plugin manual URL, whichever exists. */ + std::string getManualUrl(); + void appendContextMenu(ui::Menu* menu); }; diff --git a/include/system.hpp b/include/system.hpp index 1f048d70..63d5761a 100644 --- a/include/system.hpp +++ b/include/system.hpp @@ -168,10 +168,12 @@ std::string getOperatingSystemInfo(); /** Opens a URL in a browser. Shell injection is possible, so make sure the URL is trusted or hard coded. +Does nothing if string is blank. Does not block. */ void openBrowser(const std::string& url); /** Opens Windows Explorer, Finder, etc at a directory location. +Does nothing if string is blank. Does not block. */ void openDirectory(const std::string& path); diff --git a/src/app/Browser.cpp b/src/app/Browser.cpp index d927617d..6e9a50be 100644 --- a/src/app/Browser.cpp +++ b/src/app/Browser.cpp @@ -284,8 +284,11 @@ struct ModelBox : widget::OpaqueWidget { void createContextMenu() { ui::Menu* menu = createMenu(); - // menu->addChild(createMenuLabel(model->name)); - // menu->addChild(createMenuLabel(model->plugin->brand)); + menu->addChild(createMenuLabel(model->name)); + menu->addChild(createMenuLabel(model->plugin->brand)); + model->appendContextMenu(menu); + + menu->addChild(new ui::MenuSeparator); menu->addChild(createBoolMenuItem("Favorite", [=]() { diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index f8412d9e..76e3f571 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -16,7 +16,6 @@ #include #include #include -#include namespace rack { @@ -358,9 +357,7 @@ void ModuleWidget::onHoverKey(const HoverKeyEvent& e) { return; } if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { - std::string manualUrl = (model->manualUrl != "") ? model->manualUrl : model->plugin->manualUrl; - if (!manualUrl.empty()) - system::openBrowser(manualUrl); + system::openBrowser(model->getManualUrl()); e.consume(this); } } @@ -919,92 +916,7 @@ void ModuleWidget::createContextMenu() { // Info menu->addChild(createSubmenuItem("Info", "", [=](ui::Menu* menu) { - if (!weakThis) - return; - - // plugin - menu->addChild(createMenuItem("Plugin: " + model->plugin->name, "", [=]() { - system::openBrowser(model->plugin->pluginUrl); - }, model->plugin->pluginUrl == "")); - - // version - menu->addChild(createMenuLabel(model->plugin->version)); - - // author - if (model->plugin->author != "") { - menu->addChild(createMenuItem("Author: " + model->plugin->author, "", [=]() { - system::openBrowser(model->plugin->authorUrl); - }, model->plugin->authorUrl.empty())); - } - - // license - std::string license = model->plugin->license; - if (string::startsWith(license, "https://") || string::startsWith(license, "http://")) { - menu->addChild(createMenuItem("License: Open in browser", "", [=]() { - system::openBrowser(license); - })); - } - else if (license != "") { - menu->addChild(createMenuLabel("License: " + license)); - } - - // tags - if (!model->tagIds.empty()) { - menu->addChild(createMenuLabel("Tags:")); - for (int tagId : model->tagIds) { - menu->addChild(createMenuLabel("• " + tag::getTag(tagId))); - } - } - - menu->addChild(new ui::MenuSeparator); - - // VCV Library page - menu->addChild(createMenuItem("VCV Library page", "", [=]() { - system::openBrowser("https://library.vcvrack.com/" + model->plugin->slug + "/" + model->slug); - })); - - // modularGridUrl - if (model->modularGridUrl != "") { - menu->addChild(createMenuItem("ModularGrid page", "", [=]() { - system::openBrowser(model->modularGridUrl); - })); - } - - // manual - std::string manualUrl = (model->manualUrl != "") ? model->manualUrl : model->plugin->manualUrl; - if (manualUrl != "") { - menu->addChild(createMenuItem("User manual", RACK_MOD_CTRL_NAME "+F1", [=]() { - system::openBrowser(manualUrl); - })); - } - - // donate - if (model->plugin->donateUrl != "") { - menu->addChild(createMenuItem("Donate", "", [=]() { - system::openBrowser(model->plugin->donateUrl); - })); - } - - // source code - if (model->plugin->sourceUrl != "") { - menu->addChild(createMenuItem("Source code", "", [=]() { - system::openBrowser(model->plugin->sourceUrl); - })); - } - - // changelog - if (model->plugin->changelogUrl != "") { - menu->addChild(createMenuItem("Changelog", "", [=]() { - system::openBrowser(model->plugin->changelogUrl); - })); - } - - // plugin folder - if (model->plugin->path != "") { - menu->addChild(createMenuItem("Open plugin folder", "", [=]() { - system::openDirectory(model->plugin->path); - })); - } + model->appendContextMenu(menu); })); // Preset diff --git a/src/plugin/Model.cpp b/src/plugin/Model.cpp index 323ca3e3..e9321a32 100644 --- a/src/plugin/Model.cpp +++ b/src/plugin/Model.cpp @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include namespace rack { @@ -84,6 +87,98 @@ std::string Model::getUserPresetDirectory() { } +std::string Model::getManualUrl() { + if (!manualUrl.empty()) + return manualUrl; + return plugin->manualUrl; +} + + +void Model::appendContextMenu(ui::Menu* menu) { + // plugin + menu->addChild(createMenuItem("Plugin: " + plugin->name, "", [=]() { + system::openBrowser(plugin->pluginUrl); + }, plugin->pluginUrl == "")); + + // version + menu->addChild(createMenuLabel(plugin->version)); + + // author + if (plugin->author != "") { + menu->addChild(createMenuItem("Author: " + plugin->author, "", [=]() { + system::openBrowser(plugin->authorUrl); + }, plugin->authorUrl.empty())); + } + + // license + std::string license = plugin->license; + if (string::startsWith(license, "https://") || string::startsWith(license, "http://")) { + menu->addChild(createMenuItem("License: Open in browser", "", [=]() { + system::openBrowser(license); + })); + } + else if (license != "") { + menu->addChild(createMenuLabel("License: " + license)); + } + + // tags + if (!tagIds.empty()) { + menu->addChild(createMenuLabel("Tags:")); + for (int tagId : tagIds) { + menu->addChild(createMenuLabel("• " + tag::getTag(tagId))); + } + } + + menu->addChild(new ui::MenuSeparator); + + // VCV Library page + menu->addChild(createMenuItem("VCV Library page", "", [=]() { + system::openBrowser("https://library.vcvrack.com/" + plugin->slug + "/" + slug); + })); + + // modularGridUrl + if (modularGridUrl != "") { + menu->addChild(createMenuItem("ModularGrid page", "", [=]() { + system::openBrowser(modularGridUrl); + })); + } + + // manual + std::string manualUrl = getManualUrl(); + if (manualUrl != "") { + menu->addChild(createMenuItem("User manual", RACK_MOD_CTRL_NAME "+F1", [=]() { + system::openBrowser(manualUrl); + })); + } + + // donate + if (plugin->donateUrl != "") { + menu->addChild(createMenuItem("Donate", "", [=]() { + system::openBrowser(plugin->donateUrl); + })); + } + + // source code + if (plugin->sourceUrl != "") { + menu->addChild(createMenuItem("Source code", "", [=]() { + system::openBrowser(plugin->sourceUrl); + })); + } + + // changelog + if (plugin->changelogUrl != "") { + menu->addChild(createMenuItem("Changelog", "", [=]() { + system::openBrowser(plugin->changelogUrl); + })); + } + + // plugin folder + if (plugin->path != "") { + menu->addChild(createMenuItem("Open plugin folder", "", [=]() { + system::openDirectory(plugin->path); + })); + } +} } // namespace plugin diff --git a/src/system.cpp b/src/system.cpp index 51e53047..e79d5e3d 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -712,6 +712,9 @@ std::string getOperatingSystemInfo() { void openBrowser(const std::string& url) { + if (url.empty()) + return; + std::string urlL = url; std::thread t([=] { #if defined ARCH_LIN @@ -731,6 +734,9 @@ void openBrowser(const std::string& url) { void openDirectory(const std::string& path) { + if (path.empty()) + return; + std::string pathL = path; std::thread t([=] { #if defined ARCH_LIN