Browse Source

Allow usage of local user dir and config

I held on for as long as I could, but plugin host caching needs it

Signed-off-by: falkTX <falktx@falktx.com>
tags/23.07
falkTX 2 years ago
parent
commit
e7bb99c3ce
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
13 changed files with 220 additions and 70 deletions
  1. +9
    -1
      include/common.hpp
  2. +0
    -0
      patches/templates/fx.vcv
  3. +0
    -0
      patches/templates/main.vcv
  4. +0
    -0
      patches/templates/mini.vcv
  5. +0
    -0
      patches/templates/native.vcv
  6. +0
    -0
      patches/templates/synth.vcv
  7. +124
    -28
      src/CardinalCommon.cpp
  8. +7
    -2
      src/CardinalCommon.hpp
  9. +20
    -22
      src/CardinalPlugin.cpp
  10. +21
    -5
      src/CardinalUI.cpp
  11. +11
    -7
      src/custom/asset.cpp
  12. +27
    -4
      src/override/MenuBar.cpp
  13. +1
    -1
      src/override/Scene.cpp

+ 9
- 1
include/common.hpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -97,3 +97,11 @@ void async_dialog_message(const char* message, std::function<void()> action);
// opens a text input dialog, message and text can be null // opens a text input dialog, message and text can be null
// action is always triggered on close (newText can be null), must be freed if not null // action is always triggered on close (newText can be null), must be freed if not null
void async_dialog_text_input(const char* message, const char* text, std::function<void(char* newText)> action); void async_dialog_text_input(const char* message, const char* text, std::function<void(char* newText)> action);

// Cardinal specific config dir (might be equal to userDir)
namespace rack {
namespace asset {
extern std::string configDir;
std::string config(std::string filename = "");
}
}

patches/init/fx.vcv → patches/templates/fx.vcv View File


patches/init/main.vcv → patches/templates/main.vcv View File


patches/init/mini.vcv → patches/templates/mini.vcv View File


patches/init/native.vcv → patches/templates/native.vcv View File


patches/init/synth.vcv → patches/templates/synth.vcv View File


+ 124
- 28
src/CardinalCommon.cpp View File

@@ -76,15 +76,15 @@
#endif #endif


#if CARDINAL_VARIANT_FX #if CARDINAL_VARIANT_FX
# define CARDINAL_TEMPLATE_NAME "init/fx.vcv"
# define CARDINAL_VARIANT_NAME "fx"
#elif CARDINAL_VARIANT_MINI #elif CARDINAL_VARIANT_MINI
# define CARDINAL_TEMPLATE_NAME "init/mini.vcv"
# define CARDINAL_VARIANT_NAME "mini"
#elif CARDINAL_VARIANT_NATIVE #elif CARDINAL_VARIANT_NATIVE
# define CARDINAL_TEMPLATE_NAME "init/native.vcv"
# define CARDINAL_VARIANT_NAME "native"
#elif CARDINAL_VARIANT_SYNTH #elif CARDINAL_VARIANT_SYNTH
# define CARDINAL_TEMPLATE_NAME "init/synth.vcv"
# define CARDINAL_VARIANT_NAME "synth"
#else #else
# define CARDINAL_TEMPLATE_NAME "init/main.vcv"
# define CARDINAL_VARIANT_NAME "main"
#endif #endif


#ifdef DISTRHO_OS_WASM #ifdef DISTRHO_OS_WASM
@@ -379,12 +379,8 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
using namespace rack; using namespace rack;


settings::allowCursorLock = false; settings::allowCursorLock = false;
settings::autoCheckUpdates = false;
settings::autosaveInterval = 0;
settings::devMode = true; settings::devMode = true;
settings::isPlugin = true; settings::isPlugin = true;
settings::skipLoadOnLaunch = true;
settings::showTipsOnLaunch = false;
settings::windowPos = math::Vec(0, 0); settings::windowPos = math::Vec(0, 0);
#ifdef HEADLESS_BEHAVIOUR #ifdef HEADLESS_BEHAVIOUR
settings::headless = true; settings::headless = true;
@@ -446,27 +442,58 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
#elif defined(ARCH_MAC) #elif defined(ARCH_MAC)
asset::systemDir = "/Library/Application Support/Cardinal"; asset::systemDir = "/Library/Application Support/Cardinal";
#elif defined(ARCH_WIN) #elif defined(ARCH_WIN)
const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles);
if (! commonprogfiles.empty())
asset::systemDir = system::join(commonprogfiles, "Cardinal");
asset::systemDir = system::join(getSpecialPath(kSpecialPathCommonProgramFiles), "Cardinal");
#else #else
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal"; asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
#endif #endif

asset::bundlePath = system::join(asset::systemDir, "PluginManifests"); asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
} }
} }
}


asset::userDir = asset::systemDir;
if (asset::userDir.empty())
{
#if defined(DISTRHO_OS_WASM)
asset::userDir = "/userfiles";
#elif defined(ARCH_MAC)
asset::userDir = system::join(homeDir(), "Documents", "Cardinal");
#elif defined(ARCH_WIN)
asset::userDir = system::join(getSpecialPath(kSpecialPathMyDocuments), "Cardinal");
#else
if (const char* const xdgEnv = getenv("XDG_DOCUMENTS_DIR"))
asset::userDir = system::join(xdgEnv, "Cardinal");
else
asset::userDir = system::join(homeDir(), "Documents", "Cardinal");
#endif
system::createDirectory(asset::userDir);
} }


#ifndef CARDINAL_COMMON_DSP_ONLY
if (asset::configDir.empty())
{
#if defined(ARCH_MAC) || defined(ARCH_WIN) || defined(DISTRHO_OS_WASM)
asset::configDir = asset::userDir;
#else
if (const char* const xdgEnv = getenv("XDG_CONFIG_HOME"))
asset::configDir = system::join(xdgEnv, "Cardinal");
else
asset::configDir = system::join(homeDir(), ".config", "Cardinal");
system::createDirectory(asset::configDir);
#endif
}
#endif
if (settings::settingsPath.empty())
settings::settingsPath = asset::config(CARDINAL_VARIANT_NAME ".json");

const std::string patchesPath = asset::patchesPath(); const std::string patchesPath = asset::patchesPath();
#ifdef DISTRHO_OS_WASM #ifdef DISTRHO_OS_WASM
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME);
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv");
factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv");
#else #else
templatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
templatePath = asset::user("templates/" CARDINAL_VARIANT_NAME ".vcv");
factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv");
#endif #endif
factoryTemplatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);


// Log environment // Log environment
INFO("%s %s %s, compatible with Rack version %s", APP_NAME.c_str(), APP_EDITION.c_str(), CARDINAL_VERSION.c_str(), APP_VERSION.c_str()); INFO("%s %s %s, compatible with Rack version %s", APP_NAME.c_str(), APP_EDITION.c_str(), CARDINAL_VERSION.c_str(), APP_VERSION.c_str());
@@ -502,6 +529,27 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB
INFO("Initializing plugin browser DB"); INFO("Initializing plugin browser DB");
app::browserInit(); app::browserInit();


if (! plugin->isDummyInstance())
{
INFO("Loading settings");
settings::load();
}
// enforce settings that do not make sense as anything else
settings::safeMode = false;
settings::token.clear();
settings::windowMaximized = false;
settings::windowPos = math::Vec(0, 0);
settings::pixelRatio = 0.0;
settings::sampleRate = 0;
settings::threadCount = 1;
settings::frameSwapInterval = 1;
settings::autosaveInterval = 0;
settings::skipLoadOnLaunch = true;
settings::autoCheckUpdates = false;
settings::showTipsOnLaunch = false;
settings::tipIndex = -1;

#ifdef CARDINAL_INIT_OSC_THREAD #ifdef CARDINAL_INIT_OSC_THREAD
INFO("Initializing OSC Remote control"); INFO("Initializing OSC Remote control");
const char* port; const char* port;
@@ -538,6 +586,9 @@ Initializer::~Initializer()
} }
#endif #endif


INFO("Save settings");
settings::save();

INFO("Clearing asset paths"); INFO("Clearing asset paths");
asset::bundlePath.clear(); asset::bundlePath.clear();
asset::systemDir.clear(); asset::systemDir.clear();
@@ -596,6 +647,8 @@ std::string getSpecialPath(const SpecialPath type)
case kSpecialPathAppData: case kSpecialPathAppData:
csidl = CSIDL_APPDATA; csidl = CSIDL_APPDATA;
break; break;
case kSpecialPathMyDocuments:
csidl = CSIDL_MYDOCUMENTS;
default: default:
return {}; return {};
} }
@@ -617,14 +670,14 @@ char* patchStorageSlug = nullptr;


std::string homeDir() std::string homeDir()
{ {
# ifdef ARCH_WIN
#ifdef ARCH_WIN
return getSpecialPath(kSpecialPathUserProfile); return getSpecialPath(kSpecialPathUserProfile);
# else
#else
if (const char* const home = getenv("HOME")) if (const char* const home = getenv("HOME"))
return home; return home;
if (struct passwd* const pwd = getpwuid(getuid())) if (struct passwd* const pwd = getpwuid(getuid()))
return pwd->pw_dir; return pwd->pw_dir;
# endif
#endif
return {}; return {};
} }


@@ -719,15 +772,38 @@ void loadSelectionDialog()
}); });
} }


void loadTemplateDialog()
void loadTemplate(const bool factory)
{ {
#ifndef HEADLESS_BEHAVIOUR
promptClear("The current patch is unsaved. Clear it and start a new patch?", []() {
APP->patch->loadTemplate();
try {
APP->patch->load(factory ? APP->patch->factoryTemplatePath : APP->patch->templatePath);
}
catch (Exception& e) {
// if user template failed, try the factory one
if (!factory)
return loadTemplate(true);


if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
if (remoteDetails->autoDeploy)
remoteUtils::sendFullPatchToRemote(remoteDetails);
const std::string message = string::f("Could not load template patch, clearing rack: %s", e.what());
asyncDialog::create(message.c_str());

APP->patch->clear();
APP->patch->clearAutosave();
}

// load() sets the patch's original patch, but we don't want to use that.
APP->patch->path.clear();
APP->history->setSaved();

if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote())
if (remoteDetails->autoDeploy)
remoteUtils::sendFullPatchToRemote(remoteDetails);
}


void loadTemplateDialog(const bool factory)
{
#ifndef HEADLESS_BEHAVIOUR
promptClear("The current patch is unsaved. Clear it and start a new patch?", [factory]() {
loadTemplate(factory);
}); });
#endif #endif
} }
@@ -772,9 +848,14 @@ static void saveAsDialog(const bool uncompressed)
{ {
std::string dir; std::string dir;
if (! APP->patch->path.empty()) if (! APP->patch->path.empty())
{
dir = system::getDirectory(APP->patch->path); dir = system::getDirectory(APP->patch->path);
}
else else
dir = homeDir();
{
dir = asset::user("patches");
system::createDirectories(dir);
}


CardinalPluginContext* const pcontext = static_cast<CardinalPluginContext*>(APP); CardinalPluginContext* const pcontext = static_cast<CardinalPluginContext*>(APP);
DISTRHO_SAFE_ASSERT_RETURN(pcontext != nullptr,); DISTRHO_SAFE_ASSERT_RETURN(pcontext != nullptr,);
@@ -806,6 +887,21 @@ void saveAsDialogUncompressed()
#endif #endif
} }


