Skip to content

Commit

Permalink
local tree: allow copy-paste of local tree address of inlets and objects
Browse files Browse the repository at this point in the history
  • Loading branch information
jcelerier committed Jan 13, 2025
1 parent 5a67b13 commit 40d0f1c
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class SCORE_LIB_PROCESS_EXPORT ProcessComponent
ABSTRACT_COMPONENT_METADATA(
LocalTree::ProcessComponent, "0732ab51-a052-4e2e-a1f7-9bf2926c199c")
public:
static constexpr bool is_unique = true;
ProcessComponent(
ossia::net::node_base& node, Process::ProcessModel& proc,
const score::DocumentContext& doc, const QString& name, QObject* parent);
Expand Down
16 changes: 15 additions & 1 deletion src/plugins/score-lib-process/Process/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <Process/PresetHelpers.hpp>
#include <Process/TimeValue.hpp>

#include <LocalTree/ProcessComponent.hpp>

#include <score/model/ComponentUtils.hpp>
#include <score/model/EntitySerialization.hpp>
#include <score/model/IdentifiedObject.hpp>
#include <score/model/Identifier.hpp>
Expand All @@ -16,12 +19,13 @@

#include <ossia/detail/algorithms.hpp>
#include <ossia/detail/disable_fpe.hpp>
#include <ossia/network/base/device.hpp>
#include <ossia/network/base/node.hpp>

#include <QObject>

#include <wobjectimpl.h>

#include <stdexcept>
W_OBJECT_IMPL(Process::ProcessModel)

#if !defined(SCORE_ALL_UNITY)
Expand Down Expand Up @@ -362,4 +366,14 @@ const ProcessModel* parentProcess(const QObject* obj) noexcept
return static_cast<const ProcessModel*>(obj);
return nullptr;
}

QString processLocalTreeAddress(const ProcessModel& proc)
{
if(auto lt = findComponent<LocalTree::ProcessComponent>(proc.components()))
{
return QString::fromStdString(
lt->node().get_device().get_name() + ":" + lt->node().osc_address());
}
return {};
}
}
3 changes: 3 additions & 0 deletions src/plugins/score-lib-process/Process/Process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ SCORE_LIB_PROCESS_EXPORT
ProcessModel* parentProcess(QObject* obj) noexcept;
SCORE_LIB_PROCESS_EXPORT
const ProcessModel* parentProcess(const QObject* obj) noexcept;

SCORE_LIB_PROCESS_EXPORT
QString processLocalTreeAddress(const Process::ProcessModel& proc);
}
DEFAULT_MODEL_METADATA(Process::ProcessModel, "Process")

Expand Down
28 changes: 23 additions & 5 deletions src/plugins/score-plugin-dataflow/Dataflow/PortItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@
#include <ossia/network/domain/domain.hpp>

#include <QApplication>
#include <QClipboard>
#include <QGraphicsSceneDragDropEvent>
#include <QMenu>
#include <QMimeData>

namespace Dataflow
{
template <typename Vec>
bool intersection_empty(const Vec& v1, const Vec& v2)
static bool intersection_empty(const Vec& v1, const Vec& v2)
{
for(const auto& e1 : v1)
{
Expand Down Expand Up @@ -105,10 +106,27 @@ void AutomatablePortItem::setupMenu(QMenu& menu, const score::DocumentContext& c
return;
if(this->port().type() != Process::PortType::Message)
return;
auto act = menu.addAction(QObject::tr("Create automation"));
QObject::connect(
act, &QAction::triggered, this, [this, &ctx] { on_createAutomation(ctx); },
Qt::QueuedConnection);
{
auto act = menu.addAction(QObject::tr("Create automation"));
QObject::connect(act, &QAction::triggered, this, [this, &ctx] {
on_createAutomation(ctx);
}, Qt::QueuedConnection);
}

if(auto proc = qobject_cast<Process::ProcessModel*>(this->port().parent()))
{
if(auto addr = Process::processLocalTreeAddress(*proc); !addr.isEmpty())
{
addr += "/";
addr += this->port().exposed();
addr += "/value";
auto act = menu.addAction(QObject::tr("Copy address"));
QObject::connect(act, &QAction::triggered, &port(), [addr] {
auto& cb = *qApp->clipboard();
cb.setText(addr);
}, Qt::QueuedConnection);
}
}
}

void AutomatablePortItem::on_createAutomation(const score::DocumentContext& ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class SCORE_PLUGIN_SCENARIO_EXPORT Event final : public CommonComponent
{
COMMON_COMPONENT_METADATA("918b757d-d304-4362-bbd3-120f84e229fe")
public:
static constexpr bool is_unique = true;
Event(
ossia::net::node_base& parent, Scenario::EventModel& event,
const score::DocumentContext& doc, QObject* parent_comp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class SCORE_PLUGIN_SCENARIO_EXPORT IntervalBase
{
COMMON_COMPONENT_METADATA("11d928b5-eaeb-471c-b3b7-dc453180b10f")
public:
static constexpr bool is_unique = true;
using parent_t
= Component<Scenario::GenericIntervalComponent<const score::DocumentContext>>;
using model_t = Process::ProcessModel;
Expand Down
28 changes: 17 additions & 11 deletions src/plugins/score-plugin-scenario/LocalTree/LTIntervalComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,20 +81,20 @@ auto add_value_property(
}
class DefaultProcessComponent final : public ProcessComponent
{
COMMON_COMPONENT_METADATA("0b801b8f-41db-49ca-a396-c26aadf3f1b5")
COMPONENT_METADATA("0b801b8f-41db-49ca-a396-c26aadf3f1b5")
public:
DefaultProcessComponent(
ossia::net::node_base& node, Process::ProcessModel& proc,
const score::DocumentContext& doc, QObject* parent)
: ProcessComponent{node, proc, doc, "ProcessComponent", parent}
{
try
for(Process::Inlet* inlet : proc.inlets())
{
for(Process::Inlet* inlet : proc.inlets())
if(auto control = qobject_cast<Process::ControlInlet*>(inlet))
{
if(auto control = qobject_cast<Process::ControlInlet*>(inlet))
if(!inlet->exposed().isEmpty())
{
if(!inlet->exposed().isEmpty())
try
{
m_properties.push_back(add_property<Process::Inlet::p_address>(
this->node(), *inlet, inlet->exposed().toStdString(), this));
Expand All @@ -105,14 +105,20 @@ class DefaultProcessComponent final : public ProcessComponent
p.set_domain(control->domain());
m_properties.push_back(std::move(prop));
}
catch(...)
{
}
}
}
}

for(auto& outlet : proc.outlets())
for(auto& outlet : proc.outlets())
{
if(auto control = qobject_cast<Process::ControlOutlet*>(outlet))
{
if(auto control = qobject_cast<Process::ControlOutlet*>(outlet))
if(!outlet->exposed().isEmpty())
{
if(!outlet->exposed().isEmpty())
try
{
m_properties.push_back(add_property<Process::Outlet::p_address>(
this->node(), *outlet, outlet->exposed().toStdString(), this));
Expand All @@ -123,12 +129,12 @@ class DefaultProcessComponent final : public ProcessComponent
p.set_domain(control->domain());
m_properties.push_back(std::move(prop));
}
catch(...)
{
}
}
}
}
catch(...)
{
}
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class SCORE_PLUGIN_SCENARIO_EXPORT State final : public CommonComponent
{
COMMON_COMPONENT_METADATA("2e5fefa2-3442-4c08-9f3e-564ab65f7b22")
public:
static constexpr bool is_unique = true;
State(
ossia::net::node_base& parent, Scenario::StateModel& event,
const score::DocumentContext& doc, QObject* parent_comp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class SCORE_PLUGIN_SCENARIO_EXPORT TimeSync final : public CommonComponent
{
COMMON_COMPONENT_METADATA("104e4446-b09f-4bf6-92ef-0fe360397066")
public:
static constexpr bool is_unique = true;
TimeSync(
ossia::net::node_base& parent, Scenario::TimeSyncModel& event,
const score::DocumentContext& doc, QObject* parent_comp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,25 @@
#include <Scenario/Process/ScenarioInterface.hpp>

#include <Effect/EffectFactory.hpp>
#include <LocalTree/EventComponent.hpp>
#include <LocalTree/IntervalComponent.hpp>
#include <LocalTree/ProcessComponent.hpp>
#include <LocalTree/StateComponent.hpp>
#include <LocalTree/TimeSyncComponent.hpp>

#include <score/application/GUIApplicationContext.hpp>
#include <score/command/Dispatchers/CommandDispatcher.hpp>
#include <score/command/Dispatchers/MacroCommandDispatcher.hpp>
#include <score/model/ComponentUtils.hpp>
#include <score/model/EntitySerialization.hpp>
#include <score/tools/Bind.hpp>
#include <score/widgets/ArrowButton.hpp>
#include <score/widgets/HelpInteraction.hpp>
#include <score/widgets/TextLabel.hpp>

#include <ossia/network/base/device.hpp>
#include <ossia/network/base/node.hpp>

#include <QAction>
#include <QApplication>
#include <QClipboard>
Expand Down Expand Up @@ -1141,10 +1150,37 @@ void ObjectWidget::contextMenuEvent(QContextMenuEvent* ev)

QMenu* m = new QMenu{this};
m->addAction(tr("Copy remote control path"), [ptr] {
auto path = score::IDocument::unsafe_path(*ptr);

auto& cb = *qApp->clipboard();
cb.setText(path.toString());
std::string path;
if(auto cst = qobject_cast<Scenario::IntervalModel*>(ptr))
{
if(auto lt = findComponent<LocalTree::Interval>(cst->components()))
path = lt->node().get_device().get_name() + ":" + lt->node().osc_address();
}
else if(auto ev = qobject_cast<Scenario::EventModel*>(ptr))
{
if(auto lt = findComponent<LocalTree::Event>(ev->components()))
path = lt->node().get_device().get_name() + ":" + lt->node().osc_address();
}
else if(auto tn = qobject_cast<Scenario::TimeSyncModel*>(ptr))
{
if(auto lt = findComponent<LocalTree::TimeSync>(tn->components()))
path = lt->node().get_device().get_name() + ":" + lt->node().osc_address();
}
else if(auto st = qobject_cast<Scenario::StateModel*>(ptr))
{
if(auto lt = findComponent<LocalTree::State>(st->components()))
path = lt->node().get_device().get_name() + ":" + lt->node().osc_address();
}
else if(auto p = qobject_cast<Process::ProcessModel*>(ptr))
{
if(auto lt = findComponent<LocalTree::ProcessComponent>(p->components()))
path = lt->node().get_device().get_name() + ":" + lt->node().osc_address();
}
if(!path.empty())
{
auto& cb = *qApp->clipboard();
cb.setText(QString::fromStdString(path));
}
});

if(auto cst = qobject_cast<Scenario::IntervalModel*>(ptr))
Expand Down

0 comments on commit 40d0f1c

Please sign in to comment.