2 #include <score/graphics/DefaultControlImpl.hpp>
3 #include <score/model/Skin.hpp>
4 #include <score/widgets/DoubleSpinBox.hpp>
5 #include <score/widgets/SignalUtils.hpp>
7 #include <ossia/detail/math.hpp>
9 #include <QGraphicsProxyWidget>
10 #include <QGraphicsScene>
11 #include <QGraphicsSceneMouseEvent>
12 #include <QGuiApplication>
18 #include <score_lib_base_export.h>
26 QPointer<DoubleSpinboxWithEnter> spinbox{};
27 QPointer<QGraphicsProxyWidget> spinboxProxy{};
34 T&
self,
const score::Skin& skin,
const QString& text, QPainter* painter,
37 painter->setRenderHint(QPainter::Antialiasing,
false);
39 painter->setPen(skin.NoPen);
40 painter->setBrush(skin.Emphasis2.main.brush);
43 const QRectF brect =
self.boundingRect();
44 const QRectF srect =
self.sliderRect();
45 painter->drawRoundedRect(srect, 1, 1);
48 #if defined(__linux__)
49 static const auto dpi_adjust = widget->devicePixelRatioF() > 1 ? 0 : -1;
51 static const constexpr
auto dpi_adjust = 0;
53 static const constexpr
auto dpi_adjust = -2;
55 painter->setPen(skin.Base4.lighter180.pen1);
56 painter->setFont(skin.Medium8Pt);
57 const auto textrect = brect.adjusted(2, srect.height() + 3 + dpi_adjust, -2, -1);
58 painter->drawText(textrect, text, QTextOption(Qt::AlignCenter));
61 painter->fillRect(
self.handleRect(), skin.Base4);
63 painter->fillRect(
self.execHandleRect(), skin.Base4.lighter180.brush);
74 static void mousePressEvent(T&
self, QGraphicsSceneMouseEvent* event)
76 if(event->button() == Qt::LeftButton &&
self.isInHandle(event->pos()))
80 const auto srect =
self.sliderRect();
81 const auto posX =
event->pos().x() - srect.x();
82 double curPos =
self.from01(ossia::clamp(posX, 0., srect.width()) / srect.width());
83 if(curPos !=
self.m_value)
85 self.m_value = curPos;
95 static void mouseMoveEvent(T&
self, QGraphicsSceneMouseEvent* event)
97 if((event->buttons() & Qt::LeftButton) &&
self.m_grab)
99 const auto srect =
self.sliderRect();
100 const auto posX =
event->pos().x() - srect.x();
101 double curPos =
self.from01(ossia::clamp(posX, 0., srect.width()) / srect.width());
102 if(curPos !=
self.m_value)
104 if constexpr(std::is_same_v<decltype(
self.m_value),
int>)
106 self.m_value = curPos;
110 double ratio = qGuiApp->keyboardModifiers() & Qt::CTRL ? 0.1 : 1.;
111 self.m_value = std::clamp(
112 double(
self.m_value + ((curPos -
self.m_value) * ratio)), 0., 1.);
122 template <
typename T>
123 static void mouseReleaseEvent(T&
self, QGraphicsSceneMouseEvent* event)
127 const auto srect =
self.sliderRect();
128 const auto posX =
event->pos().x() - srect.x();
129 double curPos =
self.from01(ossia::clamp(posX, 0., srect.width()) / srect.width());
130 if(curPos !=
self.m_value)
132 if constexpr(std::is_same_v<decltype(
self.m_value),
int>)
134 self.m_value = curPos;
138 double ratio = qGuiApp->keyboardModifiers() & Qt::CTRL ? 0.1 : 1.;
139 self.m_value = std::clamp(
140 double(
self.m_value + ((curPos -
self.m_value) * ratio)), 0., 1.);
147 self.sliderReleased();
149 if(event->button() == Qt::RightButton)
151 contextMenuEvent(
self, event->scenePos());
156 template <
typename T>
157 static void contextMenuEvent(T&
self, QPointF pos)
159 QTimer::singleShot(0, &
self, [&, self_p = &
self, pos] {
161 self.impl->spinbox = w;
162 w->setRange(
self.min,
self.max);
165 w->setValue(
self.map(
self.m_value));
166 auto obj =
self.scene()->addWidget(
167 w, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
169 self.impl->spinboxProxy = obj;
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, [obj, con, self_p] {
181 if(self_p->impl->spinbox)
183 self_p->sliderReleased();
184 QObject::disconnect(con);
185 QTimer::singleShot(0, self_p, [self_p, scene = self_p->scene(), obj] {
186 scene->removeItem(obj);
188 self_p->impl->spinbox = nullptr;
189 self_p->impl->spinboxProxy = nullptr;
191 self_p->impl->spinbox =
nullptr;
192 self_p->impl->spinboxProxy =
nullptr;
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: DefaultGraphicsSliderImpl.hpp:31
Definition: DoubleSpinBox.hpp:17
Definition: DefaultGraphicsSliderImpl.hpp:25