/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "sliderladder.h" #include #include #include #include #include #ifdef Q_OS_MAC #include #endif #include "common/clamp.h" #include "common/lerp.h" OLIVE_NAMESPACE_ENTER SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget* parent) : QFrame(parent, Qt::Popup), y_mobility_(0) { QVBoxLayout* layout = new QVBoxLayout(this); layout->setMargin(0); layout->setSpacing(0); setFrameShape(QFrame::Box); setLineWidth(1); for (int i=nb_outer_values-1;i>=0;i--) { elements_.append(new SliderLadderElement(qPow(10, i + 1) * 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;iaddWidget(e); } if (elements_.size() == 1) { elements_.first()->SetMultiplierVisible(false); } drag_timer_.setInterval(10); connect(&drag_timer_, &QTimer::timeout, this, &SliderLadder::TimerUpdate); #if defined(Q_OS_MAC) CGAssociateMouseAndMouseCursorPosition(false); CGDisplayHideCursor(kCGDirectMainDisplay); CGGetLastMouseDelta(nullptr, nullptr); #else drag_start_ = QCursor::pos(); static_cast(QApplication::instance())->setOverrideCursor(Qt::BlankCursor); #endif } SliderLadder::~SliderLadder() { #if defined(Q_OS_MAC) CGAssociateMouseAndMouseCursorPosition(true); CGDisplayShowCursor(kCGDirectMainDisplay); #else static_cast(QApplication::instance())->restoreOverrideCursor(); #endif } void SliderLadder::SetValue(const QString &s) { foreach (SliderLadderElement* e, elements_) { e->SetValue(s); } } void SliderLadder::mouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event) drag_timer_.stop(); emit Released(); } void SliderLadder::showEvent(QShowEvent *event) { QWidget::showEvent(event); drag_timer_.start(); } void SliderLadder::TimerUpdate() { int32_t x_mvmt, y_mvmt; // Keep cursor in the same position #if defined(Q_OS_MAC) CGGetLastMouseDelta(&x_mvmt, &y_mvmt); #else QPoint current_pos = QCursor::pos(); x_mvmt = current_pos.x() - drag_start_.x(); y_mvmt = current_pos.y() - drag_start_.y(); QCursor::setPos(drag_start_); #endif if (!x_mvmt && !y_mvmt) { return; } 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; } // 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 { y_mobility_ = 0; emit DraggedByValue(x_mvmt + y_mvmt, elements_.at(active_element_)->GetMultiplier()); } } SliderLadderElement::SliderLadderElement(const double &multiplier, QWidget *parent) : QWidget(parent), multiplier_(multiplier), highlighted_(false), multiplier_visible_(true) { QVBoxLayout* layout = new QVBoxLayout(this); label_ = new QLabel(); label_->setAlignment(Qt::AlignCenter); layout->addWidget(label_); QPalette p = palette(); QColor highlight_color = palette().text().color(); highlight_color.setAlpha(64); p.setColor(QPalette::Highlight, highlight_color); setPalette(p); setAutoFillBackground(true); UpdateLabel(); } void SliderLadderElement::SetHighlighted(bool e) { highlighted_ = e; if (highlighted_) { setBackgroundRole(QPalette::Highlight); } else { setBackgroundRole(QPalette::Window); } UpdateLabel(); } void SliderLadderElement::SetValue(const QString &value) { value_ = value; UpdateLabel(); } void SliderLadderElement::SetMultiplierVisible(bool e) { multiplier_visible_ = e; UpdateLabel(); } void SliderLadderElement::UpdateLabel() { if (multiplier_visible_) { QString val_text; if (highlighted_) { val_text = value_; } label_->setText(QStringLiteral("%1\n%2").arg(QString::number(multiplier_), val_text)); } else { label_->setText(value_); } } OLIVE_NAMESPACE_EXIT