Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions src/plugins/score-plugin-avnd/Crousti/Layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
#include <Crousti/Painter.hpp>
#include <Crousti/ProcessModel.hpp>

#include <Process/Dataflow/WidgetInlets.hpp>

#include <score/graphics/layouts/GraphicsBoxLayout.hpp>
#include <score/graphics/layouts/GraphicsGridLayout.hpp>
#include <score/graphics/layouts/GraphicsSplitLayout.hpp>
#include <score/graphics/layouts/GraphicsTabLayout.hpp>
#include <score/graphics/widgets/QGraphicsLineEdit.hpp>
#include <score/tools/File.hpp>

#include <avnd/common/aggregates.hpp>
#include <avnd/concepts/layout.hpp>
Expand Down Expand Up @@ -140,6 +143,22 @@ struct LayoutBuilder final : Process::LayoutBuilderBase
const Process::ControlLayout& lay, Item& item)
= delete; // TODO

// File paths are stored in the document as templates (<PROJECT>:...,
// <LIBRARY>:..., or document-relative); resolve them so the ui items
// always receive a usable absolute path, like the score-side file
// widgets do.
static ossia::value resolveFilePath(
const ossia::value& v, Process::ControlInlet* inl,
const score::DocumentContext& ctx) noexcept
{
if(qobject_cast<Process::FileChooserBase*>(inl)
|| qobject_cast<Process::FolderChooser*>(inl))
if(auto str = v.target<std::string>(); str && !str->empty())
return score::locateFilePath(QString::fromStdString(*str), ctx)
.toStdString();
return v;
}

template <typename Item>
void setupControl(
QGraphicsItem* parent, Process::ControlInlet* inl,
Expand All @@ -149,14 +168,16 @@ struct LayoutBuilder final : Process::LayoutBuilderBase
{
using avnd_port_type = pmf_member_type_t<decltype(item.model)>;
avnd_port_type p;
oscr::from_ossia_value(p, inl->value(), item.value);
oscr::from_ossia_value(p, resolveFilePath(inl->value(), inl, doc), item.value);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arf, this is incurring the qobject_cast cost *2 on every widget creation, that's not great :/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the correct way here would be to do it statically: from avnd_port_type we know whether something is a file port, folder port, or something else. I'd add a separate "SetGUIValue" struct that follows the existing patterns for pattern-matching avendish port types at compile-time with concepts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way instead of being done at run-time it is done 100% at compile-time

if constexpr(requires { rootUi->on_control_update(); })
{
QObject::connect(
inl, &Process::ControlInlet::valueChanged, &context,
[rui = rootUi, layout = this->layout, &item](const ossia::value& v) {
[rui = rootUi, layout = this->layout, &item, inl,
&ctx = static_cast<const score::DocumentContext&>(this->doc)](
const ossia::value& v) {
avnd_port_type p;
oscr::from_ossia_value(p, v, item.value);
oscr::from_ossia_value(p, resolveFilePath(v, inl, ctx), item.value);

rui->on_control_update();
layout->update();
Expand All @@ -166,9 +187,11 @@ struct LayoutBuilder final : Process::LayoutBuilderBase
{
QObject::connect(
inl, &Process::ControlInlet::valueChanged, &context,
[layout = this->layout, &item](const ossia::value& v) {
[layout = this->layout, &item, inl,
&ctx = static_cast<const score::DocumentContext&>(this->doc)](
const ossia::value& v) {
avnd_port_type p;
oscr::from_ossia_value(p, v, item.value);
oscr::from_ossia_value(p, resolveFilePath(v, inl, ctx), item.value);
layout->update();
});
}
Expand Down
Loading