void saveTemplateDialog()
{
asyncDialog::create("Overwrite template patch?", []{
rack::system::createDirectories(system::getDirectory(APP->patch->templatePath));

try {
APP->patch->save(APP->patch->templatePath);
}
catch (Exception& e) {
asyncDialog::create(string::f("Could not save template patch: %s", e.what()).c_str());
return;
}
});
}

void openBrowser(const std::string& url) void openBrowser(const std::string& url)
{ {
#ifdef DISTRHO_OS_WASM #ifdef DISTRHO_OS_WASM


+ 7
- 2
src/CardinalCommon.hpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -44,6 +44,7 @@ enum SpecialPath {
kSpecialPathCommonProgramFiles, kSpecialPathCommonProgramFiles,
kSpecialPathProgramFiles, kSpecialPathProgramFiles,
kSpecialPathAppData, kSpecialPathAppData,
kSpecialPathMyDocuments,
}; };
std::string getSpecialPath(SpecialPath type); std::string getSpecialPath(SpecialPath type);
#endif #endif
@@ -54,6 +55,8 @@ extern char* patchRemoteURL;
extern char* patchStorageSlug; extern char* patchStorageSlug;
#endif #endif


std::string homeDir();

} // namespace rack } // namespace rack


// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
@@ -63,11 +66,13 @@ namespace patchUtils {
void loadDialog(); void loadDialog();
void loadPathDialog(const std::string& path, bool asTemplate = false); void loadPathDialog(const std::string& path, bool asTemplate = false);
void loadSelectionDialog(); void loadSelectionDialog();
void loadTemplateDialog();
void loadTemplate(bool factory);
void loadTemplateDialog(bool factory);
void revertDialog(); void revertDialog();
void saveDialog(const std::string& path); void saveDialog(const std::string& path);
void saveAsDialog(); void saveAsDialog();
void saveAsDialogUncompressed(); void saveAsDialogUncompressed();
void saveTemplateDialog();
void appendSelectionContextMenu(rack::ui::Menu* menu); void appendSelectionContextMenu(rack::ui::Menu* menu);
void openBrowser(const std::string& url); void openBrowser(const std::string& url);




+ 20
- 22
src/CardinalPlugin.cpp View File

@@ -198,20 +198,20 @@ public:
fWasBypassed(false) fWasBypassed(false)
{ {
#if CARDINAL_VARIANT_MINI || !defined(HEADLESS) #if CARDINAL_VARIANT_MINI || !defined(HEADLESS)
fWindowParameters[kWindowParameterShowTooltips] = 1.0f;
fWindowParameters[kWindowParameterCableOpacity] = 50.0f;
fWindowParameters[kWindowParameterCableTension] = 75.0f;
fWindowParameters[kWindowParameterRackBrightness] = 100.0f;
fWindowParameters[kWindowParameterHaloBrightness] = 25.0f;
fWindowParameters[kWindowParameterShowTooltips] = rack::settings::tooltips ? 1.f : 0.f;
fWindowParameters[kWindowParameterCableOpacity] = std::min(100.f, std::max(0.f, rack::settings::cableOpacity * 100));
fWindowParameters[kWindowParameterCableTension] = std::min(100.f, std::max(0.f, rack::settings::cableTension * 100));
fWindowParameters[kWindowParameterRackBrightness] = std::min(100.f, std::max(0.f, rack::settings::rackBrightness * 100));
fWindowParameters[kWindowParameterHaloBrightness] = std::min(100.f, std::max(0.f, rack::settings::haloBrightness * 100));
fWindowParameters[kWindowParameterKnobMode] = 0.0f; fWindowParameters[kWindowParameterKnobMode] = 0.0f;
fWindowParameters[kWindowParameterWheelKnobControl] = 0.0f;
fWindowParameters[kWindowParameterWheelSensitivity] = 1.0f;
fWindowParameters[kWindowParameterLockModulePositions] = 0.0f;
fWindowParameters[kWindowParameterWheelKnobControl] = rack::settings::knobScroll ? 1.f : 0.f;
fWindowParameters[kWindowParameterWheelSensitivity] = std::min(10.f, std::max(0.1f, rack::settings::knobScrollSensitivity * 1000));
fWindowParameters[kWindowParameterLockModulePositions] = rack::settings::lockModules ? 1.f : 0.f;
fWindowParameters[kWindowParameterUpdateRateLimit] = 0.0f; fWindowParameters[kWindowParameterUpdateRateLimit] = 0.0f;
fWindowParameters[kWindowParameterBrowserSort] = 3.0f; fWindowParameters[kWindowParameterBrowserSort] = 3.0f;
fWindowParameters[kWindowParameterBrowserZoom] = 50.0f; fWindowParameters[kWindowParameterBrowserZoom] = 50.0f;
fWindowParameters[kWindowParameterInvertZoom] = 0.0f;
fWindowParameters[kWindowParameterSqueezeModulePositions] = 1.0f;
fWindowParameters[kWindowParameterInvertZoom] = rack::settings::invertZoom ? 1.f : 0.f;
fWindowParameters[kWindowParameterSqueezeModulePositions] = rack::settings::squeezeModules ? 1.f : 0.f;
#endif #endif
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
std::memset(fMiniReportValues, 0, sizeof(fMiniReportValues)); std::memset(fMiniReportValues, 0, sizeof(fMiniReportValues));
@@ -283,8 +283,6 @@ public:
{ {
context->patch->loadTemplate(); context->patch->loadTemplate();
context->scene->rackScroll->reset(); context->scene->rackScroll->reset();
// swap to factory template after first load
context->patch->templatePath = context->patch->factoryTemplatePath;
} }
#ifdef CARDINAL_INIT_OSC_THREAD #ifdef CARDINAL_INIT_OSC_THREAD
@@ -463,7 +461,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 1.0f;
parameter.ranges.def = rack::settings::tooltips ? 1.f : 0.f;
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f; parameter.ranges.max = 1.0f;
break; break;
@@ -475,7 +473,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 50.0f;
parameter.ranges.def = std::min(100.f, std::max(0.f, rack::settings::cableOpacity * 100));
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 100.0f; parameter.ranges.max = 100.0f;
break; break;
@@ -487,7 +485,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 75.0f;
parameter.ranges.def = std::min(100.f, std::max(0.f, rack::settings::cableTension * 100));
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 100.0f; parameter.ranges.max = 100.0f;
break; break;
@@ -499,7 +497,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 100.0f;
parameter.ranges.def = std::min(100.f, std::max(0.f, rack::settings::rackBrightness * 100));
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 100.0f; parameter.ranges.max = 100.0f;
break; break;
@@ -511,7 +509,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 25.0f;
parameter.ranges.def = std::min(100.f, std::max(0.f, rack::settings::haloBrightness * 100));
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 100.0f; parameter.ranges.max = 100.0f;
break; break;
@@ -542,7 +540,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 0.0f;
parameter.ranges.def = rack::settings::knobScroll ? 1.f : 0.f;
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f; parameter.ranges.max = 1.0f;
break; break;
@@ -553,7 +551,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 1.0f;
parameter.ranges.def = std::min(10.f, std::max(0.1f, rack::settings::knobScrollSensitivity * 1000));
parameter.ranges.min = 0.1f; parameter.ranges.min = 0.1f;
parameter.ranges.max = 10.0f; parameter.ranges.max = 10.0f;
break; break;
@@ -564,7 +562,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 0.0f;
parameter.ranges.def = rack::settings::lockModules ? 1.f : 0.f;
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f; parameter.ranges.max = 1.0f;
break; break;
@@ -650,7 +648,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 0.0f;
parameter.ranges.def = rack::settings::invertZoom ? 1.f : 0.f;
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f; parameter.ranges.max = 1.0f;
break; break;
@@ -661,7 +659,7 @@ protected:
#if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if CARDINAL_VARIANT_MINI && ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
parameter.hints |= kParameterIsHidden; parameter.hints |= kParameterIsHidden;
#endif #endif
parameter.ranges.def = 1.0f;
parameter.ranges.def = rack::settings::squeezeModules ? 1.f : 0.f;
parameter.ranges.min = 0.0f; parameter.ranges.min = 0.0f;
parameter.ranges.max = 1.0f; parameter.ranges.max = 1.0f;
break; break;


+ 21
- 5
src/CardinalUI.cpp View File

@@ -277,8 +277,8 @@ static void downloadRemotePatchSucceeded(const char* const filename)
return; return;
} }


context->patch->path.clear();
context->scene->rackScroll->reset(); context->scene->rackScroll->reset();
context->patch->path = "";
context->history->setSaved(); context->history->setSaved();
} }
#endif #endif
@@ -415,8 +415,16 @@ public:


