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