diff --git a/effects/crossdissolvetransition.cpp b/effects/crossdissolvetransition.cpp new file mode 100644 index 000000000..d1eb18835 --- /dev/null +++ b/effects/crossdissolvetransition.cpp @@ -0,0 +1,9 @@ +#include "transition.h" + +#include + +void CrossDissolveTransition::process_transition(float progress) { + float color[4]; + glGetFloatv(GL_CURRENT_COLOR, color); + glColor4f(1.0, 1.0, 1.0, color[3]*progress); +} diff --git a/effects/transformeffect.cpp b/effects/transformeffect.cpp index 3fa164bf5..8240de467 100644 --- a/effects/transformeffect.cpp +++ b/effects/transformeffect.cpp @@ -205,5 +205,7 @@ void TransformEffect::process_gl(int* anchor_x, int* anchor_y) { } // opacity - glColor4f(1.0, 1.0, 1.0, opacity->value()*0.01); + float color[4]; + glGetFloatv(GL_CURRENT_COLOR, color); + glColor4f(1.0, 1.0, 1.0, color[3]*(opacity->value()*0.01)); } diff --git a/effects/transition.cpp b/effects/transition.cpp new file mode 100644 index 000000000..24719adba --- /dev/null +++ b/effects/transition.cpp @@ -0,0 +1,7 @@ +#include "transition.h" + +Transition::Transition() { + length = 30; +} + +void Transition::process_transition(float) {} diff --git a/effects/transition.h b/effects/transition.h new file mode 100644 index 000000000..d77c5ae26 --- /dev/null +++ b/effects/transition.h @@ -0,0 +1,17 @@ +#ifndef TRANSITION_H +#define TRANSITION_H + +class Transition +{ +public: + Transition(); + int length; + virtual void process_transition(float); +}; + +class CrossDissolveTransition : public Transition { +public: + void process_transition(float); +}; + +#endif // TRANSITION_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 9ae020b49..2aae07dd9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -76,7 +76,9 @@ MainWindow::MainWindow(QWidget *parent) : setWindowTitle("Olive (June 2018 | Pre-Alpha)"); statusBar()->showMessage("Welcome to Olive"); - setCentralWidget(NULL); + ui->centralWidget->setMaximumSize(0, 0); + setDockNestingEnabled(true); + // TODO maybe replace these with non-pointers later on? panel_project = new Project(this); diff --git a/olive.pro b/olive.pro index b5cb38177..ae770f67d 100644 --- a/olive.pro +++ b/olive.pro @@ -55,7 +55,9 @@ SOURCES += \ ui/timelineheader.cpp \ io/previewgenerator.cpp \ ui/labelslider.cpp \ - dialogs/preferencesdialog.cpp + dialogs/preferencesdialog.cpp \ + effects/transition.cpp \ + effects/crossdissolvetransition.cpp HEADERS += \ mainwindow.h \ @@ -86,7 +88,8 @@ HEADERS += \ ui/timelineheader.h \ io/previewgenerator.h \ ui/labelslider.h \ - dialogs/preferencesdialog.h + dialogs/preferencesdialog.h \ + effects/transition.h FORMS += \ mainwindow.ui \ diff --git a/olive.pro.user b/olive.pro.user index 875e838e4..3faa11855 100644 --- a/olive.pro.user +++ b/olive.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 0f465395d..77bc89a4a 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -17,7 +17,7 @@ EffectControls::EffectControls(QWidget *parent) : { ui->setupUi(this); init_effects(); - clear_effects(); + clear_effects(false); } EffectControls::~EffectControls() @@ -62,7 +62,7 @@ void EffectControls::show_menu(bool video) { effects_menu.exec(QCursor::pos()); } -void EffectControls::clear_effects() { +void EffectControls::clear_effects(bool clear_cache) { // clear existing clips QVBoxLayout* video_layout = static_cast(ui->video_effect_area->layout()); QVBoxLayout* audio_layout = static_cast(ui->audio_effect_area->layout()); @@ -77,7 +77,7 @@ void EffectControls::clear_effects() { } ui->vcontainer->setVisible(false); ui->acontainer->setVisible(false); - selected_clips.clear(); + if (clear_cache) selected_clips.clear(); } void EffectControls::deselect_all_effects(QWidget* sender) { @@ -137,12 +137,12 @@ void EffectControls::delete_clips() { } void EffectControls::reload_clips() { - clear_effects(); + clear_effects(false); load_effects(); } void EffectControls::set_clips(QVector& clips) { - clear_effects(); + clear_effects(true); // replace clip vector selected_clips = clips; diff --git a/panels/effectcontrols.h b/panels/effectcontrols.h index b3dee68dd..31e9d52d6 100644 --- a/panels/effectcontrols.h +++ b/panels/effectcontrols.h @@ -19,7 +19,7 @@ public: ~EffectControls(); // void set_clip(Clip* c); void set_clips(QVector& clips); - void clear_effects(); + void clear_effects(bool clear_cache); void delete_clips(); bool is_focused(); diff --git a/panels/project.cpp b/panels/project.cpp index 0bd57c86e..c5e0faf2b 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -210,6 +210,8 @@ void Project::delete_selected_media() { items.removeAt(i); i--; remove = true; + } else if (confirm.clickedButton() == abort_button) { + break; } } } diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 4707a3fd3..e30772143 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -213,7 +213,7 @@ bool Timeline::focused() { void Timeline::undo() { // qDebug() << "[INFO] Undo/redo was so buggy, it's been disabled. Sorry for any inconvenience"; if (sequence != NULL) { - panel_effect_controls->clear_effects(); + panel_effect_controls->clear_effects(true); sequence->undo(); redraw_all_clips(false); } @@ -222,7 +222,7 @@ void Timeline::undo() { void Timeline::redo() { // qDebug() << "[INFO] Undo/redo was so buggy, it's been disabled. Sorry for any inconvenience"; if (sequence != NULL) { - panel_effect_controls->clear_effects(); + panel_effect_controls->clear_effects(true); sequence->redo(); redraw_all_clips(false); } @@ -270,7 +270,7 @@ void Timeline::select_all() { void Timeline::delete_selection(bool ripple_delete) { if (selections.size() > 0) { - panel_effect_controls->clear_effects(); + panel_effect_controls->clear_effects(true); long ripple_point = selections.at(0).in; long ripple_length = selections.at(0).out - selections.at(0).in; diff --git a/project/clip.cpp b/project/clip.cpp index f852cea3c..c2a45fb18 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -12,7 +12,17 @@ extern "C" { } Clip::Clip() { - init(); + reset(); + enabled = true; + clip_in = 0; + timeline_in = 0; + timeline_out = 0; + track = 0; + undeletable = 0; + texture = NULL; + opening_transition = NULL; + closing_transition = NULL; + pkt = new AVPacket(); } Clip* Clip::copy() { @@ -39,18 +49,6 @@ Clip* Clip::copy() { return copy; } -void Clip::init() { - reset(); - enabled = true; - clip_in = 0; - timeline_in = 0; - timeline_out = 0; - track = 0; - undeletable = 0; - texture = NULL; - pkt = new AVPacket(); -} - void Clip::reset() { cache_size = false; audio_just_reset = false; @@ -87,6 +85,9 @@ Clip::~Clip() { open_lock.lock(); open_lock.unlock(); + if (opening_transition != NULL) delete opening_transition; + if (closing_transition != NULL) delete closing_transition; + for (int i=0;i effects; QVector linked; + Transition* opening_transition; + Transition* closing_transition; // media handling AVFormatContext* formatCtx; diff --git a/ui/sourcetable.cpp b/ui/sourcetable.cpp index 5f5f318dc..c9154fc70 100644 --- a/ui/sourcetable.cpp +++ b/ui/sourcetable.cpp @@ -59,5 +59,4 @@ void SourceTable::dropEvent(QDropEvent* event) { } event->acceptProposedAction(); } - QTreeWidget::dropEvent(event); } diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index 32da1ce03..167bea80b 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -11,6 +11,7 @@ #include "panels/effectcontrols.h" #include "effects/effects.h" +#include "effects/transition.h" #include #include @@ -138,6 +139,17 @@ void TimelineWidget::dropEvent(QDropEvent* event) { c->effects.append(create_effect(AUDIO_PAN_EFFECT, c)); } + /* + * TEMP DEBUG CODE TO REMOVE LATER + */ + + c->opening_transition = new CrossDissolveTransition(); + c->closing_transition = new CrossDissolveTransition(); + + /* + * END OF TEMP DEBUG CODE + */ + sequence->add_clip(c); added_clips.append(c); } @@ -963,6 +975,7 @@ void TimelineWidget::redraw_clips() { QPainter clip_painter(&clip_pixmap); int video_track_limit = 0; int audio_track_limit = 0; + QColor transition_color(160, 128, 192); for (int i=0;iclip_count();i++) { Clip* clip = sequence->get_clip(i); if (clip != NULL && is_track_visible(clip->track)) { @@ -1005,6 +1018,25 @@ void TimelineWidget::redraw_clips() { } } + QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - CLIP_TEXT_PADDING, clip_rect.height() - CLIP_TEXT_PADDING - CLIP_TEXT_PADDING); + + if (clip->opening_transition != NULL) { + int transition_width = panel_timeline->getScreenPointFromFrame(clip->opening_transition->length); + QRect transition_rect(clip_rect.x(), clip_rect.y(), transition_width, clip_rect.height()); + text_rect.setX(text_rect.x()+transition_width); + clip_painter.fillRect(transition_rect, transition_color); + clip_painter.setPen(Qt::black); + clip_painter.drawRect(transition_rect); + } + if (clip->closing_transition != NULL) { + int transition_width = panel_timeline->getScreenPointFromFrame(clip->opening_transition->length); + QRect transition_rect(clip_rect.right()-transition_width, clip_rect.y(), transition_width, clip_rect.height()); + text_rect.setWidth(text_rect.width()-transition_width); + clip_painter.fillRect(transition_rect, transition_color); + clip_painter.setPen(Qt::black); + clip_painter.drawRect(transition_rect); + } + // top left bevel clip_painter.setPen(Qt::white); clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft()); @@ -1015,13 +1047,12 @@ void TimelineWidget::redraw_clips() { // set to black if color is bright clip_painter.setPen(Qt::black); } - QRect text_rect(clip_rect.left() + CLIP_TEXT_PADDING, clip_rect.top() + CLIP_TEXT_PADDING, clip_rect.width() - CLIP_TEXT_PADDING - CLIP_TEXT_PADDING, clip_rect.height() - CLIP_TEXT_PADDING - CLIP_TEXT_PADDING); - clip_painter.drawText(text_rect, 0, clip->name, &text_rect); if (clip->linked.size() > 0) { int underline_y = CLIP_TEXT_PADDING + clip_painter.fontMetrics().height() + clip_rect.top(); - int underline_width = qMin(clip_rect.left() + clip_rect.width() - CLIP_TEXT_PADDING, clip_rect.left() + CLIP_TEXT_PADDING + clip_painter.fontMetrics().width(clip->name)); - clip_painter.drawLine(clip_rect.left() + CLIP_TEXT_PADDING, underline_y, underline_width, underline_y); + int underline_width = qMin(text_rect.width(), clip_painter.fontMetrics().width(clip->name)); + clip_painter.drawLine(text_rect.x(), underline_y, text_rect.x() + underline_width, underline_y); } + clip_painter.drawText(text_rect, 0, clip->name, &text_rect); // bottom right gray clip_painter.setPen(Qt::gray); diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index efe45d021..a0f037aea 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -5,6 +5,7 @@ #include "panels/timeline.h" #include "project/sequence.h" #include "project/effect.h" +#include "effects/transition.h" #include "playback/playback.h" #include "playback/audio.h" #include "io/media.h" @@ -58,8 +59,8 @@ void ViewerWidget::paintGL() if (multithreaded) retry_timer.stop(); glClear(GL_COLOR_BUFFER_BIT); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1.0, 1.0, 1.0, 1.0); current_clips.clear(); @@ -125,6 +126,19 @@ void ViewerWidget::paintGL() c->effects.at(j)->process_gl(&anchor_x, &anchor_y); } + if (c->opening_transition != NULL) { + int transition_progress = panel_timeline->playhead-c->timeline_in; + if (transition_progress < c->opening_transition->length) { + c->opening_transition->process_transition((float)transition_progress/(float)c->opening_transition->length); + } + } + if (c->closing_transition != NULL) { + int transition_progress = c->closing_transition->length-(panel_timeline->playhead-c->timeline_in-c->getLength()+c->closing_transition->length); + if (transition_progress < c->closing_transition->length) { + c->closing_transition->process_transition((float)transition_progress/(float)c->closing_transition->length); + } + } + int anchor_right = c->media_stream->video_width - anchor_x; int anchor_bottom = c->media_stream->video_height - anchor_y;