slider: improved ladder usability
This commit is contained in:
@@ -250,7 +250,8 @@ void SliderBase::LabelDragged()
|
||||
break;
|
||||
case kInteger:
|
||||
case kFloat:
|
||||
drag_ladder_ = new SliderLadder(value_.toDouble(), drag_multiplier_, enable_ladder_ ? ladder_element_count_ : 0);
|
||||
drag_ladder_ = new SliderLadder(drag_multiplier_, enable_ladder_ ? ladder_element_count_ : 0);
|
||||
drag_ladder_->SetValue(ValueToString(value_));
|
||||
drag_ladder_->show();
|
||||
|
||||
QPoint label_global_pos = label_->mapToGlobal(label_->pos());
|
||||
@@ -263,7 +264,7 @@ void SliderBase::LabelDragged()
|
||||
}
|
||||
}
|
||||
|
||||
void SliderBase::LadderDragged(int value, double multiplier)
|
||||
void SliderBase::LadderDragged(double value, double multiplier)
|
||||
{
|
||||
switch (mode_) {
|
||||
case kString:
|
||||
@@ -272,7 +273,7 @@ void SliderBase::LadderDragged(int value, double multiplier)
|
||||
case kInteger:
|
||||
case kFloat:
|
||||
{
|
||||
dragged_diff_ += static_cast<double>(value) * drag_multiplier_ * multiplier;
|
||||
dragged_diff_ += value * drag_multiplier_ * multiplier;
|
||||
|
||||
double drag_val = AdjustDragDistanceInternal(value_.toDouble(), dragged_diff_);
|
||||
|
||||
@@ -291,7 +292,7 @@ void SliderBase::LadderDragged(int value, double multiplier)
|
||||
}
|
||||
|
||||
UpdateLabel(temp_dragged_value_);
|
||||
drag_ladder_->SetValue(temp_dragged_value_.toDouble());
|
||||
drag_ladder_->SetValue(ValueToString(temp_dragged_value_));
|
||||
emit ValueChanged(temp_dragged_value_);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ private slots:
|
||||
|
||||
void LabelDragged();
|
||||
|
||||
void LadderDragged(int value, double multiplier);
|
||||
void LadderDragged(double value, double multiplier);
|
||||
|
||||
void LadderReleased();
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
SliderLabel::SliderLabel(QWidget *parent) :
|
||||
|
||||
@@ -26,16 +26,18 @@
|
||||
#include <QtMath>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#include "common/clamp.h"
|
||||
#include "common/lerp.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
SliderLadder::SliderLadder(double start_val, double drag_multiplier, int nb_outer_values, QWidget* parent) :
|
||||
SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget* parent) :
|
||||
QFrame(parent, Qt::Popup),
|
||||
start_val_(start_val),
|
||||
active_element_(nullptr),
|
||||
relative_y_(-1)
|
||||
y_mobility_(0)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
@@ -48,14 +50,17 @@ SliderLadder::SliderLadder(double start_val, double drag_multiplier, int nb_oute
|
||||
elements_.append(new SliderLadderElement(qPow(10, i + 1) * drag_multiplier));
|
||||
}
|
||||
|
||||
elements_.append(new SliderLadderElement(drag_multiplier));
|
||||
// Create center entry
|
||||
SliderLadderElement* start_element = new SliderLadderElement(drag_multiplier);
|
||||
active_element_ = elements_.size();
|
||||
start_element->SetHighlighted(true);
|
||||
elements_.append(start_element);
|
||||
|
||||
for (int i=0;i<nb_outer_values;i++) {
|
||||
elements_.append(new SliderLadderElement(qPow(10, - i - 1) * drag_multiplier));
|
||||
}
|
||||
|
||||
foreach (SliderLadderElement* e, elements_) {
|
||||
e->SetValue(start_val_);
|
||||
layout->addWidget(e);
|
||||
}
|
||||
|
||||
@@ -87,10 +92,10 @@ SliderLadder::~SliderLadder()
|
||||
#endif
|
||||
}
|
||||
|
||||
void SliderLadder::SetValue(double val)
|
||||
void SliderLadder::SetValue(const QString &s)
|
||||
{
|
||||
foreach (SliderLadderElement* e, elements_) {
|
||||
e->SetValue(val);
|
||||
e->SetValue(s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,38 +110,7 @@ void SliderLadder::showEvent(QShowEvent *event)
|
||||
{
|
||||
QWidget::showEvent(event);
|
||||
|
||||
QMetaObject::invokeMethod(this, "InitRelativeY", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(&drag_timer_, "start", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void SliderLadder::SetActiveElement()
|
||||
{
|
||||
if (!active_element_
|
||||
|| relative_y_ < active_element_->y()
|
||||
|| relative_y_ >= active_element_->y() + active_element_->height()) {
|
||||
if (active_element_) {
|
||||
// Un-highlight active element if one is set
|
||||
active_element_->SetHighlighted(false);
|
||||
}
|
||||
|
||||
// Find new active element
|
||||
foreach (SliderLadderElement* ele, elements_) {
|
||||
if (relative_y_ >= ele->y() && relative_y_ < ele->y() + ele->height()) {
|
||||
// This is the element!
|
||||
active_element_ = ele;
|
||||
active_element_->SetHighlighted(true);
|
||||
relative_y_ = active_element_->y() + active_element_->height() / 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SliderLadder::InitRelativeY()
|
||||
{
|
||||
relative_y_ = QCursor::pos().y() - this->y();
|
||||
|
||||
SetActiveElement();
|
||||
drag_timer_.start();
|
||||
}
|
||||
|
||||
void SliderLadder::TimerUpdate()
|
||||
@@ -155,22 +129,45 @@ void SliderLadder::TimerUpdate()
|
||||
QCursor::setPos(drag_start_);
|
||||
#endif
|
||||
|
||||
int target = active_element_->y() + active_element_->height() / 2;
|
||||
relative_y_ = lerp(relative_y_, static_cast<float>(target), 0.1f);
|
||||
int y_threshold = fontMetrics().height() / 2;
|
||||
|
||||
if (!x_mvmt && !y_mvmt) {
|
||||
return;
|
||||
}
|
||||
if (qAbs(y_mvmt) > qAbs(x_mvmt)
|
||||
|| qApp->keyboardModifiers() & Qt::ControlModifier) {
|
||||
// Movement is vertical
|
||||
y_mobility_ += y_mvmt;
|
||||
|
||||
// Determine which element we're in
|
||||
relative_y_ = clamp(relative_y_ + y_mvmt,
|
||||
static_cast<float>(elements_.first()->y()),
|
||||
static_cast<float>(elements_.last()->y() + elements_.last()->height() - 1));
|
||||
if (qAbs(y_mobility_) > y_threshold) {
|
||||
int new_active_element;
|
||||
|
||||
SetActiveElement();
|
||||
if (y_mvmt < 0) {
|
||||
// Movement is UP
|
||||
new_active_element = active_element_ - 1;
|
||||
} else {
|
||||
// Movement is DOWN
|
||||
new_active_element = active_element_ + 1;
|
||||
}
|
||||
|
||||
if (qAbs(x_mvmt) > qAbs(y_mvmt)) {
|
||||
emit DraggedByValue(x_mvmt, active_element_->GetMultiplier());
|
||||
// Check if the proposed element is valid
|
||||
if (new_active_element >= 0 && new_active_element < elements_.size()) {
|
||||
elements_.at(active_element_)->SetHighlighted(false);
|
||||
|
||||
active_element_ = new_active_element;
|
||||
|
||||
elements_.at(active_element_)->SetHighlighted(true);
|
||||
}
|
||||
|
||||
y_mobility_ = 0;
|
||||
}
|
||||
} else {
|
||||
// Movement is horizontal
|
||||
emit DraggedByValue(x_mvmt , elements_.at(active_element_)->GetMultiplier());
|
||||
|
||||
// Reduce Y mobility
|
||||
if (y_mobility_ > 0) {
|
||||
y_mobility_--;
|
||||
} else if (y_mobility_ < 0) {
|
||||
y_mobility_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +207,7 @@ void SliderLadderElement::SetHighlighted(bool e)
|
||||
UpdateLabel();
|
||||
}
|
||||
|
||||
void SliderLadderElement::SetValue(double value)
|
||||
void SliderLadderElement::SetValue(const QString &value)
|
||||
{
|
||||
value_ = value;
|
||||
|
||||
@@ -230,13 +227,13 @@ void SliderLadderElement::UpdateLabel()
|
||||
QString val_text;
|
||||
|
||||
if (highlighted_) {
|
||||
val_text = QString::number(value_);
|
||||
val_text = value_;
|
||||
}
|
||||
|
||||
label_->setText(QStringLiteral("%1\n%2").arg(QString::number(multiplier_),
|
||||
val_text));
|
||||
} else {
|
||||
label_->setText(QString::number(value_));
|
||||
label_->setText(value_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
void SetHighlighted(bool e);
|
||||
|
||||
void SetValue(double value);
|
||||
void SetValue(const QString& value);
|
||||
|
||||
void SetMultiplierVisible(bool e);
|
||||
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
QLabel* label_;
|
||||
|
||||
double multiplier_;
|
||||
double value_;
|
||||
QString value_;
|
||||
|
||||
bool highlighted_;
|
||||
|
||||
@@ -64,11 +64,11 @@ class SliderLadder : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SliderLadder(double start_val, double drag_multiplier, int nb_outer_values, QWidget* parent = nullptr);
|
||||
SliderLadder(double drag_multiplier, int nb_outer_values, QWidget* parent = nullptr);
|
||||
|
||||
virtual ~SliderLadder() override;
|
||||
|
||||
void SetValue(double val);
|
||||
void SetValue(const QString& s);
|
||||
|
||||
protected:
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
@@ -81,23 +81,17 @@ signals:
|
||||
void Released();
|
||||
|
||||
private:
|
||||
void SetActiveElement();
|
||||
|
||||
QPoint drag_start_;
|
||||
|
||||
double start_val_;
|
||||
|
||||
QList<SliderLadderElement*> elements_;
|
||||
|
||||
SliderLadderElement* active_element_;
|
||||
|
||||
float relative_y_;
|
||||
int active_element_;
|
||||
|
||||
QTimer drag_timer_;
|
||||
|
||||
private slots:
|
||||
void InitRelativeY();
|
||||
int y_mobility_;
|
||||
|
||||
private slots:
|
||||
void TimerUpdate();
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user