improved slider ladders
This commit is contained in:
@@ -92,6 +92,7 @@ void Config::SetDefaults()
|
||||
SetEntryInternal(QStringLiteral("SplitClipsCopyNodes"), NodeValue::kBoolean, true);
|
||||
SetEntryInternal(QStringLiteral("UseGradients"), NodeValue::kBoolean, true);
|
||||
SetEntryInternal(QStringLiteral("AutoMergeTracks"), NodeValue::kBoolean, true);
|
||||
SetEntryInternal(QStringLiteral("UseSliderLadders"), NodeValue::kBoolean, true);
|
||||
|
||||
SetEntryInternal(QStringLiteral("AutoCacheDelay"), NodeValue::kInt, 1000);
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@ PreferencesBehaviorTab::PreferencesBehaviorTab()
|
||||
QStringLiteral("ScrollZooms"),
|
||||
tr("Holding CTRL while using Olive toggles this setting"),
|
||||
general_group);
|
||||
AddItem(tr("Enable slider ladder"),
|
||||
QStringLiteral("UseSliderLadders"),
|
||||
general_group);
|
||||
|
||||
QTreeWidgetItem* audio_group = AddParent(tr("Audio"));
|
||||
AddItem(tr("Enable audio scrubbing"),
|
||||
|
||||
@@ -62,7 +62,7 @@ SliderBase::SliderBase(Mode mode, QWidget *parent) :
|
||||
switch (mode_) {
|
||||
case kString:
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
SetValue("");
|
||||
SetValue(QString());
|
||||
break;
|
||||
case kInteger:
|
||||
case kFloat:
|
||||
@@ -200,22 +200,6 @@ QString SliderBase::GetFormat() const
|
||||
}
|
||||
}
|
||||
|
||||
void SliderBase::RepositionLadder()
|
||||
{
|
||||
QPoint label_global_pos = label_->mapToGlobal(label_->pos());
|
||||
int text_width = QtUtils::QFontMetricsWidth(label_->fontMetrics(), label_->text());
|
||||
QPoint ladder_pos(label_global_pos.x(),
|
||||
label_global_pos.y() + label_->height() / 2 - drag_ladder_->height() / 2);
|
||||
|
||||
if (ladder_element_count_ > 0) {
|
||||
ladder_pos.setX(ladder_pos.x() + text_width + QtUtils::QFontMetricsWidth(label_->fontMetrics(), QStringLiteral("H")));
|
||||
} else {
|
||||
ladder_pos.setX(ladder_pos.x() + text_width / 2 - drag_ladder_->width() / 2);
|
||||
}
|
||||
|
||||
drag_ladder_->move(ladder_pos);
|
||||
}
|
||||
|
||||
void SliderBase::UpdateLabel(const QVariant &v)
|
||||
{
|
||||
if (tristate_) {
|
||||
@@ -268,7 +252,7 @@ void SliderBase::LabelPressed()
|
||||
drag_ladder_->SetValue(ValueToString(value_));
|
||||
drag_ladder_->show();
|
||||
|
||||
RepositionLadder();
|
||||
QMetaObject::invokeMethod(this, "RepositionLadder", Qt::QueuedConnection);
|
||||
|
||||
connect(drag_ladder_, &SliderLadder::DraggedByValue, this, &SliderBase::LadderDragged);
|
||||
connect(drag_ladder_, &SliderLadder::Released, this, &SliderBase::LadderReleased);
|
||||
@@ -309,7 +293,10 @@ void SliderBase::LadderDragged(int value, double multiplier)
|
||||
UpdateLabel(temp_dragged_value_);
|
||||
|
||||
drag_ladder_->SetValue(ValueToString(temp_dragged_value_));
|
||||
RepositionLadder();
|
||||
|
||||
if (!Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
RepositionLadder();
|
||||
}
|
||||
|
||||
emit ValueChanged(temp_dragged_value_);
|
||||
break;
|
||||
@@ -395,4 +382,19 @@ void SliderBase::ResetValue()
|
||||
}
|
||||
}
|
||||
|
||||
void SliderBase::RepositionLadder()
|
||||
{
|
||||
if (Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
drag_ladder_->move(QCursor::pos() - QPoint(drag_ladder_->width()/2, drag_ladder_->height()/2));
|
||||
} else {
|
||||
QPoint label_global_pos = label_->mapToGlobal(label_->pos());
|
||||
int text_width = QtUtils::QFontMetricsWidth(label_->fontMetrics(), label_->text());
|
||||
|
||||
int ladder_x = label_global_pos.x() + text_width / 2 - drag_ladder_->width() / 2;
|
||||
int ladder_y = label_global_pos.y() + label_->height() / 2 - drag_ladder_->height() / 2;
|
||||
|
||||
drag_ladder_->move(ladder_x, ladder_y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -92,8 +92,6 @@ private:
|
||||
|
||||
QString GetFormat() const;
|
||||
|
||||
void RepositionLadder();
|
||||
|
||||
SliderLabel* label_;
|
||||
|
||||
FocusableLineEdit* editor_;
|
||||
@@ -139,6 +137,9 @@ private slots:
|
||||
void LineEditCancelled();
|
||||
|
||||
void ResetValue();
|
||||
|
||||
void RepositionLadder();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -32,12 +32,13 @@
|
||||
|
||||
#include "common/clamp.h"
|
||||
#include "common/lerp.h"
|
||||
#include "common/qtutils.h"
|
||||
#include "config/config.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget* parent) :
|
||||
QFrame(parent, Qt::Popup),
|
||||
y_mobility_(0)
|
||||
QFrame(parent, Qt::Popup)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
@@ -46,6 +47,10 @@ SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget*
|
||||
setFrameShape(QFrame::Box);
|
||||
setLineWidth(1);
|
||||
|
||||
if (!Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
nb_outer_values = 0;
|
||||
}
|
||||
|
||||
for (int i=nb_outer_values-1;i>=0;i--) {
|
||||
elements_.append(new SliderLadderElement(qPow(10, i + 1) * drag_multiplier));
|
||||
}
|
||||
@@ -71,25 +76,36 @@ SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget*
|
||||
drag_timer_.setInterval(10);
|
||||
connect(&drag_timer_, &QTimer::timeout, this, &SliderLadder::TimerUpdate);
|
||||
|
||||
if (Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
drag_start_x_ = -1;
|
||||
} else {
|
||||
#if defined(Q_OS_MAC)
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
CGGetLastMouseDelta(nullptr, nullptr);
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
CGGetLastMouseDelta(nullptr, nullptr);
|
||||
#else
|
||||
drag_start_ = QCursor::pos();
|
||||
drag_start_x_ = QCursor::pos().x();
|
||||
drag_start_y_ = QCursor::pos().y();
|
||||
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->setOverrideCursor(Qt::BlankCursor);
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->setOverrideCursor(Qt::BlankCursor);
|
||||
#endif
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(this, "UpdatePosition", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
SliderLadder::~SliderLadder()
|
||||
{
|
||||
if (Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
|
||||
} else {
|
||||
#if defined(Q_OS_MAC)
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
#else
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->restoreOverrideCursor();
|
||||
static_cast<QGuiApplication*>(QApplication::instance())->restoreOverrideCursor();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void SliderLadder::SetValue(const QString &s)
|
||||
@@ -124,54 +140,91 @@ void SliderLadder::closeEvent(QCloseEvent *event)
|
||||
|
||||
void SliderLadder::TimerUpdate()
|
||||
{
|
||||
int32_t x_mvmt, y_mvmt;
|
||||
int ladder_left = this->x();
|
||||
int ladder_right = this->x() + this->width() - 1;
|
||||
int now_pos = QCursor::pos().x();
|
||||
|
||||
// Keep cursor in the same position
|
||||
if (Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
|
||||
bool is_under_mouse = (now_pos >= ladder_left && now_pos <= ladder_right);
|
||||
|
||||
if (drag_start_x_ != -1 && (is_under_mouse
|
||||
|| (drag_start_x_ < ladder_left && now_pos > ladder_right)
|
||||
|| (drag_start_x_ > ladder_right && now_pos < ladder_left))) {
|
||||
// We're ending a drag, try to return the value back to its beginning
|
||||
int anchor;
|
||||
|
||||
if (drag_start_x_ < ladder_left) {
|
||||
anchor = ladder_left;
|
||||
} else {
|
||||
anchor = ladder_right;
|
||||
}
|
||||
|
||||
int makeup_value = anchor - drag_start_x_;
|
||||
emit DraggedByValue(makeup_value, elements_.at(active_element_)->GetMultiplier());
|
||||
|
||||
drag_start_x_ = -1;
|
||||
}
|
||||
|
||||
if (is_under_mouse) {
|
||||
|
||||
// Determine which element is currently active
|
||||
for (int i=0; i<elements_.size(); i++) {
|
||||
if (elements_.at(i)->underMouse()) {
|
||||
if (i != active_element_) {
|
||||
elements_.at(active_element_)->SetHighlighted(false);
|
||||
active_element_ = i;
|
||||
elements_.at(active_element_)->SetHighlighted(true);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (drag_start_x_ == -1) {
|
||||
// Drag is a new leave from the ladder, calculate origin
|
||||
if (now_pos < ladder_left) {
|
||||
drag_start_x_ = ladder_left;
|
||||
} else {
|
||||
drag_start_x_ = ladder_right;
|
||||
}
|
||||
}
|
||||
|
||||
emit DraggedByValue(now_pos - drag_start_x_, elements_.at(active_element_)->GetMultiplier());
|
||||
drag_start_x_ = now_pos;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
int32_t x_mvmt, y_mvmt;
|
||||
|
||||
// Keep cursor in the same position
|
||||
#if defined(Q_OS_MAC)
|
||||
CGGetLastMouseDelta(&x_mvmt, &y_mvmt);
|
||||
CGGetLastMouseDelta(&x_mvmt, &y_mvmt);
|
||||
#else
|
||||
QPoint current_pos = QCursor::pos();
|
||||
QPoint current_pos = QCursor::pos();
|
||||
|
||||
x_mvmt = current_pos.x() - drag_start_.x();
|
||||
y_mvmt = current_pos.y() - drag_start_.y();
|
||||
x_mvmt = current_pos.x() - drag_start_x_;
|
||||
y_mvmt = current_pos.y() - drag_start_y_;
|
||||
|
||||
QCursor::setPos(drag_start_);
|
||||
QCursor::setPos(QPoint(drag_start_x_, drag_start_y_));
|
||||
#endif
|
||||
|
||||
if (!x_mvmt && !y_mvmt) {
|
||||
return;
|
||||
}
|
||||
if (x_mvmt || y_mvmt) {
|
||||
double multiplier = 1.0;
|
||||
|
||||
if (qApp->keyboardModifiers() & Qt::ControlModifier) {
|
||||
// Movement is vertical
|
||||
y_mobility_ += y_mvmt;
|
||||
|
||||
if (qAbs(y_mobility_) > fontMetrics().height()) {
|
||||
int new_active_element;
|
||||
|
||||
if (y_mvmt < 0) {
|
||||
// Movement is UP
|
||||
new_active_element = active_element_ - 1;
|
||||
} else {
|
||||
// Movement is DOWN
|
||||
new_active_element = active_element_ + 1;
|
||||
if (qApp->keyboardModifiers() & Qt::ControlModifier) {
|
||||
multiplier *= 0.1;
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (qApp->keyboardModifiers() & Qt::ShiftModifier) {
|
||||
multiplier *= 0.1;
|
||||
}
|
||||
|
||||
y_mobility_ = 0;
|
||||
emit DraggedByValue(x_mvmt + y_mvmt, multiplier);
|
||||
}
|
||||
} else {
|
||||
y_mobility_ = 0;
|
||||
|
||||
emit DraggedByValue(x_mvmt + y_mvmt, elements_.at(active_element_)->GetMultiplier());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +238,7 @@ SliderLadderElement::SliderLadderElement(const double &multiplier, QWidget *pare
|
||||
|
||||
label_ = new QLabel();
|
||||
label_->setAlignment(Qt::AlignCenter);
|
||||
label_->setFixedWidth(QtUtils::QFontMetricsWidth(label_->fontMetrics(), QStringLiteral("0000000")));
|
||||
layout->addWidget(label_);
|
||||
|
||||
QPalette p = palette();
|
||||
|
||||
@@ -83,7 +83,8 @@ signals:
|
||||
void Released();
|
||||
|
||||
private:
|
||||
QPoint drag_start_;
|
||||
int drag_start_x_;
|
||||
int drag_start_y_;
|
||||
|
||||
QList<SliderLadderElement*> elements_;
|
||||
|
||||
@@ -91,8 +92,6 @@ private:
|
||||
|
||||
QTimer drag_timer_;
|
||||
|
||||
int y_mobility_;
|
||||
|
||||
private slots:
|
||||
void TimerUpdate();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user