Cardinal/src/override/diffs/MenuBar.cpp.diff
falkTX 1262f318da
Update and adapt to Rack 2.3
Signed-off-by: falkTX <falktx@falktx.com>
2023-05-20 19:38:29 +02:00

920 lines
26 KiB
Diff

--- ../Rack/src/app/MenuBar.cpp 2023-05-20 17:03:33.005081737 +0200
+++ MenuBar.cpp 2023-05-20 19:32:57.019576570 +0200
@@ -1,8 +1,33 @@
+/*
+ * DISTRHO Cardinal Plugin
+ * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * For a full copy of the GNU General Public License see the LICENSE file.
+ */
+
+/**
+ * This file is an edited version of VCVRack's app/MenuBar.cpp
+ * Copyright (C) 2016-2023 VCV.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ */
+
#include <thread>
#include <utility>
-#include <osdialog.h>
-
#include <app/MenuBar.hpp>
#include <app/TipWindow.hpp>
#include <widget/OpaqueWidget.hpp>
@@ -15,6 +40,7 @@
#include <ui/ProgressBar.hpp>
#include <ui/Label.hpp>
#include <engine/Engine.hpp>
+#include <widget/FramebufferWidget.hpp>
#include <window/Window.hpp>
#include <asset.hpp>
#include <context.hpp>
@@ -25,8 +51,26 @@
#include <patch.hpp>
#include <library.hpp>
+#include "../CardinalCommon.hpp"
+#include "../CardinalRemote.hpp"
+#include "DistrhoPlugin.hpp"
+#include "DistrhoStandaloneUtils.hpp"
+
+#ifdef HAVE_LIBLO
+# include <lo/lo.h>
+#endif
namespace rack {
+namespace asset {
+std::string patchesPath();
+}
+namespace engine {
+void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*);
+}
+namespace plugin {
+void updateStaticPluginsDarkMode();
+}
+
namespace app {
namespace menuBar {
@@ -48,79 +92,180 @@
};
-struct NotificationIcon : widget::Widget {
- void draw(const DrawArgs& args) override {
- nvgBeginPath(args.vg);
- float radius = 4;
- nvgCircle(args.vg, radius, radius, radius);
- nvgFillColor(args.vg, nvgRGBf(1.0, 0.0, 0.0));
- nvgFill(args.vg);
- nvgStrokeColor(args.vg, nvgRGBf(0.5, 0.0, 0.0));
- nvgStroke(args.vg);
- }
-};
-
-
////////////////////
// File
////////////////////
struct FileButton : MenuButton {
+ const bool isStandalone;
+ std::vector<std::string> demoPatches;
+
+ FileButton(const bool standalone)
+ : MenuButton(), isStandalone(standalone)
+ {
+#if CARDINAL_VARIANT_MINI
+ const std::string patchesDir = asset::patchesPath() + DISTRHO_OS_SEP_STR "mini";
+#else
+ const std::string patchesDir = asset::patchesPath() + DISTRHO_OS_SEP_STR "examples";
+#endif
+
+ if (system::isDirectory(patchesDir))
+ {
+ demoPatches = system::getEntries(patchesDir);
+ std::sort(demoPatches.begin(), demoPatches.end(), [](const std::string& a, const std::string& b){
+ return string::lowercase(a) < string::lowercase(b);
+ });
+ }
+ }
+
void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu();
menu->cornerFlags = BND_CORNER_TOP;
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
- menu->addChild(createMenuItem("New", RACK_MOD_CTRL_NAME "+N", []() {
- APP->patch->loadTemplateDialog();
+#ifndef DISTRHO_OS_WASM
+ constexpr const char* const NewShortcut = RACK_MOD_CTRL_NAME "+N";
+#else
+ constexpr const char* const NewShortcut = "";
+#endif
+ menu->addChild(createMenuItem("New", NewShortcut, []() {
+ patchUtils::loadTemplateDialog(false);
+ }));
+
+#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
+#ifndef DISTRHO_OS_WASM
+ menu->addChild(createMenuItem("New (factory template)", "", []() {
+ patchUtils::loadTemplateDialog(true);
}));
- menu->addChild(createMenuItem("Open", RACK_MOD_CTRL_NAME "+O", []() {
- APP->patch->loadDialog();
+ menu->addChild(createMenuItem("Open / Import...", RACK_MOD_CTRL_NAME "+O", []() {
+ patchUtils::loadDialog();
}));
menu->addChild(createSubmenuItem("Open recent", "", [](ui::Menu* menu) {
for (const std::string& path : settings::recentPatchPaths) {
std::string name = system::getStem(path);
menu->addChild(createMenuItem(name, "", [=]() {
- APP->patch->loadPathDialog(path);
+ patchUtils::loadPathDialog(path, false);
}));
}
}, settings::recentPatchPaths.empty()));
menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
- APP->patch->saveDialog();
+ // NOTE: will do nothing if path is empty, intentionally
+ patchUtils::saveDialog(APP->patch->path);
+ }, APP->patch->path.empty()));
+
+ menu->addChild(createMenuItem("Save as / Export...", RACK_MOD_CTRL_NAME "+Shift+S", []() {
+ patchUtils::saveAsDialog();
+ }));
+#else
+ menu->addChild(createMenuItem("Import patch...", RACK_MOD_CTRL_NAME "+O", []() {
+ patchUtils::loadDialog();
}));
- menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() {
- APP->patch->saveAsDialog();
+ menu->addChild(createMenuItem("Import selection...", "", [=]() {
+ patchUtils::loadSelectionDialog();
+ }, false, true));
+
+ menu->addChild(createMenuItem("Save and download compressed", RACK_MOD_CTRL_NAME "+Shift+S", []() {
+ patchUtils::saveAsDialog();
}));
- menu->addChild(createMenuItem("Save a copy", "", []() {
- APP->patch->saveAsDialog(false);
+ menu->addChild(createMenuItem("Save and download uncompressed", "", []() {
+ patchUtils::saveAsDialogUncompressed();
}));
+#endif
+#endif
menu->addChild(createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() {
- APP->patch->revertDialog();
- }, APP->patch->path == ""));
+ patchUtils::revertDialog();
+ }, APP->patch->path.empty()));
menu->addChild(createMenuItem("Overwrite template", "", []() {
- APP->patch->saveTemplateDialog();
+ patchUtils::saveTemplateDialog();
}));
+#if defined(HAVE_LIBLO) || ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
+#ifdef __MOD_DEVICES__
+#define REMOTE_NAME "MOD"
+#else
+#define REMOTE_NAME "Remote"
+#endif
menu->addChild(new ui::MenuSeparator);
- // Load selection
- menu->addChild(createMenuItem("Import selection", "", [=]() {
- APP->scene->rack->loadSelectionDialog();
- }, false, true));
+ remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote();
+
+ if (remoteDetails != nullptr && remoteDetails->connected) {
+ menu->addChild(createMenuItem("Deploy to " REMOTE_NAME, "F7", [remoteDetails]() {
+ remoteUtils::sendFullPatchToRemote(remoteDetails);
+ }));
+ menu->addChild(createCheckMenuItem("Auto deploy to " REMOTE_NAME, "",
+ [remoteDetails]() {return remoteDetails->autoDeploy;},
+ [remoteDetails]() {
+ remoteDetails->autoDeploy = !remoteDetails->autoDeploy;
+ Engine_setRemoteDetails(APP->engine, remoteDetails->autoDeploy ? remoteDetails : nullptr);
+ }
+ ));
+ } else {
+ menu->addChild(createMenuItem("Connect to " REMOTE_NAME, "", []() {
+ DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote());
+ }));
+ }
+#endif
+
+#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
+#ifndef DISTRHO_OS_WASM
menu->addChild(new ui::MenuSeparator);
- menu->addChild(createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() {
- APP->window->close();
+ // Load selection
+ menu->addChild(createMenuItem("Import selection...", "", [=]() {
+ patchUtils::loadSelectionDialog();
+ }, false, true));
+
+ menu->addChild(createMenuItem("Export uncompressed json...", "", []() {
+ patchUtils::saveAsDialogUncompressed();
}));
+#endif
+#endif
+
+ if (!demoPatches.empty())
+ {
+ menu->addChild(new ui::MenuSeparator);
+
+ menu->addChild(createSubmenuItem("Open Demo / Example project", "", [=](ui::Menu* const menu) {
+ for (std::string path : demoPatches) {
+ std::string label = system::getStem(path);
+
+ for (size_t i=0, len=label.size(); i<len; ++i) {
+ if (label[i] == '_')
+ label[i] = ' ';
+ }
+
+ menu->addChild(createMenuItem(label, "", [path]() {
+ patchUtils::loadPathDialog(path, true);
+ }));
+ }
+
+ menu->addChild(new ui::MenuSeparator);
+
+ menu->addChild(createMenuItem("Open PatchStorage.com for more patches", "", []() {
+ patchUtils::openBrowser("https://patchstorage.com/platform/cardinal/");
+ }));
+ }));
+ }
+
+#ifndef DISTRHO_OS_WASM
+ if (isStandalone) {
+ menu->addChild(new ui::MenuSeparator);
+
+ menu->addChild(createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() {
+ APP->window->close();
+ }));
+ }
+#endif
}
};
@@ -166,7 +311,7 @@
menu->addChild(new ui::MenuSeparator);
- APP->scene->rack->appendSelectionContextMenu(menu);
+ patchUtils::appendSelectionContextMenu(menu);
}
};
@@ -256,7 +401,7 @@
return settings::cableTension;
}
float getDefaultValue() override {
- return 0.5;
+ return 0.75;
}
float getDisplayValue() override {
return getValue() * 100;
@@ -393,49 +538,36 @@
};
+static void setAllFramebufferWidgetsDirty(widget::Widget* const widget)
+{
+ for (widget::Widget* child : widget->children)
+ {
+ if (widget::FramebufferWidget* const fbw = dynamic_cast<widget::FramebufferWidget*>(child))
+ {
+ fbw->setDirty();
+ break;
+ }
+ setAllFramebufferWidgetsDirty(child);
+ }
+}
+
+
struct ViewButton : MenuButton {
void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu();
menu->cornerFlags = BND_CORNER_TOP;
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
- menu->addChild(createMenuLabel("Window"));
-
- bool fullscreen = APP->window->isFullScreen();
- std::string fullscreenText = "F11";
- if (fullscreen)
- fullscreenText += " " CHECKMARK_STRING;
- menu->addChild(createMenuItem("Fullscreen", fullscreenText, [=]() {
- APP->window->setFullScreen(!fullscreen);
- }));
-
- menu->addChild(createSubmenuItem("Frame rate", string::f("%.0f Hz", settings::frameRateLimit), [=](ui::Menu* menu) {
- for (int i = 1; i <= 6; i++) {
- double frameRate = APP->window->getMonitorRefreshRate() / i;
- menu->addChild(createCheckMenuItem(string::f("%.0f Hz", frameRate), "",
- [=]() {return settings::frameRateLimit == frameRate;},
- [=]() {settings::frameRateLimit = frameRate;}
- ));
- }
- }));
-
- menu->addChild(new ui::MenuSeparator);
menu->addChild(createMenuLabel("Appearance"));
- static const std::vector<std::string> uiThemes = {"dark", "light", "hcdark"};
- static const std::vector<std::string> uiThemeLabels = {"Dark", "Light", "High contrast dark"};
- menu->addChild(createIndexSubmenuItem("Theme", uiThemeLabels,
- [=]() -> size_t {
- auto it = std::find(uiThemes.begin(), uiThemes.end(), settings::uiTheme);
- if (it == uiThemes.end())
- return -1;
- return it - uiThemes.begin();
- },
- [=](size_t i) {
- settings::uiTheme = uiThemes[i];
- ui::refreshTheme();
- }
- ));
+ std::string darkModeText;
+ if (settings::darkMode)
+ darkModeText = CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Dark Mode", darkModeText, []() {
+ switchDarkMode(!settings::darkMode);
+ plugin::updateStaticPluginsDarkMode();
+ setAllFramebufferWidgetsDirty(APP->scene);
+ }));
menu->addChild(createBoolPtrMenuItem("Show tooltips", "", &settings::tooltips));
@@ -460,9 +592,18 @@
menu->addChild(haloBrightnessSlider);
menu->addChild(new ui::MenuSeparator);
+ menu->addChild(createMenuLabel("Module dragging"));
+
+ menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules));
+
+ menu->addChild(createBoolPtrMenuItem("Auto-squeeze modules when dragging", "", &settings::squeezeModules));
+
+ menu->addChild(new ui::MenuSeparator);
menu->addChild(createMenuLabel("Parameters"));
+#ifdef DISTRHO_OS_WASM
menu->addChild(createBoolPtrMenuItem("Lock cursor while dragging", "", &settings::allowCursorLock));
+#endif
static const std::vector<std::string> knobModeLabels = {
"Linear",
@@ -487,11 +628,34 @@
menu->addChild(knobScrollSensitivitySlider);
menu->addChild(new ui::MenuSeparator);
- menu->addChild(createMenuLabel("Module"));
+ menu->addChild(createMenuLabel("Window"));
- menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules));
+#ifdef DISTRHO_OS_WASM
+ const bool fullscreen = APP->window->isFullScreen();
+ std::string rightText = "F11";
+ if (fullscreen)
+ rightText += " " CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Fullscreen", rightText, [=]() {
+ APP->window->setFullScreen(!fullscreen);
+ }));
+#endif
+
+ menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom));
- menu->addChild(createBoolPtrMenuItem("Auto-squeeze algorithm (experimental)", "", &settings::squeezeModules));
+ static const std::vector<std::string> rateLimitLabels = {
+ "None",
+ "2x",
+ "4x",
+ };
+ static const std::vector<int> rateLimits = {0, 1, 2};
+ menu->addChild(createSubmenuItem("Update rate limit", rateLimitLabels[settings::rateLimit], [=](ui::Menu* menu) {
+ for (int rateLimit : rateLimits) {
+ menu->addChild(createCheckMenuItem(rateLimitLabels[rateLimit], "",
+ [=]() {return settings::rateLimit == rateLimit;},
+ [=]() {settings::rateLimit = rateLimit;}
+ ));
+ }
+ }));
}
};
@@ -501,47 +665,6 @@
////////////////////
-struct SampleRateItem : ui::MenuItem {
- ui::Menu* createChildMenu() override {
- ui::Menu* menu = new ui::Menu;
-
- // Auto sample rate
- std::string rightText;
- if (settings::sampleRate == 0) {
- float sampleRate = APP->engine->getSampleRate();
- rightText += string::f("(%g kHz) ", sampleRate / 1000.f);
- }
- menu->addChild(createCheckMenuItem("Auto", rightText,
- [=]() {return settings::sampleRate == 0;},
- [=]() {settings::sampleRate = 0;}
- ));
-
- // Power-of-2 oversample times 44.1kHz or 48kHz
- for (int i = -2; i <= 4; i++) {
- for (int j = 0; j < 2; j++) {
- float oversample = std::pow(2.f, i);
- float sampleRate = (j == 0) ? 44100.f : 48000.f;
- sampleRate *= oversample;
-
- std::string text = string::f("%g kHz", sampleRate / 1000.f);
- std::string rightText;
- if (oversample > 1.f) {
- rightText += string::f("(%.0fx)", oversample);
- }
- else if (oversample < 1.f) {
- rightText += string::f("(1/%.0fx)", 1.f / oversample);
- }
- menu->addChild(createCheckMenuItem(text, rightText,
- [=]() {return settings::sampleRate == sampleRate;},
- [=]() {settings::sampleRate = sampleRate;}
- ));
- }
- }
- return menu;
- }
-};
-
-
struct EngineButton : MenuButton {
void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu();
@@ -555,268 +678,46 @@
settings::cpuMeter ^= true;
}));
- menu->addChild(createMenuItem<SampleRateItem>("Sample rate", RIGHT_ARROW));
-
- menu->addChild(createSubmenuItem("Threads", string::f("%d", settings::threadCount), [=](ui::Menu* menu) {
- // BUG This assumes SMT is enabled.
- int cores = system::getLogicalCoreCount() / 2;
-
- for (int i = 1; i <= 2 * cores; i++) {
+ if (isUsingNativeAudio()) {
+ if (supportsAudioInput()) {
+ const bool enabled = isAudioInputEnabled();
std::string rightText;
- if (i == cores)
- rightText += "(most modules)";
- else if (i == 1)
- rightText += "(lowest CPU usage)";
- menu->addChild(createCheckMenuItem(string::f("%d", i), rightText,
- [=]() {return settings::threadCount == i;},
- [=]() {settings::threadCount = i;}
- ));
- }
- }));
- }
-};
-
-
-////////////////////
-// Plugins
-////////////////////
-
-
-struct AccountPasswordField : ui::PasswordField {
- ui::MenuItem* logInItem;
- void onAction(const ActionEvent& e) override {
- logInItem->doAction();
- }
-};
-
-
-struct LogInItem : ui::MenuItem {
- ui::TextField* emailField;
- ui::TextField* passwordField;
-
- void onAction(const ActionEvent& e) override {
- std::string email = emailField->text;
- std::string password = passwordField->text;
- std::thread t([=] {
- library::logIn(email, password);
- library::checkUpdates();
- });
- t.detach();
- e.unconsume();
- }
-
- void step() override {
- text = "Log in";
- rightText = library::loginStatus;
- MenuItem::step();
- }
-};
-
-
-struct SyncUpdatesItem : ui::MenuItem {
- void step() override {
- if (library::updateStatus != "") {
- text = library::updateStatus;
- }
- else if (library::isSyncing) {
- text = "Updating...";
- }
- else if (!library::hasUpdates()) {
- text = "Up-to-date";
- }
- else {
- text = "Update all";
- }
-
- disabled = library::isSyncing || !library::hasUpdates();
- MenuItem::step();
- }
-
- void onAction(const ActionEvent& e) override {
- std::thread t([=] {
- library::syncUpdates();
- });
- t.detach();
- e.unconsume();
- }
-};
-
-
-struct SyncUpdateItem : ui::MenuItem {
- std::string slug;
-
- void setUpdate(const std::string& slug) {
- this->slug = slug;
-
- auto it = library::updateInfos.find(slug);
- if (it == library::updateInfos.end())
- return;
- library::UpdateInfo update = it->second;
-
- text = update.name;
- }
-
- ui::Menu* createChildMenu() override {
- auto it = library::updateInfos.find(slug);
- if (it == library::updateInfos.end())
- return NULL;
- library::UpdateInfo update = it->second;
-
- if (update.changelogUrl == "")
- return NULL;
-
- ui::Menu* menu = new ui::Menu;
-
- std::string changelogUrl = update.changelogUrl;
- menu->addChild(createMenuItem("Changelog", "", [=]() {
- system::openBrowser(changelogUrl);
- }));
-
- return menu;
- }
-
- void step() override {
- disabled = library::isSyncing;
-
- auto it = library::updateInfos.find(slug);
- if (it != library::updateInfos.end()) {
- library::UpdateInfo update = it->second;
-
- if (update.downloaded) {
- rightText = CHECKMARK_STRING;
- disabled = true;
- }
- else if (slug == library::updateSlug) {
- rightText = string::f("%.0f%%", library::updateProgress * 100.f);
- }
- else {
- rightText = "";
- plugin::Plugin* p = plugin::getPlugin(slug);
- if (p) {
- rightText += p->version + " → ";
- }
- rightText += update.version;
+ if (enabled)
+ rightText = CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Enable Audio Input", rightText, [enabled]() {
+ if (!enabled)
+ requestAudioInput();
+ }));
}
- }
-
- MenuItem::step();
- }
- void onAction(const ActionEvent& e) override {
- std::thread t([=] {
- library::syncUpdate(slug);
- });
- t.detach();
- e.unconsume();
- }
-};
-
-
-struct LibraryMenu : ui::Menu {
- LibraryMenu() {
- refresh();
- }
-
- void step() override {
- // Refresh menu when appropriate
- if (library::refreshRequested) {
- library::refreshRequested = false;
- refresh();
- }
- Menu::step();
- }
-
- void refresh() {
- setChildMenu(NULL);
- clearChildren();
-
- if (settings::devMode) {
- addChild(createMenuLabel("Disabled in development mode"));
- }
- else if (!library::isLoggedIn()) {
- addChild(createMenuItem("Register VCV account", "", [=]() {
- system::openBrowser("https://vcvrack.com/login");
- }));
-
- ui::TextField* emailField = new ui::TextField;
- emailField->placeholder = "Email";
- emailField->box.size.x = 240.0;
- addChild(emailField);
-
- AccountPasswordField* passwordField = new AccountPasswordField;
- passwordField->placeholder = "Password";
- passwordField->box.size.x = 240.0;
- passwordField->nextField = emailField;
- emailField->nextField = passwordField;
- addChild(passwordField);
-
- LogInItem* logInItem = new LogInItem;
- logInItem->emailField = emailField;
- logInItem->passwordField = passwordField;
- passwordField->logInItem = logInItem;
- addChild(logInItem);
- }
- else {
- addChild(createMenuItem("Log out", "", [=]() {
- library::logOut();
- }));
-
- addChild(createMenuItem("Browse VCV Library", "", [=]() {
- system::openBrowser("https://library.vcvrack.com/");
- }));
-
- SyncUpdatesItem* syncItem = new SyncUpdatesItem;
- syncItem->text = "Update all";
- addChild(syncItem);
-
- if (!library::updateInfos.empty()) {
- addChild(new ui::MenuSeparator);
- addChild(createMenuLabel("Updates"));
-
- for (auto& pair : library::updateInfos) {
- SyncUpdateItem* updateItem = new SyncUpdateItem;
- updateItem->setUpdate(pair.first);
- addChild(updateItem);
- }
+ if (supportsMIDI()) {
+ std::string rightText;
+ if (isMIDIEnabled())
+ rightText = CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Enable/Reconnect MIDI", rightText, []() {
+ requestMIDI();
+ }));
}
- }
- }
-};
-
-
-struct LibraryButton : MenuButton {
- NotificationIcon* notification;
-
- LibraryButton() {
- notification = new NotificationIcon;
- addChild(notification);
- }
-
- void onAction(const ActionEvent& e) override {
- ui::Menu* menu = createMenu<LibraryMenu>();
- menu->cornerFlags = BND_CORNER_TOP;
- menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
- // Check for updates when menu is opened
- std::thread t([&]() {
- system::setThreadName("Library");
- library::checkUpdates();
- });
- t.detach();
- }
- void step() override {
- notification->box.pos = math::Vec(0, 0);
- notification->visible = library::hasUpdates();
-
- // Popup when updates finish downloading
- if (library::restartRequested) {
- library::restartRequested = false;
- if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been downloaded. Close and re-launch Rack to load new updates.")) {
- APP->window->close();
+ if (supportsBufferSizeChanges()) {
+ static const std::vector<uint32_t> bufferSizes = {
+ #ifdef DISTRHO_OS_WASM
+ 256, 512, 1024, 2048, 4096, 8192, 16384
+ #else
+ 128, 256, 512, 1024, 2048, 4096, 8192
+ #endif
+ };
+ const uint32_t currentBufferSize = getBufferSize();
+ menu->addChild(createSubmenuItem("Buffer Size", std::to_string(currentBufferSize), [=](ui::Menu* menu) {
+ for (uint32_t bufferSize : bufferSizes) {
+ menu->addChild(createCheckMenuItem(std::to_string(bufferSize), "",
+ [=]() {return currentBufferSize == bufferSize;},
+ [=]() {requestBufferSizeChange(bufferSize);}
+ ));
+ }
+ }));
}
}
-
- MenuButton::step();
}
};
@@ -827,32 +728,17 @@
struct HelpButton : MenuButton {
- NotificationIcon* notification;
-
- HelpButton() {
- notification = new NotificationIcon;
- addChild(notification);
- }
-
void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu();
menu->cornerFlags = BND_CORNER_TOP;
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
- menu->addChild(createMenuItem("Tips", "", [=]() {
- APP->scene->addChild(tipWindowCreate());
+ menu->addChild(createMenuItem("Rack User manual", "F1", [=]() {
+ patchUtils::openBrowser("https://vcvrack.com/manual");
}));
- menu->addChild(createMenuItem("User manual", "F1", [=]() {
- system::openBrowser("https://vcvrack.com/manual");
- }));
-
- menu->addChild(createMenuItem("Support", "", [=]() {
- system::openBrowser("https://vcvrack.com/support");
- }));
-
- menu->addChild(createMenuItem("VCVRack.com", "", [=]() {
- system::openBrowser("https://vcvrack.com/");
+ menu->addChild(createMenuItem("Cardinal project page", "", [=]() {
+ patchUtils::openBrowser("https://github.com/DISTRHO/Cardinal/");
}));
menu->addChild(new ui::MenuSeparator);
@@ -861,29 +747,9 @@
system::openDirectory(asset::user(""));
}));
- menu->addChild(createMenuItem("Changelog", "", [=]() {
- system::openBrowser("https://github.com/VCVRack/Rack/blob/v2/CHANGELOG.md");
- }));
-
- if (library::isAppUpdateAvailable()) {
- menu->addChild(createMenuItem("Update " + APP_NAME, APP_VERSION + " → " + library::appVersion, [=]() {
- system::openBrowser(library::appDownloadUrl);
- }));
- }
- else if (!settings::autoCheckUpdates && !settings::devMode) {
- menu->addChild(createMenuItem("Check for " + APP_NAME + " update", "", [=]() {
- std::thread t([&]() {
- library::checkAppUpdate();
- });
- t.detach();
- }, false, true));
- }
- }
+ menu->addChild(new ui::MenuSeparator);
- void step() override {
- notification->box.pos = math::Vec(0, 0);
- notification->visible = library::isAppUpdateAvailable();
- MenuButton::step();
+ menu->addChild(createMenuLabel("Rack " + APP_VERSION + " Compatible"));
}
};
@@ -926,15 +792,19 @@
text = "";
- if (box.size.x >= 460) {
+ if (box.size.x >= 400) {
double fps = std::isfinite(frameDurationAvg) ? 1.0 / frameDurationAvg : 0.0;
+#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
double meterAverage = APP->engine->getMeterAverage();
double meterMax = APP->engine->getMeterMax();
- text += string::f("%.1f fps %.1f%% avg %.1f%% max", fps, meterAverage * 100, meterMax * 100);
+ text = string::f("%.1f fps %.1f%% avg %.1f%% max", fps, meterAverage * 100, meterMax * 100);
+#else
+ text = string::f("%.1f fps", fps);
+#endif
text += " ";
}
- text += APP_NAME + " " + APP_EDITION_NAME + " " + APP_VERSION + " " + APP_OS_NAME + " " + APP_CPU_NAME;
+ text += "Cardinal " + APP_EDITION + " " + CARDINAL_VERSION;
Label::step();
}
@@ -944,7 +814,9 @@
struct MenuBar : widget::OpaqueWidget {
InfoLabel* infoLabel;
- MenuBar() {
+ MenuBar(const bool isStandalone)
+ : widget::OpaqueWidget()
+ {
const float margin = 5;
box.size.y = BND_WIDGET_HEIGHT + 2 * margin;
@@ -953,7 +825,7 @@
layout->spacing = math::Vec(0, 0);
addChild(layout);
- FileButton* fileButton = new FileButton;
+ FileButton* fileButton = new FileButton(isStandalone);
fileButton->text = "File";
layout->addChild(fileButton);
@@ -965,13 +837,11 @@
viewButton->text = "View";
layout->addChild(viewButton);
+#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
EngineButton* engineButton = new EngineButton;
engineButton->text = "Engine";
layout->addChild(engineButton);
-
- LibraryButton* libraryButton = new LibraryButton;
- libraryButton->text = "Library";
- layout->addChild(libraryButton);
+#endif
HelpButton* helpButton = new HelpButton;
helpButton->text = "Help";
@@ -1003,7 +873,7 @@
widget::Widget* createMenuBar() {
- menuBar::MenuBar* menuBar = new menuBar::MenuBar;
+ menuBar::MenuBar* menuBar = new menuBar::MenuBar(isStandalone());
return menuBar;
}