From c6a2349ad6d6eb60cbc2668bf6a701d3d8cab46d Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 15 Mar 2021 13:43:04 +1100 Subject: [PATCH] improved slider ladders --- app/config/config.cpp | 1 + .../tabs/preferencesbehaviortab.cpp | 3 + app/widget/slider/sliderbase.cpp | 40 ++--- app/widget/slider/sliderbase.h | 5 +- app/widget/slider/sliderladder.cpp | 144 ++++++++++++------ app/widget/slider/sliderladder.h | 5 +- 6 files changed, 129 insertions(+), 69 deletions(-) diff --git a/app/config/config.cpp b/app/config/config.cpp index 4f4bffc59..f3d69f13d 100644 --- a/app/config/config.cpp +++ b/app/config/config.cpp @@ -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); diff --git a/app/dialog/preferences/tabs/preferencesbehaviortab.cpp b/app/dialog/preferences/tabs/preferencesbehaviortab.cpp index b27dca71c..eee5680c1 100644 --- a/app/dialog/preferences/tabs/preferencesbehaviortab.cpp +++ b/app/dialog/preferences/tabs/preferencesbehaviortab.cpp @@ -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"), diff --git a/app/widget/slider/sliderbase.cpp b/app/widget/slider/sliderbase.cpp index b3e6ce6ee..737612464 100644 --- a/app/widget/slider/sliderbase.cpp +++ b/app/widget/slider/sliderbase.cpp @@ -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); + } +} + } diff --git a/app/widget/slider/sliderbase.h b/app/widget/slider/sliderbase.h index 31c6d31c4..f4b77200e 100644 --- a/app/widget/slider/sliderbase.h +++ b/app/widget/slider/sliderbase.h @@ -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(); + }; } diff --git a/app/widget/slider/sliderladder.cpp b/app/widget/slider/sliderladder.cpp index 3412f7d5f..5b34b57fe 100644 --- a/app/widget/slider/sliderladder.cpp +++ b/app/widget/slider/sliderladder.cpp @@ -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(QApplication::instance())->setOverrideCursor(Qt::BlankCursor); + static_cast(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(QApplication::instance())->restoreOverrideCursor(); + static_cast(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; iunderMouse()) { + 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(); diff --git a/app/widget/slider/sliderladder.h b/app/widget/slider/sliderladder.h index aac5c1bd3..a881cd75a 100644 --- a/app/widget/slider/sliderladder.h +++ b/app/widget/slider/sliderladder.h @@ -83,7 +83,8 @@ signals: void Released(); private: - QPoint drag_start_; + int drag_start_x_; + int drag_start_y_; QList elements_; @@ -91,8 +92,6 @@ private: QTimer drag_timer_; - int y_mobility_; - private slots: void TimerUpdate();