created time slider UI widget

Based on the integer slider, this can be used to interactively control time.
This commit is contained in:
itsmattkc
2019-12-08 00:11:47 +11:00
parent 2fe03debec
commit f2013a6f3d
12 changed files with 140 additions and 48 deletions
@@ -58,7 +58,7 @@ void NodeParamViewWidgetBridge::CreateWidgets()
{
IntegerSlider* slider = new IntegerSlider();
widgets_.append(slider);
connect(slider, SIGNAL(ValueChanged(int)), this, SLOT(WidgetCallback()));
connect(slider, SIGNAL(ValueChanged(int64_t)), this, SLOT(WidgetCallback()));
break;
}
case NodeParam::kFloat:
+2
View File
@@ -28,5 +28,7 @@ set(OLIVE_SOURCES
widget/slider/sliderlineedit.cpp
widget/slider/stringslider.h
widget/slider/stringslider.cpp
widget/slider/timeslider.h
widget/slider/timeslider.cpp
PARENT_SCOPE
)
+11
View File
@@ -53,6 +53,17 @@ void FloatSlider::SetDecimalPlaces(int i)
UpdateLabel(Value());
}
QString FloatSlider::ValueToString(const QVariant &v)
{
return QString::number(v.toDouble(), 'f', decimal_places_);
}
QVariant FloatSlider::StringToValue(const QString &s, bool *ok)
{
// Allow both floats and integers for either modes
return s.toDouble(ok);
}
void FloatSlider::ConvertValue(QVariant v)
{
emit ValueChanged(v.toDouble());
+5
View File
@@ -39,6 +39,11 @@ public:
void SetDecimalPlaces(int i);
protected:
virtual QString ValueToString(const QVariant& v) override;
virtual QVariant StringToValue(const QString& s, bool* ok) override;
signals:
void ValueChanged(double);
+22 -3
View File
@@ -31,21 +31,40 @@ int IntegerSlider::GetValue()
return Value().toInt();
}
void IntegerSlider::SetValue(const int &v)
void IntegerSlider::SetValue(const int64_t &v)
{
SliderBase::SetValue(v);
}
void IntegerSlider::SetMinimum(const int &d)
void IntegerSlider::SetMinimum(const int64_t &d)
{
SetMinimumInternal(d);
}
void IntegerSlider::SetMaximum(const int &d)
void IntegerSlider::SetMaximum(const int64_t &d)
{
SetMaximumInternal(d);
}
QVariant IntegerSlider::StringToValue(const QString &s, bool *ok)
{
bool valid;
// Allow both floats and integers for either modes
double decimal_val = s.toDouble(&valid);
if (ok) {
*ok = valid;
}
if (valid) {
// But for an integer, we round it
return qRound(decimal_val);
}
return QVariant();
}
void IntegerSlider::ConvertValue(QVariant v)
{
emit ValueChanged(v.toInt());
+7 -4
View File
@@ -31,14 +31,17 @@ public:
int GetValue();
void SetValue(const int& v);
void SetValue(const int64_t& v);
void SetMinimum(const int& d);
void SetMinimum(const int64_t& d);
void SetMaximum(const int& d);
void SetMaximum(const int64_t& d);
protected:
virtual QVariant StringToValue(const QString& s, bool* ok) override;
signals:
void ValueChanged(int);
void ValueChanged(int64_t);
private slots:
void ConvertValue(QVariant v);
+20 -40
View File
@@ -31,7 +31,8 @@ SliderBase::SliderBase(Mode mode, QWidget *parent) :
has_min_(false),
has_max_(false),
mode_(mode),
dragged_(false)
dragged_(false),
require_valid_input_(true)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
@@ -66,6 +67,11 @@ void SliderBase::SetDragMultiplier(const double &d)
drag_multiplier_ = d;
}
void SliderBase::SetRequireValidInput(bool e)
{
require_valid_input_ = e;
}
const QVariant &SliderBase::Value()
{
if (dragged_) {
@@ -127,26 +133,18 @@ const QVariant &SliderBase::ClampValue(const QVariant &v)
void SliderBase::UpdateLabel(const QVariant &v)
{
switch (mode_) {
case kString:
{
QString vstr = v.toString();
label_->setText(ValueToString(v));
}
if (vstr.isEmpty()) {
label_->setText(tr("(none)"));
} else {
label_->setText(vstr);
}
break;
}
case kInteger:
label_->setText(v.toString());
break;
case kFloat:
// For floats, we show a limited number of decimal places
label_->setText(QString::number(v.toDouble(), 'f', decimal_places_));
break;
}
QString SliderBase::ValueToString(const QVariant &v)
{
return v.toString();
}
QVariant SliderBase::StringToValue(const QString &s, bool *ok)
{
*ok = true;
return s;
}
void SliderBase::LabelPressed()
@@ -224,25 +222,7 @@ void SliderBase::LabelDragged(int i)
void SliderBase::LineEditConfirmed()
{
bool is_valid = true;
QVariant test_val;
// Check whether the entered value is valid for this mode
switch (mode_) {
case kString:
// Anything goes for a string
test_val = editor_->text();
break;
case kInteger:
case kFloat:
// Allow both floats and integers for either modes
test_val = editor_->text().toDouble(&is_valid);
if (is_valid && mode_ == kInteger) {
// But for an integer, we round it
test_val = qRound(test_val.toDouble());
}
break;
}
QVariant test_val = StringToValue(editor_->text(), &is_valid);
// Ensure editor doesn't signal that the focus is lost
editor_->blockSignals(true);
@@ -253,7 +233,7 @@ void SliderBase::LineEditConfirmed()
setCurrentWidget(label_);
emit ValueChanged(value_);
} else {
} else if (require_valid_input_) {
QMessageBox::critical(this,
tr("Invalid Value"),
tr("The entered value is not valid for this field."),
+8
View File
@@ -40,6 +40,8 @@ public:
void SetDragMultiplier(const double& d);
void SetRequireValidInput(bool e);
signals:
void ValueChanged(QVariant v);
@@ -54,6 +56,10 @@ protected:
void UpdateLabel(const QVariant& v);
virtual QString ValueToString(const QVariant &v);
virtual QVariant StringToValue(const QString& s, bool* ok);
virtual void changeEvent(QEvent* e) override;
int decimal_places_;
@@ -83,6 +89,8 @@ private:
QVariant temp_dragged_value_;
bool require_valid_input_;
private slots:
void LabelPressed();
+6
View File
@@ -36,6 +36,12 @@ void StringSlider::SetValue(const QString &v)
SliderBase::SetValue(v);
}
QString StringSlider::ValueToString(const QVariant &v)
{
QString vstr = v.toString();
return (vstr.isEmpty()) ? tr("(none)") : vstr;
}
void StringSlider::ConvertValue(QVariant v)
{
emit ValueChanged(v.toString());
+3
View File
@@ -35,6 +35,9 @@ public:
void SetValue(const QString& v);
protected:
virtual QString ValueToString(const QVariant& value) override;
signals:
void ValueChanged(QString);
+31
View File
@@ -0,0 +1,31 @@
#include "timeslider.h"
#include "common/timecodefunctions.h"
TimeSlider::TimeSlider(QWidget *parent) :
IntegerSlider(parent)
{
SetMinimum(0);
}
void TimeSlider::SetTimebase(const rational &timebase)
{
timebase_ = timebase;
}
QString TimeSlider::ValueToString(const QVariant &v)
{
if (timebase_.isNull()) {
// We can't generate a timecode without a timebase, so we just return the number
return IntegerSlider::ValueToString(v);
}
return olive::timestamp_to_timecode(v.toLongLong(),
timebase_,
olive::CurrentTimecodeDisplay());
}
QVariant TimeSlider::StringToValue(const QString &s, bool *ok)
{
return olive::timecode_to_timestamp(s, timebase_, olive::CurrentTimecodeDisplay(), ok);
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef TIMESLIDER_H
#define TIMESLIDER_H
#include "common/rational.h"
#include "integerslider.h"
class TimeSlider : public IntegerSlider
{
public:
TimeSlider(QWidget* parent = nullptr);
void SetTimebase(const rational& timebase);
protected:
virtual QString ValueToString(const QVariant& v) override;
virtual QVariant StringToValue(const QString& s, bool* ok) override;
private:
rational timebase_;
};
#endif // TIMESLIDER_H