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 constexpr
const double adj = 6.;
33 constexpr
const double space = 50.;
34 constexpr
const double start = (270. - space) * 16.;
35 constexpr
const double totalSpan = (360. - 2. * space) * 16.;
37 const QRectF srect =
self.boundingRect();
38 const QRectF r = srect.adjusted(adj, adj, -adj, -adj);
39 const double rw = r.width();
42 painter->setPen(skin.Emphasis2.main.pen1);
43 painter->setBrush(skin.Emphasis2.main.brush);
44 painter->drawChord(r, start, -totalSpan);
46 const double valueSpan = -
self.m_value * totalSpan;
47 double textDelta = 0.;
50 painter->setPen(skin.Base4.main.pen3_solid_round_round);
55 painter->setPen(skin.Base4.main.pen2_solid_round_round);
60 painter->setPen(skin.Base4.main.pen1_5);
65 painter->setPen(skin.Base4.main.pen1);
68 painter->drawArc(r, start, valueSpan);
71 const double r1 = 0.5 * rw;
72 const double x0 = r.center().x();
73 const double y0 = r.center().y();
74 const double theta = -0.0174533 * (start + valueSpan) / 16.;
75 const double x1 = r.center().x() + r1 * cos(theta);
76 const double y1 = r.center().y() + r1 * sin(theta);
78 painter->drawLine(QPointF{x0, y0}, QPointF{x1, y1});
80 painter->setPen(skin.Base4.lighter180.pen1);
83 const QRectF er = r.adjusted(1.5, 1.5, -1.5, -1.5);
84 const double valueSpan = -
self.m_execValue * totalSpan;
85 painter->drawArc(er, start, valueSpan);
89 painter->setFont(skin.Medium8Pt);
91 QRectF{0., srect.height() + textDelta, srect.width(), 10.}, text,
92 QTextOption(Qt::AlignCenter));
94 painter->setRenderHint(QPainter::Antialiasing,
false);
98 static void mousePressEvent(T&
self, QGraphicsSceneMouseEvent* event)
100 if(event->button() == Qt::LeftButton)
103 InfiniteScroller::start(
self,
self.m_value);
109 template <
typename T>
110 static void mouseMoveEvent(T&
self, QGraphicsSceneMouseEvent* event)
112 if((event->buttons() & Qt::LeftButton) &&
self.m_grab)
114 double v = InfiniteScroller::move(event);
115 if(v !=
self.m_value)
125 template <
typename T>
126 static void mouseReleaseEvent(T&
self, QGraphicsSceneMouseEvent* event)
128 InfiniteScroller::stop(
self, event);
131 double v = InfiniteScroller::move(event);
132 if(v !=
self.m_value)
140 self.sliderReleased();
142 if(event->button() == Qt::RightButton)
144 contextMenuEvent(
self, event->scenePos());
150 template <
typename T>
151 requires std::is_integral_v<std::decay_t<decltype(std::declval<T>().value())>>
152 static void contextMenuEvent(T&
self, QPointF pos)
154 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
156 w->setRange(
self.min,
self.max);
158 w->setValue(
self.map(
self.m_value));
159 auto obj =
self.scene()->addWidget(
160 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
163 QTimer::singleShot(0, w, [w] { w->setFocus(); });
165 auto con = QObject::connect(
166 w, SignalUtils::QSpinBox_valueChanged_int(), &
self,
167 [&
self, obj, scene =
self.scene()](
double v) {
168 DefaultControlImpl::editWidgetInContextMenu(
self, scene, obj, v);
172 w, &SpinboxWithEnter::editingFinished, &
self, [obj, con, self_p]()
mutable {
175 self_p->sliderReleased();
176 QObject::disconnect(con);
177 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
178 scene->removeItem(obj);
187 template <
typename T>
188 requires std::is_floating_point_v<std::decay_t<decltype(std::declval<T>().value())>>
189 static void contextMenuEvent(T&
self, QPointF pos)
191 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
193 w->setRange(
self.min,
self.max);
196 w->setValue(
self.map(
self.m_value));
197 auto obj =
self.scene()->addWidget(
198 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
201 QTimer::singleShot(0, w, [w] { w->setFocus(); });
203 auto con = QObject::connect(
204 w, SignalUtils::QDoubleSpinBox_valueChanged_double(), &
self,
205 [&
self, obj, scene =
self.scene()](
double v) {
206 DefaultControlImpl::editWidgetInContextMenu(
self, scene, obj, v);
210 w, &DoubleSpinboxWithEnter::editingFinished, &
self,
211 [obj, con, self_p]()
mutable {
214 self_p->sliderReleased();
215 QObject::disconnect(con);
216 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
217 scene->removeItem(obj);
226 template <
typename T>
227 static void mouseDoubleClickEvent(T&
self, QGraphicsSceneMouseEvent* event)
229 self.m_value =
self.unmap(
self.init);
233 self.sliderReleased();
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: DefaultGraphicsKnobImpl.hpp:24
Definition: DoubleSpinBox.hpp:17
Definition: DoubleSpinBox.hpp:9