Signed-off-by: falkTX <falktx@falktx.com>tags/22.05
| @@ -0,0 +1,31 @@ | |||
| /* | |||
| * DISTRHO Cardinal Plugin | |||
| * Copyright (C) 2021-2022 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. | |||
| */ | |||
| #pragma once | |||
| #define SCHEME_YELLOW SCHEME_YELLOW_OldVCV | |||
| #include_next "componentlibrary.hpp" | |||
| #undef SCHEME_YELLOW | |||
| namespace rack { | |||
| namespace componentlibrary { | |||
| // Yellow? What's that? | |||
| static const NVGcolor SCHEME_YELLOW = nvgRGBf(0.76f, 0.11f, 0.22f); | |||
| } | |||
| } | |||
| @@ -49,12 +49,14 @@ | |||
| #include "extra/Base64.hpp" | |||
| #include "extra/SharedResourcePointer.hpp" | |||
| static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment | |||
| #ifndef HEADLESS | |||
| # include "WindowParameters.hpp" | |||
| static const constexpr uint kCardinalStateCount = 4; // patch, screenshot, comment, windowSize | |||
| static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount + 2; // moduleInfos, windowSize | |||
| #else | |||
| # define kWindowParameterCount 0 | |||
| static const constexpr uint kCardinalStateCount = 3; // patch, screenshot, comment | |||
| static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount; | |||
| #endif | |||
| #if CARDINAL_VARIANT_FX | |||
| @@ -447,9 +449,14 @@ class CardinalPlugin : public CardinalBasePlugin | |||
| std::string fAutosavePath; | |||
| uint64_t fPreviousFrame; | |||
| String fStateComment; | |||
| String fStateScreenshot; | |||
| String fWindowSize; | |||
| struct { | |||
| String comment; | |||
| String screenshot; | |||
| #ifndef HEADLESS | |||
| String windowSize; | |||
| #endif | |||
| } fState; | |||
| // bypass handling | |||
| bool fWasBypassed; | |||
| @@ -481,6 +488,9 @@ public: | |||
| fWindowParameters[kWindowParameterWheelSensitivity] = 1.0f; | |||
| fWindowParameters[kWindowParameterLockModulePositions] = 0.0f; | |||
| fWindowParameters[kWindowParameterUpdateRateLimit] = 0.0f; | |||
| fWindowParameters[kWindowParameterBrowserSort] = 3.0f; | |||
| fWindowParameters[kWindowParameterBrowserZoom] = 50.0f; | |||
| fWindowParameters[kWindowParameterInvertZoom] = 0.0f; | |||
| #endif | |||
| // create unique temporary path for this instance | |||
| @@ -758,6 +768,63 @@ protected: | |||
| parameter.enumValues.values[2].label = "4x"; | |||
| parameter.enumValues.values[2].value = 2.0f; | |||
| break; | |||
| case kWindowParameterBrowserSort: | |||
| parameter.name = "Browser sort"; | |||
| parameter.symbol = "browserSort"; | |||
| parameter.hints = kParameterIsAutomatable|kParameterIsInteger; | |||
| parameter.ranges.def = 3.0f; | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 5.0f; | |||
| parameter.enumValues.count = 6; | |||
| parameter.enumValues.restrictedMode = true; | |||
| parameter.enumValues.values = new ParameterEnumerationValue[6]; | |||
| parameter.enumValues.values[0].label = "Updated"; | |||
| parameter.enumValues.values[0].value = 0.0f; | |||
| parameter.enumValues.values[1].label = "Last used"; | |||
| parameter.enumValues.values[1].value = 1.0f; | |||
| parameter.enumValues.values[2].label = "Most used"; | |||
| parameter.enumValues.values[2].value = 2.0f; | |||
| parameter.enumValues.values[3].label = "Brand"; | |||
| parameter.enumValues.values[3].value = 3.0f; | |||
| parameter.enumValues.values[4].label = "Name"; | |||
| parameter.enumValues.values[4].value = 4.0f; | |||
| parameter.enumValues.values[5].label = "Random"; | |||
| parameter.enumValues.values[5].value = 5.0f; | |||
| break; | |||
| case kWindowParameterBrowserZoom: | |||
| parameter.name = "Browser zoom"; | |||
| parameter.symbol = "browserZoom"; | |||
| parameter.hints = kParameterIsAutomatable; | |||
| parameter.unit = "%"; | |||
| parameter.ranges.def = 50.0f; | |||
| parameter.ranges.min = 25.0f; | |||
| parameter.ranges.max = 200.0f; | |||
| parameter.enumValues.count = 7; | |||
| parameter.enumValues.restrictedMode = true; | |||
| parameter.enumValues.values = new ParameterEnumerationValue[7]; | |||
| parameter.enumValues.values[0].label = "25"; | |||
| parameter.enumValues.values[0].value = 25.0f; | |||
| parameter.enumValues.values[1].label = "35"; | |||
| parameter.enumValues.values[1].value = 35.0f; | |||
| parameter.enumValues.values[2].label = "50"; | |||
| parameter.enumValues.values[2].value = 50.0f; | |||
| parameter.enumValues.values[3].label = "71"; | |||
| parameter.enumValues.values[3].value = 71.0f; | |||
| parameter.enumValues.values[4].label = "100"; | |||
| parameter.enumValues.values[4].value = 100.0f; | |||
| parameter.enumValues.values[5].label = "141"; | |||
| parameter.enumValues.values[5].value = 141.0f; | |||
| parameter.enumValues.values[6].label = "200"; | |||
| parameter.enumValues.values[6].value = 200.0f; | |||
| break; | |||
| case kWindowParameterInvertZoom: | |||
| parameter.name = "Invert zoom"; | |||
| parameter.symbol = "invertZoom"; | |||
| parameter.hints = kParameterIsAutomatable|kParameterIsInteger|kParameterIsBoolean; | |||
| parameter.ranges.def = 0.0f; | |||
| parameter.ranges.min = 0.0f; | |||
| parameter.ranges.max = 1.0f; | |||
| break; | |||
| } | |||
| #endif | |||
| } | |||
| @@ -782,6 +849,11 @@ protected: | |||
| state.label = "Comment"; | |||
| break; | |||
| case 3: | |||
| state.hints = kStateIsOnlyForUI; | |||
| state.key = "moduleInfos"; | |||
| state.label = "moduleInfos"; | |||
| break; | |||
| case 4: | |||
| state.hints = kStateIsOnlyForUI; | |||
| state.key = "windowSize"; | |||
| state.label = "Window size"; | |||
| @@ -844,14 +916,57 @@ protected: | |||
| String getState(const char* const key) const override | |||
| { | |||
| #ifndef HEADLESS | |||
| if (std::strcmp(key, "moduleInfos") == 0) | |||
| { | |||
| json_t* const rootJ = json_object(); | |||
| DISTRHO_SAFE_ASSERT_RETURN(rootJ != nullptr, String()); | |||
| for (const auto& pluginPair : rack::settings::moduleInfos) | |||
| { | |||
| json_t* const pluginJ = json_object(); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(pluginJ != nullptr); | |||
| for (const auto& modulePair : pluginPair.second) | |||
| { | |||
| json_t* const moduleJ = json_object(); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(moduleJ != nullptr); | |||
| const rack::settings::ModuleInfo& m(modulePair.second); | |||
| // To make setting.json smaller, only set properties if not default values. | |||
| if (m.favorite) | |||
| json_object_set_new(moduleJ, "favorite", json_boolean(m.favorite)); | |||
| if (m.added > 0) | |||
| json_object_set_new(moduleJ, "added", json_integer(m.added)); | |||
| if (std::isfinite(m.lastAdded)) | |||
| json_object_set_new(moduleJ, "lastAdded", json_real(m.lastAdded)); | |||
| if (json_object_size(moduleJ)) | |||
| json_object_set_new(pluginJ, modulePair.first.c_str(), moduleJ); | |||
| else | |||
| json_decref(moduleJ); | |||
| } | |||
| if (json_object_size(pluginJ)) | |||
| json_object_set_new(rootJ, pluginPair.first.c_str(), pluginJ); | |||
| else | |||
| json_decref(pluginJ); | |||
| } | |||
| const String info(json_dumps(rootJ, JSON_COMPACT), false); | |||
| json_decref(rootJ); | |||
| return info; | |||
| } | |||
| if (std::strcmp(key, "windowSize") == 0) | |||
| return fWindowSize; | |||
| return fState.windowSize; | |||
| #endif | |||
| if (std::strcmp(key, "comment") == 0) | |||
| return fStateComment; | |||
| return fState.comment; | |||
| if (std::strcmp(key, "screenshot") == 0) | |||
| return fStateScreenshot; | |||
| return fState.screenshot; | |||
| if (std::strcmp(key, "patch") != 0) | |||
| return String(); | |||
| @@ -879,22 +994,56 @@ protected: | |||
| void setState(const char* const key, const char* const value) override | |||
| { | |||
| #ifndef HEADLESS | |||
| if (std::strcmp(key, "moduleInfos") == 0) | |||
| { | |||
| json_error_t error; | |||
| json_t* const rootJ = json_loads(value, 0, &error); | |||
| DISTRHO_SAFE_ASSERT_RETURN(rootJ != nullptr,); | |||
| const char* pluginSlug; | |||
| json_t* pluginJ; | |||
| json_object_foreach(rootJ, pluginSlug, pluginJ) | |||
| { | |||
| const char* moduleSlug; | |||
| json_t* moduleJ; | |||
| json_object_foreach(pluginJ, moduleSlug, moduleJ) | |||
| { | |||
| rack::settings::ModuleInfo m; | |||
| if (json_t* const favoriteJ = json_object_get(moduleJ, "favorite")) | |||
| m.favorite = json_boolean_value(favoriteJ); | |||
| if (json_t* const addedJ = json_object_get(moduleJ, "added")) | |||
| m.added = json_integer_value(addedJ); | |||
| if (json_t* const lastAddedJ = json_object_get(moduleJ, "lastAdded")) | |||
| m.lastAdded = json_number_value(lastAddedJ); | |||
| rack::settings::moduleInfos[pluginSlug][moduleSlug] = m; | |||
| } | |||
| } | |||
| json_decref(rootJ); | |||
| return; | |||
| } | |||
| if (std::strcmp(key, "windowSize") == 0) | |||
| { | |||
| fWindowSize = value; | |||
| fState.windowSize = value; | |||
| return; | |||
| } | |||
| #endif | |||
| if (std::strcmp(key, "comment") == 0) | |||
| { | |||
| fStateComment = value; | |||
| fState.comment = value; | |||
| return; | |||
| } | |||
| if (std::strcmp(key, "screenshot") == 0) | |||
| { | |||
| fStateScreenshot = value; | |||
| fState.screenshot = value; | |||
| #if defined(HAVE_LIBLO) && !defined(HEADLESS) | |||
| patchUtils::sendScreenshotToRemote(value); | |||
| #endif | |||
| @@ -304,9 +304,7 @@ public: | |||
| // hide "Browse VCV Library" button | |||
| rack::widget::Widget* const browser = context->scene->browser->children.back(); | |||
| rack::widget::Widget* const headerLayout = browser->children.front(); | |||
| rack::widget::Widget* const favoriteButton = *std::next(headerLayout->children.begin(), 3); | |||
| rack::widget::Widget* const libraryButton = headerLayout->children.back(); | |||
| favoriteButton->hide(); | |||
| libraryButton->hide(); | |||
| // Report to user if something is wrong with the installation | |||
| @@ -453,6 +451,16 @@ public: | |||
| windowParameters.rateLimit = static_cast<int>(value + 0.5f); | |||
| rateLimitStep = 0; | |||
| break; | |||
| case kWindowParameterBrowserSort: | |||
| windowParameters.browserSort = static_cast<int>(value + 0.5f); | |||
| break; | |||
| case kWindowParameterBrowserZoom: | |||
| windowParameters.browserZoom = value; | |||
| value = std::pow(2.f, value) * 100.0f; | |||
| break; | |||
| case kWindowParameterInvertZoom: | |||
| windowParameters.invertZoom = value > 0.5f; | |||
| break; | |||
| default: | |||
| return; | |||
| } | |||
| @@ -518,6 +526,37 @@ protected: | |||
| windowParameters.rateLimit = static_cast<int>(value + 0.5f); | |||
| rateLimitStep = 0; | |||
| break; | |||
| case kWindowParameterBrowserSort: | |||
| windowParameters.browserSort = static_cast<int>(value + 0.5f); | |||
| break; | |||
| case kWindowParameterBrowserZoom: | |||
| // round up to nearest valid value | |||
| { | |||
| float rvalue = value - 1.0f; | |||
| if (rvalue <= 25.0f) | |||
| rvalue = -2.0f; | |||
| else if (rvalue <= 35.0f) | |||
| rvalue = -1.5f; | |||
| else if (rvalue <= 50.0f) | |||
| rvalue = -1.0f; | |||
| else if (rvalue <= 71.0f) | |||
| rvalue = -0.5f; | |||
| else if (rvalue <= 100.0f) | |||
| rvalue = 0.0f; | |||
| else if (rvalue <= 141.0f) | |||
| rvalue = 0.5f; | |||
| else if (rvalue <= 200.0f) | |||
| rvalue = 1.0f; | |||
| else | |||
| rvalue = 0.0f; | |||
| windowParameters.browserZoom = rvalue; | |||
| } | |||
| break; | |||
| case kWindowParameterInvertZoom: | |||
| windowParameters.invertZoom = value > 0.5f; | |||
| break; | |||
| default: | |||
| return; | |||
| } | |||
| @@ -525,7 +564,7 @@ protected: | |||
| WindowParametersSetValues(context->window, windowParameters); | |||
| } | |||
| void stateChanged(const char* key, const char* value) override | |||
| void stateChanged(const char* const key, const char* const value) override | |||
| { | |||
| if (std::strcmp(key, "windowSize") != 0) | |||
| return; | |||
| @@ -44,6 +44,9 @@ enum WindowParameterList { | |||
| kWindowParameterWheelSensitivity, | |||
| kWindowParameterLockModulePositions, | |||
| kWindowParameterUpdateRateLimit, | |||
| kWindowParameterBrowserSort, | |||
| kWindowParameterBrowserZoom, | |||
| kWindowParameterInvertZoom, | |||
| kWindowParameterCount, | |||
| }; | |||
| @@ -53,10 +56,13 @@ struct WindowParameters { | |||
| float rackBrightness = 1.0f; | |||
| float haloBrightness = 0.25f; | |||
| float knobScrollSensitivity = 0.001f; | |||
| float browserZoom = -1.0f; | |||
| int knobMode = 0; | |||
| int browserSort = 3; | |||
| bool tooltips = true; | |||
| bool knobScroll = false; | |||
| bool lockModules = false; | |||
| bool invertZoom = false; | |||
| // cardinal specific | |||
| int rateLimit = 0; | |||
| }; | |||
| @@ -479,6 +479,8 @@ struct ViewButton : MenuButton { | |||
| menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules)); | |||
| menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom)); | |||
| menu->addChild(new ui::MenuSeparator); | |||
| static const std::vector<std::string> rateLimitLabels = { | |||
| @@ -117,7 +117,7 @@ std::string Model::getManualUrl() { | |||
| } | |||
| void Model::appendContextMenu(ui::Menu* menu, bool) { | |||
| void Model::appendContextMenu(ui::Menu* menu, bool inBrowser) { | |||
| // plugin | |||
| menu->addChild(createMenuItem("Plugin: " + plugin->name, "", [=]() { | |||
| system::openBrowser(plugin->pluginUrl); | |||
| @@ -182,15 +182,28 @@ void Model::appendContextMenu(ui::Menu* menu, bool) { | |||
| system::openBrowser(plugin->changelogUrl); | |||
| })); | |||
| } | |||
| // Favorite | |||
| std::string favoriteRightText = inBrowser ? (RACK_MOD_CTRL_NAME "+click") : ""; | |||
| if (isFavorite()) | |||
| favoriteRightText += " " CHECKMARK_STRING; | |||
| menu->addChild(createMenuItem("Favorite", favoriteRightText, | |||
| [=]() { | |||
| setFavorite(!isFavorite()); | |||
| } | |||
| )); | |||
| } | |||
| bool Model::isFavorite() { | |||
| return false; | |||
| const settings::ModuleInfo* mi = settings::getModuleInfo(plugin->slug, slug); | |||
| return mi && mi->favorite; | |||
| } | |||
| void Model::setFavorite(bool) { | |||
| void Model::setFavorite(bool favorite) { | |||
| settings::ModuleInfo& mi = settings::moduleInfos[plugin->slug][slug]; | |||
| mi.favorite = favorite; | |||
| } | |||
| @@ -718,6 +718,13 @@ void WindowParametersSave(rack::window::Window* const window) | |||
| window->internal->callback->WindowParametersChanged(kWindowParameterWheelSensitivity, | |||
| rack::settings::knobScrollSensitivity); | |||
| } | |||
| if (d_isNotEqual(window->internal->params.browserZoom, rack::settings::browserZoom)) | |||
| { | |||
| window->internal->params.browserZoom = rack::settings::browserZoom; | |||
| if (window->internal->callback != nullptr) | |||
| window->internal->callback->WindowParametersChanged(kWindowParameterBrowserZoom, | |||
| rack::settings::browserZoom); | |||
| } | |||
| if (window->internal->params.knobMode != rack::settings::knobMode) | |||
| { | |||
| window->internal->params.knobMode = rack::settings::knobMode; | |||
| @@ -725,6 +732,13 @@ void WindowParametersSave(rack::window::Window* const window) | |||
| window->internal->callback->WindowParametersChanged(kWindowParameterKnobMode, | |||
| rack::settings::knobMode); | |||
| } | |||
| if (window->internal->params.browserSort != rack::settings::browserSort) | |||
| { | |||
| window->internal->params.browserSort = rack::settings::browserSort; | |||
| if (window->internal->callback != nullptr) | |||
| window->internal->callback->WindowParametersChanged(kWindowParameterBrowserSort, | |||
| rack::settings::browserSort); | |||
| } | |||
| if (window->internal->params.tooltips != rack::settings::tooltips) | |||
| { | |||
| window->internal->params.tooltips = rack::settings::tooltips; | |||
| @@ -746,6 +760,13 @@ void WindowParametersSave(rack::window::Window* const window) | |||
| window->internal->callback->WindowParametersChanged(kWindowParameterLockModulePositions, | |||
| rack::settings::lockModules); | |||
| } | |||
| if (window->internal->params.invertZoom != rack::settings::invertZoom) | |||
| { | |||
| window->internal->params.invertZoom = rack::settings::invertZoom; | |||
| if (window->internal->callback != nullptr) | |||
| window->internal->callback->WindowParametersChanged(kWindowParameterInvertZoom, | |||
| rack::settings::invertZoom); | |||
| } | |||
| if (window->internal->params.rateLimit != rack::settings::rateLimit) | |||
| { | |||
| window->internal->params.rateLimit = rack::settings::rateLimit; | |||
| @@ -762,10 +783,13 @@ void WindowParametersRestore(rack::window::Window* const window) | |||
| rack::settings::rackBrightness = window->internal->params.rackBrightness; | |||
| rack::settings::haloBrightness = window->internal->params.haloBrightness; | |||
| rack::settings::knobScrollSensitivity = window->internal->params.knobScrollSensitivity; | |||
| rack::settings::browserZoom = window->internal->params.browserZoom; | |||
| rack::settings::knobMode = static_cast<rack::settings::KnobMode>(window->internal->params.knobMode); | |||
| rack::settings::browserSort = static_cast<rack::settings::BrowserSort>(window->internal->params.browserSort); | |||
| rack::settings::tooltips = window->internal->params.tooltips; | |||
| rack::settings::knobScroll = window->internal->params.knobScroll; | |||
| rack::settings::lockModules = window->internal->params.lockModules; | |||
| rack::settings::invertZoom = window->internal->params.invertZoom; | |||
| rack::settings::rateLimit = window->internal->params.rateLimit; | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/app/MenuBar.cpp 2022-02-26 23:08:06.697192725 +0000 | |||
| +++ MenuBar.cpp 2022-02-26 23:19:38.779828613 +0000 | |||
| +++ MenuBar.cpp 2022-04-27 17:30:16.653341980 +0100 | |||
| @@ -1,8 +1,33 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -218,35 +218,20 @@ | |||
| static const std::vector<std::string> knobModeLabels = { | |||
| "Linear", | |||
| @@ -467,6 +478,25 @@ | |||
| @@ -467,56 +478,34 @@ | |||
| menu->addChild(knobScrollSensitivitySlider); | |||
| menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules)); | |||
| + | |||
| +#ifndef DISTRHO_OS_MAC | |||
| + menu->addChild(new ui::MenuSeparator); | |||
| + | |||
| + 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;} | |||
| + )); | |||
| + } | |||
| + })); | |||
| +#endif | |||
| } | |||
| }; | |||
| - } | |||
| -}; | |||
| - | |||
| @@ -476,47 +506,6 @@ | |||
| //////////////////// | |||
| -//////////////////// | |||
| -// Engine | |||
| -//////////////////// | |||
| + menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom)); | |||
| + menu->addChild(new ui::MenuSeparator); | |||
| -struct SampleRateItem : ui::MenuItem { | |||
| - ui::Menu* createChildMenu() override { | |||
| @@ -281,14 +266,31 @@ | |||
| - menu->addChild(createCheckMenuItem(text, rightText, | |||
| - [=]() {return settings::sampleRate == sampleRate;}, | |||
| - [=]() {settings::sampleRate = sampleRate;} | |||
| - )); | |||
| - } | |||
| + 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;} | |||
| )); | |||
| } | |||
| - } | |||
| - return menu; | |||
| - } | |||
| -}; | |||
| - | |||
| - | |||
| + })); | |||
| } | |||
| }; | |||
| +//////////////////// | |||
| +// Engine | |||
| +//////////////////// | |||
| + | |||
| + | |||
| struct EngineButton : MenuButton { | |||
| void onAction(const ActionEvent& e) override { | |||
| ui::Menu* menu = createMenu(); | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/plugin/Model.cpp 2021-10-17 13:57:23.257633662 +0100 | |||
| +++ Model.cpp 2022-01-23 17:13:22.080013846 +0000 | |||
| +++ Model.cpp 2022-04-27 17:55:57.362107553 +0100 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -61,15 +61,6 @@ | |||
| return plugin->getBrand() + " " + name; | |||
| } | |||
| @@ -95,7 +117,7 @@ | |||
| } | |||
| -void Model::appendContextMenu(ui::Menu* menu, bool inBrowser) { | |||
| +void Model::appendContextMenu(ui::Menu* menu, bool) { | |||
| // plugin | |||
| menu->addChild(createMenuItem("Plugin: " + plugin->name, "", [=]() { | |||
| system::openBrowser(plugin->pluginUrl); | |||
| @@ -132,18 +154,6 @@ | |||
| menu->addChild(new ui::MenuSeparator); | |||
| @@ -89,11 +80,10 @@ | |||
| // manual | |||
| std::string manualUrl = getManualUrl(); | |||
| if (manualUrl != "") { | |||
| @@ -172,35 +182,15 @@ | |||
| system::openBrowser(plugin->changelogUrl); | |||
| @@ -173,13 +183,6 @@ | |||
| })); | |||
| } | |||
| - | |||
| - // plugin folder | |||
| - if (plugin->path != "") { | |||
| - menu->addChild(createMenuItem("Open plugin folder", "", [=]() { | |||
| @@ -101,29 +91,6 @@ | |||
| - })); | |||
| - } | |||
| - | |||
| - // Favorite | |||
| - std::string favoriteRightText = inBrowser ? (RACK_MOD_CTRL_NAME "+click") : ""; | |||
| - if (isFavorite()) | |||
| - favoriteRightText += " " CHECKMARK_STRING; | |||
| - menu->addChild(createMenuItem("Favorite", favoriteRightText, | |||
| - [=]() { | |||
| - setFavorite(!isFavorite()); | |||
| - } | |||
| - )); | |||
| } | |||
| bool Model::isFavorite() { | |||
| - const settings::ModuleInfo* mi = settings::getModuleInfo(plugin->slug, slug); | |||
| - return mi && mi->favorite; | |||
| + return false; | |||
| } | |||
| -void Model::setFavorite(bool favorite) { | |||
| - settings::ModuleInfo& mi = settings::moduleInfos[plugin->slug][slug]; | |||
| - mi.favorite = favorite; | |||
| +void Model::setFavorite(bool) { | |||
| } | |||
| // Favorite | |||
| std::string favoriteRightText = inBrowser ? (RACK_MOD_CTRL_NAME "+click") : ""; | |||
| if (isFavorite()) | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/app/Scene.cpp 2022-02-26 23:08:06.701192797 +0000 | |||
| +++ Scene.cpp 2022-02-17 23:13:46.013018500 +0000 | |||
| +++ Scene.cpp 2022-04-02 03:13:14.856813800 +0100 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -39,7 +39,7 @@ | |||
| #include <system.hpp> | |||
| #include <network.hpp> | |||
| #include <history.hpp> | |||
| @@ -14,6 +42,18 @@ | |||
| @@ -14,6 +42,22 @@ | |||
| #include <patch.hpp> | |||
| #include <asset.hpp> | |||
| @@ -47,6 +47,10 @@ | |||
| +# undef DEBUG | |||
| +#endif | |||
| + | |||
| +#ifdef STATIC_BUILD | |||
| +# undef HAVE_LIBLO | |||
| +#endif | |||
| + | |||
| +#ifdef HAVE_LIBLO | |||
| +# include <lo/lo.h> | |||
| +#endif | |||
| @@ -58,7 +62,7 @@ | |||
| namespace rack { | |||
| namespace app { | |||
| @@ -23,21 +63,60 @@ | |||
| @@ -23,32 +67,94 @@ | |||
| math::Vec size; | |||
| void draw(const DrawArgs& args) override { | |||
| @@ -126,12 +130,14 @@ | |||
| APP->window->setSize(size.round()); | |||
| } | |||
| }; | |||
| @@ -46,9 +125,32 @@ | |||
| struct Scene::Internal { | |||
| ResizeHandle* resizeHandle; | |||
| - double lastAutosaveTime = 0.0; | |||
| struct Scene::Internal { | |||
| - ResizeHandle* resizeHandle; | |||
| - | |||
| - double lastAutosaveTime = 0.0; | |||
| + ResizeHandle* resizeHandle = nullptr; | |||
| bool heldArrowKeys[4] = {}; | |||
| + | |||
| +#ifdef HAVE_LIBLO | |||
| @@ -161,14 +167,16 @@ | |||
| }; | |||
| @@ -67,13 +169,8 @@ | |||
| @@ -67,13 +173,11 @@ | |||
| browser->hide(); | |||
| addChild(browser); | |||
| - if (settings::showTipsOnLaunch) { | |||
| - addChild(tipWindowCreate()); | |||
| - } | |||
| - | |||
| + if (isStandalone()) | |||
| + return; | |||
| internal->resizeHandle = new ResizeHandle; | |||
| - internal->resizeHandle->box.size = math::Vec(15, 15); | |||
| - internal->resizeHandle->hide(); | |||
| @@ -176,7 +184,15 @@ | |||
| addChild(internal->resizeHandle); | |||
| } | |||
| @@ -105,16 +202,6 @@ | |||
| @@ -99,22 +203,13 @@ | |||
| rackScroll->box.pos.y = menuBar->box.size.y; | |||
| } | |||
| - internal->resizeHandle->box.pos = box.size.minus(internal->resizeHandle->box.size); | |||
| + if (internal->resizeHandle != nullptr) | |||
| + internal->resizeHandle->box.pos = box.size.minus(internal->resizeHandle->box.size); | |||
| // Resize owned descendants | |||
| menuBar->box.size.x = box.size.x; | |||
| rackScroll->box.size = box.size.minus(rackScroll->box.pos); | |||
| @@ -193,7 +209,7 @@ | |||
| // Scroll RackScrollWidget with arrow keys | |||
| math::Vec arrowDelta; | |||
| if (internal->heldArrowKeys[0]) { | |||
| @@ -143,6 +230,23 @@ | |||
| @@ -143,6 +238,23 @@ | |||
| rackScroll->offset += arrowDelta * arrowSpeed; | |||
| } | |||
| @@ -217,7 +233,7 @@ | |||
| Widget::step(); | |||
| } | |||
| @@ -172,7 +276,7 @@ | |||
| @@ -172,7 +284,7 @@ | |||
| if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | |||
| // DEBUG("key '%d '%c' scancode %d '%c' keyName '%s'", e.key, e.key, e.scancode, e.scancode, e.keyName.c_str()); | |||
| if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
| @@ -226,7 +242,7 @@ | |||
| e.consume(this); | |||
| } | |||
| if (e.keyName == "q" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
| @@ -180,19 +284,20 @@ | |||
| @@ -180,19 +292,20 @@ | |||
| e.consume(this); | |||
| } | |||
| if (e.keyName == "o" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
| @@ -251,7 +267,7 @@ | |||
| e.consume(this); | |||
| } | |||
| if (e.keyName == "z" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
| @@ -220,10 +325,14 @@ | |||
| @@ -220,10 +333,14 @@ | |||
| APP->scene->rackScroll->setZoom(std::pow(2.f, zoom)); | |||
| e.consume(this); | |||
| } | |||
| @@ -267,7 +283,7 @@ | |||
| if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) { | |||
| system::openBrowser("https://vcvrack.com/manual/"); | |||
| e.consume(this); | |||
| @@ -232,10 +341,13 @@ | |||
| @@ -232,10 +349,13 @@ | |||
| settings::cpuMeter ^= true; | |||
| e.consume(this); | |||
| } | |||
| @@ -285,7 +301,7 @@ | |||
| e.consume(this); | |||
| } | |||
| @@ -326,13 +438,6 @@ | |||
| @@ -326,13 +446,6 @@ | |||
| // Key commands that can be overridden by children | |||
| if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | |||
| @@ -299,7 +315,7 @@ | |||
| if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
| rack->pasteClipboardAction(); | |||
| e.consume(this); | |||
| @@ -351,7 +456,7 @@ | |||
| @@ -351,7 +464,7 @@ | |||
| std::string extension = system::getExtension(path); | |||
| if (extension == ".vcv") { | |||
| @@ -308,7 +324,7 @@ | |||
| e.consume(this); | |||
| return; | |||
| } | |||
| @@ -368,3 +473,94 @@ | |||
| @@ -368,3 +481,94 @@ | |||
| } // namespace app | |||
| } // namespace rack | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/window/Window.cpp 2022-02-09 15:35:19.238863170 +0000 | |||
| +++ Window.cpp 2022-02-13 21:19:37.799091196 +0000 | |||
| +++ Window.cpp 2022-04-27 16:53:59.743671091 +0100 | |||
| @@ -1,33 +1,83 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -162,8 +162,12 @@ | |||
| bool fbDirtyOnSubpixelChange = true; | |||
| int fbCount = 0; | |||
| -}; | |||
| - | |||
| + | |||
| + Internal() | |||
| + : hiddenApp(false), | |||
| + hiddenWindow(hiddenApp) { hiddenApp.idle(); } | |||
| }; | |||
| -static void windowPosCallback(GLFWwindow* win, int x, int y) { | |||
| - if (glfwGetWindowAttrib(win, GLFW_MAXIMIZED)) | |||
| @@ -175,11 +179,14 @@ | |||
| - settings::windowPos = math::Vec(x, y); | |||
| - // DEBUG("windowPosCallback %d %d", x, y); | |||
| -} | |||
| + Internal() | |||
| + : hiddenApp(false), | |||
| + hiddenWindow(hiddenApp) { hiddenApp.idle(); } | |||
| +}; | |||
| +#ifndef DGL_NO_SHARED_RESOURCES | |||
| +static int loadFallbackFont(NVGcontext* const vg) | |||
| +{ | |||
| + const int font = nvgFindFont(vg, NANOVG_DEJAVU_SANS_TTF); | |||
| + if (font >= 0) | |||
| + return font; | |||
| + using namespace dpf_resources; | |||
| -static void windowSizeCallback(GLFWwindow* win, int width, int height) { | |||
| - if (glfwGetWindowAttrib(win, GLFW_MAXIMIZED)) | |||
| @@ -190,24 +197,17 @@ | |||
| - return; | |||
| - settings::windowSize = math::Vec(width, height); | |||
| - // DEBUG("windowSizeCallback %d %d", width, height); | |||
| -} | |||
| +#ifndef DGL_NO_SHARED_RESOURCES | |||
| +static int loadFallbackFont(NVGcontext* const vg) | |||
| +{ | |||
| + const int font = nvgFindFont(vg, NANOVG_DEJAVU_SANS_TTF); | |||
| + if (font >= 0) | |||
| + return font; | |||
| + using namespace dpf_resources; | |||
| -static void windowMaximizeCallback(GLFWwindow* win, int maximized) { | |||
| - settings::windowMaximized = maximized; | |||
| - // DEBUG("windowMaximizeCallback %d", maximized); | |||
| + return nvgCreateFontMem(vg, NANOVG_DEJAVU_SANS_TTF, | |||
| + (uchar*)dejavusans_ttf, dejavusans_ttf_size, 0); | |||
| } | |||
| - | |||
| - | |||
| -static void windowMaximizeCallback(GLFWwindow* win, int maximized) { | |||
| - settings::windowMaximized = maximized; | |||
| - // DEBUG("windowMaximizeCallback %d", maximized); | |||
| -} | |||
| - | |||
| - | |||
| -static void mouseButtonCallback(GLFWwindow* win, int button, int action, int mods) { | |||
| - contextSet((Context*) glfwGetWindowUserPointer(win)); | |||
| -#if defined ARCH_MAC | |||
| @@ -225,15 +225,15 @@ | |||
| - APP->event->handleButton(APP->window->internal->lastMousePos, button, action, mods); | |||
| -} | |||
| +Window::Window() { | |||
| + internal = new Internal; | |||
| - | |||
| -static void cursorPosCallback(GLFWwindow* win, double xpos, double ypos) { | |||
| - contextSet((Context*) glfwGetWindowUserPointer(win)); | |||
| - math::Vec mousePos = math::Vec(xpos, ypos).div(APP->window->pixelRatio / APP->window->windowRatio).round(); | |||
| - math::Vec mouseDelta = mousePos.minus(APP->window->internal->lastMousePos); | |||
| - | |||
| +Window::Window() { | |||
| + internal = new Internal; | |||
| - // Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked. | |||
| - if (APP->window->internal->ignoreNextMouseDelta) { | |||
| - APP->window->internal->ignoreNextMouseDelta = false; | |||
| @@ -435,8 +435,8 @@ | |||
| +#endif | |||
| } | |||
| -} | |||
| - | |||
| -static void dropCallback(GLFWwindow* win, int count, const char** paths) { | |||
| - contextSet((Context*) glfwGetWindowUserPointer(win)); | |||
| - std::vector<std::string> pathsVec; | |||
| @@ -1069,7 +1069,7 @@ | |||
| } | |||
| internal->imageCache[filename] = image; | |||
| return image; | |||
| @@ -766,28 +662,122 @@ | |||
| @@ -766,28 +662,146 @@ | |||
| } | |||
| @@ -1143,6 +1143,13 @@ | |||
| + window->internal->callback->WindowParametersChanged(kWindowParameterWheelSensitivity, | |||
| + rack::settings::knobScrollSensitivity); | |||
| + } | |||
| + if (d_isNotEqual(window->internal->params.browserZoom, rack::settings::browserZoom)) | |||
| + { | |||
| + window->internal->params.browserZoom = rack::settings::browserZoom; | |||
| + if (window->internal->callback != nullptr) | |||
| + window->internal->callback->WindowParametersChanged(kWindowParameterBrowserZoom, | |||
| + rack::settings::browserZoom); | |||
| + } | |||
| + if (window->internal->params.knobMode != rack::settings::knobMode) | |||
| + { | |||
| + window->internal->params.knobMode = rack::settings::knobMode; | |||
| @@ -1150,6 +1157,13 @@ | |||
| + window->internal->callback->WindowParametersChanged(kWindowParameterKnobMode, | |||
| + rack::settings::knobMode); | |||
| + } | |||
| + if (window->internal->params.browserSort != rack::settings::browserSort) | |||
| + { | |||
| + window->internal->params.browserSort = rack::settings::browserSort; | |||
| + if (window->internal->callback != nullptr) | |||
| + window->internal->callback->WindowParametersChanged(kWindowParameterBrowserSort, | |||
| + rack::settings::browserSort); | |||
| + } | |||
| + if (window->internal->params.tooltips != rack::settings::tooltips) | |||
| + { | |||
| + window->internal->params.tooltips = rack::settings::tooltips; | |||
| @@ -1171,6 +1185,13 @@ | |||
| + window->internal->callback->WindowParametersChanged(kWindowParameterLockModulePositions, | |||
| + rack::settings::lockModules); | |||
| + } | |||
| + if (window->internal->params.invertZoom != rack::settings::invertZoom) | |||
| + { | |||
| + window->internal->params.invertZoom = rack::settings::invertZoom; | |||
| + if (window->internal->callback != nullptr) | |||
| + window->internal->callback->WindowParametersChanged(kWindowParameterInvertZoom, | |||
| + rack::settings::invertZoom); | |||
| + } | |||
| + if (window->internal->params.rateLimit != rack::settings::rateLimit) | |||
| + { | |||
| + window->internal->params.rateLimit = rack::settings::rateLimit; | |||
| @@ -1187,10 +1208,13 @@ | |||
| + rack::settings::rackBrightness = window->internal->params.rackBrightness; | |||
| + rack::settings::haloBrightness = window->internal->params.haloBrightness; | |||
| + rack::settings::knobScrollSensitivity = window->internal->params.knobScrollSensitivity; | |||
| + rack::settings::browserZoom = window->internal->params.browserZoom; | |||
| + rack::settings::knobMode = static_cast<rack::settings::KnobMode>(window->internal->params.knobMode); | |||
| + rack::settings::browserSort = static_cast<rack::settings::BrowserSort>(window->internal->params.browserSort); | |||
| + rack::settings::tooltips = window->internal->params.tooltips; | |||
| + rack::settings::knobScroll = window->internal->params.knobScroll; | |||
| + rack::settings::lockModules = window->internal->params.lockModules; | |||
| + rack::settings::invertZoom = window->internal->params.invertZoom; | |||
| + rack::settings::rateLimit = window->internal->params.rateLimit; | |||
| +} | |||
| + | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/common.cpp 2021-11-23 19:57:23.719015894 +0000 | |||
| +++ common.cpp 2022-02-27 00:17:50.908149000 +0000 | |||
| +++ common.cpp 2022-03-14 23:25:17.492322806 +0000 | |||
| @@ -1,6 +1,38 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -55,7 +55,8 @@ | |||
| +const std::string APP_VERSION = "2.1"; | |||
| #if defined ARCH_WIN | |||
| const std::string APP_OS = "win"; | |||
| #elif ARCH_MAC | |||
| -#elif ARCH_MAC | |||
| +#elif defined ARCH_MAC | |||
| const std::string APP_OS = "mac"; | |||
| #elif defined ARCH_LIN | |||
| const std::string APP_OS = "lin"; | |||