Signed-off-by: falkTX <falktx@falktx.com>tags/22.02
| @@ -29,6 +29,7 @@ | |||||
| # undef DEBUG | # undef DEBUG | ||||
| #endif | #endif | ||||
| #include <Application.hpp> | |||||
| #include "DistrhoUI.hpp" | #include "DistrhoUI.hpp" | ||||
| #include "PluginContext.hpp" | #include "PluginContext.hpp" | ||||
| #include "WindowParameters.hpp" | #include "WindowParameters.hpp" | ||||
| @@ -40,6 +41,9 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode) { return nullptr; } | |||||
| GLFWAPI int glfwGetKeyScancode(int key) { return 0; } | GLFWAPI int glfwGetKeyScancode(int key) { return 0; } | ||||
| namespace rack { | namespace rack { | ||||
| namespace app { | |||||
| widget::Widget* createMenuBar(CardinalPluginContext* context, bool isStandalone); | |||||
| } | |||||
| namespace window { | namespace window { | ||||
| void WindowInit(Window* window, DISTRHO_NAMESPACE::UI* ui); | void WindowInit(Window* window, DISTRHO_NAMESPACE::UI* ui); | ||||
| void WindowMods(Window* window, int mods); | void WindowMods(Window* window, int mods); | ||||
| @@ -50,66 +54,6 @@ START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| struct CardinalMenuButton : rack::ui::Button { | |||||
| void step() override { | |||||
| box.size.x = bndLabelWidth(APP->window->vg, -1, text.c_str()) + 1.0; | |||||
| Widget::step(); | |||||
| } | |||||
| void draw(const DrawArgs& args) override { | |||||
| BNDwidgetState state = BND_DEFAULT; | |||||
| if (APP->event->hoveredWidget == this) | |||||
| state = BND_HOVER; | |||||
| if (APP->event->draggedWidget == this) | |||||
| state = BND_ACTIVE; | |||||
| bndMenuItem(args.vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str()); | |||||
| Widget::draw(args); | |||||
| } | |||||
| }; | |||||
| struct CardinalFileButton : CardinalMenuButton { | |||||
| CardinalFileButton() | |||||
| : CardinalMenuButton() | |||||
| { | |||||
| text = "File"; | |||||
| } | |||||
| void onAction(const ActionEvent& e) override { | |||||
| rack::ui::Menu* menu = rack::createMenu(); | |||||
| menu->cornerFlags = BND_CORNER_TOP; | |||||
| menu->box.pos = getAbsoluteOffset(rack::math::Vec(0, box.size.y)); | |||||
| menu->addChild(rack::createMenuItem("New", RACK_MOD_CTRL_NAME "+N", []() { | |||||
| APP->patch->loadTemplateDialog(); | |||||
| })); | |||||
| menu->addChild(rack::createMenuItem("Open", RACK_MOD_CTRL_NAME "+O", []() { | |||||
| APP->patch->loadDialog(); | |||||
| })); | |||||
| /* | |||||
| menu->addChild(rack::createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() { | |||||
| APP->patch->saveDialog(); | |||||
| })); | |||||
| menu->addChild(rack::createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() { | |||||
| APP->patch->saveAsDialog(); | |||||
| })); | |||||
| */ | |||||
| menu->addChild(rack::createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() { | |||||
| APP->patch->revertDialog(); | |||||
| }, APP->patch->path == "")); | |||||
| menu->addChild(new rack::ui::MenuSeparator); | |||||
| menu->addChild(rack::createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() { | |||||
| APP->window->close(); | |||||
| })); | |||||
| } | |||||
| }; | |||||
| // ----------------------------------------------------------------------------------------------------------- | |||||
| CardinalPluginContext* getRackContextFromPlugin(void* ptr); | CardinalPluginContext* getRackContextFromPlugin(void* ptr); | ||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| @@ -169,56 +113,11 @@ public: | |||||
| { | { | ||||
| const ScopedContext sc(this); | const ScopedContext sc(this); | ||||
| rack::window::WindowInit(fContext->window, this); | rack::window::WindowInit(fContext->window, this); | ||||
| // Hide non-wanted menu entries | |||||
| typedef rack::ui::Button rButton; | |||||
| // typedef rack::ui::MenuItem rMenuItem; | |||||
| typedef rack::widget::Widget rWidget; | |||||
| typedef std::list<rWidget*>::iterator rWidgetIterator; | |||||
| rWidget* const layout = fContext->scene->menuBar->children.front(); | |||||
| const auto removeMenu = [layout](const char* const name) -> void | |||||
| { | |||||
| for (rWidgetIterator it = layout->children.begin(); it != layout->children.end(); ++it) | |||||
| { | |||||
| if (rButton* const button = reinterpret_cast<rButton*>(*it)) | |||||
| { | |||||
| if (button->text == name) | |||||
| { | |||||
| layout->removeChild(button); | |||||
| // button->parent = nullptr; | |||||
| delete button; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| }; | |||||
| removeMenu("File"); | |||||
| removeMenu("Library"); | |||||
| layout->addChildBottom(new CardinalFileButton()); | |||||
| /* FIXME this doesnt work | |||||
| if (button->text == "Engine") | |||||
| { | |||||
| for (rWidgetIterator it2 = button->children.begin(); it2 != button->children.end(); ++it2) | |||||
| { | |||||
| if (rMenuItem* const item = reinterpret_cast<rMenuItem*>(*it2)) | |||||
| { | |||||
| if (item->text == "Sample rate") | |||||
| { | |||||
| button->children.erase(it2); | |||||
| delete button; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| */ | |||||
| fContext->scene->removeChild(fContext->scene->menuBar); | |||||
| fContext->scene->menuBar = rack::app::createMenuBar(fContext, getApp().isStandalone()); | |||||
| fContext->scene->addChildBelow(fContext->scene->menuBar, fContext->scene->rackScroll); | |||||
| } | } | ||||
| WindowParametersSetCallback(fContext->window, this); | WindowParametersSetCallback(fContext->window, this); | ||||
| @@ -20,13 +20,18 @@ NAME = Cardinal | |||||
| # Files to build (DPF stuff) | # Files to build (DPF stuff) | ||||
| FILES_DSP = \ | FILES_DSP = \ | ||||
| CardinalPlugin.cpp | |||||
| CardinalPlugin.cpp \ | |||||
| override/asset.cpp \ | |||||
| override/common.cpp \ | |||||
| override/context.cpp \ | |||||
| override/dep.cpp \ | |||||
| override/library.cpp \ | |||||
| override/network.cpp | |||||
| FILES_UI = \ | FILES_UI = \ | ||||
| CardinalUI.cpp \ | CardinalUI.cpp \ | ||||
| context.cpp \ | |||||
| dep.cpp \ | |||||
| Window.cpp | |||||
| override/MenuBar.cpp \ | |||||
| override/Window.cpp | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Import base definitions | # Import base definitions | ||||
| @@ -67,7 +72,7 @@ IGNORED_FILES += Rack/src/rtmidi.cpp | |||||
| FILES_DSP += $(wildcard Rack/src/*.c) | FILES_DSP += $(wildcard Rack/src/*.c) | ||||
| FILES_DSP += $(wildcard Rack/src/*/*.c) | FILES_DSP += $(wildcard Rack/src/*/*.c) | ||||
| FILES_DSP += $(filter-out $(IGNORED_FILES),$(wildcard Rack/src/*.cpp)) | FILES_DSP += $(filter-out $(IGNORED_FILES),$(wildcard Rack/src/*.cpp)) | ||||
| FILES_DSP += $(filter-out Rack/src/window/Window.cpp, $(wildcard Rack/src/*/*.cpp)) | |||||
| FILES_DSP += $(filter-out Rack/src/app/MenuBar.cpp Rack/src/window/Window.cpp, $(wildcard Rack/src/*/*.cpp)) | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| # Extra libraries to link against | # Extra libraries to link against | ||||
| @@ -1,180 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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. | |||||
| */ | |||||
| #include <common.hpp> | |||||
| #include <string.hpp> | |||||
| #ifdef NDEBUG | |||||
| # undef DEBUG | |||||
| #endif | |||||
| #include "OpenGL.hpp" | |||||
| #include "DistrhoPluginUtils.hpp" | |||||
| // fix blendish build, missing symbol in debug mode | |||||
| #ifdef DEBUG | |||||
| extern "C" { | |||||
| float bnd_clamp(float v, float mn, float mx) { | |||||
| return (v > mx)?mx:(v < mn)?mn:v; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| // fix bogaudio build, another missing symbol | |||||
| #ifdef DEBUG | |||||
| namespace bogaudio { | |||||
| struct FollowerBase { | |||||
| static float efGainMaxDecibelsDebug; | |||||
| }; | |||||
| float FollowerBase::efGainMaxDecibelsDebug = 12.0f; | |||||
| } | |||||
| #endif | |||||
| // fopen_u8 | |||||
| #ifdef ARCH_WIN | |||||
| #include <windows.h> | |||||
| FILE* fopen_u8(const char* filename, const char* mode) | |||||
| { | |||||
| return _wfopen(rack::string::UTF8toUTF16(filename).c_str(), rack::string::UTF8toUTF16(mode).c_str()); | |||||
| } | |||||
| #endif | |||||
| // Compile those nice implementation-in-header little libraries | |||||
| #define NANOSVG_IMPLEMENTATION | |||||
| #define NANOSVG_ALL_COLOR_KEYWORDS | |||||
| #include <nanosvg.h> | |||||
| // Define the global names to indicate this is Cardinal and not VCVRack | |||||
| namespace rack { | |||||
| const std::string APP_NAME = "Cardinal"; | |||||
| const std::string APP_EDITION = getPluginFormatName(); | |||||
| const std::string APP_EDITION_NAME = "Audio Plugin"; | |||||
| const std::string APP_VERSION_MAJOR = "2"; | |||||
| const std::string APP_VERSION = "2.0"; | |||||
| #if defined(ARCH_WIN) | |||||
| const std::string APP_ARCH = "win"; | |||||
| #elif defined(ARCH_MAC) | |||||
| const std::string APP_ARCH = "mac"; | |||||
| #else | |||||
| const std::string APP_ARCH = "lin"; | |||||
| #endif | |||||
| const std::string API_URL = ""; | |||||
| Exception::Exception(const char* format, ...) | |||||
| { | |||||
| va_list args; | |||||
| va_start(args, format); | |||||
| msg = string::fV(format, args); | |||||
| va_end(args); | |||||
| } | |||||
| } | |||||
| // Custom assets location | |||||
| #include <algorithm> | |||||
| #include <asset.hpp> | |||||
| #include <system.hpp> | |||||
| #include <plugin/Plugin.hpp> | |||||
| namespace rack { | |||||
| namespace asset { | |||||
| std::string userDir; // ignored | |||||
| std::string systemDir; // points to plugin resources dir (or installed/local Rack dir) | |||||
| std::string bundlePath; // points to plugin manifests dir (or empty) | |||||
| // get rid of "res/" prefix | |||||
| static inline std::string& trim(std::string& s) | |||||
| { | |||||
| if (std::strncmp(s.c_str(), "res" DISTRHO_OS_SEP_STR, 4) == 0) | |||||
| s = s.substr(4, s.size()-4); | |||||
| #if DISTRHO_OS_SEP != '/' | |||||
| if (std::strncmp(s.c_str(), "res/", 4) == 0) | |||||
| s = s.substr(4, s.size()-4); | |||||
| #endif | |||||
| return s; | |||||
| } | |||||
| // ignored, returns the same as `system` | |||||
| std::string user(std::string filename) { | |||||
| return system(filename); | |||||
| } | |||||
| // get system resource, trimming "res/" prefix if we are loaded as a plugin bundle | |||||
| std::string system(std::string filename) { | |||||
| return system::join(systemDir, bundlePath.empty() ? filename : trim(filename)); | |||||
| } | |||||
| // get plugin resource, also trims "res/" as needed | |||||
| std::string plugin(plugin::Plugin* plugin, std::string filename) { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, {}); | |||||
| return system::join(plugin->path, bundlePath.empty() ? filename : trim(filename)); | |||||
| } | |||||
| // path to plugin manifest | |||||
| std::string pluginManifest(const std::string& dirname) { | |||||
| if (bundlePath.empty()) | |||||
| { | |||||
| if (dirname == "Core") | |||||
| return system::join(systemDir, "Core.json"); | |||||
| return system::join(systemDir, "..", "..", "plugins", dirname, "plugin.json"); | |||||
| } | |||||
| return system::join(bundlePath, dirname + ".json"); | |||||
| } | |||||
| // path to plugin files | |||||
| std::string pluginPath(const std::string& dirname) { | |||||
| if (bundlePath.empty()) | |||||
| { | |||||
| if (dirname == "Core") | |||||
| return systemDir; | |||||
| return system::join(systemDir, "..", "..", "plugins", dirname); | |||||
| } | |||||
| return system::join(systemDir, dirname); | |||||
| } | |||||
| } | |||||
| } | |||||
| // Define the stuff needed for VCVRack but unused for Cardinal | |||||
| #include <library.hpp> | |||||
| #include <network.hpp> | |||||
| namespace rack { | |||||
| namespace library { | |||||
| std::string appChangelogUrl; | |||||
| std::string appDownloadUrl; | |||||
| std::string appVersion; | |||||
| std::string loginStatus; | |||||
| std::map<std::string, UpdateInfo> updateInfos; | |||||
| std::string updateStatus; | |||||
| std::string updateSlug; | |||||
| float updateProgress = 0.f; | |||||
| bool isSyncing = false; | |||||
| bool restartRequested = false; | |||||
| void checkAppUpdate() {} | |||||
| void checkUpdates() {} | |||||
| bool hasUpdates() { return false; } | |||||
| bool isAppUpdateAvailable() { return false; } | |||||
| bool isLoggedIn() { return false; } | |||||
| void logIn(const std::string&, const std::string&) {} | |||||
| void logOut() {} | |||||
| void syncUpdate(const std::string&) {} | |||||
| void syncUpdates() {} | |||||
| } | |||||
| namespace network { | |||||
| std::string encodeUrl(const std::string&) { return {}; } | |||||
| json_t* requestJson(Method, const std::string&, json_t*, const CookieMap&) { return nullptr; } | |||||
| bool requestDownload(const std::string&, const std::string&, float*, const CookieMap&) { return false; } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,646 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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 MenuBar.cpp | |||||
| * Copyright (C) 2016-2021 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> | |||||
| #include <ui/Button.hpp> | |||||
| #include <ui/MenuItem.hpp> | |||||
| #include <ui/MenuSeparator.hpp> | |||||
| #include <ui/SequentialLayout.hpp> | |||||
| #include <ui/Slider.hpp> | |||||
| #include <ui/TextField.hpp> | |||||
| #include <ui/PasswordField.hpp> | |||||
| #include <ui/ProgressBar.hpp> | |||||
| #include <ui/Label.hpp> | |||||
| #include <engine/Engine.hpp> | |||||
| #include <window/Window.hpp> | |||||
| #include <asset.hpp> | |||||
| #include <context.hpp> | |||||
| #include <settings.hpp> | |||||
| #include <helpers.hpp> | |||||
| #include <system.hpp> | |||||
| #include <plugin.hpp> | |||||
| #include <patch.hpp> | |||||
| #include <library.hpp> | |||||
| #ifdef NDEBUG | |||||
| # undef DEBUG | |||||
| #endif | |||||
| #include "../PluginContext.hpp" | |||||
| namespace rack { | |||||
| namespace app { | |||||
| namespace menuBar { | |||||
| struct MenuButton : ui::Button { | |||||
| void step() override { | |||||
| box.size.x = bndLabelWidth(APP->window->vg, -1, text.c_str()) + 1.0; | |||||
| Widget::step(); | |||||
| } | |||||
| void draw(const DrawArgs& args) override { | |||||
| BNDwidgetState state = BND_DEFAULT; | |||||
| if (APP->event->hoveredWidget == this) | |||||
| state = BND_HOVER; | |||||
| if (APP->event->draggedWidget == this) | |||||
| state = BND_ACTIVE; | |||||
| bndMenuItem(args.vg, 0.0, 0.0, box.size.x, box.size.y, state, -1, text.c_str()); | |||||
| Widget::draw(args); | |||||
| } | |||||
| }; | |||||
| //////////////////// | |||||
| // File | |||||
| //////////////////// | |||||
| struct FileButton : MenuButton { | |||||
| const bool isStandalone; | |||||
| FileButton(const bool standalone) | |||||
| : MenuButton(), isStandalone(standalone) {} | |||||
| 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(); | |||||
| })); | |||||
| menu->addChild(createMenuItem("Open", RACK_MOD_CTRL_NAME "+O", []() { | |||||
| APP->patch->loadDialog(); | |||||
| })); | |||||
| /* | |||||
| menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() { | |||||
| APP->patch->saveDialog(); | |||||
| })); | |||||
| menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() { | |||||
| APP->patch->saveAsDialog(); | |||||
| })); | |||||
| menu->addChild(createMenuItem("Save template", "", []() { | |||||
| APP->patch->saveTemplateDialog(); | |||||
| })); | |||||
| */ | |||||
| menu->addChild(createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() { | |||||
| APP->patch->revertDialog(); | |||||
| }, APP->patch->path == "")); | |||||
| if (isStandalone) { | |||||
| menu->addChild(new ui::MenuSeparator); | |||||
| menu->addChild(createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() { | |||||
| APP->window->close(); | |||||
| })); | |||||
| }; | |||||
| } | |||||
| }; | |||||
| //////////////////// | |||||
| // Edit | |||||
| //////////////////// | |||||
| struct EditButton : 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)); | |||||
| struct UndoItem : ui::MenuItem { | |||||
| void step() override { | |||||
| text = "Undo " + APP->history->getUndoName(); | |||||
| disabled = !APP->history->canUndo(); | |||||
| MenuItem::step(); | |||||
| } | |||||
| void onAction(const ActionEvent& e) override { | |||||
| APP->history->undo(); | |||||
| } | |||||
| }; | |||||
| menu->addChild(createMenuItem<UndoItem>("", RACK_MOD_CTRL_NAME "+Z")); | |||||
| struct RedoItem : ui::MenuItem { | |||||
| void step() override { | |||||
| text = "Redo " + APP->history->getRedoName(); | |||||
| disabled = !APP->history->canRedo(); | |||||
| MenuItem::step(); | |||||
| } | |||||
| void onAction(const ActionEvent& e) override { | |||||
| APP->history->redo(); | |||||
| } | |||||
| }; | |||||
| menu->addChild(createMenuItem<RedoItem>("", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+Z")); | |||||
| menu->addChild(createMenuItem("Clear cables", "", [=]() { | |||||
| APP->patch->disconnectDialog(); | |||||
| })); | |||||
| menu->addChild(new ui::MenuSeparator); | |||||
| APP->scene->rack->appendSelectionContextMenu(menu); | |||||
| } | |||||
| }; | |||||
| //////////////////// | |||||
| // View | |||||
| //////////////////// | |||||
| struct ZoomQuantity : Quantity { | |||||
| void setValue(float value) override { | |||||
| APP->scene->rackScroll->setZoom(std::pow(2.f, value)); | |||||
| } | |||||
| float getValue() override { | |||||
| return std::log2(APP->scene->rackScroll->getZoom()); | |||||
| } | |||||
| float getMinValue() override { | |||||
| return -2.f; | |||||
| } | |||||
| float getMaxValue() override { | |||||
| return 2.f; | |||||
| } | |||||
| float getDefaultValue() override { | |||||
| return 0.0; | |||||
| } | |||||
| float getDisplayValue() override { | |||||
| return std::round(std::pow(2.f, getValue()) * 100); | |||||
| } | |||||
| void setDisplayValue(float displayValue) override { | |||||
| setValue(std::log2(displayValue / 100)); | |||||
| } | |||||
| std::string getLabel() override { | |||||
| return "Zoom"; | |||||
| } | |||||
| std::string getUnit() override { | |||||
| return "%"; | |||||
| } | |||||
| }; | |||||
| struct ZoomSlider : ui::Slider { | |||||
| ZoomSlider() { | |||||
| quantity = new ZoomQuantity; | |||||
| } | |||||
| ~ZoomSlider() { | |||||
| delete quantity; | |||||
| } | |||||
| }; | |||||
| struct CableOpacityQuantity : Quantity { | |||||
| void setValue(float value) override { | |||||
| settings::cableOpacity = math::clamp(value, getMinValue(), getMaxValue()); | |||||
| } | |||||
| float getValue() override { | |||||
| return settings::cableOpacity; | |||||
| } | |||||
| float getDefaultValue() override { | |||||
| return 0.5; | |||||
| } | |||||
| float getDisplayValue() override { | |||||
| return getValue() * 100; | |||||
| } | |||||
| void setDisplayValue(float displayValue) override { | |||||
| setValue(displayValue / 100); | |||||
| } | |||||
| std::string getLabel() override { | |||||
| return "Cable opacity"; | |||||
| } | |||||
| std::string getUnit() override { | |||||
| return "%"; | |||||
| } | |||||
| }; | |||||
| struct CableOpacitySlider : ui::Slider { | |||||
| CableOpacitySlider() { | |||||
| quantity = new CableOpacityQuantity; | |||||
| } | |||||
| ~CableOpacitySlider() { | |||||
| delete quantity; | |||||
| } | |||||
| }; | |||||
| struct CableTensionQuantity : Quantity { | |||||
| void setValue(float value) override { | |||||
| settings::cableTension = math::clamp(value, getMinValue(), getMaxValue()); | |||||
| } | |||||
| float getValue() override { | |||||
| return settings::cableTension; | |||||
| } | |||||
| float getDefaultValue() override { | |||||
| return 0.5; | |||||
| } | |||||
| std::string getLabel() override { | |||||
| return "Cable tension"; | |||||
| } | |||||
| int getDisplayPrecision() override { | |||||
| return 2; | |||||
| } | |||||
| }; | |||||
| struct CableTensionSlider : ui::Slider { | |||||
| CableTensionSlider() { | |||||
| quantity = new CableTensionQuantity; | |||||
| } | |||||
| ~CableTensionSlider() { | |||||
| delete quantity; | |||||
| } | |||||
| }; | |||||
| struct RackBrightnessQuantity : Quantity { | |||||
| void setValue(float value) override { | |||||
| settings::rackBrightness = math::clamp(value, getMinValue(), getMaxValue()); | |||||
| } | |||||
| float getValue() override { | |||||
| return settings::rackBrightness; | |||||
| } | |||||
| float getDefaultValue() override { | |||||
| return 1.0; | |||||
| } | |||||
| float getDisplayValue() override { | |||||
| return getValue() * 100; | |||||
| } | |||||
| void setDisplayValue(float displayValue) override { | |||||
| setValue(displayValue / 100); | |||||
| } | |||||
| std::string getUnit() override { | |||||
| return "%"; | |||||
| } | |||||
| std::string getLabel() override { | |||||
| return "Room brightness"; | |||||
| } | |||||
| int getDisplayPrecision() override { | |||||
| return 3; | |||||
| } | |||||
| }; | |||||
| struct RackBrightnessSlider : ui::Slider { | |||||
| RackBrightnessSlider() { | |||||
| quantity = new RackBrightnessQuantity; | |||||
| } | |||||
| ~RackBrightnessSlider() { | |||||
| delete quantity; | |||||
| } | |||||
| }; | |||||
| struct HaloBrightnessQuantity : Quantity { | |||||
| void setValue(float value) override { | |||||
| settings::haloBrightness = math::clamp(value, getMinValue(), getMaxValue()); | |||||
| } | |||||
| float getValue() override { | |||||
| return settings::haloBrightness; | |||||
| } | |||||
| float getDefaultValue() override { | |||||
| return 0.25; | |||||
| } | |||||
| float getDisplayValue() override { | |||||
| return getValue() * 100; | |||||
| } | |||||
| void setDisplayValue(float displayValue) override { | |||||
| setValue(displayValue / 100); | |||||
| } | |||||
| std::string getUnit() override { | |||||
| return "%"; | |||||
| } | |||||
| std::string getLabel() override { | |||||
| return "Light bloom"; | |||||
| } | |||||
| int getDisplayPrecision() override { | |||||
| return 3; | |||||
| } | |||||
| }; | |||||
| struct HaloBrightnessSlider : ui::Slider { | |||||
| HaloBrightnessSlider() { | |||||
| quantity = new HaloBrightnessQuantity; | |||||
| } | |||||
| ~HaloBrightnessSlider() { | |||||
| delete quantity; | |||||
| } | |||||
| }; | |||||
| struct KnobScrollSensitivityQuantity : Quantity { | |||||
| void setValue(float value) override { | |||||
| value = math::clamp(value, getMinValue(), getMaxValue()); | |||||
| settings::knobScrollSensitivity = std::pow(2.f, value); | |||||
| } | |||||
| float getValue() override { | |||||
| return std::log2(settings::knobScrollSensitivity); | |||||
| } | |||||
| float getMinValue() override { | |||||
| return std::log2(1e-4f); | |||||
| } | |||||
| float getMaxValue() override { | |||||
| return std::log2(1e-2f); | |||||
| } | |||||
| float getDefaultValue() override { | |||||
| return std::log2(1e-3f); | |||||
| } | |||||
| float getDisplayValue() override { | |||||
| return std::pow(2.f, getValue() - getDefaultValue()); | |||||
| } | |||||
| void setDisplayValue(float displayValue) override { | |||||
| setValue(std::log2(displayValue) + getDefaultValue()); | |||||
| } | |||||
| std::string getLabel() override { | |||||
| return "Scroll wheel knob sensitivity"; | |||||
| } | |||||
| int getDisplayPrecision() override { | |||||
| return 2; | |||||
| } | |||||
| }; | |||||
| struct KnobScrollSensitivitySlider : ui::Slider { | |||||
| KnobScrollSensitivitySlider() { | |||||
| quantity = new KnobScrollSensitivityQuantity; | |||||
| } | |||||
| ~KnobScrollSensitivitySlider() { | |||||
| delete quantity; | |||||
| } | |||||
| }; | |||||
| 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(createBoolPtrMenuItem("Show tooltips", "", &settings::tooltips)); | |||||
| ZoomSlider* zoomSlider = new ZoomSlider; | |||||
| zoomSlider->box.size.x = 250.0; | |||||
| menu->addChild(zoomSlider); | |||||
| CableOpacitySlider* cableOpacitySlider = new CableOpacitySlider; | |||||
| cableOpacitySlider->box.size.x = 250.0; | |||||
| menu->addChild(cableOpacitySlider); | |||||
| CableTensionSlider* cableTensionSlider = new CableTensionSlider; | |||||
| cableTensionSlider->box.size.x = 250.0; | |||||
| menu->addChild(cableTensionSlider); | |||||
| RackBrightnessSlider* rackBrightnessSlider = new RackBrightnessSlider; | |||||
| rackBrightnessSlider->box.size.x = 250.0; | |||||
| menu->addChild(rackBrightnessSlider); | |||||
| HaloBrightnessSlider* haloBrightnessSlider = new HaloBrightnessSlider; | |||||
| haloBrightnessSlider->box.size.x = 250.0; | |||||
| menu->addChild(haloBrightnessSlider); | |||||
| menu->addChild(new ui::MenuSeparator); | |||||
| // menu->addChild(createBoolPtrMenuItem("Hide cursor while dragging", "", &settings::allowCursorLock)); | |||||
| static const std::vector<std::string> knobModeLabels = { | |||||
| "Linear", | |||||
| "Scaled linear", | |||||
| "Absolute rotary", | |||||
| "Relative rotary", | |||||
| }; | |||||
| static const std::vector<int> knobModes = {0, 2, 3}; | |||||
| menu->addChild(createSubmenuItem("Knob mode", knobModeLabels[settings::knobMode], [=](ui::Menu* menu) { | |||||
| for (int knobMode : knobModes) { | |||||
| menu->addChild(createCheckMenuItem(knobModeLabels[knobMode], "", | |||||
| [=]() {return settings::knobMode == knobMode;}, | |||||
| [=]() {settings::knobMode = (settings::KnobMode) knobMode;} | |||||
| )); | |||||
| } | |||||
| })); | |||||
| menu->addChild(createBoolPtrMenuItem("Scroll wheel knob control", "", &settings::knobScroll)); | |||||
| KnobScrollSensitivitySlider* knobScrollSensitivitySlider = new KnobScrollSensitivitySlider; | |||||
| knobScrollSensitivitySlider->box.size.x = 250.0; | |||||
| menu->addChild(knobScrollSensitivitySlider); | |||||
| menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules)); | |||||
| } | |||||
| }; | |||||
| //////////////////// | |||||
| // Engine | |||||
| //////////////////// | |||||
| struct EngineButton : 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)); | |||||
| std::string cpuMeterText = "F3"; | |||||
| if (settings::cpuMeter) | |||||
| cpuMeterText += " " CHECKMARK_STRING; | |||||
| menu->addChild(createMenuItem("Performance meters", cpuMeterText, [=]() { | |||||
| settings::cpuMeter ^= true; | |||||
| })); | |||||
| menu->addChild(createSubmenuItem("Threads | DO NOT USE", 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++) { | |||||
| 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;} | |||||
| )); | |||||
| } | |||||
| })); | |||||
| } | |||||
| }; | |||||
| //////////////////// | |||||
| // Help | |||||
| //////////////////// | |||||
| struct HelpButton : 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(createMenuItem("Tips", "", [=]() { | |||||
| APP->scene->addChild(tipWindowCreate()); | |||||
| })); | |||||
| menu->addChild(createMenuItem("VCV User manual", "F1", [=]() { | |||||
| system::openBrowser("https://vcvrack.com/manual/"); | |||||
| })); | |||||
| menu->addChild(createMenuItem("Cardinal Project page", "", [=]() { | |||||
| system::openBrowser("https://github.com/DISTRHO/Cardinal/"); | |||||
| })); | |||||
| menu->addChild(new ui::MenuSeparator); | |||||
| menu->addChild(createMenuLabel(APP_EDITION + " " + APP_EDITION_NAME)); | |||||
| menu->addChild(createMenuLabel("VCVRack " + APP_VERSION + " Compatible")); | |||||
| } | |||||
| }; | |||||
| //////////////////// | |||||
| // MenuBar | |||||
| //////////////////// | |||||
| struct MeterLabel : ui::Label { | |||||
| int frameIndex = 0; | |||||
| double frameDurationTotal = 0.0; | |||||
| double frameDurationAvg = 0.0; | |||||
| double uiLastTime = 0.0; | |||||
| double uiLastThreadTime = 0.0; | |||||
| double uiFrac = 0.0; | |||||
| void step() override { | |||||
| // Compute frame rate | |||||
| double frameDuration = APP->window->getLastFrameDuration(); | |||||
| frameDurationTotal += frameDuration; | |||||
| frameIndex++; | |||||
| if (frameDurationTotal >= 1.0) { | |||||
| frameDurationAvg = frameDurationTotal / frameIndex; | |||||
| frameDurationTotal = 0.0; | |||||
| frameIndex = 0; | |||||
| } | |||||
| // Compute UI thread CPU | |||||
| // double time = system::getTime(); | |||||
| // double uiDuration = time - uiLastTime; | |||||
| // if (uiDuration >= 1.0) { | |||||
| // double threadTime = system::getThreadTime(); | |||||
| // uiFrac = (threadTime - uiLastThreadTime) / uiDuration; | |||||
| // uiLastThreadTime = threadTime; | |||||
| // uiLastTime = time; | |||||
| // } | |||||
| double meterAverage = APP->engine->getMeterAverage(); | |||||
| double meterMax = APP->engine->getMeterMax(); | |||||
| text = string::f("%.1f fps %.1f%% avg %.1f%% max", 1.0 / frameDurationAvg, meterAverage * 100, meterMax * 100); | |||||
| Label::step(); | |||||
| } | |||||
| }; | |||||
| struct MenuBar : widget::OpaqueWidget { | |||||
| CardinalPluginContext* const context; | |||||
| MeterLabel* meterLabel; | |||||
| MenuBar(CardinalPluginContext* const ctx, const bool isStandalone) | |||||
| : context(ctx) | |||||
| { | |||||
| const float margin = 5; | |||||
| box.size.y = BND_WIDGET_HEIGHT + 2 * margin; | |||||
| ui::SequentialLayout* layout = new ui::SequentialLayout; | |||||
| layout->margin = math::Vec(margin, margin); | |||||
| layout->spacing = math::Vec(0, 0); | |||||
| addChild(layout); | |||||
| FileButton* fileButton = new FileButton(isStandalone); | |||||
| fileButton->text = "File"; | |||||
| layout->addChild(fileButton); | |||||
| EditButton* editButton = new EditButton; | |||||
| editButton->text = "Edit"; | |||||
| layout->addChild(editButton); | |||||
| ViewButton* viewButton = new ViewButton; | |||||
| viewButton->text = "View"; | |||||
| layout->addChild(viewButton); | |||||
| EngineButton* engineButton = new EngineButton; | |||||
| engineButton->text = "Engine"; | |||||
| layout->addChild(engineButton); | |||||
| HelpButton* helpButton = new HelpButton; | |||||
| helpButton->text = "Help"; | |||||
| layout->addChild(helpButton); | |||||
| // ui::Label* titleLabel = new ui::Label; | |||||
| // titleLabel->color.a = 0.5; | |||||
| // layout->addChild(titleLabel); | |||||
| meterLabel = new MeterLabel; | |||||
| meterLabel->box.pos.y = margin; | |||||
| meterLabel->box.size.x = 300; | |||||
| meterLabel->alignment = ui::Label::RIGHT_ALIGNMENT; | |||||
| meterLabel->color.a = 0.5; | |||||
| addChild(meterLabel); | |||||
| } | |||||
| void draw(const DrawArgs& args) override { | |||||
| bndMenuBackground(args.vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_ALL); | |||||
| bndBevel(args.vg, 0.0, 0.0, box.size.x, box.size.y); | |||||
| Widget::draw(args); | |||||
| } | |||||
| void step() override { | |||||
| meterLabel->box.pos.x = box.size.x - meterLabel->box.size.x - 5; | |||||
| Widget::step(); | |||||
| } | |||||
| }; | |||||
| } // namespace menuBar | |||||
| widget::Widget* createMenuBar() { | |||||
| return new widget::Widget; | |||||
| } | |||||
| widget::Widget* createMenuBar(CardinalPluginContext* const context, const bool isStandalone) { | |||||
| menuBar::MenuBar* menuBar = new menuBar::MenuBar(context, isStandalone); | |||||
| return menuBar; | |||||
| } | |||||
| } // namespace app | |||||
| } // namespace rack | |||||
| @@ -1,3 +1,30 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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 Window.cpp | |||||
| * Copyright (C) 2016-2021 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 <map> | #include <map> | ||||
| #include <queue> | #include <queue> | ||||
| #include <thread> | #include <thread> | ||||
| @@ -19,7 +46,7 @@ | |||||
| #endif | #endif | ||||
| #include "DistrhoUI.hpp" | #include "DistrhoUI.hpp" | ||||
| #include "WindowParameters.hpp" | |||||
| #include "../WindowParameters.hpp" | |||||
| namespace rack { | namespace rack { | ||||
| namespace window { | namespace window { | ||||
| @@ -0,0 +1,84 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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. | |||||
| */ | |||||
| #include <asset.hpp> | |||||
| #include <system.hpp> | |||||
| #include <plugin/Plugin.hpp> | |||||
| #include <algorithm> | |||||
| #include "DistrhoUtils.hpp" | |||||
| namespace rack { | |||||
| namespace asset { | |||||
| std::string userDir; // ignored | |||||
| std::string systemDir; // points to plugin resources dir (or installed/local Rack dir) | |||||
| std::string bundlePath; // points to plugin manifests dir (or empty) | |||||
| // get rid of "res/" prefix | |||||
| static inline std::string& trim(std::string& s) | |||||
| { | |||||
| if (std::strncmp(s.c_str(), "res" DISTRHO_OS_SEP_STR, 4) == 0) | |||||
| s = s.substr(4, s.size()-4); | |||||
| #if DISTRHO_OS_SEP != '/' | |||||
| if (std::strncmp(s.c_str(), "res/", 4) == 0) | |||||
| s = s.substr(4, s.size()-4); | |||||
| #endif | |||||
| return s; | |||||
| } | |||||
| // ignored, returns the same as `system` | |||||
| std::string user(std::string filename) { | |||||
| return system(filename); | |||||
| } | |||||
| // get system resource, trimming "res/" prefix if we are loaded as a plugin bundle | |||||
| std::string system(std::string filename) { | |||||
| return system::join(systemDir, bundlePath.empty() ? filename : trim(filename)); | |||||
| } | |||||
| // get plugin resource, also trims "res/" as needed | |||||
| std::string plugin(plugin::Plugin* plugin, std::string filename) { | |||||
| DISTRHO_SAFE_ASSERT_RETURN(plugin != nullptr, {}); | |||||
| return system::join(plugin->path, bundlePath.empty() ? filename : trim(filename)); | |||||
| } | |||||
| // path to plugin manifest | |||||
| std::string pluginManifest(const std::string& dirname) { | |||||
| if (bundlePath.empty()) | |||||
| { | |||||
| if (dirname == "Core") | |||||
| return system::join(systemDir, "Core.json"); | |||||
| return system::join(systemDir, "..", "..", "plugins", dirname, "plugin.json"); | |||||
| } | |||||
| return system::join(bundlePath, dirname + ".json"); | |||||
| } | |||||
| // path to plugin files | |||||
| std::string pluginPath(const std::string& dirname) { | |||||
| if (bundlePath.empty()) | |||||
| { | |||||
| if (dirname == "Core") | |||||
| return systemDir; | |||||
| return system::join(systemDir, "..", "..", "plugins", dirname); | |||||
| } | |||||
| return system::join(systemDir, dirname); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,59 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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. | |||||
| */ | |||||
| #include <common.hpp> | |||||
| #include <string.hpp> | |||||
| #include "DistrhoPluginUtils.hpp" | |||||
| // fopen_u8 | |||||
| #ifdef ARCH_WIN | |||||
| #include <windows.h> | |||||
| FILE* fopen_u8(const char* filename, const char* mode) | |||||
| { | |||||
| return _wfopen(rack::string::UTF8toUTF16(filename).c_str(), rack::string::UTF8toUTF16(mode).c_str()); | |||||
| } | |||||
| #endif | |||||
| // Define the global names to indicate this is Cardinal and not VCVRack | |||||
| namespace rack { | |||||
| const std::string APP_NAME = "Cardinal"; | |||||
| const std::string APP_EDITION = getPluginFormatName(); | |||||
| const std::string APP_EDITION_NAME = "Audio Plugin"; | |||||
| const std::string APP_VERSION_MAJOR = "2"; | |||||
| const std::string APP_VERSION = "2.0"; | |||||
| #if defined(ARCH_WIN) | |||||
| const std::string APP_ARCH = "win"; | |||||
| #elif defined(ARCH_MAC) | |||||
| const std::string APP_ARCH = "mac"; | |||||
| #else | |||||
| const std::string APP_ARCH = "lin"; | |||||
| #endif | |||||
| const std::string API_URL = ""; | |||||
| Exception::Exception(const char* format, ...) | |||||
| { | |||||
| va_list args; | |||||
| va_start(args, format); | |||||
| msg = string::fV(format, args); | |||||
| va_end(args); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,42 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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. | |||||
| */ | |||||
| #include "OpenGL.hpp" | |||||
| // fix blendish build, missing symbol in debug mode | |||||
| #ifdef DEBUG | |||||
| extern "C" { | |||||
| float bnd_clamp(float v, float mn, float mx) { | |||||
| return (v > mx)?mx:(v < mn)?mn:v; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| // fix bogaudio build, another missing symbol | |||||
| #ifdef DEBUG | |||||
| namespace bogaudio { | |||||
| struct FollowerBase { | |||||
| static float efGainMaxDecibelsDebug; | |||||
| }; | |||||
| float FollowerBase::efGainMaxDecibelsDebug = 12.0f; | |||||
| } | |||||
| #endif | |||||
| // Compile those nice implementation-in-header little libraries | |||||
| #define NANOSVG_IMPLEMENTATION | |||||
| #define NANOSVG_ALL_COLOR_KEYWORDS | |||||
| #include <nanosvg.h> | |||||
| @@ -0,0 +1,46 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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. | |||||
| */ | |||||
| #include <library.hpp> | |||||
| // Define the stuff needed for VCVRack but unused for Cardinal | |||||
| namespace rack { | |||||
| namespace library { | |||||
| std::string appChangelogUrl; | |||||
| std::string appDownloadUrl; | |||||
| std::string appVersion; | |||||
| std::string loginStatus; | |||||
| std::map<std::string, UpdateInfo> updateInfos; | |||||
| std::string updateStatus; | |||||
| std::string updateSlug; | |||||
| float updateProgress = 0.f; | |||||
| bool isSyncing = false; | |||||
| bool restartRequested = false; | |||||
| void checkAppUpdate() {} | |||||
| void checkUpdates() {} | |||||
| bool hasUpdates() { return false; } | |||||
| bool isAppUpdateAvailable() { return false; } | |||||
| bool isLoggedIn() { return false; } | |||||
| void logIn(const std::string&, const std::string&) {} | |||||
| void logOut() {} | |||||
| void syncUpdate(const std::string&) {} | |||||
| void syncUpdates() {} | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| /* | |||||
| * DISTRHO Cardinal Plugin | |||||
| * Copyright (C) 2021 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. | |||||
| */ | |||||
| #include <network.hpp> | |||||
| // Define the stuff needed for VCVRack but unused for Cardinal | |||||
| namespace rack { | |||||
| namespace network { | |||||
| std::string encodeUrl(const std::string&) { return {}; } | |||||
| json_t* requestJson(Method, const std::string&, json_t*, const CookieMap&) { return nullptr; } | |||||
| bool requestDownload(const std::string&, const std::string&, float*, const CookieMap&) { return false; } | |||||
| } | |||||
| } | |||||