Scrub numbers by dragging their labels in the tool bars and layer opacity (12.12c1)
This commit is contained in:
1 parent
f335818e53
commit
5bc7889387
25 files changed
+1126
-32
No files matched your search
@@ -0,0 +1,76 @@
|
||||
#include "UI/NumericScrub.h"
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QWidget>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
NumericScrub::NumericScrub(QWidget *label, Options options) : QObject(label), m_label(label), m_options(std::move(options))
|
||||
{
|
||||
// A disabled label shows its parent's cursor, as Qt does.
|
||||
label->setCursor(Qt::SizeHorCursor);
|
||||
// Buttonless moves must arrive to end a lost release.
|
||||
label->setMouseTracking(true);
|
||||
label->installEventFilter(this);
|
||||
}
|
||||
|
||||
bool NumericScrub::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
const QEvent::Type type = event->type();
|
||||
// A double click's second press is a press too.
|
||||
const bool press = type == QEvent::MouseButtonPress || type == QEvent::MouseButtonDblClick;
|
||||
if (!press && type != QEvent::MouseMove && type != QEvent::MouseButtonRelease)
|
||||
return false;
|
||||
const auto *mouse = static_cast<QMouseEvent *>(event);
|
||||
if (watched != m_label) {
|
||||
// A popup opened mid-drag takes the release.
|
||||
if (type == QEvent::MouseButtonRelease && mouse->button() == Qt::LeftButton)
|
||||
end();
|
||||
return false;
|
||||
}
|
||||
if (press) {
|
||||
// Filters see a disabled label's presses before Qt drops them.
|
||||
if (mouse->button() != Qt::LeftButton || !m_label->isEnabled())
|
||||
return false;
|
||||
// The label holds the grab: its own points stay exact.
|
||||
m_press = mouse->position();
|
||||
qApp->installEventFilter(this);
|
||||
return true;
|
||||
}
|
||||
if (!m_press)
|
||||
return false;
|
||||
if (type == QEvent::MouseButtonRelease) {
|
||||
if (mouse->button() == Qt::LeftButton)
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
// Qt can lose a release: a buttonless move ends.
|
||||
if (!mouse->buttons().testFlag(Qt::LeftButton)) {
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
const QPointF translation = mouse->position() - *m_press;
|
||||
if (!m_start) {
|
||||
if (std::hypot(translation.x(), translation.y()) < 1)
|
||||
return true;
|
||||
m_start = m_options.value();
|
||||
m_options.onStart();
|
||||
}
|
||||
double proposed = *m_start + translation.x() * m_options.sensitivity;
|
||||
if (m_options.step && *m_options.step > 0)
|
||||
proposed = std::round(proposed / *m_options.step) * *m_options.step;
|
||||
m_options.set(std::min(m_options.high, std::max(m_options.low, proposed)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void NumericScrub::end()
|
||||
{
|
||||
if (!m_press)
|
||||
return;
|
||||
qApp->removeEventFilter(this);
|
||||
m_press.reset();
|
||||
if (m_start) {
|
||||
m_start.reset();
|
||||
m_options.onEnd();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user