Browse Source

Reorder file menu, use input text for remote url

Signed-off-by: falkTX <falktx@falktx.com>
tags/23.07
falkTX 2 years ago
parent
commit
cf45ff62fc
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
5 changed files with 97 additions and 54 deletions
  1. +18
    -14
      src/CardinalRemote.cpp
  2. +5
    -3
      src/CardinalRemote.hpp
  3. +1
    -1
      src/CardinalUI.cpp
  4. +66
    -34
      src/override/MenuBar.cpp
  5. +7
    -2
      src/override/Scene.cpp

+ 18
- 14
src/CardinalRemote.cpp View File

@@ -38,8 +38,6 @@


#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
# include <lo/lo.h> # include <lo/lo.h>
// # define REMOTE_HOST "localhost"
# define REMOTE_HOST "192.168.51.1"
#endif #endif


// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------
@@ -77,7 +75,7 @@ RemoteDetails* getRemote()
#endif #endif
} }


bool connectToRemote()
bool connectToRemote(const char* const url)
{ {
#ifdef CARDINAL_REMOTE_ENABLED #ifdef CARDINAL_REMOTE_ENABLED
CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP); CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP);
@@ -93,10 +91,14 @@ bool connectToRemote()
{ {
ui->remoteDetails = remoteDetails = new RemoteDetails; ui->remoteDetails = remoteDetails = new RemoteDetails;
remoteDetails->handle = ui; remoteDetails->handle = ui;
remoteDetails->url = strdup(url);
remoteDetails->connected = true; remoteDetails->connected = true;
remoteDetails->autoDeploy = true; remoteDetails->autoDeploy = true;
} }
#elif defined(HAVE_LIBLO) #elif defined(HAVE_LIBLO)
const lo_address addr = lo_address_new_from_url(url);
DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr, false);

if (remoteDetails == nullptr) if (remoteDetails == nullptr)
{ {
const lo_server oscServer = lo_server_new_with_proto(nullptr, LO_UDP, 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; ui->remoteDetails = remoteDetails = new RemoteDetails;
remoteDetails->handle = oscServer; remoteDetails->handle = oscServer;
remoteDetails->url = strdup(url);
remoteDetails->connected = false; remoteDetails->connected = false;
remoteDetails->autoDeploy = false; remoteDetails->autoDeploy = false;


lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails); 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 #endif


return remoteDetails != nullptr; return remoteDetails != nullptr;
@@ -133,6 +136,7 @@ void disconnectFromRemote(RemoteDetails* const remote)
#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
lo_server_free(static_cast<lo_server>(remote->handle)); lo_server_free(static_cast<lo_server>(remote->handle));
#endif #endif
std::free(const_cast<char*>(remote->url));
delete remote; delete remote;
} }
} }
@@ -156,7 +160,7 @@ void sendParamChangeToRemote(RemoteDetails* const remote, int64_t moduleId, int
} }
static_cast<CardinalBaseUI*>(remote->handle)->setState("param", paramBuf); static_cast<CardinalBaseUI*>(remote->handle)->setState("param", paramBuf);
#elif defined(HAVE_LIBLO) #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,); DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,);


lo_send(addr, "/param", "hif", moduleId, paramId, value); lo_send(addr, "/param", "hif", moduleId, paramId, value);
@@ -205,7 +209,7 @@ void sendFullPatchToRemote(RemoteDetails* const remote)


DISTRHO_SAFE_ASSERT_RETURN(data.size() >= 4,); 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,); DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,);


if (const lo_blob blob = lo_blob_new(data.size(), data.data())) if (const lo_blob blob = lo_blob_new(data.size(), data.data()))
@@ -219,10 +223,10 @@ void sendFullPatchToRemote(RemoteDetails* const remote)
#endif #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 #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,); DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,);


std::vector<uint8_t> data(d_getChunkFromBase64String(screenshot)); std::vector<uint8_t> data(d_getChunkFromBase64String(screenshot));


+ 5
- 3
src/CardinalRemote.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
@@ -17,7 +17,8 @@


#pragma once #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 { struct RemoteDetails {
void* handle; void* handle;
const char* url;
bool connected; bool connected;
bool autoDeploy; bool autoDeploy;
}; };


RemoteDetails* getRemote(); RemoteDetails* getRemote();
bool connectToRemote();
bool connectToRemote(const char* url);
void disconnectFromRemote(RemoteDetails* remote); void disconnectFromRemote(RemoteDetails* remote);
void idleRemote(RemoteDetails* remote); void idleRemote(RemoteDetails* remote);
void sendParamChangeToRemote(RemoteDetails* remote, int64_t moduleId, int paramId, float value); void sendParamChangeToRemote(RemoteDetails* remote, int64_t moduleId, int paramId, float value);


+ 1
- 1
src/CardinalUI.cpp View File

@@ -406,7 +406,7 @@ public:
context->patch->loadTemplate(); context->patch->loadTemplate();
context->scene->rackScroll->reset(); context->scene->rackScroll->reset();


DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote());
DISTRHO_SAFE_ASSERT(remoteUtils::connectToRemote(CARDINAL_DEFAULT_REMOTE_URL));


Engine_setRemoteDetails(context->engine, remoteDetails); Engine_setRemoteDetails(context->engine, remoteDetails);
#endif #endif


+ 66
- 34
src/override/MenuBar.cpp View File

@@ -115,10 +115,15 @@ struct FileButton : MenuButton {
async_dialog_text_input("Filename", nullptr, [](char* const filename) { async_dialog_text_input("Filename", nullptr, [](char* const filename) {
if (filename == nullptr) if (filename == nullptr)
return; 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; APP->patch->path += filename;
if (rack::system::getExtension(filename) != ".vcv") if (rack::system::getExtension(filename) != ".vcv")
APP->patch->path += ".vcv"; APP->patch->path += ".vcv";

patchUtils::saveDialog(APP->patch->path); patchUtils::saveDialog(APP->patch->path);
std::free(filename); std::free(filename);
}); });
@@ -161,11 +166,28 @@ struct FileButton : MenuButton {
menu->addChild(createMenuItem("New (factory template)", "", []() { menu->addChild(createMenuItem("New (factory template)", "", []() {
patchUtils::loadTemplateDialog(true); 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(); patchUtils::loadDialog();
})); }));


const std::string patchesDir = asset::user("patches");
const std::vector<std::string> patches = system::isDirectory(patchesDir) ? system::getEntries(patchesDir) : std::vector<std::string>();
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) { menu->addChild(createSubmenuItem("Open recent", "", [](ui::Menu* menu) {
for (const std::string& path : settings::recentPatchPaths) { for (const std::string& path : settings::recentPatchPaths) {
std::string name = system::getStem(path); std::string name = system::getStem(path);
@@ -175,15 +197,42 @@ struct FileButton : MenuButton {
} }
}, settings::recentPatchPaths.empty())); }, 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(); i<len; ++i) {
if (label[i] == '_')
label[i] = ' ';
}

menu->addChild(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...", "", [=]() { menu->addChild(createMenuItem("Import selection...", "", [=]() {
patchUtils::loadSelectionDialog(); patchUtils::loadSelectionDialog();
}, false, true)); }, false, true));


#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
menu->addChild(new ui::MenuSeparator);

#ifndef DISTRHO_OS_WASM #ifndef DISTRHO_OS_WASM
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: for plugin versions it will do nothing if path is empty, intentionally
patchUtils::saveDialog(APP->patch->path); 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", []() { menu->addChild(createMenuItem("Save as / Export...", RACK_MOD_CTRL_NAME "+Shift+S", []() {
patchUtils::saveAsDialog(); patchUtils::saveAsDialog();
@@ -196,11 +245,11 @@ struct FileButton : MenuButton {
patchUtils::saveDialog(APP->patch->path); patchUtils::saveDialog(APP->patch->path);
})); }));


menu->addChild(createMenuItem("Save as", "", []() {
menu->addChild(createMenuItem("Save as...", "", []() {
wasmSaveAs(); wasmSaveAs();
})); }));


menu->addChild(createMenuItem("Save and download compressed", RACK_MOD_CTRL_NAME "+Shift+S", []() {
menu->addChild(createMenuItem("Save and download compressed", "", []() {
patchUtils::saveAsDialog(); patchUtils::saveAsDialog();
})); }));


@@ -251,38 +300,21 @@ struct FileButton : MenuButton {
Engine_setRemoteDetails(APP->engine, remoteDetails->autoDeploy ? remoteDetails : nullptr); Engine_setRemoteDetails(APP->engine, remoteDetails->autoDeploy ? remoteDetails : nullptr);
} }
)); ));
#ifndef __MOD_DEVICES__
} else { } 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 #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(); i<len; ++i) {
if (label[i] == '_')
label[i] = ' ';
}

menu->addChild(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 #ifndef DISTRHO_OS_WASM
if (isStandalone) { if (isStandalone) {


+ 7
- 2
src/override/Scene.cpp View File

@@ -277,8 +277,13 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
e.consume(this); e.consume(this);
} }
if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { 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); e.consume(this);
} }
if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {


Loading…
Cancel
Save