diff --git a/app/widget/slider/CMakeLists.txt b/app/widget/slider/CMakeLists.txt index ef2b3443c..0d9d22944 100644 --- a/app/widget/slider/CMakeLists.txt +++ b/app/widget/slider/CMakeLists.txt @@ -20,6 +20,8 @@ set(OLIVE_SOURCES widget/slider/floatslider.cpp widget/slider/integerslider.h widget/slider/integerslider.cpp + widget/slider/rationalslider.h + widget/slider/rationalslider.cpp widget/slider/sliderbase.h widget/slider/sliderbase.cpp widget/slider/sliderlabel.h diff --git a/app/widget/slider/rationalslider.cpp b/app/widget/slider/rationalslider.cpp new file mode 100644 index 000000000..a2650207e --- /dev/null +++ b/app/widget/slider/rationalslider.cpp @@ -0,0 +1,142 @@ +/*** + Olive - Non-Linear Video Editor + Copyright (C) 2020 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 "rationalslider.h" + +#include "common/timecodefunctions.h" +#include "core.h" + +namespace olive { + +RationalSlider::RationalSlider(rational timebase, QWidget *parent) : + SliderBase(SliderBase::kRational, parent), + display_type_(kTimecode), + decimal_places_(2), + autotrim_decimal_places_(false), + timebase_(timebase) +{ + connect(this, SIGNAL(ValueChanged(QVariant)), this, SLOT(ConvertValue(QVariant))); +} + +rational RationalSlider::GetValue() +{ + return Value().value(); +} + +void RationalSlider::SetValue(const rational &d) +{ + QVariant r; + r.setValue(d); + SliderBase::SetValue(r); +} + +void RationalSlider::SetMinimum(const rational &d) +{ + QVariant r; + r.setValue(d); + SetMinimumInternal(r); +} + +void RationalSlider::SetMaximum(const rational &d) +{ + QVariant r; + r.setValue(d); + SetMaximumInternal(r); +} + +void RationalSlider::SetDecimalPlaces(int i) +{ + decimal_places_ = i; + + ForceLabelUpdate(); +} + +void RationalSlider::SetTimebase(const rational &timebase) +{ + timebase_ = timebase; + + // Refresh label since we have a new timebase to generate a timecode with + UpdateLabel(Value()); +} + +void RationalSlider::SetAutoTrimDecimalPlaces(bool e) { + autotrim_decimal_places_ = e; + + ForceLabelUpdate(); +} + +void RationalSlider::SetDisplayType(const RationalSlider::DisplayType &type) +{ + display_type_ = type; + + switch (display_type_) { + case kTimecode: + case kRational: + ClearFormat(); + break; + case kTimestamp: + SetFormat("%1 Frames"); + break; + case kFloat: + SetFormat("%1 Seconds"); + break; + } +} + +QString RationalSlider::ValueToString(const QVariant &v) +{ + rational r = v.value(); + switch (display_type_) { + case kTimecode: + return Timecode::time_to_timecode(r, timebase_, Core::instance()->GetTimecodeDisplay()); + case kTimestamp: + return QString::number(Timecode::time_to_timestamp(r, timebase_)); + case kRational: + // Might we want to call reduce() on r here? + return r.toString(); + case kFloat: + { + QString s = QString::number(r.toDouble(), 'f', decimal_places_); + + if (autotrim_decimal_places_) { + while (s.endsWith('0') && s.at(s.size() - 2).isDigit()) { + s = s.left(s.size() - 1); + } + } + return s; + } + } + return r.toString(); +} + +QVariant RationalSlider::StringToValue(const QString &s, bool *ok) +{ + // Just try to convert the string to a double + // REMEMBER TO IMPLEMENT!!!! + return s.toDouble(ok); +} + +double RationalSlider::AdjustDragDistanceInternal(const double &start, const double &drag) +{ + // Assume we want smallest increment to be timebase or 1 frame + return start + drag*timebase_.toDouble(); +} + +void RationalSlider::ConvertValue(QVariant v) +{ + emit ValueChanged(v.value()); +} + +} diff --git a/app/widget/slider/rationalslider.h b/app/widget/slider/rationalslider.h new file mode 100644 index 000000000..916b06513 --- /dev/null +++ b/app/widget/slider/rationalslider.h @@ -0,0 +1,80 @@ +/*** + Olive - Non-Linear Video Editor + Copyright (C) 2020 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 . +***/ + +#ifndef RATIONALSLIDER_H +#define RATIONALSLIDER_H + +#include "sliderbase.h" + +#include "common/rational.h" + +namespace olive { + +class RationalSlider : public SliderBase +{ + Q_OBJECT +public: + RationalSlider(QWidget* parent = nullptr); + + enum DisplayType { + kTimecode, + kTimestamp, + kRational, + kFloat + }; + + rational GetValue(); + + void SetValue(const rational& d); + + void SetMinimum(const rational& d); + + void SetMaximum(const rational& d); + + void SetDecimalPlaces(int i); + + void SetTimebase(const rational& timebase); + + void SetDisplayType(const DisplayType& type); + + void SetAutoTrimDecimalPlaces(bool e); + +protected: + virtual QString ValueToString(const QVariant& v) override; + + virtual QVariant StringToValue(const QString& s, bool* ok) override; + + virtual double AdjustDragDistanceInternal(const double& start, const double& drag) override; + +signals: + void ValueChanged(rational); + +private slots: + void ConvertValue(QVariant v); + +private: + DisplayType display_type_; + + int decimal_places_; + + bool autotrim_decimal_places_; + + rational timebase_; + +}; + +} + +#endif // RATIONALSLIDER_H diff --git a/app/widget/slider/sliderbase.cpp b/app/widget/slider/sliderbase.cpp index 25d36f10b..5d1781b27 100644 --- a/app/widget/slider/sliderbase.cpp +++ b/app/widget/slider/sliderbase.cpp @@ -65,6 +65,7 @@ SliderBase::SliderBase(Mode mode, QWidget *parent) : break; case kInteger: case kFloat: + case kRational: setCursor(Qt::SizeHorCursor); break; } @@ -276,6 +277,7 @@ void SliderBase::LadderDragged(int value, double multiplier) break; case kInteger: case kFloat: + case kRational: { dragged_diff_ += value * drag_multiplier_ * multiplier; @@ -322,6 +324,10 @@ void SliderBase::LadderReleased() case kFloat: SetValue(clamped_temp_dragged_value_.toDouble()); break; + case kRational: + QVariant r; + r.setValue(rational(temp_dragged_value_.toDouble())); + SetValue(r); } emit ValueChanged(value_); diff --git a/app/widget/slider/sliderbase.h b/app/widget/slider/sliderbase.h index 5d5a9fc95..19d7dd897 100644 --- a/app/widget/slider/sliderbase.h +++ b/app/widget/slider/sliderbase.h @@ -35,7 +35,8 @@ public: enum Mode { kString, kInteger, - kFloat + kFloat, + kRational }; SliderBase(Mode mode, QWidget* parent = nullptr);