Loading...
Searching...
No Matches
TextBox.hpp
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>
31namespace Ui::TextBox
32{
33struct 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
56 {
57 public:
58 const Process::ProcessModel& m_process;
59 const Process::Context& m_context;
61 Process::ControlInlet* value_inlet;
62 score::TextItem* m_textItem{};
63 Layer(
64 const Process::ProcessModel& process, const Process::Context& doc,
65 QGraphicsItem* 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}
Definition Port.hpp:206
Definition EffectLayer.hpp:16
The Process class.
Definition score-lib-process/Process/Process.hpp:62
The SingleOngoingCommandDispatcher class.
Definition SingleOngoingCommandDispatcher.hpp:17
Definition TextItem.hpp:13
Definition ProcessContext.hpp:12
Definition TextBox.hpp:56
Definition TextBox.hpp:34