slider: reworked sliderbase and derivatives
Mostly cleaning up code, SliderBase was fairly messy.
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
/***
|
||||
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 Olive Team
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
***/
|
||||
|
||||
#include "rationalslider.h"
|
||||
@@ -22,40 +27,33 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
#define super DecimalSliderBase
|
||||
|
||||
RationalSlider::RationalSlider(QWidget *parent) :
|
||||
SliderBase(SliderBase::kRational, parent),
|
||||
display_type_(kTimecode),
|
||||
decimal_places_(2),
|
||||
autotrim_decimal_places_(false),
|
||||
super(parent),
|
||||
lock_display_type_(false)
|
||||
{
|
||||
connect(this, SIGNAL(ValueChanged(QVariant)), this, SLOT(ConvertValue(QVariant)));
|
||||
connect(Core::instance(), &Core::TimecodeDisplayChanged, this, &RationalSlider::ChangeTimecodeDisplayType);
|
||||
connect(SliderBase::label(), &SliderLabel::customContextMenuRequested, this, &RationalSlider::changeDisplayType);
|
||||
connect(Core::instance(), &Core::TimecodeDisplayChanged, this, &RationalSlider::UpdateLabel);
|
||||
connect(SliderBase::label(), &SliderLabel::customContextMenuRequested, this, &RationalSlider::ShowDisplayTypeMenu);
|
||||
|
||||
SetDisplayType(display_type_);
|
||||
SetDisplayType(kFloat);
|
||||
|
||||
SetValue(rational(0, 0));
|
||||
}
|
||||
|
||||
rational RationalSlider::GetValue()
|
||||
{
|
||||
return Value().value<rational>();
|
||||
return GetValueInternal().value<rational>();
|
||||
}
|
||||
|
||||
void RationalSlider::SetValue(const rational &d)
|
||||
{
|
||||
SliderBase::SetValue(QVariant::fromValue(d));
|
||||
SetValueInternal(QVariant::fromValue(d));
|
||||
}
|
||||
|
||||
void RationalSlider::SetDefaultValue(const rational &r)
|
||||
{
|
||||
SliderBase::SetDefaultValue(QVariant::fromValue(r));
|
||||
}
|
||||
|
||||
void RationalSlider::SetDefaultValue(const QVariant &v) {
|
||||
rational r = v.value<rational>();
|
||||
SetDefaultValue(r);
|
||||
super::SetDefaultValue(QVariant::fromValue(r));
|
||||
}
|
||||
|
||||
void RationalSlider::SetMinimum(const rational &d)
|
||||
@@ -68,42 +66,19 @@ void RationalSlider::SetMaximum(const rational &d)
|
||||
SetMaximumInternal(QVariant::fromValue(d));
|
||||
}
|
||||
|
||||
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();
|
||||
UpdateLabel();
|
||||
}
|
||||
|
||||
void RationalSlider::SetDisplayType(const RationalSlider::DisplayType &type)
|
||||
{
|
||||
display_type_ = type;
|
||||
|
||||
switch (display_type_) {
|
||||
case kTimecode:
|
||||
ClearFormat();
|
||||
break;
|
||||
case kTimestamp:
|
||||
SetFormat("%1 Frames");
|
||||
break;
|
||||
case kFloat:
|
||||
SetFormat("%1 s");
|
||||
break;
|
||||
}
|
||||
UpdateLabel();
|
||||
}
|
||||
|
||||
void RationalSlider::SetLockDisplayType(bool e)
|
||||
@@ -111,87 +86,130 @@ void RationalSlider::SetLockDisplayType(bool e)
|
||||
lock_display_type_ = e;
|
||||
}
|
||||
|
||||
bool RationalSlider::LockDisplayType()
|
||||
bool RationalSlider::GetLockDisplayType()
|
||||
{
|
||||
return lock_display_type_;
|
||||
}
|
||||
|
||||
QString RationalSlider::ValueToString(const QVariant &v)
|
||||
void RationalSlider::DisableDisplayType(RationalSlider::DisplayType type)
|
||||
{
|
||||
double time = v.value<rational>().toDouble() + GetOffset().value<rational>().toDouble();
|
||||
disabled_.append(type);
|
||||
}
|
||||
|
||||
QString RationalSlider::ValueToString(const QVariant &v) const
|
||||
{
|
||||
double val = v.value<rational>().toDouble() + GetOffset().value<rational>().toDouble();
|
||||
|
||||
switch (display_type_) {
|
||||
case kTimecode:
|
||||
return Timecode::time_to_timecode(v.value<rational>(), timebase_, Core::instance()->GetTimecodeDisplay());
|
||||
case kTimestamp:
|
||||
return QString::number(Timecode::time_to_timestamp(time, timebase_));
|
||||
case kFloat:
|
||||
{
|
||||
QString s = QString::number(time, '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;
|
||||
}
|
||||
case kTime:
|
||||
return Timecode::time_to_timecode(v.value<rational>(), timebase_, Core::instance()->GetTimecodeDisplay());
|
||||
case kFloat:
|
||||
return FloatToString(val, GetDecimalPlaces(), GetAutoTrimDecimalPlaces());
|
||||
case kRational:
|
||||
return v.value<rational>().toString();
|
||||
}
|
||||
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
QVariant RationalSlider::StringToValue(const QString &s, bool *ok)
|
||||
QVariant RationalSlider::StringToValue(const QString &s, bool *ok) const
|
||||
{
|
||||
rational r;
|
||||
*ok = false;
|
||||
|
||||
switch (display_type_) {
|
||||
case kTimecode:
|
||||
{
|
||||
int t = Timecode::timecode_to_timestamp(s, timebase_, Core::instance()->GetTimecodeDisplay(), ok);
|
||||
r = rational(t, timebase_.denominator());
|
||||
case kTime:
|
||||
{
|
||||
r = Timecode::timecode_to_time(s, timebase_, Core::instance()->GetTimecodeDisplay(), ok);
|
||||
break;
|
||||
}
|
||||
case kFloat:
|
||||
{
|
||||
// First, convert to a double
|
||||
double d = s.toDouble(ok);
|
||||
if (!(*ok)) {
|
||||
break;
|
||||
}
|
||||
case kTimestamp:
|
||||
r = rational(s.toInt(ok), timebase_.denominator());
|
||||
break;
|
||||
case kFloat:
|
||||
r = rational::fromDouble(s.toDouble(ok));
|
||||
if (!r.isNull()) {
|
||||
*ok = true;
|
||||
}
|
||||
break;
|
||||
|
||||
// If double conversion succeeded, convert to a rational
|
||||
r = rational::fromDouble(d, ok);
|
||||
break;
|
||||
}
|
||||
case kRational:
|
||||
r = rational::fromString(s, ok);
|
||||
break;
|
||||
}
|
||||
|
||||
return QVariant::fromValue(r - GetOffset().value<rational>());
|
||||
//return QVariant::fromValue(r - GetOffset().value<rational>());
|
||||
return QVariant::fromValue(r);
|
||||
}
|
||||
|
||||
double RationalSlider::AdjustDragDistanceInternal(const double &start, const double &drag)
|
||||
QVariant RationalSlider::AdjustDragDistanceInternal(const QVariant &start, const double &drag) const
|
||||
{
|
||||
// Assume we want smallest increment to be timebase or 1 frame
|
||||
return start + drag*timebase_.toDouble();
|
||||
return QVariant::fromValue(start.value<rational>() + rational::fromDouble(drag)*timebase_);
|
||||
}
|
||||
|
||||
void RationalSlider::ConvertValue(QVariant v)
|
||||
void RationalSlider::ValueSignalEvent(const QVariant &v)
|
||||
{
|
||||
emit ValueChanged(v.value<rational>());
|
||||
}
|
||||
|
||||
void RationalSlider::changeDisplayType()
|
||||
bool RationalSlider::ValueGreaterThan(const QVariant &lhs, const QVariant &rhs) const
|
||||
{
|
||||
if (!LockDisplayType()) {
|
||||
Menu m(this);
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(&m, timebase_);
|
||||
MenuShared::instance()->AboutToShowTimeRulerActions();
|
||||
return lhs.value<rational>() > rhs.value<rational>();
|
||||
}
|
||||
|
||||
bool RationalSlider::ValueLessThan(const QVariant &lhs, const QVariant &rhs) const
|
||||
{
|
||||
return lhs.value<rational>() < rhs.value<rational>();
|
||||
}
|
||||
|
||||
void RationalSlider::ShowDisplayTypeMenu()
|
||||
{
|
||||
Menu m(this);
|
||||
|
||||
if (!GetLockDisplayType()) {
|
||||
if (!disabled_.contains(kFloat)) {
|
||||
QAction* float_action = m.addAction(tr("Float"));
|
||||
float_action->setData(kFloat);
|
||||
connect(float_action, &QAction::triggered, this, &RationalSlider::SetDisplayTypeFromMenu);
|
||||
}
|
||||
|
||||
if (!disabled_.contains(kRational)) {
|
||||
QAction* rational_action = m.addAction(tr("Rational"));
|
||||
rational_action->setData(kRational);
|
||||
connect(rational_action, &QAction::triggered, this, &RationalSlider::SetDisplayTypeFromMenu);
|
||||
}
|
||||
|
||||
if (!disabled_.contains(kTime)) {
|
||||
QAction* time_action = m.addAction(tr("Time"));
|
||||
time_action->setData(kTime);
|
||||
connect(time_action, &QAction::triggered, this, &RationalSlider::SetDisplayTypeFromMenu);
|
||||
}
|
||||
}
|
||||
|
||||
if (display_type_ == kTime) {
|
||||
if (!m.actions().isEmpty()) {
|
||||
m.addSeparator();
|
||||
}
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(&m);
|
||||
MenuShared::instance()->AboutToShowTimeRulerActions(timebase_);
|
||||
}
|
||||
|
||||
if (!m.actions().isEmpty()) {
|
||||
m.exec(QCursor::pos());
|
||||
ForceLabelUpdate();
|
||||
UpdateLabel();
|
||||
}
|
||||
}
|
||||
|
||||
void RationalSlider::ChangeTimecodeDisplayType()
|
||||
void RationalSlider::SetDisplayTypeFromMenu()
|
||||
{
|
||||
ForceLabelUpdate();
|
||||
QAction* action = static_cast<QAction*>(sender());
|
||||
|
||||
DisplayType type = static_cast<DisplayType>(action->data().toInt());
|
||||
|
||||
SetDisplayType(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user