setGeometryConstraints(648 * scaleFactor, 538 * scaleFactor); setGeometryConstraints(648 * scaleFactor, 538 * scaleFactor);


if (scaleFactor != 1.0)
if (rack::isStandalone() && rack::system::exists(rack::settings::settingsPath))
{
const double width = std::max(648.f, rack::settings::windowSize.x) * scaleFactor;
const double height = std::max(538.f, rack::settings::windowSize.y) * scaleFactor;
setSize(width, height);
}
else if (scaleFactor != 1.0)
{
setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor); setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor);
}


rack::window::WindowSetPluginUI(context->window, this); rack::window::WindowSetPluginUI(context->window, this);


@@ -1137,10 +1145,15 @@ protected:
WindowSetInternalSize(context->window, rack::math::Vec(ev.size.getWidth(), ev.size.getHeight())); WindowSetInternalSize(context->window, rack::math::Vec(ev.size.getWidth(), ev.size.getHeight()));


const double scaleFactor = getScaleFactor(); const double scaleFactor = getScaleFactor();
char sizeString[64];
std::snprintf(sizeString, sizeof(sizeString), "%d:%d",
(int)(ev.size.getWidth() / scaleFactor), (int)(ev.size.getHeight() / scaleFactor));
const int width = static_cast<int>(ev.size.getWidth() / scaleFactor + 0.5);
const int height = static_cast<int>(ev.size.getHeight() / scaleFactor + 0.5);

