merged fxrestructure

This commit is contained in:
itsmattkc
2019-03-16 20:14:36 +11:00
289 changed files with 8975 additions and 6556 deletions
+260 -167
View File
@@ -33,35 +33,36 @@
#include <QApplication>
#include "panels/panels.h"
#include "project/effect.h"
#include "project/clip.h"
#include "project/transition.h"
#include "effects/effect.h"
#include "effects/effectloaders.h"
#include "effects/transition.h"
#include "timeline/clip.h"
#include "ui/collapsiblewidget.h"
#include "project/sequence.h"
#include "project/undo.h"
#include "project/effectloaders.h"
#include "timeline/sequence.h"
#include "undo/undo.h"
#include "undo/undostack.h"
#include "panels/project.h"
#include "panels/timeline.h"
#include "panels/viewer.h"
#include "panels/grapheditor.h"
#include "ui/viewerwidget.h"
#include "io/clipboard.h"
#include "io/config.h"
#include "ui/menuhelper.h"
#include "project/clipboard.h"
#include "global/config.h"
#include "ui/timelineheader.h"
#include "ui/keyframeview.h"
#include "ui/resizablescrollbar.h"
#include "debug.h"
#include "global/debug.h"
EffectControls::EffectControls(QWidget *parent) :
Panel(parent),
multiple(false),
zoom(1),
mode(kTransitionNone)
zoom(1)
{
setup_ui();
Retranslate();
clear_effects(false);
Clear(false);
headers->viewer = panel_sequence_viewer;
headers->snapping = false;
@@ -70,8 +71,6 @@ EffectControls::EffectControls(QWidget *parent) :
effects_area->header = headers;
keyframeView->header = headers;
lblMultipleClipsSelected->setVisible(false);
connect(keyframeView, SIGNAL(wheel_event_signal(QWheelEvent*)), effects_area, SLOT(receive_wheel_event(QWheelEvent*)));
connect(horizontalScrollBar, SIGNAL(valueChanged(int)), headers, SLOT(set_scroll(int)));
connect(horizontalScrollBar, SIGNAL(resize_move(double)), keyframeView, SLOT(resize_move(double)));
@@ -81,10 +80,9 @@ EffectControls::EffectControls(QWidget *parent) :
connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar, SLOT(setValue(int)));
}
EffectControls::~EffectControls() {}
int EffectControls::get_mode() {
return mode;
EffectControls::~EffectControls()
{
Clear(true);
}
bool EffectControls::keyframe_focus() {
@@ -99,8 +97,8 @@ void EffectControls::set_zoom(bool in) {
void EffectControls::menu_select(QAction* q) {
ComboAction* ca = new ComboAction();
for (int i=0;i<selected_clips.size();i++) {
Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)).get();
for (int i=0;i<selected_clips_.size();i++) {
Clip* c = selected_clips_.at(i);
if ((c->track() < 0) == (effect_menu_subtype == EFFECT_TYPE_VIDEO)) {
const EffectMeta* meta = reinterpret_cast<const EffectMeta*>(q->data().value<quintptr>());
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
@@ -127,12 +125,17 @@ void EffectControls::menu_select(QAction* q) {
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
update_ui(true);
} else {
reload_clips();
Reload();
panel_sequence_viewer->viewer_widget->frame_update();
}
}
void EffectControls::update_keyframes() {
for (int i=0;i<open_effects_.size();i++) {
EffectUI* ui = open_effects_.at(i);
ui->UpdateFromEffect();
}
headers->update_zoom(zoom);
keyframeView->update();
}
@@ -142,39 +145,43 @@ void EffectControls::delete_selected_keyframes() {
}
void EffectControls::copy(bool del) {
if (mode == kTransitionNone) {
bool cleared = false;
bool cleared = false;
ComboAction* ca = new ComboAction();
EffectDeleteCommand* del_com = (del) ? new EffectDeleteCommand() : nullptr;
for (int i=0;i<selected_clips.size();i++) {
Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)).get();
for (int j=0;j<c->effects.size();j++) {
EffectPtr effect = c->effects.at(j);
if (effect->container->selected) {
if (!cleared) {
clear_clipboard();
cleared = true;
clipboard_type = CLIPBOARD_TYPE_EFFECT;
}
ComboAction* ca = nullptr;
if (del) {
ca = new ComboAction();
}
clipboard.append(EffectPtr(effect->copy(nullptr)));
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i)->IsSelected()) {
Effect* e = open_effects_.at(i)->GetEffect();
if (del_com != nullptr) {
del_com->clips.append(c);
del_com->fx.append(j);
}
if (e->meta->type == EFFECT_TYPE_EFFECT) {
if (!cleared) {
clear_clipboard();
cleared = true;
clipboard_type = CLIPBOARD_TYPE_EFFECT;
}
clipboard.append(e->copy(nullptr));
if (del) {
DeleteEffect(ca, e);
}
}
}
if (del_com != nullptr) {
if (del_com->clips.size() > 0) {
ca->append(del_com);
} else {
delete del_com;
}
}
if (del) {
if (ca->hasActions()) {
olive::UndoStack.push(ca);
} else {
delete ca;
}
olive::UndoStack.push(ca);
}
}
@@ -182,11 +189,6 @@ void EffectControls::scroll_to_frame(long frame) {
scroll_to_frame_internal(horizontalScrollBar, frame - keyframeView->visible_in, zoom, keyframeView->width());
}
void EffectControls::add_effect_paste_action(QMenu *menu) {
QAction* paste_action = menu->addAction(tr("&Paste"), panel_timeline, SLOT(paste(bool)));
paste_action->setEnabled(clipboard.size() > 0 && clipboard_type == CLIPBOARD_TYPE_EFFECT);
}
void EffectControls::cut() {
copy(true);
}
@@ -261,56 +263,68 @@ void EffectControls::show_effect_menu(int type, int subtype) {
effects_menu.exec(QCursor::pos());
}
void EffectControls::clear_effects(bool clear_cache) {
void EffectControls::Clear(bool clear_cache) {
// clear existing clips
deselect_all_effects(nullptr);
// clear graph editor
if (panel_graph_editor != nullptr) panel_graph_editor->set_row(nullptr);
for (int i=0;i<open_effects_.size();i++) {
delete open_effects_.at(i);
}
open_effects_.clear();
keyframeView->SetEffects(open_effects_);
QVBoxLayout* video_layout = static_cast<QVBoxLayout*>(video_effect_area->layout());
QVBoxLayout* audio_layout = static_cast<QVBoxLayout*>(audio_effect_area->layout());
QLayoutItem* item;
while ((item = video_layout->takeAt(0))) {
item->widget()->setParent(nullptr);
disconnect(static_cast<CollapsibleWidget*>(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
}
while ((item = audio_layout->takeAt(0))) {
item->widget()->setParent(nullptr);
disconnect(static_cast<CollapsibleWidget*>(item->widget()), SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
}
lblMultipleClipsSelected->setVisible(false);
vcontainer->setVisible(false);
acontainer->setVisible(false);
headers->setVisible(false);
keyframeView->setEnabled(false);
if (clear_cache) selected_clips.clear();
if (clear_cache) {
selected_clips_.clear();
}
UpdateTitle();
}
void EffectControls::deselect_all_effects(QWidget* sender) {
for (int i=0;i<selected_clips.size();i++) {
const ClipPtr& c = olive::ActiveSequence->clips.at(selected_clips.at(i));
for (int j=0;j<c->effects.size();j++) {
if (c->effects.at(j)->container != sender) {
c->effects.at(j)->container->header_click(false, false);
}
bool EffectControls::IsEffectSelected(Effect *e)
{
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i)->GetEffect() == e && open_effects_.at(i)->IsSelected()) {
return true;
}
}
panel_sequence_viewer->viewer_widget->update();
return false;
}
void EffectControls::open_effect(QVBoxLayout* layout, EffectPtr e) {
CollapsibleWidget* container = e->container;
layout->addWidget(container);
void EffectControls::deselect_all_effects(QWidget* sender) {
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i) != sender) {
open_effects_.at(i)->header_click(false, false);
}
}
if (panel_sequence_viewer != nullptr) {
panel_sequence_viewer->viewer_widget->update();
}
}
void EffectControls::open_effect(QVBoxLayout* layout, Effect* e) {
EffectUI* container = new EffectUI(e);
connect(container, SIGNAL(CutRequested()), this, SLOT(cut()));
connect(container, SIGNAL(CopyRequested()), this, SLOT(copy()));
connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
open_effects_.append(container);
layout->addWidget(container);
}
void EffectControls::UpdateTitle() {
if (selected_clips.empty()) {
if (selected_clips_.isEmpty()) {
setWindowTitle(panel_name + tr("(none)"));
} else {
setWindowTitle(panel_name + olive::ActiveSequence->clips.at(selected_clips.at(0))->name());
setWindowTitle(panel_name + selected_clips_.first()->name());
}
}
@@ -387,9 +401,9 @@ void EffectControls::setup_ui() {
vcontainerLayout->addWidget(veHeader);
video_effect_area = new QWidget();
QVBoxLayout* veAreaLayout = new QVBoxLayout(video_effect_area);
veAreaLayout->setSpacing(0);
veAreaLayout->setMargin(0);
video_effect_layout = new QVBoxLayout(video_effect_area);
video_effect_layout->setSpacing(0);
video_effect_layout->setMargin(0);
vcontainerLayout->addWidget(video_effect_area);
@@ -429,18 +443,14 @@ void EffectControls::setup_ui() {
acontainerLayout->addWidget(aeHeader);
audio_effect_area = new QWidget();
QVBoxLayout* aeAreaLayout = new QVBoxLayout(audio_effect_area);
aeAreaLayout->setSpacing(0);
aeAreaLayout->setMargin(0);
audio_effect_layout = new QVBoxLayout(audio_effect_area);
audio_effect_layout->setSpacing(0);
audio_effect_layout->setMargin(0);
acontainerLayout->addWidget(audio_effect_area);
effects_area_layout->addWidget(acontainer);
lblMultipleClipsSelected = new QLabel();
lblMultipleClipsSelected->setAlignment(Qt::AlignCenter);
effects_area_layout->addWidget(lblMultipleClipsSelected);
effects_area_layout->addStretch();
scrollAreaLayout->addWidget(effects_area);
@@ -502,7 +512,6 @@ void EffectControls::Retranslate() {
btnAddAudioEffect->setToolTip(tr("Add Audio Effect"));
lblAudioEffects->setText(tr("AUDIO EFFECTS"));
btnAddAudioTransition->setToolTip(tr("Add Audio Transition"));
lblMultipleClipsSelected->setText(tr("(Multiple clips selected)"));
UpdateTitle();
}
@@ -530,83 +539,167 @@ void EffectControls::queue_post_update() {
void EffectControls::effects_area_context_menu() {
QMenu menu(this);
add_effect_paste_action(&menu);
olive::MenuHelper.create_effect_paste_action(&menu);
menu.exec(QCursor::pos());
}
void EffectControls::load_effects() {
lblMultipleClipsSelected->setVisible(multiple);
void EffectControls::DeleteEffect(ComboAction* ca, Effect* effect_ref) {
if (effect_ref->meta->type == EFFECT_TYPE_EFFECT) {
if (!multiple) {
// load in new clips
for (int i=0;i<selected_clips.size();i++) {
ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i));
QVBoxLayout* layout;
if (c->track() < 0) {
vcontainer->setVisible(true);
layout = static_cast<QVBoxLayout*>(video_effect_area->layout());
} else {
acontainer->setVisible(true);
layout = static_cast<QVBoxLayout*>(audio_effect_area->layout());
ca->append(new EffectDeleteCommand(effect_ref));
} else if (effect_ref->meta->type == EFFECT_TYPE_TRANSITION) {
// Retrieve shared ptr for this transition
Clip* attached_clip = effect_ref->parent_clip;
TransitionPtr t = nullptr;
if (attached_clip->opening_transition.get() == effect_ref) {
t = attached_clip->opening_transition;
} else if (attached_clip->closing_transition.get() == effect_ref) {
t = attached_clip->closing_transition;
}
if (t == nullptr) {
qWarning() << "Failed to delete transition, couldn't find clip link.";
} else {
ca->append(new DeleteTransitionCommand(t));
}
}
}
void EffectControls::DeleteSelectedEffects() {
ComboAction* ca = new ComboAction();
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i)->IsSelected()) {
DeleteEffect(ca, open_effects_.at(i)->GetEffect());
}
}
if (ca->hasActions()) {
olive::UndoStack.push(ca);
update_ui(true);
} else {
delete ca;
}
}
void EffectControls::Reload() {
Clear(false);
Load();
}
void EffectControls::SetClips()
{
Clear(true);
// replace clip vector
selected_clips_ = olive::ActiveSequence->SelectedClips(false);
Load();
}
void EffectControls::Load() {
bool graph_editor_row_is_still_active = false;
// load in new clips
for (int i=0;i<selected_clips_.size();i++) {
Clip* c = selected_clips_.at(i);
QVBoxLayout* layout;
if (c->track() < 0) {
vcontainer->setVisible(true);
layout = video_effect_layout;
} else {
acontainer->setVisible(true);
layout = audio_effect_layout;
}
// Create a list of the effects we'll open
QVector<Effect*> effects_to_open;
// Determine based on the current selections whether to load all effects or just the transitions
bool whole_clip_is_selected = c->IsSelected();
if (whole_clip_is_selected) {
for (int j=0;j<c->effects.size();j++) {
effects_to_open.append(c->effects.at(j).get());
}
if (mode == kTransitionNone) {
for (int j=0;j<c->effects.size();j++) {
open_effect(layout, c->effects.at(j));
}
if (c->opening_transition != nullptr
&& (whole_clip_is_selected || c->sequence->IsTransitionSelected(c->opening_transition.get()))) {
effects_to_open.append(c->opening_transition.get());
}
if (c->closing_transition != nullptr
&& (whole_clip_is_selected || c->sequence->IsTransitionSelected(c->closing_transition.get()))) {
effects_to_open.append(c->closing_transition.get());
}
for (int j=0;j<effects_to_open.size();j++) {
// Check if we've already opened an effect of this type before
bool already_opened = false;
for (int k=0;k<open_effects_.size();k++) {
if (open_effects_.at(k)->GetEffect()->meta == effects_to_open.at(j)->meta
&& !open_effects_.at(k)->IsAttachedToClip(c)) {
open_effects_.at(k)->AddAdditionalEffect(effects_to_open.at(j));
already_opened = true;
break;
}
}
if (!already_opened) {
open_effect(layout, effects_to_open.at(j));
}
// Check if one of the open effects contains the row currently active in the graph editor. If not, we'll have
// to clear the graph editor later.
if (!graph_editor_row_is_still_active) {
for (int k=0;k<effects_to_open.at(j)->row_count();k++) {
EffectRow* row = effects_to_open.at(j)->row(k);
if (row == panel_graph_editor->get_row()) {
graph_editor_row_is_still_active = true;
break;
}
}
} else if (mode == kTransitionOpening && c->opening_transition != nullptr) {
open_effect(layout, c->opening_transition);
} else if (mode == kTransitionClosing && c->closing_transition != nullptr) {
open_effect(layout, c->closing_transition);
}
}
if (selected_clips.size() > 0) {
keyframeView->setEnabled(true);
headers->setVisible(true);
}
QTimer::singleShot(50, this, SLOT(queue_post_update()));
}
keyframeView->SetEffects(open_effects_);
if (selected_clips_.size() > 0) {
keyframeView->setEnabled(true);
headers->setVisible(true);
QTimer::singleShot(50, this, SLOT(queue_post_update()));
}
// If the graph editor's currently active row is not part of the current effects, clear it
if (!graph_editor_row_is_still_active) {
panel_graph_editor->set_row(nullptr);
}
UpdateTitle();
}
void EffectControls::delete_effects() {
// load in new clips
if (mode == kTransitionNone) {
EffectDeleteCommand* command = new EffectDeleteCommand();
for (int i=0;i<selected_clips.size();i++) {
Clip* c = olive::ActiveSequence->clips.at(selected_clips.at(i)).get();
for (int j=0;j<c->effects.size();j++) {
EffectPtr effect = c->effects.at(j);
if (effect->container->selected) {
command->clips.append(c);
command->fx.append(j);
}
}
}
if (command->clips.size() > 0) {
olive::UndoStack.push(command);
panel_sequence_viewer->viewer_widget->frame_update();
} else {
delete command;
}
}
}
void EffectControls::reload_clips() {
clear_effects(false);
load_effects();
}
void EffectControls::set_clips(QVector<int>& clips, int m) {
clear_effects(true);
// replace clip vector
selected_clips = clips;
mode = m;
load_effects();
update_keyframes();
}
void EffectControls::video_effect_click() {
@@ -631,18 +724,13 @@ void EffectControls::resizeEvent(QResizeEvent*) {
bool EffectControls::is_focused() {
if (this->hasFocus()) return true;
for (int i=0;i<selected_clips.size();i++) {
ClipPtr c = olive::ActiveSequence->clips.at(selected_clips.at(i));
if (c != nullptr) {
for (int j=0;j<c->effects.size();j++) {
if (c->effects.at(j)->container->is_focused()) {
return true;
}
}
} else {
qWarning() << "Tried to check focus of a nullptr clip";
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i)->IsFocused()) {
return true;
}
}
return false;
}
@@ -650,6 +738,11 @@ EffectsArea::EffectsArea(QWidget* parent) :
QWidget(parent)
{}
void EffectsArea::resizeEvent(QResizeEvent *)
{
parent_widget->setMinimumWidth(sizeHint().width());
}
void EffectsArea::receive_wheel_event(QWheelEvent *e) {
QApplication::sendEvent(this, e);
}
+29 -20
View File
@@ -37,14 +37,17 @@
#include "ui/resizablescrollbar.h"
#include "ui/keyframeview.h"
#include "ui/panel.h"
#include "ui/effectui.h"
class EffectsArea : public QWidget {
Q_OBJECT
public:
EffectsArea(QWidget* parent = 0);
EffectsArea(QWidget* parent = nullptr);
QScrollArea* parent_widget;
KeyframeView* keyframe_area;
TimelineHeader* header;
protected:
void resizeEvent(QResizeEvent*);
public slots:
void receive_wheel_event(QWheelEvent* e);
};
@@ -53,29 +56,28 @@ class EffectControls : public Panel
{
Q_OBJECT
public:
explicit EffectControls(QWidget *parent = 0);
~EffectControls();
int get_mode();
void set_clips(QVector<int>& clips, int mode);
void clear_effects(bool clear_cache);
void delete_effects();
explicit EffectControls(QWidget *parent = nullptr);
virtual ~EffectControls() override;
void Reload();
void SetClips();
void Clear(bool clear_cache = true);
bool IsEffectSelected(Effect* e);
void DeleteSelectedEffects();
bool is_focused();
void reload_clips();
void set_zoom(bool in);
bool keyframe_focus();
void delete_selected_keyframes();
bool multiple;
void scroll_to_frame(long frame);
QVector<int> selected_clips;
double zoom;
ResizableScrollBar* horizontalScrollBar;
QScrollBar* verticalScrollBar;
void add_effect_paste_action(QMenu* menu);
virtual void Retranslate() override;
virtual void LoadLayoutState(const QByteArray& data) override;
@@ -101,10 +103,16 @@ private slots:
protected:
virtual void resizeEvent(QResizeEvent *event) override;
private:
QVector<Clip*> selected_clips_;
QVector<EffectUI*> open_effects_;
void Load();
void DeleteEffect(ComboAction* ca, Effect* effect_ref);
void show_effect_menu(int type, int subtype);
void load_effects();
void load_keyframes();
void open_effect(QVBoxLayout* hlayout, EffectPtr e);
void open_effect(QVBoxLayout* hlayout, Effect *e);
void UpdateTitle();
void setup_ui();
@@ -112,22 +120,23 @@ private:
int effect_menu_type;
int effect_menu_subtype;
QString panel_name;
int mode;
QWidget* video_effect_area;
QWidget* audio_effect_area;
QVBoxLayout* video_effect_layout;
QVBoxLayout* audio_effect_layout;
QSplitter* splitter;
QPushButton* btnAddVideoEffect;
QLabel* lblVideoEffects;
QLabel* lblAudioEffects;
QPushButton* btnAddVideoTransition;
QPushButton* btnAddAudioEffect;
QPushButton* btnAddAudioTransition;
QLabel* lblMultipleClipsSelected;
QLabel* lblAudioEffects;
TimelineHeader* headers;
EffectsArea* effects_area;
QScrollArea* scrollArea;
KeyframeView* keyframeView;
QWidget* video_effect_area;
QWidget* audio_effect_area;
QWidget* vcontainer;
QWidget* acontainer;
};
+39 -45
View File
@@ -30,12 +30,13 @@
#include "ui/timelinetools.h"
#include "ui/labelslider.h"
#include "ui/graphview.h"
#include "project/effect.h"
#include "project/effectfield.h"
#include "project/effectrow.h"
#include "project/clip.h"
#include "effects/effect.h"
#include "effects/effectfields.h"
#include "effects/effectrow.h"
#include "timeline/clip.h"
#include "rendering/renderfunctions.h"
#include "panels.h"
#include "debug.h"
#include "global/debug.h"
GraphEditor::GraphEditor(QWidget* parent) : Panel(parent), row(nullptr) {
resize(720, 480);
@@ -129,6 +130,11 @@ GraphEditor::GraphEditor(QWidget* parent) : Panel(parent), row(nullptr) {
Retranslate();
}
EffectRow *GraphEditor::get_row()
{
return row;
}
void GraphEditor::Retranslate() {
setWindowTitle(tr("Graph Editor"));
linear_button->setText(tr("Linear"));
@@ -140,10 +146,10 @@ void GraphEditor::update_panel() {
if (isVisible()) {
if (row != nullptr) {
int slider_index = 0;
for (int i=0;i<row->fieldCount();i++) {
EffectField* field = row->field(i);
if (field->type == EFFECT_FIELD_DOUBLE) {
slider_proxies.at(slider_index)->set_value(row->field(i)->get_current_data().toDouble(), false);
for (int i=0;i<row->FieldCount();i++) {
EffectField* field = row->Field(i);
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
field->UpdateWidgetValue(field_sliders_.at(slider_index), field->Now());
slider_index++;
}
}
@@ -155,45 +161,41 @@ void GraphEditor::update_panel() {
}
void GraphEditor::set_row(EffectRow *r) {
for (int i=0;i<slider_proxies.size();i++) {
delete slider_proxies.at(i);
delete slider_proxy_buttons.at(i);
for (int i=0;i<field_sliders_.size();i++) {
delete field_sliders_.at(i);
delete field_enable_buttons.at(i);
}
slider_proxies.clear();
slider_proxy_buttons.clear();
slider_proxy_sources.clear();
field_sliders_.clear();
field_enable_buttons.clear();
if (row != nullptr) {
// clear old row connections
disconnect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
disconnect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
disconnect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key()));
disconnect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(GoToPreviousKeyframe()));
disconnect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(ToggleKeyframe()));
disconnect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(GoToNextKeyframe()));
}
bool found_vals = false;
if (r != nullptr && r->isKeyframing()) {
for (int i=0;i<r->fieldCount();i++) {
EffectField* field = r->field(i);
if (field->type == EFFECT_FIELD_DOUBLE) {
if (r != nullptr && r->IsKeyframing()) {
for (int i=0;i<r->FieldCount();i++) {
EffectField* field = r->Field(i);
if (field->type() == EffectField::EFFECT_FIELD_DOUBLE) {
QPushButton* slider_button = new QPushButton();
slider_button->setCheckable(true);
slider_button->setChecked(field->is_enabled());
slider_button->setChecked(field->IsEnabled());
slider_button->setIcon(QIcon(":/icons/record.svg"));
slider_button->setProperty("field", i);
slider_button->setIconSize(slider_button->iconSize()*0.5);
connect(slider_button, SIGNAL(toggled(bool)), this, SLOT(set_field_visibility(bool)));
slider_proxy_buttons.append(slider_button);
field_enable_buttons.append(slider_button);
value_layout->addWidget(slider_button);
LabelSlider* slider = new LabelSlider();
slider->set_color(get_curve_color(i, r->fieldCount()).name());
connect(slider, SIGNAL(valueChanged()), this, SLOT(passthrough_slider_value()));
slider_proxies.append(slider);
LabelSlider* slider = static_cast<LabelSlider*>(field->CreateWidget());
slider->SetColor(get_curve_color(i, r->FieldCount()).name());
field_sliders_.append(slider);
value_layout->addWidget(slider);
slider_proxy_sources.append(static_cast<LabelSlider*>(field->ui_element));
found_vals = true;
}
}
@@ -201,14 +203,14 @@ void GraphEditor::set_row(EffectRow *r) {
if (found_vals) {
row = r;
current_row_desc->setText(row->parent_effect->parent_clip->name()
+ " :: " + row->parent_effect->meta->name
+ " :: " + row->get_name());
header->set_visible_in(r->parent_effect->parent_clip->timeline_in());
current_row_desc->setText(row->GetParentEffect()->parent_clip->name()
+ " :: " + row->GetParentEffect()->meta->name
+ " :: " + row->name());
header->set_visible_in(r->GetParentEffect()->parent_clip->timeline_in());
connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(goto_previous_key()));
connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(toggle_key()));
connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(goto_next_key()));
connect(keyframe_nav, SIGNAL(goto_previous_key()), row, SLOT(GoToPreviousKeyframe()));
connect(keyframe_nav, SIGNAL(toggle_key()), row, SLOT(ToggleKeyframe()));
connect(keyframe_nav, SIGNAL(goto_next_key()), row, SLOT(GoToNextKeyframe()));
} else {
row = nullptr;
current_row_desc->setText(nullptr);
@@ -242,14 +244,6 @@ void GraphEditor::set_key_button_enabled(bool e, int type) {
hold_button->setChecked(type == EFFECT_KEYFRAME_HOLD);
}
void GraphEditor::passthrough_slider_value() {
for (int i=0;i<slider_proxies.size();i++) {
if (slider_proxies.at(i) == sender()) {
slider_proxy_sources.at(i)->set_value(slider_proxies.at(i)->value(), true);
}
}
}
void GraphEditor::set_keyframe_type() {
linear_button->setChecked(linear_button == sender());
bezier_button->setChecked(bezier_button == sender());
+6 -6
View File
@@ -30,15 +30,17 @@
#include "ui/timelineheader.h"
#include "ui/labelslider.h"
#include "ui/keyframenavigator.h"
#include "project/effectrow.h"
#include "effects/effectrow.h"
class GraphEditor : public Panel {
Q_OBJECT
public:
GraphEditor(QWidget* parent = nullptr);
void update_panel();
EffectRow* get_row();
void set_row(EffectRow* r);
void update_panel();
bool view_is_focused();
bool view_is_under_mouse();
void delete_selected_keys();
@@ -50,9 +52,8 @@ private:
GraphView* view;
TimelineHeader* header;
QHBoxLayout* value_layout;
QVector<LabelSlider*> slider_proxies;
QVector<QPushButton*> slider_proxy_buttons;
QVector<LabelSlider*> slider_proxy_sources;
QVector<LabelSlider*> field_sliders_;
QVector<QPushButton*> field_enable_buttons;
QLabel* current_row_desc;
EffectRow* row;
KeyframeNavigator* keyframe_nav;
@@ -61,7 +62,6 @@ private:
QPushButton* hold_button;
private slots:
void set_key_button_enabled(bool e, int type);
void passthrough_slider_value();
void set_keyframe_type();
void set_field_visibility(bool b);
};
+9 -97
View File
@@ -20,13 +20,12 @@
#include "panels.h"
#include "project/sequence.h"
#include "project/clip.h"
#include "project/transition.h"
#include "io/config.h"
#include "project/effectloaders.h"
#include "debug.h"
#include "timeline/sequence.h"
#include "timeline/clip.h"
#include "effects/transition.h"
#include "global/config.h"
#include "effects/effectloaders.h"
#include "global/debug.h"
#include <QScrollBar>
#include <QCoreApplication>
@@ -38,95 +37,9 @@ Viewer* panel_footage_viewer = nullptr;
Timeline* panel_timeline = nullptr;
GraphEditor* panel_graph_editor = nullptr;
void update_effect_controls() {
// SEND CLIPS TO EFFECT CONTROLS
// find out how many clips are selected
// limits to one video clip and one audio clip and only if they're linked
// one of these days it might be nice to have multiple clips in the effects panel
bool multiple = false;
int vclip = -1;
int aclip = -1;
QVector<int> selected_clips;
int mode = kTransitionNone;
if (olive::ActiveSequence != nullptr) {
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
Clip* clip = olive::ActiveSequence->clips.at(i).get();
if (clip != nullptr) {
for (int j=0;j<olive::ActiveSequence->selections.size();j++) {
const Selection& s = olive::ActiveSequence->selections.at(j);
bool add = true;
if (clip->timeline_in() >= s.in && clip->timeline_out() <= s.out && clip->track() == s.track) {
mode = kTransitionNone;
} else if (selection_contains_transition(s, clip, kTransitionOpening)) {
mode = kTransitionOpening;
} else if (selection_contains_transition(s, clip, kTransitionClosing)) {
mode = kTransitionClosing;
} else {
add = false;
}
if (add) {
if (clip->track() < 0 && vclip == -1) {
vclip = i;
} else if (clip->track() >= 0 && aclip == -1) {
aclip = i;
} else {
vclip = -2;
aclip = -2;
multiple = true;
multiple = true;
break;
}
}
}
}
}
if (!multiple) {
// check if aclip is linked to vclip
if (vclip >= 0) selected_clips.append(vclip);
if (aclip >= 0) selected_clips.append(aclip);
if (vclip >= 0 && aclip >= 0) {
bool found = false;
ClipPtr vclip_ref = olive::ActiveSequence->clips.at(vclip);
for (int i=0;i<vclip_ref->linked.size();i++) {
if (vclip_ref->linked.at(i) == aclip) {
found = true;
break;
}
}
if (!found) {
// only display multiple clips if they're linked
selected_clips.clear();
multiple = true;
}
}
}
}
bool same = (selected_clips.size() == panel_effect_controls->selected_clips.size()
&& panel_effect_controls->get_mode() == mode);
if (same) {
for (int i=0;i<selected_clips.size();i++) {
if (selected_clips.at(i) != panel_effect_controls->selected_clips.at(i)) {
same = false;
break;
}
}
}
if (panel_effect_controls->multiple != multiple || !same) {
panel_effect_controls->multiple = multiple;
panel_effect_controls->set_clips(selected_clips, mode);
}
}
void update_ui(bool modified) {
if (modified) {
update_effect_controls();
panel_effect_controls->SetClips();
}
panel_effect_controls->update_keyframes();
panel_timeline->repaint_timeline();
@@ -170,15 +83,14 @@ QDockWidget *get_focused_panel(bool force_hover) {
}
void alloc_panels(QWidget* parent) {
// TODO maybe replace these with non-pointers later on?
panel_sequence_viewer = new Viewer(parent);
panel_sequence_viewer->setObjectName("seq_viewer");
panel_sequence_viewer->setObjectName("seq_viewer");
panel_footage_viewer = new Viewer(parent);
panel_footage_viewer->setObjectName("footage_viewer");
panel_project = new Project(parent);
panel_project->setObjectName("proj_root");
panel_effect_controls = new EffectControls(parent);
init_effects();
EffectInit::StartLoading();
panel_effect_controls->setObjectName("fx_controls");
panel_timeline = new Timeline(parent);
panel_timeline->setObjectName("timeline");
+60 -48
View File
@@ -20,21 +20,21 @@
#include "project.h"
#include "oliveglobal.h"
#include "global/global.h"
#include "panels.h"
#include "rendering/renderfunctions.h"
#include "io/previewgenerator.h"
#include "project/undo.h"
#include "mainwindow.h"
#include "io/config.h"
#include "project/previewgenerator.h"
#include "undo/undo.h"
#include "undo/undostack.h"
#include "ui/mainwindow.h"
#include "global/config.h"
#include "rendering/cacher.h"
#include "dialogs/replaceclipmediadialog.h"
#include "panels/effectcontrols.h"
#include "dialogs/newsequencedialog.h"
#include "dialogs/mediapropertiesdialog.h"
#include "dialogs/loaddialog.h"
#include "io/clipboard.h"
#include "project/clipboard.h"
#include "ui/sourcetable.h"
#include "ui/sourceiconview.h"
#include "ui/icons.h"
@@ -42,7 +42,7 @@
#include "ui/mediaiconservice.h"
#include "project/sourcescommon.h"
#include "project/projectfilter.h"
#include "debug.h"
#include "global/debug.h"
#include <QApplication>
#include <QFileDialog>
@@ -264,7 +264,7 @@ SequencePtr create_sequence_from_media(QVector<Media*>& media_list) {
switch (media->get_type()) {
case MEDIA_TYPE_FOOTAGE:
{
FootagePtr m = media->to_footage();
Footage* m = media->to_footage();
if (m->ready) {
if (!got_video_values) {
for (int j=0;j<m->video_tracks.size();j++) {
@@ -292,7 +292,9 @@ SequencePtr create_sequence_from_media(QVector<Media*>& media_list) {
break;
case MEDIA_TYPE_SEQUENCE:
{
SequencePtr seq = media->to_sequence();
// Clone all attributes of the original sequence (seq) into the new one (s)
Sequence* seq = media->to_sequence().get();
s->width = seq->width;
s->height = seq->height;
s->frame_rate = seq->frame_rate;
@@ -331,14 +333,14 @@ void Project::duplicate_selected() {
void Project::replace_selected_file() {
QModelIndexList selected_items = get_current_selected();
if (selected_items.size() == 1) {
Media* item = item_to_media(selected_items.at(0));
MediaPtr item = item_to_media_ptr(selected_items.at(0));
if (item->get_type() == MEDIA_TYPE_FOOTAGE) {
replace_media(item, nullptr);
}
}
}
void Project::replace_media(Media* item, QString filename) {
void Project::replace_media(MediaPtr item, QString filename) {
if (filename.isEmpty()) {
filename = QFileDialog::getOpenFileName(
this,
@@ -410,10 +412,10 @@ void Project::open_properties() {
}
void Project::new_folder() {
Media* m = create_folder_internal(nullptr);
MediaPtr m = create_folder_internal(nullptr);
olive::UndoStack.push(new AddMediaCommand(m, get_selected_folder()));
QModelIndex index = olive::project_model.create_index(m->row(), 0, m);
QModelIndex index = olive::project_model.create_index(m->row(), 0, m.get());
switch (olive::CurrentConfig.project_view_type) {
case olive::PROJECT_VIEW_TREE:
tree_view->edit(sorter->mapFromSource(index));
@@ -430,19 +432,21 @@ void Project::new_sequence() {
nsd.exec();
}
Media* Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) {
MediaPtr Project::create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent) {
if (parent == nullptr) {
parent = olive::project_model.get_root();
}
Media* item = new Media(parent);
MediaPtr item = std::make_shared<Media>(parent);
item->set_sequence(s);
if (ca != nullptr) {
ca->append(new NewSequenceCommand(item, parent));
if (open) ca->append(new ChangeSequenceAction(s));
} else {
ca->append(new AddMediaCommand(item, parent));
if (open) {
ca->append(new ChangeSequenceAction(s));
}
} else {
olive::project_model.appendChild(parent, item);
if (open) {
@@ -456,26 +460,25 @@ QString Project::get_file_name_from_path(const QString& path) {
return path.mid(path.lastIndexOf('/')+1);
}
/*Media* Project::new_item() {
Media* item = new Media(0);
//item->setFlags(item->flags() | Qt::ItemIsEditable);
return item;
}*/
bool Project::is_focused() {
return tree_view->hasFocus() || icon_view->hasFocus();
}
Media* Project::create_folder_internal(QString name) {
Media* item = new Media(nullptr);
MediaPtr Project::create_folder_internal(QString name) {
MediaPtr item = std::make_shared<Media>();
item->set_folder();
item->set_name(name);
return item;
}
Media *Project::item_to_media(const QModelIndex &index) {
Media* Project::item_to_media(const QModelIndex &index) {
return static_cast<Media*>(sorter->mapToSource(index).internalPointer());
// return static_cast<Media*>(index.internalPointer());
}
MediaPtr Project::item_to_media_ptr(const QModelIndex &index) {
Media* raw_ptr = item_to_media(index);
return raw_ptr->parentItem()->get_shared_ptr(raw_ptr);
}
void Project::get_all_media_from_table(QList<Media*>& items, QList<Media*>& list, int search_type) {
@@ -510,10 +513,12 @@ bool delete_clips_in_clipboard_with_media(ComboAction* ca, Media* m) {
void Project::delete_selected_media() {
ComboAction* ca = new ComboAction();
QModelIndexList selected_items = get_current_selected();
QList<Media*> items;
for (int i=0;i<selected_items.size();i++) {
items.append(item_to_media(selected_items.at(i)));
}
bool remove = true;
bool redraw = false;
@@ -526,14 +531,16 @@ void Project::delete_selected_media() {
}
get_all_media_from_table(all_top_level_items, sequence_items, MEDIA_TYPE_SEQUENCE); // find all sequences in project
if (sequence_items.size() > 0) {
QList<Media*> media_items;
get_all_media_from_table(items, media_items, MEDIA_TYPE_FOOTAGE);
for (int i=0;i<media_items.size();i++) {
Media* item = media_items.at(i);
FootagePtr media = item->to_footage();
Footage* media = item->to_footage();
bool confirm_delete = false;
for (int j=0;j<sequence_items.size();j++) {
SequencePtr s = sequence_items.at(j)->to_sequence();
Sequence* s = sequence_items.at(j)->to_sequence().get();
for (int k=0;k<s->clips.size();k++) {
ClipPtr c = s->clips.at(k);
if (c != nullptr && c->media() == item) {
@@ -600,7 +607,9 @@ void Project::delete_selected_media() {
// remove
if (remove) {
panel_effect_controls->clear_effects(true);
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
if (olive::ActiveSequence != nullptr) olive::ActiveSequence->selections.clear();
// remove media and parents
@@ -614,18 +623,19 @@ void Project::delete_selected_media() {
}
for (int i=0;i<items.size();i++) {
ca->append(new DeleteMediaCommand(items.at(i)));
ca->append(new DeleteMediaCommand(items.at(i)->parentItem()->get_shared_ptr(items.at(i))));
if (items.at(i)->get_type() == MEDIA_TYPE_SEQUENCE) {
redraw = true;
SequencePtr s = items.at(i)->to_sequence();
Sequence* s = items.at(i)->to_sequence().get();
if (s == olive::ActiveSequence) {
if (s == olive::ActiveSequence.get()) {
ca->append(new ChangeSequenceAction(nullptr));
}
if (s == panel_footage_viewer->seq) {
if (s == panel_footage_viewer->seq.get()) {
panel_footage_viewer->set_media(nullptr);
}
} else if (items.at(i)->get_type() == MEDIA_TYPE_FOOTAGE) {
@@ -651,7 +661,7 @@ void Project::delete_selected_media() {
}
}
void Project::process_file_list(QStringList& files, bool recursive, Media* replace, Media* parent) {
void Project::process_file_list(QStringList& files, bool recursive, MediaPtr replace, Media* parent) {
bool imported = false;
// retrieve the array of image formats from the user's configuration
@@ -674,7 +684,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
if (QFileInfo(files.at(i)).isDir()) {
QString folder_name = get_file_name_from_path(files.at(i));
Media* folder = create_folder_internal(folder_name);
MediaPtr folder = create_folder_internal(folder_name);
QDir directory(files.at(i));
directory.setFilter(QDir::NoDotAndDotDot | QDir::AllEntries);
@@ -686,7 +696,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
subdir_filenames.append(subdir_files.at(j).filePath());
}
process_file_list(subdir_filenames, true, nullptr, folder);
process_file_list(subdir_filenames, true, nullptr, folder.get());
if (create_undo_action) {
ca->append(new AddMediaCommand(folder, parent));
@@ -848,13 +858,13 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
// If we're not skipping this file, let's import it
if (!skip) {
Media* item;
MediaPtr item;
FootagePtr m;
if (replace != nullptr) {
item = replace;
} else {
item = new Media(parent);
item = std::make_shared<Media>(parent);
}
m = FootagePtr(new Footage());
@@ -866,7 +876,7 @@ void Project::process_file_list(QStringList& files, bool recursive, Media* repla
item->set_footage(m);
last_imported_media.append(item);
last_imported_media.append(item.get());
if (replace == nullptr) {
if (create_undo_action) {
@@ -988,7 +998,7 @@ void Project::delete_clips_using_selected_media() {
for (int j=0;j<items.size();j++) {
Media* m = item_to_media(items.at(j));
if (c->media() == m) {
ca->append(new DeleteClipAction(olive::ActiveSequence, i));
ca->append(new DeleteClipAction(olive::ActiveSequence.get(), i));
deleted = true;
}
}
@@ -1008,13 +1018,15 @@ void Project::delete_clips_using_selected_media() {
}
void Project::clear() {
// clear graph editor
panel_graph_editor->set_row(nullptr);
// clear effects cache
panel_effect_controls->clear_effects(true);
panel_effect_controls->Clear(true);
// delete sequences first because it's important to close all the clips before deleting the media
QVector<Media*> sequences = list_all_project_sequences();
for (int i=0;i<sequences.size();i++) {
sequences.at(i)->to_sequence().reset();
sequences.at(i)->set_sequence(nullptr);
}
@@ -1079,7 +1091,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
} else {
int folder = m->parentItem()->temp_id;
if (type == MEDIA_TYPE_FOOTAGE) {
FootagePtr f = m->to_footage();
Footage* f = m->to_footage();
f->save_id = media_id;
stream.writeStartElement("footage");
stream.writeAttribute("id", QString::number(media_id));
@@ -1128,7 +1140,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
stream.writeEndElement(); // footage
media_id++;
} else if (type == MEDIA_TYPE_SEQUENCE) {
SequencePtr s = m->to_sequence();
Sequence* s = m->to_sequence().get();
if (set_ids_only) {
s->save_id = sequence_id;
sequence_id++;
@@ -1142,7 +1154,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
stream.writeAttribute("framerate", QString::number(s->frame_rate, 'f', 10));
stream.writeAttribute("afreq", QString::number(s->audio_frequency));
stream.writeAttribute("alayout", QString::number(s->audio_layout));
if (s == olive::ActiveSequence) {
if (s == olive::ActiveSequence.get()) {
stream.writeAttribute("open", "1");
}
stream.writeAttribute("workarea", QString::number(s->using_workarea));
+7 -5
View File
@@ -32,10 +32,10 @@
#include "project/projectmodel.h"
#include "project/projectfilter.h"
#include "project/projectelements.h"
#include "project/undo.h"
#include "project/sourcescommon.h"
#include "ui/panel.h"
#include "ui/sourceiconview.h"
#include "undo/undo.h"
#include "ui/sourcetable.h"
@@ -58,10 +58,10 @@ public:
bool is_focused();
void clear();
Media* create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent);
MediaPtr create_sequence_internal(ComboAction *ca, SequencePtr s, bool open, Media* parent);
QString get_next_sequence_name(QString start = nullptr);
void process_file_list(QStringList& files, bool recursive = false, Media* replace = nullptr, Media *parent = nullptr);
void replace_media(Media* item, QString filename);
void process_file_list(QStringList& files, bool recursive = false, MediaPtr replace = nullptr, Media *parent = nullptr);
void replace_media(MediaPtr item, QString filename);
Media* get_selected_folder();
bool reveal_media(Media *media, QModelIndex parent = QModelIndex());
void add_recent_project(QString url);
@@ -70,8 +70,10 @@ public:
void load_project(const QString &filename, bool autorecovery, bool clear);
void save_project(bool autorecovery);
Media* create_folder_internal(QString name);
MediaPtr create_folder_internal(QString name);
Media* item_to_media(const QModelIndex& index);
MediaPtr item_to_media_ptr(const QModelIndex &index);
void save_recent_projects();
+55 -53
View File
@@ -20,26 +20,25 @@
#include "timeline.h"
#include "oliveglobal.h"
#include "global/global.h"
#include "panels/panels.h"
#include "project/projectelements.h"
#include "ui/timelinewidget.h"
#include "ui/icons.h"
#include "ui/viewerwidget.h"
#include "rendering/audio.h"
#include "rendering/cacher.h"
#include "rendering/renderfunctions.h"
#include "io/config.h"
#include "io/clipboard.h"
#include "global/config.h"
#include "project/clipboard.h"
#include "ui/timelineheader.h"
#include "ui/resizablescrollbar.h"
#include "ui/audiomonitor.h"
#include "ui/flowlayout.h"
#include "ui/cursors.h"
#include "mainwindow.h"
#include "debug.h"
#include "ui/mainwindow.h"
#include "undo/undostack.h"
#include "global/debug.h"
#include <QTime>
#include <QScrollBar>
@@ -177,7 +176,7 @@ void Timeline::next_cut() {
}
}
void ripple_clips(ComboAction* ca, SequencePtr s, long point, long length, const QVector<int>& ignore) {
void ripple_clips(ComboAction* ca, Sequence* s, long point, long length, const QVector<int>& ignore) {
ca->append(new RippleAction(s, point, length, ignore));
}
@@ -193,7 +192,7 @@ void Timeline::toggle_show_all() {
}
}
void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVector<Media*>& media_list) {
void Timeline::create_ghosts_from_media(Sequence* seq, long entry_point, QVector<Media*>& media_list) {
video_ghosts = false;
audio_ghosts = false;
@@ -201,8 +200,8 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect
bool can_import = true;
Media* medium = media_list.at(i);
FootagePtr m = nullptr;
SequencePtr s = nullptr;
Footage* m = nullptr;
Sequence* s = nullptr;
long sequence_length = 0;
long default_clip_in = 0;
long default_clip_out = 0;
@@ -219,7 +218,7 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect
}
break;
case MEDIA_TYPE_SEQUENCE:
s = medium->to_sequence();
s = medium->to_sequence().get();
sequence_length = s->getEndFrame();
if (seq != nullptr) sequence_length = rescale_frame_number(sequence_length, s->frame_rate, seq->frame_rate);
can_import = (s != seq && sequence_length != 0);
@@ -298,7 +297,7 @@ void Timeline::create_ghosts_from_media(SequencePtr seq, long entry_point, QVect
}
}
void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) {
void Timeline::add_clips_from_ghosts(ComboAction* ca, Sequence* s) {
// add clips
long earliest_point = LONG_MAX;
QVector<ClipPtr> added_clips;
@@ -314,7 +313,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) {
c->set_clip_in(g.clip_in);
c->set_track(g.track);
if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
FootagePtr m = c->media()->to_footage();
Footage* m = c->media()->to_footage();
if (m->video_tracks.size() == 0) {
// audio only (greenish)
c->set_color(128, 192, 128);
@@ -330,8 +329,7 @@ void Timeline::add_clips_from_ghosts(ComboAction* ca, SequencePtr s) {
// sequence (red?ish?)
c->set_color(192, 128, 128);
SequencePtr media = c->media()->to_sequence();
c->set_name(media->name);
c->set_name(c->media()->to_sequence()->name);
}
c->refresh();
added_clips.append(c);
@@ -373,7 +371,7 @@ void Timeline::add_transition() {
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
Clip* c = olive::ActiveSequence->clips.at(i).get();
if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, true)) {
if (c != nullptr && c->IsSelected()) {
int transition_to_add = (c->track() < 0) ? TRANSITION_INTERNAL_CROSSDISSOLVE : TRANSITION_INTERNAL_LINEARFADE;
if (c->opening_transition == nullptr) {
ca->append(new AddTransitionCommand(c,
@@ -420,7 +418,7 @@ void Timeline::nest() {
ComboAction* ca = new ComboAction();
// create "nest" sequence with the same attributes as the current sequence
SequencePtr s(new Sequence());
SequencePtr s = std::make_shared<Sequence>();
s->name = panel_project->get_next_sequence_name(tr("Nested Sequence"));
s->width = olive::ActiveSequence->width;
@@ -432,10 +430,10 @@ void Timeline::nest() {
// copy all selected clips to the nest
for (int i=0;i<selected_clips.size();i++) {
// delete clip from old sequence
ca->append(new DeleteClipAction(olive::ActiveSequence, selected_clips.at(i)));
ca->append(new DeleteClipAction(olive::ActiveSequence.get(), selected_clips.at(i)));
// copy to new
ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s));
ClipPtr copy(olive::ActiveSequence->clips.at(selected_clips.at(i))->copy(s.get()));
copy->set_timeline_in(copy->timeline_in() - earliest_point);
copy->set_timeline_out(copy->timeline_out() - earliest_point);
s->clips.append(copy);
@@ -445,15 +443,16 @@ void Timeline::nest() {
relink_clips_using_ids(selected_clips, s->clips);
// add sequence to project
Media* m = panel_project->create_sequence_internal(ca, s, false, nullptr);
MediaPtr m = panel_project->create_sequence_internal(ca, s, false, nullptr);
// add nested sequence to active sequence
QVector<Media*> media_list;
media_list.append(m);
create_ghosts_from_media(olive::ActiveSequence, earliest_point, media_list);
add_clips_from_ghosts(ca, olive::ActiveSequence);
media_list.append(m.get());
create_ghosts_from_media(olive::ActiveSequence.get(), earliest_point, media_list);
add_clips_from_ghosts(ca, olive::ActiveSequence.get());
panel_effect_controls->clear_effects(true);
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
olive::ActiveSequence->selections.clear();
olive::UndoStack.push(ca);
@@ -648,8 +647,11 @@ void Timeline::delete_in_out_internal(bool ripple) {
}
ComboAction* ca = new ComboAction();
delete_areas_and_relink(ca, areas, true);
if (ripple) ripple_clips(ca, olive::ActiveSequence, olive::ActiveSequence->workarea_in, olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out);
ca->append(new SetTimelineInOutCommand(olive::ActiveSequence, false, 0, 0));
if (ripple) ripple_clips(ca,
olive::ActiveSequence.get(),
olive::ActiveSequence->workarea_in,
olive::ActiveSequence->workarea_in - olive::ActiveSequence->workarea_out);
ca->append(new SetTimelineInOutCommand(olive::ActiveSequence.get(), false, 0, 0));
olive::UndoStack.push(ca);
update_ui(true);
}
@@ -680,7 +682,8 @@ void Timeline::toggle_enable_on_selected_clips() {
void Timeline::delete_selection(QVector<Selection>& selections, bool ripple_delete) {
if (selections.size() > 0) {
panel_effect_controls->clear_effects(true);
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
ComboAction* ca = new ComboAction();
@@ -732,7 +735,7 @@ void Timeline::delete_selection(QVector<Selection>& selections, bool ripple_dele
}
if (can_ripple) {
ripple_clips(ca, olive::ActiveSequence, ripple_point, -ripple_length);
ripple_clips(ca, olive::ActiveSequence.get(), ripple_point, -ripple_length);
panel_sequence_viewer->seek(ripple_point-1);
}
@@ -851,7 +854,7 @@ ClipPtr Timeline::split_clip(ComboAction* ca, bool transitions, int p, long fram
if (pre->timeline_in() < frame && pre->timeline_out() > frame) {
// duplicate clip without duplicating its transitions, we'll restore them later
ClipPtr post = ClipPtr(pre->copy(olive::ActiveSequence));
ClipPtr post = pre->copy(olive::ActiveSequence.get());
long new_clip_length = frame - pre->timeline_in();
@@ -941,14 +944,14 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool
if (relink) {
pre_clips.append(clip);
bool original_clip_is_selected = olive::ActiveSequence->IsClipSelected(c, true);
bool original_clip_is_selected = c->IsSelected();
// find linked clips of old clip
for (int i=0;i<c->linked.size();i++) {
int l = c->linked.at(i);
if (!split_cache.contains(l)) {
Clip* link = olive::ActiveSequence->clips.at(l).get();
if ((original_clip_is_selected && olive::ActiveSequence->IsClipSelected(link, true)) || !original_clip_is_selected) {
if ((original_clip_is_selected && link->IsSelected()) || !original_clip_is_selected) {
split_cache.append(l);
ClipPtr s = split_clip(ca, true, l, frame);
if (s != nullptr) {
@@ -961,7 +964,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool
relink_clips_using_ids(pre_clips, post_clips);
}
ca->append(new AddClipCommand(olive::ActiveSequence, post_clips));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
return true;
}
}
@@ -1014,7 +1017,9 @@ bool selection_contains_transition(const Selection& s, Clip* c, int type) {
void Timeline::delete_areas_and_relink(ComboAction* ca, QVector<Selection>& areas, bool deselect_areas) {
clean_up_selections(areas);
panel_effect_controls->clear_effects(true);
panel_graph_editor->set_row(nullptr);
panel_effect_controls->Clear(true);
QVector<int> pre_clips;
QVector<ClipPtr> post_clips;
@@ -1032,7 +1037,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector<Selection>& area
ca->append(new DeleteTransitionCommand(c->closing_transition));
} else if (c->timeline_in() >= s.in && c->timeline_out() <= s.out) {
// clips falls entirely within deletion area
ca->append(new DeleteClipAction(olive::ActiveSequence, j));
ca->append(new DeleteClipAction(olive::ActiveSequence.get(), j));
} else if (c->timeline_in() < s.in && c->timeline_out() > s.out) {
// middle of clip is within deletion area
@@ -1078,7 +1083,7 @@ void Timeline::delete_areas_and_relink(ComboAction* ca, QVector<Selection>& area
}
relink_clips_using_ids(pre_clips, post_clips);
ca->append(new AddClipCommand(olive::ActiveSequence, post_clips));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
}
void Timeline::copy(bool del) {
@@ -1171,7 +1176,7 @@ void Timeline::paste(bool insert) {
ClipPtr c = std::static_pointer_cast<Clip>(clipboard.at(i));
// create copy of clip and offset by playhead
ClipPtr cc(c->copy(olive::ActiveSequence));
ClipPtr cc = c->copy(olive::ActiveSequence.get());
// convert frame rates
cc->set_timeline_in(rescale_frame_number(cc->timeline_in(), c->cached_frame_rate(), olive::ActiveSequence->frame_rate));
@@ -1198,7 +1203,7 @@ void Timeline::paste(bool insert) {
if (insert) {
split_cache.clear();
split_all_clips_at_point(ca, olive::ActiveSequence->playhead);
ripple_clips(ca, olive::ActiveSequence, paste_start, paste_end - paste_start);
ripple_clips(ca, olive::ActiveSequence.get(), paste_start, paste_end - paste_start);
} else {
delete_areas_and_relink(ca, delete_areas, false);
}
@@ -1218,7 +1223,7 @@ void Timeline::paste(bool insert) {
}
}
ca->append(new AddClipCommand(olive::ActiveSequence, pasted_clips));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), pasted_clips));
olive::UndoStack.push(ca);
@@ -1281,10 +1286,7 @@ void Timeline::paste(bool insert) {
if (found >= 0 && skip) {
// do nothing
} else if (found >= 0 && replace) {
EffectDeleteCommand* delcom = new EffectDeleteCommand();
delcom->clips.append(c);
delcom->fx.append(found);
ca->append(delcom);
ca->append(new EffectDeleteCommand(c->effects.at(found).get()));
ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found));
} else {
@@ -1370,7 +1372,7 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) {
// trim and move clips around the in point
delete_areas_and_relink(ca, areas, true);
if (ripple) ripple_clips(ca, olive::ActiveSequence, in_point, -1);
if (ripple) ripple_clips(ca, olive::ActiveSequence.get(), in_point, -1);
} else {
push_undo = false;
}
@@ -1394,7 +1396,7 @@ void Timeline::edit_to_point_internal(bool in, bool ripple) {
// trim and move clips around the in point
delete_areas_and_relink(ca, areas, true);
if (ripple) ripple_clips(ca, olive::ActiveSequence, s.in, s.in - s.out);
if (ripple) ripple_clips(ca, olive::ActiveSequence.get(), s.in, s.in - s.out);
}
}
@@ -1452,8 +1454,8 @@ bool Timeline::split_selection(ComboAction* ca) {
relink_clips_using_ids(pre_splits, post_splits);
relink_clips_using_ids(pre_splits, secondary_post_splits);
ca->append(new AddClipCommand(olive::ActiveSequence, post_splits));
ca->append(new AddClipCommand(olive::ActiveSequence, secondary_post_splits));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_splits));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), secondary_post_splits));
return true;
}
@@ -1485,7 +1487,7 @@ void Timeline::split_at_playhead() {
QVector<ClipPtr> post_clips;
for (int j=0;j<olive::ActiveSequence->clips.size();j++) {
Clip* clip = olive::ActiveSequence->clips.at(j).get();
if (clip != nullptr && olive::ActiveSequence->IsClipSelected(clip, true)) {
if (clip != nullptr && clip->IsSelected()) {
ClipPtr s = split_clip(ca, true, j, olive::ActiveSequence->playhead);
if (s != nullptr) {
pre_clips.append(j);
@@ -1498,7 +1500,7 @@ void Timeline::split_at_playhead() {
if (split_selected) {
// relink clips if we split
relink_clips_using_ids(pre_clips, post_clips);
ca->append(new AddClipCommand(olive::ActiveSequence, post_clips));
ca->append(new AddClipCommand(olive::ActiveSequence.get(), post_clips));
} else {
// split a selection if not
split_selected = split_selection(ca);
@@ -1628,7 +1630,7 @@ void Timeline::set_marker() {
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
Clip* c = olive::ActiveSequence->clips.at(i).get();
if (c != nullptr
&& olive::ActiveSequence->IsClipSelected(c, true)) {
&& c->IsSelected()) {
// only add markers if the playhead is inside the clip
if (olive::ActiveSequence->playhead >= c->timeline_in()
@@ -1649,7 +1651,7 @@ void Timeline::set_marker() {
}
// pass off to internal set marker function
set_marker_internal(olive::ActiveSequence, clips_selected);
set_marker_internal(olive::ActiveSequence.get(), clips_selected);
}
@@ -1679,10 +1681,10 @@ void Timeline::edit_to_out_point() {
void Timeline::toggle_links() {
LinkCommand* command = new LinkCommand();
command->s = olive::ActiveSequence;
command->s = olive::ActiveSequence.get();
for (int i=0;i<olive::ActiveSequence->clips.size();i++) {
Clip* c = olive::ActiveSequence->clips.at(i).get();
if (c != nullptr && olive::ActiveSequence->IsClipSelected(c, true)) {
if (c != nullptr && c->IsSelected()) {
if (!command->clips.contains(i)) command->clips.append(i);
if (c->linked.size() > 0) {
+6 -6
View File
@@ -27,9 +27,9 @@
#include "ui/timelinewidget.h"
#include "ui/timelinetools.h"
#include "project/selection.h"
#include "project/clip.h"
#include "project/undo.h"
#include "timeline/selection.h"
#include "timeline/clip.h"
#include "undo/undo.h"
#include "ui/timelineheader.h"
#include "ui/resizablescrollbar.h"
#include "ui/audiomonitor.h"
@@ -74,7 +74,7 @@ namespace olive {
int getScreenPointFromFrame(double zoom, long frame);
long getFrameFromScreenPoint(double zoom, int x);
bool selection_contains_transition(const Selection& s, Clip *c, int type);
void ripple_clips(ComboAction *ca, SequencePtr s, long point, long length, const QVector<int>& ignore = QVector<int>());
void ripple_clips(ComboAction *ca, Sequence *s, long point, long length, const QVector<int>& ignore = QVector<int>());
struct Ghost {
int clip;
@@ -125,8 +125,8 @@ public:
void edit_to_point_internal(bool in, bool ripple);
void delete_in_out_internal(bool ripple);
void create_ghosts_from_media(SequencePtr seq, long entry_point, QVector<Media *> &media_list);
void add_clips_from_ghosts(ComboAction *ca, SequencePtr s);
void create_ghosts_from_media(Sequence *seq, long entry_point, QVector<Media *> &media_list);
void add_clips_from_ghosts(ComboAction *ca, Sequence *s);
int getTimelineScreenPointFromFrame(long frame);
long getTimelineFrameFromScreenPoint(int x);
+40 -29
View File
@@ -24,13 +24,14 @@
#include "timeline.h"
#include "panels/project.h"
#include "panels/effectcontrols.h"
#include "project/sequence.h"
#include "project/clip.h"
#include "timeline/sequence.h"
#include "timeline/clip.h"
#include "panels/panels.h"
#include "io/config.h"
#include "global/config.h"
#include "project/footage.h"
#include "project/media.h"
#include "project/undo.h"
#include "undo/undo.h"
#include "undo/undostack.h"
#include "ui/audiomonitor.h"
#include "rendering/renderfunctions.h"
#include "ui/viewercontainer.h"
@@ -38,8 +39,8 @@
#include "ui/timelineheader.h"
#include "ui/resizablescrollbar.h"
#include "ui/icons.h"
#include "oliveglobal.h"
#include "debug.h"
#include "global/global.h"
#include "global/debug.h"
#define FRAMES_IN_ONE_MINUTE 1798 // 1800 - 2
#define FRAMES_IN_TEN_MINUTES 17978 // (FRAMES_IN_ONE_MINUTE * 10) - 2
@@ -79,11 +80,11 @@ Viewer::Viewer(QWidget *parent) :
set_media(nullptr);
current_timecode_slider->setEnabled(false);
current_timecode_slider->set_minimum_value(0);
current_timecode_slider->set_default_value(qSNaN());
current_timecode_slider->set_value(0, false);
current_timecode_slider->set_display_type(LABELSLIDER_FRAMENUMBER);
connect(current_timecode_slider, SIGNAL(valueChanged()), this, SLOT(update_playhead()));
current_timecode_slider->SetMinimum(0);
current_timecode_slider->SetDefault(qSNaN());
current_timecode_slider->SetValue(0);
current_timecode_slider->SetDisplayType(LabelSlider::FrameNumber);
connect(current_timecode_slider, SIGNAL(valueChanged(double)), this, SLOT(update_playhead()));
recording_flasher.setInterval(500);
@@ -376,6 +377,10 @@ void Viewer::decrease_speed() {
}
void Viewer::play(bool in_to_out) {
if (seq == nullptr) {
return;
}
if (panel_sequence_viewer->playing) panel_sequence_viewer->pause();
if (panel_footage_viewer->playing) panel_footage_viewer->pause();
@@ -449,9 +454,9 @@ void Viewer::pause() {
panel_project->process_file_list(file_list);
// add it to the sequence
ClipPtr c = std::make_shared<Clip>(seq);
ClipPtr c = std::make_shared<Clip>(seq.get());
Media* m = panel_project->last_imported_media.at(0);
FootagePtr f = m->to_footage();
Footage* f = m->to_footage();
// wait for footage to be completely ready before taking metadata from it
f->ready_lock.lock();
@@ -468,7 +473,7 @@ void Viewer::pause() {
QVector<ClipPtr> add_clips;
add_clips.append(c);
olive::UndoStack.push(new AddClipCommand(seq, add_clips)); // add clip
olive::UndoStack.push(new AddClipCommand(seq.get(), add_clips)); // add clip
}
}
}
@@ -479,7 +484,7 @@ bool Viewer::WaitingForPlayWake()
}
void Viewer::update_playhead_timecode(long p) {
current_timecode_slider->set_value(p, false);
current_timecode_slider->SetValue(p);
}
void Viewer::update_end_timecode() {
@@ -514,7 +519,7 @@ int Viewer::get_playback_speed() {
}
void Viewer::set_marker() {
set_marker_internal(seq);
set_marker_internal(seq.get());
}
void Viewer::resizeEvent(QResizeEvent *e) {
@@ -537,7 +542,7 @@ void Viewer::update_viewer() {
void Viewer::clear_in() {
if (seq != nullptr
&& seq->using_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, 0, seq->workarea_out));
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, 0, seq->workarea_out));
update_parents();
}
}
@@ -545,7 +550,7 @@ void Viewer::clear_in() {
void Viewer::clear_out() {
if (seq != nullptr
&& seq->using_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(seq, true, seq->workarea_in, seq->getEndFrame()));
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), true, seq->workarea_in, seq->getEndFrame()));
update_parents();
}
}
@@ -553,7 +558,7 @@ void Viewer::clear_out() {
void Viewer::clear_inout_point() {
if (seq != nullptr
&& seq->using_workarea) {
olive::UndoStack.push(new SetTimelineInOutCommand(seq, false, 0, 0));
olive::UndoStack.push(new SetTimelineInOutCommand(seq.get(), false, 0, 0));
update_parents();
}
}
@@ -720,11 +725,11 @@ void Viewer::set_media(Media* m) {
switch (media->get_type()) {
case MEDIA_TYPE_FOOTAGE:
{
FootagePtr footage = media->to_footage();
Footage* footage = media->to_footage();
marker_ref = &footage->markers;
seq = SequencePtr(new Sequence());
seq = std::make_shared<Sequence>();
created_sequence = true;
seq->wrapper_sequence = true;
seq->name = footage->name;
@@ -744,7 +749,7 @@ void Viewer::set_media(Media* m) {
seq->height = video_stream.video_height;
if (video_stream.video_frame_rate > 0 && !video_stream.infinite_length) seq->frame_rate = video_stream.video_frame_rate * footage->speed;
ClipPtr c = std::make_shared<Clip>(seq);
ClipPtr c = std::make_shared<Clip>(seq.get());
c->set_media(media, video_stream.file_index);
c->set_timeline_in(0);
c->set_timeline_out(footage->get_length_in_frames(seq->frame_rate));
@@ -766,7 +771,7 @@ void Viewer::set_media(Media* m) {
const FootageStream& audio_stream = footage->audio_tracks.at(0);
seq->audio_frequency = audio_stream.audio_frequency;
ClipPtr c = std::make_shared<Clip>(seq);
ClipPtr c = std::make_shared<Clip>(seq.get());
c->set_media(media, audio_stream.file_index);
c->set_timeline_in(0);
c->set_timeline_out(footage->get_length_in_frames(seq->frame_rate));
@@ -848,9 +853,13 @@ void Viewer::clean_created_seq() {
if (created_sequence) {
// TODO delete undo commands referencing this sequence to avoid crashes
/*for (int i=0;i<undo_stack.count();i++) {
undo_stack.command(i)
}*/
/*
for (int i=0;i<olive::UndoStack.count();i++) {
const QUndoCommand* oa = olive::UndoStack.command(i);
if (typeid(*oa) == typeid(SetTimelineInOutCommand)) {
}
}
*/
seq.reset();
created_sequence = false;
@@ -862,11 +871,13 @@ void Viewer::set_sequence(bool main, SequencePtr s) {
reset_all_audio();
main_sequence = main;
// If we had a current sequence open, close it
if (seq != nullptr) {
close_active_clips(seq);
close_active_clips(seq.get());
}
main_sequence = main;
seq = (main) ? olive::ActiveSequence : s;
bool null_sequence = (seq == nullptr);
@@ -882,7 +893,7 @@ void Viewer::set_sequence(bool main, SequencePtr s) {
go_to_end_frame->setEnabled(!null_sequence);
if (!null_sequence) {
current_timecode_slider->set_frame_rate(seq->frame_rate);
current_timecode_slider->SetFrameRate(seq->frame_rate);
playback_updater.setInterval(qFloor(1000 / seq->frame_rate));
+1 -1
View File
@@ -26,7 +26,7 @@
#include <QLabel>
#include <QPushButton>
#include "project/marker.h"
#include "timeline/marker.h"
#include "project/media.h"
#include "ui/panel.h"