Skip to content

Commit ed2ad1a

Browse files
committed
objects: add a node text box
1 parent 73b0d2a commit ed2ad1a

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

src/plugins/score-plugin-ui/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ endif()
88
add_library(
99
score_plugin_ui
1010
"${CMAKE_CURRENT_SOURCE_DIR}/Ui/SignalDisplay.hpp"
11+
"${CMAKE_CURRENT_SOURCE_DIR}/Ui/TextBox.hpp"
1112
"${CMAKE_CURRENT_SOURCE_DIR}/Ui/ValueDisplay.hpp"
1213
"${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_ui.hpp"
1314
"${CMAKE_CURRENT_SOURCE_DIR}/score_plugin_ui.cpp"
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#pragma once
2+
#include "score/command/Dispatchers/SingleOngoingCommandDispatcher.hpp"
3+
4+
#include <Process/Commands/Properties.hpp>
5+
#include <Process/Commands/SetControlValue.hpp>
6+
#include <Process/Dataflow/Port.hpp>
7+
#include <Process/Dataflow/PortFactory.hpp>
8+
#include <Process/Dataflow/PortItem.hpp>
9+
#include <Process/Process.hpp>
10+
11+
#include <Effect/EffectLayer.hpp>
12+
#include <Effect/EffectLayout.hpp>
13+
14+
#include <score/application/ApplicationContext.hpp>
15+
#include <score/command/Dispatchers/CommandDispatcher.hpp>
16+
#include <score/command/PropertyCommand.hpp>
17+
#include <score/graphics/TextItem.hpp>
18+
#include <score/model/Skin.hpp>
19+
20+
#include <ossia/network/value/format_value.hpp>
21+
22+
#include <QApplication>
23+
#include <QClipboard>
24+
#include <QElapsedTimer>
25+
#include <QMenu>
26+
#include <QPainter>
27+
#include <QTextCursor>
28+
29+
#include <halp/controls.hpp>
30+
#include <halp/meta.hpp>
31+
namespace Ui::TextBox
32+
{
33+
struct Node
34+
{
35+
halp_meta(name, "Text Box")
36+
halp_meta(c_name, "Display")
37+
halp_meta(category, "Control/Basic")
38+
halp_meta(author, "ossia score")
39+
halp_meta(manual_url, "")
40+
halp_meta(description, "Basic text box")
41+
halp_meta(uuid, "7be51631-fb4b-4152-9ca7-86fdafa8a989")
42+
halp_flag(fully_custom_item);
43+
halp_flag(no_background);
44+
struct
45+
{
46+
struct : halp::lineedit<"in", "(Double-click to edit)">
47+
{
48+
enum widget
49+
{
50+
control
51+
};
52+
} port;
53+
} inputs;
54+
55+
struct Layer : public Process::EffectLayerView
56+
{
57+
public:
58+
const Process::ProcessModel& m_process;
59+
const Process::Context& m_context;
60+
SingleOngoingCommandDispatcher<Process::SetControlValue> m_dispatcher;
61+
Process::ControlInlet* value_inlet;
62+
score::TextItem* m_textItem{};
63+
Layer(
64+
const Process::ProcessModel& process, const Process::Context& doc,
65+
QGraphicsItem* parent)
66+
: Process::EffectLayerView{parent}
67+
, m_process{process}
68+
, m_context{doc}
69+
, m_dispatcher{m_context.commandStack}
70+
{
71+
setAcceptedMouseButtons(Qt::LeftButton);
72+
setFlag(ItemHasNoContents, true);
73+
this->setAcceptHoverEvents(true);
74+
75+
value_inlet = static_cast<Process::ControlInlet*>(process.inlets()[0]);
76+
77+
m_textItem = new score::TextItem{"", this};
78+
this->setToolTip(
79+
tr("Comment box\nPut the text you want in here by double-clicking !"));
80+
81+
connect(m_textItem->document(), &QTextDocument::contentsChanged, this, [&]() {
82+
this->prepareGeometryChange();
83+
84+
auto other = m_textItem->toHtml().toStdString();
85+
if(auto v = value_inlet->value(); ossia::convert<std::string>(v) != other)
86+
m_dispatcher.submit(*value_inlet, other);
87+
88+
QSizeF sz = m_textItem->boundingRect().size();
89+
sz.rwidth() += 2.;
90+
((Process::ProcessModel&)m_process).setSize(sz);
91+
}, Qt::QueuedConnection);
92+
93+
// const Process::PortFactoryList& portFactory
94+
// = doc.app.interfaces<Process::PortFactoryList>();
95+
// auto fact = portFactory.get(value_inlet->concreteKey());
96+
// auto port = fact->makePortItem(*value_inlet, doc, this, this);
97+
// port->setPos(0, 5);
98+
99+
connect(
100+
value_inlet, &Process::ControlInlet::executionValueChanged, this,
101+
[this](const ossia::value& v) { update(); });
102+
connect(
103+
value_inlet, &Process::ControlInlet::valueChanged, this, &Layer::updateText);
104+
updateText(value_inlet->value());
105+
106+
connect(m_textItem, &score::TextItem::focusOut, this, &Layer::focusOut);
107+
focusOut();
108+
109+
m_lastClick.start();
110+
}
111+
112+
void updateText(const ossia::value& v)
113+
{
114+
const auto& str = ossia::convert<std::string>(v);
115+
const auto& qstr = QString::fromUtf8(str);
116+
117+
if(qstr != m_textItem->toHtml())
118+
this->m_textItem->setHtml(qstr);
119+
}
120+
121+
void reset() { update(); }
122+
123+
void paint_impl(QPainter* p) const override { }
124+
125+
void mousePressEvent(QGraphicsSceneMouseEvent* event) override
126+
{
127+
if(event->button() == Qt::MouseButton::LeftButton)
128+
{
129+
auto t = m_lastClick.elapsed();
130+
if(t > QApplication::doubleClickInterval())
131+
{
132+
event->ignore();
133+
m_lastClick.restart();
134+
return;
135+
}
136+
else
137+
{
138+
event->accept();
139+
m_lastClick.restart();
140+
focusOnText();
141+
return;
142+
}
143+
}
144+
}
145+
146+
void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override { event->accept(); }
147+
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override { event->accept(); }
148+
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* evt) override { focusOnText(); }
149+
150+
void focusOnText()
151+
{
152+
if(m_textItem->textInteractionFlags() == Qt::NoTextInteraction)
153+
{
154+
m_textItem->setTextInteractionFlags(Qt::TextEditorInteraction);
155+
m_textItem->setFocus(Qt::MouseFocusReason);
156+
QTextCursor c = m_textItem->textCursor();
157+
c.select(QTextCursor::Document);
158+
m_textItem->setTextCursor(c);
159+
}
160+
}
161+
162+
void focusOut()
163+
{
164+
m_textItem->setTextInteractionFlags(Qt::NoTextInteraction);
165+
QTextCursor c = m_textItem->textCursor();
166+
c.clearSelection();
167+
m_textItem->setTextCursor(c);
168+
clearFocus();
169+
m_dispatcher.commit();
170+
}
171+
172+
QElapsedTimer m_lastClick{};
173+
};
174+
};
175+
}

src/plugins/score-plugin-ui/score_plugin_ui.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <Avnd/Factories.hpp>
1010
#include <Ui/SignalDisplay.hpp>
11+
#include <Ui/TextBox.hpp>
1112
#include <Ui/ValueDisplay.hpp>
1213

1314
#include <score_plugin_engine.hpp>
@@ -20,6 +21,7 @@ std::vector<score::InterfaceBase*> score_plugin_ui::factories(
2021
{
2122
std::vector<score::InterfaceBase*> fx;
2223
oscr::instantiate_fx<Ui::SignalDisplay::Node>(fx, ctx, key);
24+
oscr::instantiate_fx<Ui::TextBox::Node>(fx, ctx, key);
2325
oscr::instantiate_fx<Ui::ValueDisplay::Node>(fx, ctx, key);
2426
return fx;
2527
}

0 commit comments

Comments
 (0)