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"; | |||