speedduration: more or less done now
This commit is contained in:
@@ -22,8 +22,11 @@
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "core.h"
|
||||
#include "widget/nodeparamview/nodeparamviewundo.h"
|
||||
#include "widget/timelinewidget/undo/timelineundopointer.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
@@ -105,7 +108,13 @@ SpeedDurationDialog::SpeedDurationDialog(const QVector<ClipBlock *> &clips, cons
|
||||
|
||||
void SpeedDurationDialog::accept()
|
||||
{
|
||||
super::accept();
|
||||
// We haven't implemented rippling yet, so warn the user
|
||||
if (ripple_box_->isChecked()) {
|
||||
// FIXME: Stub
|
||||
if (QMessageBox::information(this, QString(), tr("Rippling is a stub and will not do anything. Do you wish to continue?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MultiUndoCommand *command = new MultiUndoCommand();
|
||||
|
||||
@@ -114,33 +123,47 @@ void SpeedDurationDialog::accept()
|
||||
if (link_box_->isChecked() && !dur_slider_->IsTristate()) {
|
||||
// Automatically determine speed from duration
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new SetSpeedCommand(c, GetSpeedAdjustment(c->speed(), c->length(), dur_slider_->GetValue())));
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), GetSpeedAdjustment(c->speed(), c->length(), dur_slider_->GetValue())));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Set speeds to value of slider
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
command->add_child(new SetSpeedCommand(c, speed_slider_->GetValue()));
|
||||
command->add_child(new NodeParamSetStandardValueCommand(NodeKeyframeTrackReference(NodeInput(c, ClipBlock::kSpeedInput)), speed_slider_->GetValue()));
|
||||
}
|
||||
}
|
||||
|
||||
// Set duration values
|
||||
if (ripple_box_->isChecked()) {
|
||||
// Determine where and how much we need to ripple
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
rational new_len = c->length();
|
||||
if (dur_slider_->IsTristate()) {
|
||||
if (link_box_->isChecked() && !speed_slider_->IsTristate()) {
|
||||
new_len = GetLengthAdjustment(c->length(), c->speed(), speed_slider_->GetValue(), timebase_);
|
||||
foreach (ClipBlock *c, clips_) {
|
||||
rational proposed_length = c->length();
|
||||
|
||||
if (dur_slider_->IsTristate()) {
|
||||
if (link_box_->isChecked() && !speed_slider_->IsTristate()) {
|
||||
proposed_length = GetLengthAdjustment(c->length(), c->speed(), speed_slider_->GetValue(), timebase_);
|
||||
}
|
||||
} else {
|
||||
proposed_length = dur_slider_->GetValue();
|
||||
}
|
||||
|
||||
if (proposed_length != c->length()) {
|
||||
// Clip length should ideally change, but check if there's "room" to do so
|
||||
if (proposed_length > c->length() && c->next()) {
|
||||
if (GapBlock *gap = dynamic_cast<GapBlock*>(c->next())) {
|
||||
proposed_length = qMin(proposed_length, gap->out() - c->in());
|
||||
} else {
|
||||
proposed_length = c->length();
|
||||
}
|
||||
} else {
|
||||
new_len = dur_slider_->GetValue();
|
||||
}
|
||||
|
||||
if (proposed_length != c->length()) {
|
||||
command->add_child(new BlockTrimCommand(c->track(), c, proposed_length, Timeline::kTrimOut));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Core::instance()->undo_stack()->push(command);
|
||||
|
||||
super::accept();
|
||||
}
|
||||
|
||||
rational SpeedDurationDialog::GetLengthAdjustment(const rational &original_length, double original_speed, double new_speed, const rational &timebase)
|
||||
@@ -179,15 +202,4 @@ void SpeedDurationDialog::DurationChanged(const rational &r)
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedDurationDialog::SetSpeedCommand::redo()
|
||||
{
|
||||
old_speed_ = clip_->speed();
|
||||
clip_->set_speed(new_speed_);
|
||||
}
|
||||
|
||||
void SpeedDurationDialog::SetSpeedCommand::undo()
|
||||
{
|
||||
clip_->set_speed(old_speed_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QDialog>
|
||||
|
||||
#include "node/block/clip/clip.h"
|
||||
#include "node/block/gap/gap.h"
|
||||
#include "undo/undocommand.h"
|
||||
#include "widget/slider/floatslider.h"
|
||||
#include "widget/slider/rationalslider.h"
|
||||
@@ -37,30 +38,6 @@ class SpeedDurationDialog : public QDialog
|
||||
public:
|
||||
explicit SpeedDurationDialog(const QVector<ClipBlock*> &clips, const rational &timebase, QWidget *parent = nullptr);
|
||||
|
||||
class SetSpeedCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
SetSpeedCommand(ClipBlock *clip, double new_speed) :
|
||||
clip_(clip),
|
||||
new_speed_(new_speed)
|
||||
{}
|
||||
|
||||
virtual void redo() override;
|
||||
|
||||
virtual void undo() override;
|
||||
|
||||
virtual Project *GetRelevantProject() const override
|
||||
{
|
||||
return clip_->project();
|
||||
}
|
||||
|
||||
private:
|
||||
ClipBlock *clip_;
|
||||
double new_speed_;
|
||||
double old_speed_;
|
||||
|
||||
};
|
||||
|
||||
public slots:
|
||||
virtual void accept() override;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "common/qtutils.h"
|
||||
#include "core.h"
|
||||
#include "dialog/speedduration/speeddurationdialog.h"
|
||||
#include "node/project/sequence/sequence.h"
|
||||
#include "nodeparamviewundo.h"
|
||||
|
||||
@@ -35,6 +36,7 @@ namespace olive {
|
||||
const int NodeParamViewItemBody::kKeyControlColumn = 10;
|
||||
const int NodeParamViewItemBody::kArrayInsertColumn = kKeyControlColumn-1;
|
||||
const int NodeParamViewItemBody::kArrayRemoveColumn = kArrayInsertColumn-1;
|
||||
const int NodeParamViewItemBody::kExtraButtonColumn = kKeyControlColumn-1;
|
||||
|
||||
// 0 is for the array collapse button, 1 is for the main label, widgets start at 2
|
||||
const int NodeParamViewItemBody::kWidgetStartColumn = 2;
|
||||
@@ -221,7 +223,8 @@ void NodeParamViewItemTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
NodeParamViewItemBody::NodeParamViewItemBody(Node* node, QWidget *parent) :
|
||||
QWidget(parent)
|
||||
QWidget(parent),
|
||||
node_(node)
|
||||
{
|
||||
QGridLayout* root_layout = new QGridLayout(this);
|
||||
|
||||
@@ -313,6 +316,14 @@ void NodeParamViewItemBody::CreateWidgets(QGridLayout* layout, Node *node, const
|
||||
connect(remove_element_btn, &NodeParamViewArrayButton::clicked, this, &NodeParamViewItemBody::ArrayRemoveClicked);
|
||||
|
||||
}
|
||||
} else if (dynamic_cast<ClipBlock*>(node) && input == ClipBlock::kSpeedInput) {
|
||||
// Special behavior - this was the most preferable way to do this so we could support multiple
|
||||
// nodes per item one day
|
||||
QPushButton *btn = new QPushButton(tr("..."));
|
||||
btn->setFixedWidth(btn->sizeHint().height());
|
||||
connect(btn, &QPushButton::clicked, this, &NodeParamViewItemBody::ShowSpeedDurationDialogForNode);
|
||||
layout->addWidget(btn, row, kExtraButtonColumn);
|
||||
ui_objects.extra_btn = btn;
|
||||
}
|
||||
|
||||
// Create a widget/input bridge for this input
|
||||
@@ -541,6 +552,8 @@ void NodeParamViewItemBody::ToggleArrayExpanded()
|
||||
|
||||
void NodeParamViewItemBody::SetTimebase(const rational& timebase)
|
||||
{
|
||||
timebase_ = timebase;
|
||||
|
||||
foreach (const InputUI& ui_obj, input_ui_map_) {
|
||||
ui_obj.widget_bridge->SetTimebase(timebase);
|
||||
}
|
||||
@@ -552,11 +565,19 @@ void NodeParamViewItemBody::ReplaceWidgets(const NodeInput &input)
|
||||
PlaceWidgetsFromBridge(ui.layout, ui.widget_bridge, ui.row);
|
||||
}
|
||||
|
||||
void NodeParamViewItemBody::ShowSpeedDurationDialogForNode()
|
||||
{
|
||||
// We should only get there if the node is a clip, determined by the dynamic_cast in CreateWidgets
|
||||
SpeedDurationDialog sdd({static_cast<ClipBlock*>(node_)}, timebase_, this);
|
||||
sdd.exec();
|
||||
}
|
||||
|
||||
NodeParamViewItemBody::InputUI::InputUI() :
|
||||
main_label(nullptr),
|
||||
widget_bridge(nullptr),
|
||||
connected_label(nullptr),
|
||||
key_control(nullptr),
|
||||
extra_btn(nullptr),
|
||||
array_insert_btn(nullptr),
|
||||
array_remove_btn(nullptr)
|
||||
{
|
||||
|
||||
@@ -111,6 +111,7 @@ private:
|
||||
NodeParamViewKeyframeControl* key_control;
|
||||
QGridLayout* layout;
|
||||
int row;
|
||||
QPushButton *extra_btn;
|
||||
|
||||
NodeParamViewArrayButton* array_insert_btn;
|
||||
NodeParamViewArrayButton* array_remove_btn;
|
||||
@@ -124,10 +125,14 @@ private:
|
||||
NodeParamViewArrayButton* append_btn;
|
||||
};
|
||||
|
||||
Node *node_;
|
||||
|
||||
QHash<NodeInputPair, ArrayUI> array_ui_;
|
||||
|
||||
QHash<NodeInputPair, CollapseButton*> array_collapse_buttons_;
|
||||
|
||||
rational timebase_;
|
||||
|
||||
/**
|
||||
* @brief The column to place the keyframe controls in
|
||||
*
|
||||
@@ -138,6 +143,7 @@ private:
|
||||
|
||||
static const int kArrayInsertColumn;
|
||||
static const int kArrayRemoveColumn;
|
||||
static const int kExtraButtonColumn;
|
||||
|
||||
static const int kWidgetStartColumn;
|
||||
|
||||
@@ -158,6 +164,8 @@ private slots:
|
||||
|
||||
void ReplaceWidgets(const NodeInput& input);
|
||||
|
||||
void ShowSpeedDurationDialogForNode();
|
||||
|
||||
};
|
||||
|
||||
class NodeParamViewItem : public QDockWidget
|
||||
|
||||
Reference in New Issue
Block a user