Reorder file menu, use input text for remote url
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
09921e2c28
commit
cf45ff62fc
5 changed files with 97 additions and 54 deletions
|
@ -38,8 +38,6 @@
|
|||
|
||||
#ifdef HAVE_LIBLO
|
||||
# include <lo/lo.h>
|
||||
// # 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<CardinalPluginContext*>(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<lo_server>(remote->handle));
|
||||
#endif
|
||||
std::free(const_cast<char*>(remote->url));
|
||||
delete remote;
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +160,7 @@ void sendParamChangeToRemote(RemoteDetails* const remote, int64_t moduleId, int
|
|||
}
|
||||
static_cast<CardinalBaseUI*>(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<uint8_t> data(d_getChunkFromBase64String(screenshot));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
* 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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<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) {
|
||||
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(); 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...", "", [=]() {
|
||||
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,39 +300,22 @@ 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
|
||||
}
|
||||
#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/");
|
||||
}));
|
||||
}));
|
||||
}
|
||||
|
||||
#ifndef DISTRHO_OS_WASM
|
||||
if (isStandalone) {
|
||||
menu->addChild(new ui::MenuSeparator);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue