2 #include <score/graphics/InfiniteScroller.hpp>
3 #include <score/model/Skin.hpp>
4 #include <score/tools/Cursor.hpp>
5 #include <score/widgets/DoubleSpinBox.hpp>
6 #include <score/widgets/SignalUtils.hpp>
8 #include <ossia/detail/math.hpp>
10 #include <QDoubleSpinBox>
11 #include <QGraphicsProxyWidget>
12 #include <QGraphicsScene>
13 #include <QGraphicsSceneMouseEvent>
14 #include <QGuiApplication>
25 T&
self,
const score::Skin& skin,
const QString& text, QPainter* painter,
28 painter->setRenderHint(QPainter::Antialiasing,
true);
30 painter->setPen(skin.NoPen);
31 painter->setBrush(skin.Emphasis2.main.brush);
34 const QRectF brect =
self.boundingRect();
35 painter->drawRoundedRect(brect, 1, 1);
38 painter->setPen(skin.Base4.main.pen1);
39 painter->setFont(skin.Medium8Pt);
40 const auto textrect = brect.adjusted(2, 3, -2, -2);
41 painter->drawText(textrect, text, QTextOption(Qt::AlignLeft));
43 painter->setRenderHint(QPainter::Antialiasing,
false);
47 static void mousePressEvent(T&
self, QGraphicsSceneMouseEvent* event)
49 if(event->button() == Qt::LeftButton)
52 InfiniteScroller::start(
self, (
self.max -
self.min) *
self.m_value +
self.min);
59 static double mapValue(T&
self, QGraphicsSceneMouseEvent* event) noexcept
61 InfiniteScroller::move_free(event);
63 = std::pow(10., std::log10(1. + std::abs(InfiniteScroller::currentDelta)));
65 auto v = InfiniteScroller::origValue
66 - speed * InfiniteScroller::currentDelta
67 / double(InfiniteScroller::currentGeometry.height());
68 v = (v -
self.min) / (
self.max -
self.min);
69 return std::clamp(v, 0., 1.);
73 static void mouseMoveEvent(T&
self, QGraphicsSceneMouseEvent* event)
75 if((event->buttons() & Qt::LeftButton) &&
self.m_grab)
77 if(
const auto v = mapValue(
self, event); v !=
self.m_value)
88 static void mouseReleaseEvent(T&
self, QGraphicsSceneMouseEvent* event)
90 InfiniteScroller::stop(
self, event);
93 if(
const auto v = mapValue(
self, event); v !=
self.m_value)
101 self.sliderReleased();
103 if(event->button() == Qt::RightButton)
105 contextMenuEvent(
self, event->scenePos());
111 template <
typename T>
112 requires std::is_integral_v<std::decay_t<decltype(std::declval<T>().value())>>
113 static void contextMenuEvent(T&
self, QPointF pos)
115 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
117 w->setRange(
self.min,
self.max);
119 w->setValue(
self.map(
self.m_value));
120 auto obj =
self.scene()->addWidget(
121 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
124 QTimer::singleShot(0, w, [w] { w->setFocus(); });
126 auto con = QObject::connect(
127 w, SignalUtils::QSpinBox_valueChanged_int(), &
self, [&
self](
double v) {
128 self.m_value =
self.unmap(v);
134 w, &SpinboxWithEnter::editingFinished, &
self, [obj, con, self_p]()
mutable {
137 self_p->sliderReleased();
138 QObject::disconnect(con);
139 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
140 scene->removeItem(obj);
149 template <
typename T>
150 requires std::is_floating_point_v<std::decay_t<decltype(std::declval<T>().value())>>
151 static void contextMenuEvent(T&
self, QPointF pos)
153 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
155 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::QDoubleSpinBox_valueChanged_double(), &
self,
168 self.m_value =
self.unmap(v);
174 w, &DoubleSpinboxWithEnter::editingFinished, &
self,
175 [obj, con, self_p]()
mutable {
178 self_p->sliderReleased();
179 QObject::disconnect(con);
180 QTimer::singleShot(0, obj, [scene = self_p->scene(), obj] {
181 scene->removeItem(obj);
190 template <
typename T>
191 static void mouseDoubleClickEvent(T&
self, QGraphicsSceneMouseEvent* event)
Base toolkit upon which the software is built.
Definition: Application.cpp:90
Definition: DefaultGraphicsSpinboxImpl.hpp:22
Definition: DoubleSpinBox.hpp:17
Definition: DoubleSpinBox.hpp:9