2 #include <score/graphics/DefaultControlImpl.hpp>
3 #include <score/graphics/InfiniteScroller.hpp>
4 #include <score/model/Skin.hpp>
5 #include <score/tools/Cursor.hpp>
6 #include <score/widgets/DoubleSpinBox.hpp>
7 #include <score/widgets/SignalUtils.hpp>
9 #include <ossia/detail/math.hpp>
11 #include <QDoubleSpinBox>
12 #include <QGraphicsProxyWidget>
13 #include <QGraphicsScene>
14 #include <QGraphicsSceneMouseEvent>
15 #include <QGuiApplication>
27 T&
self,
const score::Skin& skin,
const QString& text, QPainter* painter,
30 painter->setRenderHint(QPainter::Antialiasing,
true);
32 painter->setPen(skin.NoPen);
33 painter->setBrush(skin.Emphasis2.main.brush);
36 const QRectF brect =
self.boundingRect();
37 painter->drawRoundedRect(brect, 1, 1);
40 painter->setPen(skin.Base4.main.pen1);
41 painter->setFont(skin.Medium8Pt);
42 const auto textrect = brect.adjusted(2, 3, -2, -2);
43 painter->drawText(textrect, text, QTextOption(Qt::AlignLeft));
45 painter->setRenderHint(QPainter::Antialiasing,
false);
49 static void mousePressEvent(T&
self, QGraphicsSceneMouseEvent* event)
51 if(event->button() == Qt::LeftButton)
54 InfiniteScroller::start(
self, (
self.max -
self.min) *
self.m_value +
self.min);
61 static double mapValue(T&
self, QGraphicsSceneMouseEvent* event) noexcept
63 InfiniteScroller::move_free(event);
65 = std::pow(10., std::log10(1. + std::abs(InfiniteScroller::currentDelta)));
67 auto v = InfiniteScroller::origValue
68 - speed * InfiniteScroller::currentDelta
69 / double(InfiniteScroller::currentGeometry.height());
70 v = (v -
self.min) / (
self.max -
self.min);
71 return std::clamp(v, 0., 1.);
75 static void mouseMoveEvent(T&
self, QGraphicsSceneMouseEvent* event)
77 if((event->buttons() & Qt::LeftButton) &&
self.m_grab)
79 if(
const auto v = mapValue(
self, event); v !=
self.m_value)
82 if(!
self.m_noValueChangeOnMove)
91 static void mouseReleaseEvent(T&
self, QGraphicsSceneMouseEvent* event)
93 InfiniteScroller::stop(
self, event);
96 if(
const auto v = mapValue(
self, event); v !=
self.m_value)
103 if(
self.m_noValueChangeOnMove)
106 self.sliderReleased();
108 if(event->button() == Qt::RightButton)
110 contextMenuEvent(
self, event->scenePos());
116 template <
typename T>
117 requires std::is_integral_v<std::decay_t<decltype(std::declval<T>().value())>>
118 static void contextMenuEvent(T&
self, QPointF pos)
120 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
122 w->setRange(
self.min,
self.max);
124 w->setValue(
self.map(
self.m_value));
125 auto obj =
self.scene()->addWidget(
126 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
129 QTimer::singleShot(0, w, [w] { w->setFocus(); });
131 auto con = QObject::connect(
132 w, SignalUtils::QSpinBox_valueChanged_int(), &
self,
133 [&
self, obj, scene =
self.scene()](
double v) {
134 DefaultControlImpl::editWidgetInContextMenu(
self, scene, obj, v);
138 w, &SpinboxWithEnter::editingFinished, &
self, [obj, con, self_p]()
mutable {
141 if(self_p->m_noValueChangeOnMove)
142 self_p->sliderMoved();
143 self_p->sliderReleased();
144 QObject::disconnect(con);
145 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
146 scene->removeItem(obj);
155 template <
typename T>
156 requires std::is_floating_point_v<std::decay_t<decltype(std::declval<T>().value())>>
157 static void contextMenuEvent(T&
self, QPointF pos)
161 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
163 w->setRange(
self.min,
self.max);
166 w->setValue(
self.map(
self.m_value));
167 auto obj =
self.scene()->addWidget(
168 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
171 QTimer::singleShot(0, w, [w] { w->setFocus(); });
173 auto con = QObject::connect(
174 w, SignalUtils::QDoubleSpinBox_valueChanged_double(), &
self,
175 [&
self, obj, scene =
self.scene()](
double v) {
176 DefaultControlImpl::editWidgetInContextMenu(
self, scene, obj, v);
180 w, &DoubleSpinboxWithEnter::editingFinished, &
self,
181 [obj, con, self_p]()
mutable {
184 if(self_p->m_noValueChangeOnMove)
185 self_p->sliderMoved();
186 self_p->sliderReleased();
187 QObject::disconnect(con);
188 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
189 scene->removeItem(obj);
198 template <
typename T>
199 static void mouseDoubleClickEvent(T&
self, QGraphicsSceneMouseEvent* event)
201 self.m_value =
self.unmap(
self.init);
205 self.sliderReleased();
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: DefaultGraphicsSpinboxImpl.hpp:24
Definition: DoubleSpinBox.hpp:17
Definition: DoubleSpinBox.hpp:9