char sizeString[64] = {};
std::snprintf(sizeString, sizeof(sizeString), "%d:%d", width, height);
setState("windowSize", sizeString); setState("windowSize", sizeString);

if (rack::isStandalone())
rack::settings::windowSize = rack::math::Vec(width, height);
} }


void uiFocus(const bool focus, CrossingMode) override void uiFocus(const bool focus, CrossingMode) override
@@ -1212,7 +1225,10 @@ protected:
} }


context->patch->path = sfilename; context->patch->path = sfilename;
context->patch->pushRecentPath(sfilename);
context->history->setSaved(); context->history->setSaved();

rack::settings::save();
} }


#if 0 #if 0


+ 11
- 7
src/custom/asset.cpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -36,10 +36,19 @@ extern bool forceBlackScrew;
extern bool forceSilverScrew; extern bool forceSilverScrew;
#endif #endif


std::string userDir; // ignored
std::string configDir; // points to writable config dir (might be equal to userDir)
std::string userDir; // points to common writable dir
std::string systemDir; // points to plugin resources dir (or installed/local Rack dir) std::string systemDir; // points to plugin resources dir (or installed/local Rack dir)
std::string bundlePath; // points to plugin manifests dir (or empty) std::string bundlePath; // points to plugin manifests dir (or empty)


std::string config(std::string filename) {
return system::join(configDir, filename);
}

std::string user(std::string filename) {
return system::join(userDir, filename);
}

// get rid of "res/" prefix // get rid of "res/" prefix
static inline std::string& trim(std::string& s) static inline std::string& trim(std::string& s)
{ {
@@ -48,11 +57,6 @@ static inline std::string& trim(std::string& s)
return s; 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 // get system resource, trimming "res/" prefix if we are loaded as a plugin bundle
std::string system(std::string filename) { std::string system(std::string filename) {
#ifndef HEADLESS #ifndef HEADLESS


+ 27
- 4
src/override/MenuBar.cpp View File

@@ -1,6 +1,6 @@
/* /*
* DISTRHO Cardinal Plugin * DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@@ -127,20 +127,33 @@ struct FileButton : MenuButton {
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));


#ifndef DISTRHO_OS_WASM #ifndef DISTRHO_OS_WASM
const char* const NewShortcut = RACK_MOD_CTRL_NAME "+N";
constexpr const char* const NewShortcut = RACK_MOD_CTRL_NAME "+N";
#else #else
const char* const NewShortcut = "";
constexpr const char* const NewShortcut = "";
#endif #endif
menu->addChild(createMenuItem("New", NewShortcut, []() { menu->addChild(createMenuItem("New", NewShortcut, []() {
patchUtils::loadTemplateDialog();
patchUtils::loadTemplateDialog(false);
})); }));


#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
#ifndef DISTRHO_OS_WASM #ifndef DISTRHO_OS_WASM
menu->addChild(createMenuItem("New (factory template)", "", []() {
patchUtils::loadTemplateDialog(true);
}));

menu->addChild(createMenuItem("Open / Import...", RACK_MOD_CTRL_NAME "+O", []() { menu->addChild(createMenuItem("Open / Import...", RACK_MOD_CTRL_NAME "+O", []() {
patchUtils::loadDialog(); patchUtils::loadDialog();
})); }));


menu->addChild(createSubmenuItem("Open recent", "", [](ui::Menu* menu) {
for (const std::string& path : settings::recentPatchPaths) {
std::string name = system::getStem(path);
menu->addChild(createMenuItem(name, "", [=]() {
patchUtils::loadPathDialog(path, false);
}));
}
}, settings::recentPatchPaths.empty()));

menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() { menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
// NOTE: will do nothing if path is empty, intentionally // NOTE: will do nothing if path is empty, intentionally
patchUtils::saveDialog(APP->patch->path); patchUtils::saveDialog(APP->patch->path);
@@ -172,6 +185,10 @@ struct FileButton : MenuButton {
patchUtils::revertDialog(); patchUtils::revertDialog();
}, APP->patch->path.empty())); }, APP->patch->path.empty()));


menu->addChild(createMenuItem("Overwrite template", "", []() {
patchUtils::saveTemplateDialog();
}));

#if defined(HAVE_LIBLO) || ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS #if defined(HAVE_LIBLO) || ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
#ifdef __MOD_DEVICES__ #ifdef __MOD_DEVICES__
#define REMOTE_NAME "MOD" #define REMOTE_NAME "MOD"
@@ -728,6 +745,12 @@ struct HelpButton : MenuButton {


menu->addChild(new ui::MenuSeparator); menu->addChild(new ui::MenuSeparator);


menu->addChild(createMenuItem("Open user folder", "", [=]() {
system::openDirectory(asset::user(""));
}));

menu->addChild(new ui::MenuSeparator);

menu->addChild(createMenuLabel("Cardinal " + APP_EDITION + " " + CARDINAL_VERSION)); menu->addChild(createMenuLabel("Cardinal " + APP_EDITION + " " + CARDINAL_VERSION));
menu->addChild(createMenuLabel("Rack " + APP_VERSION + " Compatible")); menu->addChild(createMenuLabel("Rack " + APP_VERSION + " Compatible"));
} }


+ 1
- 1
src/override/Scene.cpp View File

@@ -261,7 +261,7 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { 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()); // 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) { if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
patchUtils::loadTemplateDialog();
patchUtils::loadTemplateDialog(false);
e.consume(this); e.consume(this);
} }
if (e.keyName == "q" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { if (e.keyName == "q" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {


Loading…
Cancel
Save