created time slider UI widget
Based on the integer slider, this can be used to interactively control time.
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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."),
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -35,6 +35,9 @@ public:
|
||||
|
||||
void SetValue(const QString& v);
|
||||
|
||||
protected:
|
||||
virtual QString ValueToString(const QVariant& value) override;
|
||||
|
||||
signals:
|
||||
void ValueChanged(QString);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user