From cf45ff62fca5c1876fa308492ceacf40a2f6ab95 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 22 May 2023 17:31:51 +0200 Subject: [PATCH] Reorder file menu, use input text for remote url Signed-off-by: falkTX --- src/CardinalRemote.cpp | 32 +++++++------ src/CardinalRemote.hpp | 8 ++-- src/CardinalUI.cpp | 2 +- src/override/MenuBar.cpp | 100 ++++++++++++++++++++++++++------------- src/override/Scene.cpp | 9 +++- 5 files changed, 97 insertions(+), 54 deletions(-) diff --git a/src/CardinalRemote.cpp b/src/CardinalRemote.cpp index d27f16b..c795137 100644 --- a/src/CardinalRemote.cpp +++ b/src/CardinalRemote.cpp @@ -38,8 +38,6 @@ #ifdef HAVE_LIBLO # include -// # define REMOTE_HOST "localhost" -# define REMOTE_HOST "192.168.51.1" #endif // ----------------------------------------------------------------------------------------------------------- @@ -77,7 +75,7 @@ RemoteDetails* getRemote() #endif } -bool connectToRemote() +bool connectToRemote(const char* const url) { #ifdef CARDINAL_REMOTE_ENABLED CardinalPluginContext* const context = static_cast(APP); @@ -93,10 +91,14 @@ bool connectToRemote() { ui->remoteDetails = remoteDetails = new RemoteDetails; remoteDetails->handle = ui; + remoteDetails->url = strdup(url); remoteDetails->connected = true; remoteDetails->autoDeploy = true; } #elif defined(HAVE_LIBLO) + const lo_address addr = lo_address_new_from_url(url); + DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr, false); + if (remoteDetails == nullptr) { const lo_server oscServer = lo_server_new_with_proto(nullptr, LO_UDP, nullptr); @@ -104,20 +106,21 @@ bool connectToRemote() ui->remoteDetails = remoteDetails = new RemoteDetails; remoteDetails->handle = oscServer; + remoteDetails->url = strdup(url); remoteDetails->connected = false; remoteDetails->autoDeploy = false; lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails); } - - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); - DISTRHO_SAFE_ASSERT(addr != nullptr); - - if (addr != nullptr) + else if (std::strcmp(remoteDetails->url, url) != 0) { - lo_send(addr, "/hello", ""); - lo_address_free(addr); + ui->remoteDetails = nullptr; + disconnectFromRemote(remoteDetails); + return connectToRemote(url); } + + lo_send(addr, "/hello", ""); + lo_address_free(addr); #endif return remoteDetails != nullptr; @@ -133,6 +136,7 @@ void disconnectFromRemote(RemoteDetails* const remote) #ifdef HAVE_LIBLO lo_server_free(static_cast(remote->handle)); #endif + std::free(const_cast(remote->url)); delete remote; } } @@ -156,7 +160,7 @@ void sendParamChangeToRemote(RemoteDetails* const remote, int64_t moduleId, int } static_cast(remote->handle)->setState("param", paramBuf); #elif defined(HAVE_LIBLO) - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); + const lo_address addr = lo_address_new_from_url(remote->url); DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); lo_send(addr, "/param", "hif", moduleId, paramId, value); @@ -205,7 +209,7 @@ void sendFullPatchToRemote(RemoteDetails* const remote) DISTRHO_SAFE_ASSERT_RETURN(data.size() >= 4,); - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); + const lo_address addr = lo_address_new_from_url(remote->url); DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); if (const lo_blob blob = lo_blob_new(data.size(), data.data())) @@ -219,10 +223,10 @@ void sendFullPatchToRemote(RemoteDetails* const remote) #endif } -void sendScreenshotToRemote(RemoteDetails*, const char* const screenshot) +void sendScreenshotToRemote(RemoteDetails* const remote, const char* const screenshot) { #if defined(HAVE_LIBLO) && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, CARDINAL_DEFAULT_REMOTE_HOST_PORT); + const lo_address addr = lo_address_new_from_url(remote->url); DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); std::vector data(d_getChunkFromBase64String(screenshot)); diff --git a/src/CardinalRemote.hpp b/src/CardinalRemote.hpp index e45c569..a639120 100644 --- a/src/CardinalRemote.hpp +++ b/src/CardinalRemote.hpp @@ -1,6 +1,6 @@ /* * DISTRHO Cardinal Plugin - * Copyright (C) 2021-2022 Filipe Coelho + * Copyright (C) 2021-2023 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,7 +17,8 @@ #pragma once -#define CARDINAL_DEFAULT_REMOTE_HOST_PORT "2228" +// #define CARDINAL_DEFAULT_REMOTE_URL "osc.udp://localhost:2228" +#define CARDINAL_DEFAULT_REMOTE_URL "osc.udp://192.168.51.1:2228" // ----------------------------------------------------------------------------------------------------------- @@ -25,12 +26,13 @@ namespace remoteUtils { struct RemoteDetails { void* handle; + const char* url; bool connected; bool autoDeploy; }; RemoteDetails* getRemote(); -bool connectToRemote(); +bool connectToRemote(const char* url); void disconnectFromRemote(RemoteDetails* remote); void idleRemote(RemoteDetails* remote); void sendParamChangeToRemote(RemoteDetails* remote, int64_t moduleId, int paramId, float value); diff --git a/src/CardinalUI.cpp b/src/CardinalUI.cpp index f5131f4..af71530 100644 --- a/src/CardinalUI.cpp +++ b/src/CardinalUI.cpp @@ -406,7 +406,7 @@ public: context->patch->loadTemplate(); context->scene->rackScroll->reset(); - DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote()); + DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote(CARDINAL_DEFAULT_REMOTE_URL)); Engine_setRemoteDetails(context->engine, remoteDetails); #endif diff --git a/src/override/MenuBar.cpp b/src/override/MenuBar.cpp index d273997..caabe5b 100644 --- a/src/override/MenuBar.cpp +++ b/src/override/MenuBar.cpp @@ -115,10 +115,15 @@ struct FileButton : MenuButton { async_dialog_text_input("Filename", nullptr, [](char* const filename) { if (filename == nullptr) return; - APP->patch->path = "/userfiles/"; + + APP->patch->path = asset::user("patches"); + system::createDirectories(APP->patch->path); + + APP->patch->path += DISTRHO_OS_SEP_STR; APP->patch->path += filename; if (rack::system::getExtension(filename) != ".vcv") APP->patch->path += ".vcv"; + patchUtils::saveDialog(APP->patch->path); std::free(filename); }); @@ -161,11 +166,28 @@ struct FileButton : MenuButton { menu->addChild(createMenuItem("New (factory template)", "", []() { patchUtils::loadTemplateDialog(true); })); +#endif - menu->addChild(createMenuItem("Open / Import...", RACK_MOD_CTRL_NAME "+O", []() { +#ifndef DISTRHO_OS_WASM + constexpr const char* const OpenName = "Open..."; +#else + constexpr const char* const OpenName = "Import patch..."; +#endif + menu->addChild(createMenuItem(OpenName, RACK_MOD_CTRL_NAME "+O", []() { patchUtils::loadDialog(); })); + const std::string patchesDir = asset::user("patches"); + const std::vector patches = system::isDirectory(patchesDir) ? system::getEntries(patchesDir) : std::vector(); + menu->addChild(createSubmenuItem("Open local patch", "", [patches](ui::Menu* menu) { + for (const std::string& path : patches) { + std::string name = system::getStem(path); + menu->addChild(createMenuItem(name, "", [=]() { + patchUtils::loadPathDialog(path, false); + })); + } + }, patches.empty())); + menu->addChild(createSubmenuItem("Open recent", "", [](ui::Menu* menu) { for (const std::string& path : settings::recentPatchPaths) { std::string name = system::getStem(path); @@ -175,15 +197,42 @@ struct FileButton : MenuButton { } }, settings::recentPatchPaths.empty())); + if (!demoPatches.empty()) + { + menu->addChild(createSubmenuItem("Open demo / example project", "", [=](ui::Menu* const menu) { + for (std::string path : demoPatches) { + std::string label = system::getStem(path); + + for (size_t i=0, len=label.size(); iaddChild(createMenuItem(label, "", [path]() { + patchUtils::loadPathDialog(path, true); + })); + } + + menu->addChild(new ui::MenuSeparator); + + menu->addChild(createMenuItem("Open patchstorage.com for more patches", "", []() { + patchUtils::openBrowser("https://patchstorage.com/platform/cardinal/"); + })); + })); + } + menu->addChild(createMenuItem("Import selection...", "", [=]() { patchUtils::loadSelectionDialog(); }, false, true)); +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + menu->addChild(new ui::MenuSeparator); + #ifndef DISTRHO_OS_WASM menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() { - // NOTE: will do nothing if path is empty, intentionally + // NOTE: for plugin versions it will do nothing if path is empty, intentionally patchUtils::saveDialog(APP->patch->path); - }, APP->patch->path.empty())); + }, APP->patch->path.empty() && !isStandalone)); menu->addChild(createMenuItem("Save as / Export...", RACK_MOD_CTRL_NAME "+Shift+S", []() { patchUtils::saveAsDialog(); @@ -196,11 +245,11 @@ struct FileButton : MenuButton { patchUtils::saveDialog(APP->patch->path); })); - menu->addChild(createMenuItem("Save as", "", []() { + menu->addChild(createMenuItem("Save as...", "", []() { wasmSaveAs(); })); - menu->addChild(createMenuItem("Save and download compressed", RACK_MOD_CTRL_NAME "+Shift+S", []() { + menu->addChild(createMenuItem("Save and download compressed", "", []() { patchUtils::saveAsDialog(); })); @@ -251,38 +300,21 @@ struct FileButton : MenuButton { Engine_setRemoteDetails(APP->engine, remoteDetails->autoDeploy ? remoteDetails : nullptr); } )); +#ifndef __MOD_DEVICES__ } else { - menu->addChild(createMenuItem("Connect to " REMOTE_NAME, "", []() { - DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote()); + menu->addChild(createMenuItem("Connect to " REMOTE_NAME "...", "", [remoteDetails]() { + const std::string url = remoteDetails != nullptr ? remoteDetails->url : CARDINAL_DEFAULT_REMOTE_URL; + async_dialog_text_input("Remote:", url.c_str(), [](char* const url) { + if (url == nullptr) + return; + + DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote(url)); + std::free(url); + }); })); - } #endif - - if (!demoPatches.empty()) - { - menu->addChild(new ui::MenuSeparator); - - menu->addChild(createSubmenuItem("Open Demo / Example project", "", [=](ui::Menu* const menu) { - for (std::string path : demoPatches) { - std::string label = system::getStem(path); - - for (size_t i=0, len=label.size(); iaddChild(createMenuItem(label, "", [path]() { - patchUtils::loadPathDialog(path, true); - })); - } - - menu->addChild(new ui::MenuSeparator); - - menu->addChild(createMenuItem("Open PatchStorage.com for more patches", "", []() { - patchUtils::openBrowser("https://patchstorage.com/platform/cardinal/"); - })); - })); } +#endif #ifndef DISTRHO_OS_WASM if (isStandalone) { diff --git a/src/override/Scene.cpp b/src/override/Scene.cpp index 5ddf14d..07976df 100644 --- a/src/override/Scene.cpp +++ b/src/override/Scene.cpp @@ -277,8 +277,13 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { e.consume(this); } if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { - // NOTE: will do nothing if path is empty, intentionally - patchUtils::saveDialog(APP->patch->path); + // NOTE: for plugin versions it will do nothing if path is empty, intentionally + if (APP->patch->path.empty()) { + if (isStandalone()) + patchUtils::saveAsDialog(); + } else { + patchUtils::saveDialog(APP->patch->path); + } e.consume(this); } if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {