29 T& self,
const score::Skin& skin,
const QString& text, QPainter* painter,
32 painter->setRenderHint(QPainter::Antialiasing,
true);
34 constexpr const double adj = 6.;
35 constexpr const double space = 50.;
36 constexpr const double start = (270. - space) * 16.;
37 constexpr const double totalSpan = (360. - 2. * space) * 16.;
39 const QRectF srect = defaultKnobSize;
40 const QRectF r = srect.adjusted(adj, adj, -adj, -adj);
41 const double rw = r.width();
44 painter->setPen(skin.Emphasis2.main.pen1);
45 painter->setBrush(skin.Emphasis2.main.brush);
46 painter->drawChord(r, start, -totalSpan);
48 const double valueSpan = -self.m_value * totalSpan;
49 double textDelta = 0.;
52 painter->setPen(skin.Base4.main.pen3_solid_round_round);
57 painter->setPen(skin.Base4.main.pen2_solid_round_round);
62 painter->setPen(skin.Base4.main.pen1_5);
67 painter->setPen(skin.Base4.main.pen1);
70 painter->drawArc(r, start, valueSpan);
73 const double r1 = 0.5 * rw;
74 const double x0 = r.center().x();
75 const double y0 = r.center().y();
76 const double theta = -0.0174533 * (start + valueSpan) / 16.;
77 const double x1 = r.center().x() + r1 * cos(theta);
78 const double y1 = r.center().y() + r1 * sin(theta);
80 painter->drawLine(QPointF{x0, y0}, QPointF{x1, y1});
82 painter->setPen(skin.Base4.lighter180.pen1);
85 const QRectF er = r.adjusted(1.5, 1.5, -1.5, -1.5);
86 const double valueSpan = -self.m_execValue * totalSpan;
87 painter->drawArc(er, start, valueSpan);
91 painter->setFont(skin.Medium8Pt);
93 QRectF{0., srect.height() + textDelta, srect.width(), 10.}, text,
94 QTextOption(Qt::AlignCenter));
96 painter->setRenderHint(QPainter::Antialiasing,
false);
100 static void mousePressEvent(T& self, QGraphicsSceneMouseEvent* event)
102 if(event->button() == Qt::LeftButton)
105 InfiniteScroller::start(self, self.m_value);
111 template <
typename T>
112 static void mouseMoveEvent(T& self, QGraphicsSceneMouseEvent* event)
114 if((event->buttons() & Qt::LeftButton) && self.m_grab)
116 double v = InfiniteScroller::move(event);
117 if(v != self.m_value)
127 template <
typename T>
128 static void mouseReleaseEvent(T& self, QGraphicsSceneMouseEvent* event)
136 double v = InfiniteScroller::move(event);
137 if(v != self.m_value)
142 InfiniteScroller::stop(self, event);
146 self.sliderReleased();
148 if(event->button() == Qt::RightButton)
150 contextMenuEvent(self, event->scenePos());
159 template <
typename T>
167 self.sliderReleased();
170 template <
typename T>
171 requires std::is_integral_v<std::decay_t<decltype(std::declval<T>().value())>>
172 static void contextMenuEvent(T& self, QPointF pos)
174 auto build = [&, self_p = &self, pos] {
179 w->setRange(self.min, self.max);
181 w->setValue(self.map(self.m_value));
182 auto obj = self.scene()->addWidget(
183 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
187#if defined(__EMSCRIPTEN__)
190 QTimer::singleShot(0, w, [w] { w->setFocus(); });
193 auto con = QObject::connect(
194 w, SignalUtils::QSpinBox_valueChanged_int(), &self,
195 [&self, obj, scene = self.scene()](
double v) {
196 DefaultControlImpl::editWidgetInContextMenu(self, scene, obj, v);
200 w, &SpinboxWithEnter::editingFinished, &self, [obj, con, self_p]()
mutable {
203 self_p->sliderReleased();
204 QObject::disconnect(con);
205 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
206 scene->removeItem(obj);
213#if defined(__EMSCRIPTEN__)
216 QTimer::singleShot(0, &self, build);
220 template <
typename T>
221 requires std::is_floating_point_v<std::decay_t<decltype(std::declval<T>().value())>>
222 static void contextMenuEvent(T& self, QPointF pos)
224 auto build = [&, self_p = &self, pos] {
228 auto w =
new DoubleSpinboxWithEnter;
229 w->setRange(self.min, self.max);
232 w->setValue(self.map(self.m_value));
233 auto obj = self.scene()->addWidget(
234 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
238#if defined(__EMSCRIPTEN__)
241 QTimer::singleShot(0, w, [w] { w->setFocus(); });
244 auto con = QObject::connect(
245 w, SignalUtils::QDoubleSpinBox_valueChanged_double(), &self,
246 [&self, obj, scene = self.scene()](
double v) {
247 DefaultControlImpl::editWidgetInContextMenu(self, scene, obj, v);
251 w, &DoubleSpinboxWithEnter::editingFinished, &self,
252 [obj, con, self_p]()
mutable {
255 self_p->sliderReleased();
256 QObject::disconnect(con);
257 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
258 scene->removeItem(obj);
265#if defined(__EMSCRIPTEN__)
268 QTimer::singleShot(0, &self, build);
272 template <
typename T>
273 static void mouseDoubleClickEvent(T& self, QGraphicsSceneMouseEvent* event)
275 self.m_value = self.unmap(self.init);
279 self.sliderReleased();