Merge branch 'rational_slider' of https://github.com/ThomasWilshaw/olive into ThomasWilshaw-rational_slider
This commit is contained in:
@@ -43,6 +43,7 @@ Block::Block() :
|
||||
out_transition_(nullptr)
|
||||
{
|
||||
AddInput(kLengthInput, NodeValue::kRational, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));
|
||||
SetInputProperty(kLengthInput, "min", QVariant::fromValue(rational(0, 1)));
|
||||
IgnoreInvalidationsFrom(kLengthInput);
|
||||
IgnoreHashingFrom(kLengthInput);
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ rational TimeBasedPanel::GetTime()
|
||||
return widget_->GetTime();
|
||||
}
|
||||
|
||||
const rational& TimeBasedPanel::timebase()
|
||||
{
|
||||
return widget_->timebase();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::GoToStart()
|
||||
{
|
||||
widget_->GoToStart();
|
||||
|
||||
@@ -41,6 +41,9 @@ public:
|
||||
|
||||
rational GetTime();
|
||||
|
||||
// Get the timebase of this panels widget
|
||||
const rational& timebase();
|
||||
|
||||
ViewerOutput *GetConnectedViewer() const
|
||||
{
|
||||
return widget_->GetConnectedNode();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "menushared.h"
|
||||
|
||||
#include "core.h"
|
||||
#include "common/timecodefunctions.h"
|
||||
#include "panel/panelmanager.h"
|
||||
#include "panel/timeline/timeline.h"
|
||||
|
||||
@@ -159,10 +160,25 @@ void MenuShared::AddItemsForClipEditMenu(Menu *m)
|
||||
m->addAction(clip_nest_item_);
|
||||
}
|
||||
|
||||
void MenuShared::AddItemsForTimeRulerMenu(Menu *m)
|
||||
void MenuShared::AddItemsForTimeRulerMenu(Menu *m, const rational& timebase)
|
||||
{
|
||||
m->addAction(view_timecode_view_dropframe_item_);
|
||||
m->addAction(view_timecode_view_nondropframe_item_);
|
||||
// If a menu is already created (such as the view menu) we need to remove the instance
|
||||
// of dropframe or non-dropframe timecode that is already there to avoid double displays
|
||||
|
||||
if (m->actions().contains(view_timecode_view_dropframe_item_)) {
|
||||
m->removeAction(view_timecode_view_dropframe_item_);
|
||||
}
|
||||
|
||||
if (m->actions().contains(view_timecode_view_nondropframe_item_)) {
|
||||
m->removeAction(view_timecode_view_nondropframe_item_);
|
||||
}
|
||||
|
||||
if (Timecode::TimebaseIsDropFrame(timebase)) {
|
||||
m->addAction(view_timecode_view_dropframe_item_);
|
||||
m->addAction(view_timecode_view_nondropframe_item_);
|
||||
} else {
|
||||
m->addAction(view_timecode_view_nondropframe_item_);
|
||||
}
|
||||
m->addAction(view_timecode_view_seconds_item_);
|
||||
m->addAction(view_timecode_view_frames_item_);
|
||||
m->addAction(view_timecode_view_milliseconds_item_);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef MENUSHARED_H
|
||||
#define MENUSHARED_H
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "widget/colorlabelmenu/colorlabelmenu.h"
|
||||
#include "widget/menu/menu.h"
|
||||
|
||||
@@ -45,7 +46,7 @@ public:
|
||||
void AddItemsForInOutMenu(Menu* m);
|
||||
void AddColorCodingMenu(Menu* m);
|
||||
void AddItemsForClipEditMenu(Menu* m);
|
||||
void AddItemsForTimeRulerMenu(Menu* m);
|
||||
void AddItemsForTimeRulerMenu(Menu* m, const rational& timebase);
|
||||
|
||||
void AboutToShowTimeRulerActions();
|
||||
|
||||
|
||||
@@ -214,6 +214,10 @@ void NodeParamView::TimebaseChangedEvent(const rational &timebase)
|
||||
|
||||
keyframe_view_->SetTimebase(timebase);
|
||||
|
||||
foreach (NodeParamViewItem* item, items_) {
|
||||
item->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
UpdateItemTime(GetTimestamp());
|
||||
}
|
||||
|
||||
@@ -312,6 +316,9 @@ void NodeParamView::AddNode(Node *n)
|
||||
// Set time target
|
||||
item->SetTimeTarget(GetTimeTarget());
|
||||
|
||||
// Set the timebase
|
||||
item->SetTimebase(timebase());
|
||||
|
||||
items_.insert(n, item);
|
||||
param_widget_area_->addDockWidget(Qt::LeftDockWidgetArea, item);
|
||||
|
||||
|
||||
@@ -86,6 +86,11 @@ void NodeParamViewItem::SetTime(const rational &time)
|
||||
body_->SetTime(time_);
|
||||
}
|
||||
|
||||
void NodeParamViewItem::SetTimebase(const rational& timebase)
|
||||
{
|
||||
body_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
Node *NodeParamViewItem::GetNode() const
|
||||
{
|
||||
return node_;
|
||||
@@ -532,6 +537,13 @@ void NodeParamViewItemBody::ToggleArrayExpanded()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::SetTimebase(const rational& timebase)
|
||||
{
|
||||
foreach (const InputUI& ui_obj, input_ui_map_) {
|
||||
ui_obj.widget_bridge->SetTimebase(timebase);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::ReplaceWidgets(const NodeInput &input)
|
||||
{
|
||||
InputUI ui = input_ui_map_.value(input);
|
||||
|
||||
@@ -85,6 +85,9 @@ public:
|
||||
|
||||
int GetElementY(NodeInput c) const;
|
||||
|
||||
// Set the timebase of any timebased widgets contained here
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
signals:
|
||||
void RequestSetTime(const rational& time);
|
||||
|
||||
@@ -167,6 +170,9 @@ public:
|
||||
|
||||
void SetTime(const rational& time);
|
||||
|
||||
// Set the timebase of the NodeParamViewItemBody
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
Node* GetNode() const;
|
||||
|
||||
bool IsExpanded() const;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "widget/filefield/filefield.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
#include "widget/slider/integerslider.h"
|
||||
#include "widget/slider/rationalslider.h"
|
||||
#include "widget/videoparamedit/videoparamedit.h"
|
||||
|
||||
namespace olive {
|
||||
@@ -77,7 +78,6 @@ void NodeParamViewWidgetBridge::CreateWidgets()
|
||||
case NodeValue::kNone:
|
||||
case NodeValue::kTexture:
|
||||
case NodeValue::kMatrix:
|
||||
case NodeValue::kRational:
|
||||
case NodeValue::kSamples:
|
||||
case NodeValue::kFootageJob:
|
||||
case NodeValue::kShaderJob:
|
||||
@@ -94,6 +94,11 @@ void NodeParamViewWidgetBridge::CreateWidgets()
|
||||
CreateSliders<FloatSlider>(1);
|
||||
break;
|
||||
}
|
||||
case NodeValue::kRational:
|
||||
{
|
||||
CreateSliders<RationalSlider>(1);
|
||||
break;
|
||||
}
|
||||
case NodeValue::kVec2:
|
||||
{
|
||||
CreateSliders<FloatSlider>(2);
|
||||
@@ -270,7 +275,6 @@ void NodeParamViewWidgetBridge::WidgetCallback()
|
||||
case NodeValue::kTexture:
|
||||
case NodeValue::kMatrix:
|
||||
case NodeValue::kSamples:
|
||||
case NodeValue::kRational:
|
||||
case NodeValue::kFootageJob:
|
||||
case NodeValue::kShaderJob:
|
||||
case NodeValue::kSampleJob:
|
||||
@@ -292,6 +296,13 @@ void NodeParamViewWidgetBridge::WidgetCallback()
|
||||
ProcessSlider(slider, slider->GetValue());
|
||||
break;
|
||||
}
|
||||
case NodeValue::kRational:
|
||||
{
|
||||
// Widget is a RationalSlider
|
||||
RationalSlider* slider = static_cast<RationalSlider*>(sender());
|
||||
ProcessSlider(slider, QVariant::fromValue(slider->GetValue()));
|
||||
break;
|
||||
}
|
||||
case NodeValue::kVec2:
|
||||
{
|
||||
// Widget is a FloatSlider
|
||||
@@ -416,7 +427,6 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
|
||||
case NodeValue::kNone:
|
||||
case NodeValue::kTexture:
|
||||
case NodeValue::kMatrix:
|
||||
case NodeValue::kRational:
|
||||
case NodeValue::kSamples:
|
||||
case NodeValue::kFootageJob:
|
||||
case NodeValue::kShaderJob:
|
||||
@@ -433,6 +443,11 @@ void NodeParamViewWidgetBridge::UpdateWidgetValues()
|
||||
static_cast<FloatSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).toDouble());
|
||||
break;
|
||||
}
|
||||
case NodeValue::kRational:
|
||||
{
|
||||
static_cast<RationalSlider*>(widgets_.first())->SetValue(input_.GetValueAtTime(node_time).value<rational>());
|
||||
break;
|
||||
}
|
||||
case NodeValue::kVec2:
|
||||
{
|
||||
QVector2D vec2 = input_.GetValueAtTime(node_time).value<QVector2D>();
|
||||
@@ -523,6 +538,13 @@ rational NodeParamViewWidgetBridge::GetCurrentTimeAsNodeTime() const
|
||||
return GetAdjustedTime(GetTimeTarget(), input_.node(), time_, true);
|
||||
}
|
||||
|
||||
void NodeParamViewWidgetBridge::SetTimebase(const rational& timebase)
|
||||
{
|
||||
if (input_.GetDataType() == NodeValue::kRational) {
|
||||
static_cast<RationalSlider*>(widgets_.first())->SetTimebase(timebase);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamViewWidgetBridge::InputValueChanged(const NodeInput &input, const TimeRange &range)
|
||||
{
|
||||
if (input_ == input
|
||||
@@ -572,7 +594,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QStr
|
||||
static_cast<FloatSlider*>(widgets_.first())->SetMinimum(value.toDouble());
|
||||
break;
|
||||
case NodeValue::kRational:
|
||||
// FIXME: Rational doesn't have a UI implementation yet
|
||||
static_cast<RationalSlider*>(widgets_.first())->SetMinimum(value.value<rational>());
|
||||
break;
|
||||
case NodeValue::kVec2:
|
||||
{
|
||||
@@ -610,7 +632,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QStr
|
||||
static_cast<FloatSlider*>(widgets_.first())->SetMaximum(value.toDouble());
|
||||
break;
|
||||
case NodeValue::kRational:
|
||||
// FIXME: Rational doesn't have a UI implementation yet
|
||||
static_cast<RationalSlider*>(widgets_.first())->SetMaximum(value.value<rational>());
|
||||
break;
|
||||
case NodeValue::kVec2:
|
||||
{
|
||||
@@ -648,7 +670,7 @@ void NodeParamViewWidgetBridge::PropertyChanged(const QString& input, const QStr
|
||||
static_cast<FloatSlider*>(widgets_.first())->SetOffset(value);
|
||||
break;
|
||||
case NodeValue::kRational:
|
||||
// FIXME: Rational doesn't have a UI implementation yet
|
||||
static_cast<RationalSlider*>(widgets_.first())->SetOffset(value);
|
||||
break;
|
||||
case NodeValue::kVec2:
|
||||
{
|
||||
|
||||
@@ -49,6 +49,9 @@ public:
|
||||
return widgets_;
|
||||
}
|
||||
|
||||
// Set the timebase of certain Timebased widgets
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
signals:
|
||||
void ArrayWidgetDoubleClicked();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/***
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 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"
|
||||
|
||||
#include "common/timecodefunctions.h"
|
||||
#include "core.h"
|
||||
#include "widget/menu/menu.h"
|
||||
#include "widget/menu/menushared.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
RationalSlider::RationalSlider(QWidget *parent) :
|
||||
SliderBase(SliderBase::kRational, parent),
|
||||
display_type_(kTimecode),
|
||||
decimal_places_(2),
|
||||
autotrim_decimal_places_(false),
|
||||
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);
|
||||
|
||||
SetDisplayType(display_type_);
|
||||
|
||||
SetValue(rational(0, 0));
|
||||
}
|
||||
|
||||
rational RationalSlider::GetValue()
|
||||
{
|
||||
return Value().value<rational>();
|
||||
}
|
||||
|
||||
void RationalSlider::SetValue(const rational &d)
|
||||
{
|
||||
SliderBase::SetValue(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);
|
||||
}
|
||||
|
||||
void RationalSlider::SetMinimum(const rational &d)
|
||||
{
|
||||
SetMinimumInternal(QVariant::fromValue(d));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void RationalSlider::SetLockDisplayType(bool e)
|
||||
{
|
||||
lock_display_type_ = e;
|
||||
}
|
||||
|
||||
bool RationalSlider::LockDisplayType()
|
||||
{
|
||||
return lock_display_type_;
|
||||
}
|
||||
|
||||
QString RationalSlider::ValueToString(const QVariant &v)
|
||||
{
|
||||
double time = 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;
|
||||
}
|
||||
}
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
QVariant RationalSlider::StringToValue(const QString &s, bool *ok)
|
||||
{
|
||||
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());
|
||||
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;
|
||||
}
|
||||
|
||||
return QVariant::fromValue(r - GetOffset().value<rational>());
|
||||
}
|
||||
|
||||
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<rational>());
|
||||
}
|
||||
|
||||
void RationalSlider::changeDisplayType()
|
||||
{
|
||||
if (!LockDisplayType()) {
|
||||
Menu m(this);
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(&m, timebase_);
|
||||
MenuShared::instance()->AboutToShowTimeRulerActions();
|
||||
|
||||
m.exec(QCursor::pos());
|
||||
ForceLabelUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void RationalSlider::ChangeTimecodeDisplayType()
|
||||
{
|
||||
ForceLabelUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/***
|
||||
Olive - Non-Linear Video Editor
|
||||
Copyright (C) 2021 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/>.
|
||||
***/
|
||||
|
||||
#ifndef RATIONALSLIDER_H
|
||||
#define RATIONALSLIDER_H
|
||||
|
||||
#include "sliderbase.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "common/rational.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
/**
|
||||
* @brief A olive::rational based slider
|
||||
*
|
||||
* A slider that can display rationals as either timecode (drop or non-drop), a timestamp (frames),
|
||||
* or a float (seconds).
|
||||
*/
|
||||
class RationalSlider : public SliderBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* @brief enum containing the possibly display types
|
||||
*/
|
||||
enum DisplayType {
|
||||
kTimecode,
|
||||
kTimestamp,
|
||||
kFloat
|
||||
};
|
||||
|
||||
RationalSlider(QWidget* parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Returns the sliders value as a rational
|
||||
*/
|
||||
rational GetValue();
|
||||
|
||||
/**
|
||||
* @brief Sets the sliders value
|
||||
*/
|
||||
void SetValue(const rational& d);
|
||||
|
||||
/**
|
||||
* @brief Sets the sliders default value
|
||||
*/
|
||||
void SetDefaultValue(const rational& r);
|
||||
|
||||
/**
|
||||
* @brief Sets the sliders default value
|
||||
*/
|
||||
void SetDefaultValue(const QVariant& v);
|
||||
|
||||
/**
|
||||
* @brief Sets the sliders minimum value
|
||||
*/
|
||||
void SetMinimum(const rational& d);
|
||||
|
||||
/**
|
||||
* @brief Sets the sliders maximum value
|
||||
*/
|
||||
void SetMaximum(const rational& d);
|
||||
|
||||
/**
|
||||
* @brief Sets the number of decimal places the slider shows when displaying a float
|
||||
*/
|
||||
void SetDecimalPlaces(int i);
|
||||
|
||||
/**
|
||||
* @brief Sets the sliders timebase which is also the minimum increment of the slider
|
||||
*/
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
/**
|
||||
* @brief Sets the display type of the slider
|
||||
*/
|
||||
void SetDisplayType(const DisplayType& type);
|
||||
|
||||
/**
|
||||
* @brief Set whether the user can change the display type or not
|
||||
*/
|
||||
void SetLockDisplayType(bool e);
|
||||
|
||||
/**
|
||||
* @brief Get whether the user can change the display type or not
|
||||
*/
|
||||
bool LockDisplayType();
|
||||
|
||||
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);
|
||||
|
||||
void changeDisplayType();
|
||||
|
||||
/**
|
||||
* @brief Changes the timecodes display type (e.g. drop frome to none drop frame)
|
||||
*/
|
||||
void ChangeTimecodeDisplayType();
|
||||
|
||||
private:
|
||||
DisplayType display_type_;
|
||||
|
||||
int decimal_places_;
|
||||
|
||||
bool autotrim_decimal_places_;
|
||||
|
||||
rational timebase_;
|
||||
|
||||
bool lock_display_type_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RATIONALSLIDER_H
|
||||
@@ -66,6 +66,7 @@ SliderBase::SliderBase(Mode mode, QWidget *parent) :
|
||||
break;
|
||||
case kInteger:
|
||||
case kFloat:
|
||||
case kRational:
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
break;
|
||||
}
|
||||
@@ -166,8 +167,14 @@ void SliderBase::SetMinimumInternal(const QVariant &v)
|
||||
has_min_ = true;
|
||||
|
||||
// Limit value by this new minimum value
|
||||
if (value_.toDouble() < min_value_.toDouble()) {
|
||||
SetValue(min_value_);
|
||||
if (mode_ == kRational) {
|
||||
if (value_.value<rational>().toDouble() < min_value_.value<rational>().toDouble()) {
|
||||
SetValue(min_value_);
|
||||
}
|
||||
} else {
|
||||
if (value_.toDouble() < min_value_.toDouble()) {
|
||||
SetValue(min_value_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,8 +184,14 @@ void SliderBase::SetMaximumInternal(const QVariant &v)
|
||||
has_max_ = true;
|
||||
|
||||
// Limit value by this new maximum value
|
||||
if (value_.toDouble() > max_value_.toDouble()) {
|
||||
SetValue(max_value_);
|
||||
if (mode_ == kRational) {
|
||||
if (value_.value<rational>().toDouble() > max_value_.value<rational>().toDouble()) {
|
||||
SetValue(max_value_);
|
||||
}
|
||||
} else {
|
||||
if (value_.toDouble() > max_value_.toDouble()) {
|
||||
SetValue(max_value_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,11 +205,21 @@ void SliderBase::changeEvent(QEvent *e)
|
||||
|
||||
const QVariant &SliderBase::ClampValue(const QVariant &v)
|
||||
{
|
||||
if (has_min_ && v.toDouble() < min_value_.toDouble()) {
|
||||
return min_value_;
|
||||
double value, min, max;
|
||||
|
||||
if (mode_ == kRational) {
|
||||
value = v.value<rational>().toDouble();
|
||||
min = min_value_.value<rational>().toDouble();
|
||||
max = max_value_.value<rational>().toDouble();
|
||||
} else {
|
||||
value = v.toDouble();
|
||||
min = min_value_.toDouble();
|
||||
max = max_value_.toDouble();
|
||||
}
|
||||
|
||||
if (has_max_ && v.toDouble() > max_value_.toDouble()) {
|
||||
|
||||
if (has_min_ && value < min) {
|
||||
return min_value_;
|
||||
}else if (has_max_ && value > max) {
|
||||
return max_value_;
|
||||
}
|
||||
|
||||
@@ -266,8 +289,13 @@ void SliderBase::LabelPressed()
|
||||
break;
|
||||
case kInteger:
|
||||
case kFloat:
|
||||
case kRational:
|
||||
{
|
||||
drag_ladder_ = new SliderLadder(drag_multiplier_, ladder_element_count_);
|
||||
if (mode_ == kRational) {
|
||||
drag_ladder_ = new SliderLadder(drag_multiplier_, ladder_element_count_, "00:00:00:00");
|
||||
} else {
|
||||
drag_ladder_ = new SliderLadder(drag_multiplier_, ladder_element_count_, "00000000");
|
||||
}
|
||||
drag_ladder_->SetValue(ValueToString(value_));
|
||||
drag_ladder_->show();
|
||||
|
||||
@@ -315,6 +343,28 @@ void SliderBase::LadderDragged(int value, double multiplier)
|
||||
emit ValueChanged(clamped_temp_dragged_value_);
|
||||
break;
|
||||
}
|
||||
|
||||
case kRational:
|
||||
{
|
||||
dragged_diff_ += value * drag_multiplier_ * multiplier;
|
||||
double drag_val = AdjustDragDistanceInternal(value_.value<rational>().toDouble(), dragged_diff_);
|
||||
rational d_v;
|
||||
d_v = rational::fromDouble(drag_val);
|
||||
temp_dragged_value_.setValue(d_v);
|
||||
|
||||
clamped_temp_dragged_value_ = ClampValue(temp_dragged_value_);
|
||||
|
||||
UpdateLabel(temp_dragged_value_);
|
||||
|
||||
drag_ladder_->SetValue(ValueToString(clamped_temp_dragged_value_));
|
||||
|
||||
if (!Config::Current()[QStringLiteral("UseSliderLadders")].toBool()) {
|
||||
RepositionLadder();
|
||||
}
|
||||
|
||||
emit ValueChanged(clamped_temp_dragged_value_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,6 +386,8 @@ void SliderBase::LadderReleased()
|
||||
case kFloat:
|
||||
SetValue(clamped_temp_dragged_value_.toDouble());
|
||||
break;
|
||||
case kRational:
|
||||
SetValue(temp_dragged_value_);
|
||||
}
|
||||
|
||||
emit ValueChanged(value_);
|
||||
|
||||
@@ -35,7 +35,8 @@ public:
|
||||
enum Mode {
|
||||
kString,
|
||||
kInteger,
|
||||
kFloat
|
||||
kFloat,
|
||||
kRational
|
||||
};
|
||||
|
||||
SliderBase(Mode mode, QWidget* parent = nullptr);
|
||||
@@ -84,6 +85,8 @@ protected:
|
||||
|
||||
void UpdateLabel(const QVariant& v);
|
||||
|
||||
QLabel* label() { return label_; }
|
||||
|
||||
virtual double AdjustDragDistanceInternal(const double& start, const double& drag);
|
||||
|
||||
virtual QString ValueToString(const QVariant &v) = 0;
|
||||
@@ -155,7 +158,6 @@ private slots:
|
||||
void ResetValue();
|
||||
|
||||
void RepositionLadder();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@ SliderLabel::SliderLabel(QWidget *parent) :
|
||||
|
||||
// Allow users to tab to this widget
|
||||
setFocusPolicy(Qt::TabFocus);
|
||||
|
||||
// Add ccustom context menu
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
}
|
||||
|
||||
void SliderLabel::mousePressEvent(QMouseEvent *e)
|
||||
|
||||
@@ -45,6 +45,8 @@ signals:
|
||||
|
||||
void RequestReset();
|
||||
|
||||
void ChangeSliderType();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +37,9 @@
|
||||
|
||||
namespace olive {
|
||||
|
||||
SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget* parent) :
|
||||
QFrame(parent, Qt::Popup)
|
||||
SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QString width_hint, QWidget* parent) :
|
||||
QFrame(parent, Qt::Popup),
|
||||
width_hint_(width_hint)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
@@ -52,17 +53,17 @@ SliderLadder::SliderLadder(double drag_multiplier, int nb_outer_values, QWidget*
|
||||
}
|
||||
|
||||
for (int i=nb_outer_values-1;i>=0;i--) {
|
||||
elements_.append(new SliderLadderElement(qPow(10, i + 1) * drag_multiplier));
|
||||
elements_.append(new SliderLadderElement(qPow(10, i + 1) * drag_multiplier, width_hint_));
|
||||
}
|
||||
|
||||
// Create center entry
|
||||
SliderLadderElement* start_element = new SliderLadderElement(drag_multiplier);
|
||||
SliderLadderElement* start_element = new SliderLadderElement(drag_multiplier, width_hint_);
|
||||
active_element_ = elements_.size();
|
||||
start_element->SetHighlighted(true);
|
||||
elements_.append(start_element);
|
||||
|
||||
for (int i=0;i<nb_outer_values;i++) {
|
||||
elements_.append(new SliderLadderElement(qPow(10, - i - 1) * drag_multiplier));
|
||||
elements_.append(new SliderLadderElement(qPow(10, -i - 1) * drag_multiplier, width_hint_));
|
||||
}
|
||||
|
||||
foreach (SliderLadderElement* e, elements_) {
|
||||
@@ -231,7 +232,7 @@ bool SliderLadder::UsingLadders() const
|
||||
return elements_.size() > 1;
|
||||
}
|
||||
|
||||
SliderLadderElement::SliderLadderElement(const double &multiplier, QWidget *parent) :
|
||||
SliderLadderElement::SliderLadderElement(const double &multiplier, QString width_hint, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
multiplier_(multiplier),
|
||||
highlighted_(false),
|
||||
@@ -241,7 +242,7 @@ SliderLadderElement::SliderLadderElement(const double &multiplier, QWidget *pare
|
||||
|
||||
label_ = new QLabel();
|
||||
label_->setAlignment(Qt::AlignCenter);
|
||||
label_->setFixedWidth(QtUtils::QFontMetricsWidth(label_->fontMetrics(), QStringLiteral("0000000")));
|
||||
label_->setFixedWidth(QtUtils::QFontMetricsWidth(label_->fontMetrics(), width_hint));
|
||||
layout->addWidget(label_);
|
||||
|
||||
QPalette p = palette();
|
||||
|
||||
@@ -33,7 +33,7 @@ class SliderLadderElement : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SliderLadderElement(const double& multiplier, QWidget* parent = nullptr);
|
||||
SliderLadderElement(const double& multiplier, QString width_hint, QWidget* parent = nullptr);
|
||||
|
||||
void SetHighlighted(bool e);
|
||||
|
||||
@@ -64,7 +64,7 @@ class SliderLadder : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SliderLadder(double drag_multiplier, int nb_outer_values, QWidget* parent = nullptr);
|
||||
SliderLadder(double drag_multiplier, int nb_outer_values, QString width_hint, QWidget* parent = nullptr);
|
||||
|
||||
virtual ~SliderLadder() override;
|
||||
|
||||
@@ -94,6 +94,8 @@ private:
|
||||
|
||||
QTimer drag_timer_;
|
||||
|
||||
QString width_hint_;
|
||||
|
||||
private slots:
|
||||
void TimerUpdate();
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ void TimeRuler::ShowContextMenu()
|
||||
{
|
||||
Menu m(this);
|
||||
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(&m);
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(&m, timebase());
|
||||
MenuShared::instance()->AboutToShowTimeRulerActions();
|
||||
|
||||
m.exec(QCursor::pos());
|
||||
|
||||
@@ -112,9 +112,6 @@ MainMenu::MainMenu(MainWindow *parent) :
|
||||
view_decrease_track_height_item_ = view_menu_->AddItem("vzoomout", this, &MainMenu::DecreaseTrackHeightTriggered, "Ctrl+-");
|
||||
view_show_all_item_ = view_menu_->AddItem("showall", this, &MainMenu::ToggleShowAllTriggered, "\\");
|
||||
view_show_all_item_->setCheckable(true);
|
||||
view_menu_->addSeparator();
|
||||
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(view_menu_);
|
||||
|
||||
view_menu_->addSeparator();
|
||||
|
||||
@@ -306,6 +303,15 @@ void MainMenu::ViewMenuAboutToShow()
|
||||
// Parent is QMainWindow
|
||||
view_full_screen_item_->setChecked(parentWidget()->isFullScreen());
|
||||
|
||||
// Make sure we're displaying the correct options for the timebase
|
||||
TimeBasedPanel* p = PanelManager::instance()->MostRecentlyFocused<TimeBasedPanel>();
|
||||
if (p) {
|
||||
if (p->timebase().denominator() != 0) {
|
||||
view_menu_->addSeparator();
|
||||
MenuShared::instance()->AddItemsForTimeRulerMenu(view_menu_, p->timebase());
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure checked timecode display mode is correct
|
||||
MenuShared::instance()->AboutToShowTimeRulerActions();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user