diff --git a/effects/internal/transformeffect.cpp b/effects/internal/transformeffect.cpp index 4d5e4b3b2..da03ea718 100644 --- a/effects/internal/transformeffect.cpp +++ b/effects/internal/transformeffect.cpp @@ -98,6 +98,11 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) right_center_gizmo->set_cursor(Qt::SizeHorCursor); right_center_gizmo->x_field = scale_x; + anchor_gizmo = add_gizmo(GIZMO_TYPE_TARGET); + anchor_gizmo->set_cursor(Qt::SizeAllCursor); + anchor_gizmo->x_field = anchor_x_box; + anchor_gizmo->y_field = anchor_y_box; + rotate_gizmo = add_gizmo(GIZMO_TYPE_DOT); rotate_gizmo->color = Qt::green; rotate_gizmo->set_cursor(Qt::SizeAllCursor); diff --git a/effects/internal/transformeffect.h b/effects/internal/transformeffect.h index 7fc635ad2..c198ffb0a 100644 --- a/effects/internal/transformeffect.h +++ b/effects/internal/transformeffect.h @@ -33,6 +33,7 @@ private: EffectGizmo* bottom_right_gizmo; EffectGizmo* left_center_gizmo; EffectGizmo* right_center_gizmo; + EffectGizmo* anchor_gizmo; EffectGizmo* rotate_gizmo; EffectGizmo* rect_gizmo; diff --git a/mainwindow.cpp b/mainwindow.cpp index e404b7d67..0e6e2f552 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -309,7 +309,11 @@ void MainWindow::on_actionZoom_In_triggered() panel_timeline->set_zoom(true); } else if (panel_effect_controls->keyframe_focus()) { panel_effect_controls->set_zoom(true); - } + } else if (panel_footage_viewer->is_focused()) { + panel_footage_viewer->set_zoom(true); + } else if (panel_sequence_viewer->is_focused()) { + panel_sequence_viewer->set_zoom(true); + } } void MainWindow::on_actionZoom_out_triggered() @@ -318,7 +322,11 @@ void MainWindow::on_actionZoom_out_triggered() panel_timeline->set_zoom(false); } else if (panel_effect_controls->keyframe_focus()) { panel_effect_controls->set_zoom(false); - } + } else if (panel_footage_viewer->is_focused()) { + panel_footage_viewer->set_zoom(false); + } else if (panel_sequence_viewer->is_focused()) { + panel_sequence_viewer->set_zoom(false); + } } void MainWindow::on_actionExport_triggered() @@ -580,7 +588,7 @@ void MainWindow::on_actionEdit_Tool_triggered() void MainWindow::on_actionToggle_Snapping_triggered() { - if (panel_timeline->focused()) panel_timeline->ui->snappingButton->click(); + if (panel_timeline->focused() || panel_effect_controls->keyframe_focus()) panel_timeline->ui->snappingButton->click(); } void MainWindow::on_actionPointer_Tool_triggered() diff --git a/olive.pro b/olive.pro index 897f652a5..b9cb61096 100644 --- a/olive.pro +++ b/olive.pro @@ -33,6 +33,7 @@ SOURCES += \ ui/sourcetable.cpp \ dialogs/aboutdialog.cpp \ ui/timelinewidget.cpp \ + io/media.cpp \ project/sequence.cpp \ project/clip.cpp \ playback/playback.cpp \ @@ -91,10 +92,7 @@ SOURCES += \ effects/internal/cubetransition.cpp \ project/effectgizmo.cpp \ io/clipboard.cpp \ - io/loadthread.cpp \ - project/footage.cpp \ - project/media.cpp \ - project/projectmodel.cpp + effects/internal/maskeffect.cpp HEADERS += \ mainwindow.h \ @@ -105,6 +103,7 @@ HEADERS += \ ui/sourcetable.h \ dialogs/aboutdialog.h \ ui/timelinewidget.h \ + io/media.h \ project/sequence.h \ project/clip.h \ playback/playback.h \ @@ -165,10 +164,7 @@ HEADERS += \ effects/internal/cubetransition.h \ project/effectgizmo.h \ io/clipboard.h \ - io/loadthread.h \ - project/footage.h \ - project/media.h \ - project/projectmodel.h + effects/internal/maskeffect.h FORMS += \ mainwindow.ui \ diff --git a/panels/timeline.cpp b/panels/timeline.cpp index ba02ffefe..a992e8573 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -417,16 +417,6 @@ bool Timeline::focused() { return (sequence != NULL && (ui->headers->hasFocus() || ui->video_area->hasFocus() || ui->audio_area->hasFocus())); } -bool Timeline::center_scroll_to_playhead() { - // returns true is the scroll was changed, false if not - int target_scroll = qMin(ui->horizontalScrollBar->maximum(), qMax(0, getScreenPointFromFrame(zoom, sequence->playhead)-(ui->editAreas->width()>>1))); - if (target_scroll == ui->horizontalScrollBar->value()) { - return false; - } - ui->horizontalScrollBar->setValue(target_scroll); - return true; -} - void Timeline::repaint_timeline() { bool draw = true; @@ -442,7 +432,7 @@ void Timeline::repaint_timeline() { draw = false; } } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) { - if (center_scroll_to_playhead()) { + if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) { draw = false; } } @@ -458,7 +448,7 @@ void Timeline::repaint_timeline() { if (sequence != NULL) { long sequenceEndFrame = sequence->getEndFrame(); - ui->horizontalScrollBar->setMaximum(qMax(0, getScreenPointFromFrame(zoom, sequenceEndFrame) - (ui->editAreas->width()/2))); + ui->headers->set_scrollbar_max(ui->horizontalScrollBar, sequenceEndFrame, (ui->editAreas->width()/2)); if (last_frame != sequence->playhead) { ui->audio_monitor->update(); @@ -579,7 +569,7 @@ void Timeline::set_zoom_value(double v) { repaint_timeline(); // TODO find a way to gradually move towards target_scroll instead of just centering it? - center_scroll_to_playhead(); + center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead); } void Timeline::set_zoom(bool in) { diff --git a/panels/timeline.h b/panels/timeline.h index 0bbd50d00..6d4bb4a5a 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -227,8 +227,7 @@ private: void set_zoom_value(double v); QVector tool_buttons; void decheck_tool_buttons(QObject* sender); - void set_tool(int tool); - bool center_scroll_to_playhead(); + void set_tool(int tool); long last_frame; int scroll; diff --git a/panels/viewer.cpp b/panels/viewer.cpp index 346835fbc..f70b8ecc4 100644 --- a/panels/viewer.cpp +++ b/panels/viewer.cpp @@ -39,7 +39,8 @@ Viewer::Viewer(QWidget *parent) : ui(new Ui::Viewer), created_sequence(false), cue_recording_internal(false), - panel_name("Viewer: ") + panel_name("Viewer: "), + minimum_zoom(1.0) { ui->setupUi(this); ui->headers->viewer = this; @@ -61,6 +62,8 @@ Viewer::Viewer(QWidget *parent) : connect(&playback_updater, SIGNAL(timeout()), this, SLOT(timer_update())); connect(&recording_flasher, SIGNAL(timeout()), this, SLOT(recording_flasher_update())); + connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->headers, SLOT(set_scroll(int))); + connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), ui->openGLWidget, SLOT(set_waveform_scroll(int))); update_playhead_timecode(0); update_end_timecode(); @@ -382,7 +385,14 @@ void Viewer::update_end_timecode() { void Viewer::update_header_zoom() { if (seq != NULL) { long sequenceEndFrame = seq->getEndFrame(); - ui->headers->update_zoom((sequenceEndFrame > 0) ? ((double) ui->headers->width() / (double) sequenceEndFrame) : 1); + if (cached_end_frame != sequenceEndFrame) { + minimum_zoom = (sequenceEndFrame > 0) ? ((double) ui->headers->width() / (double) sequenceEndFrame) : 1; + ui->headers->update_zoom(qMax(ui->headers->get_zoom(), minimum_zoom)); + ui->headers->set_scrollbar_max(ui->horizontalScrollBar, sequenceEndFrame, ui->headers->width()); + ui->openGLWidget->waveform_zoom = ui->headers->get_zoom(); + } else { + ui->headers->update(); + } } } @@ -395,8 +405,8 @@ void Viewer::update_parents() { } void Viewer::update_viewer() { + update_header_zoom(); viewer_widget->update(); - update_header_zoom(); if (seq != NULL) update_playhead_timecode(seq->playhead); update_end_timecode(); } @@ -413,7 +423,21 @@ void Viewer::set_in_point() { } void Viewer::set_out_point() { - ui->headers->set_out_point(seq->playhead); + ui->headers->set_out_point(seq->playhead); +} + +void Viewer::set_zoom(bool in) { + if (in) { + ui->headers->update_zoom(ui->headers->get_zoom()*2); + } else { + ui->headers->update_zoom(qMax(minimum_zoom, ui->headers->get_zoom()*0.5)); + } + if (ui->openGLWidget->waveform) { + ui->openGLWidget->waveform_zoom = ui->headers->get_zoom(); + ui->openGLWidget->update(); + } + ui->headers->set_scrollbar_max(ui->horizontalScrollBar, seq->getEndFrame(), ui->headers->width()); + center_scroll_to_playhead(ui->horizontalScrollBar, ui->headers->get_zoom(), seq->playhead); } void Viewer::set_media(Media* m) { diff --git a/panels/viewer.h b/panels/viewer.h index 3bd461ff9..a7e1d84aa 100644 --- a/panels/viewer.h +++ b/panels/viewer.h @@ -37,6 +37,7 @@ public: void clear_inout_point(); void set_in_point(); void set_out_point(); + void set_zoom(bool in); // playback functions void go_to_start(); @@ -88,7 +89,9 @@ private: void set_sequence(bool main, Sequence* s); bool main_sequence; bool created_sequence; + long cached_end_frame; QString panel_name; + double minimum_zoom; bool cue_recording_internal; QTimer recording_flasher; diff --git a/panels/viewer.ui b/panels/viewer.ui index 111812803..0a7613183 100644 --- a/panels/viewer.ui +++ b/panels/viewer.ui @@ -64,6 +64,22 @@ + + + + 0 + + + 20 + + + 1826 + + + Qt::Horizontal + + + diff --git a/playback/playback.cpp b/playback/playback.cpp index 73c3ceb91..d24a03c8b 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -106,6 +106,10 @@ void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVectorget_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate); +} + void get_clip_frame(Clip* c, long playhead) { if (c->finished_opening) { FootageStream* ms = c->media->to_footage()->get_stream_from_file_index(c->track < 0, c->media_stream); @@ -215,8 +219,29 @@ void get_clip_frame(Clip* c, long playhead) { if (target_frame != NULL) { // add gate if this is the same frame - glPixelStorei(GL_UNPACK_ROW_LENGTH, target_frame->linesize[0]/4); - c->texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, target_frame->data[0]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, target_frame->linesize[0]/4); + + bool copied = false; + uint8_t* data = target_frame->data[0]; + int frame_size; + + for (int i=0;ieffects.size();i++) { + Effect* e = c->effects.at(i); + if (e->enable_image) { + if (!copied) { + frame_size = target_frame->linesize[0]*target_frame->height; + data = new uint8_t[frame_size]; + memcpy(data, target_frame->data[0], frame_size); + copied = true; + } + e->process_image(get_timecode(c, playhead), data, frame_size); + } + } + + c->texture->setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, data); + + if (copied) delete [] data; + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } diff --git a/playback/playback.h b/playback/playback.h index ed5f19900..67a18c6d4 100644 --- a/playback/playback.h +++ b/playback/playback.h @@ -21,6 +21,7 @@ void cache_video_worker(Clip* c, long playhead); void handle_media(Sequence* sequence, long playhead, bool multithreaded); void reset_cache(Clip* c, long target_frame); void get_clip_frame(Clip* c, long playhead); +double get_timecode(Clip* c, long playhead); long playhead_to_clip_frame(Clip* c, long playhead); double playhead_to_clip_seconds(Clip* c, long playhead); diff --git a/project/effect.cpp b/project/effect.cpp index 8255631ce..7bee62a95 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -27,6 +27,7 @@ #include "effects/internal/paneffect.h" #include "effects/internal/shakeeffect.h" #include "effects/internal/cornerpineffect.h" +#include "effects/internal/maskeffect.h" #include #include @@ -59,6 +60,7 @@ Effect* create_effect(Clip* c, const EffectMeta* em) { case EFFECT_INTERNAL_TONE: return new ToneEffect(c, em); case EFFECT_INTERNAL_SHAKE: return new ShakeEffect(c, em); case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em); + case EFFECT_INTERNAL_MASK: return new MaskEffect(c, em); } } else { dout << "[ERROR] Invalid effect data"; @@ -107,8 +109,15 @@ void load_internal_effects() { effects.append(em); em.name = "Corner Pin"; - em.category = "Distort"; em.internal = EFFECT_INTERNAL_CORNERPIN; + effects.append(em); + + em.name = "Mask"; + em.internal = EFFECT_INTERNAL_MASK; + effects.append(em); + + em.name = "Shake"; + em.internal = EFFECT_INTERNAL_SHAKE; effects.append(em); em.name = "Text"; @@ -117,20 +126,13 @@ void load_internal_effects() { effects.append(em); em.name = "Timecode"; - em.category = "Render"; em.internal = EFFECT_INTERNAL_TIMECODE; effects.append(em); - em.name = "Solid"; - em.category = "Render"; + em.name = "Solid"; em.internal = EFFECT_INTERNAL_SOLID; effects.append(em); - em.name = "Shake"; - em.category = "Distort"; - em.internal = EFFECT_INTERNAL_SHAKE; - effects.append(em); - // internal transitions em.type = EFFECT_TYPE_TRANSITION; em.category = ""; @@ -230,6 +232,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) : enable_shader(false), enable_coords(false), enable_superimpose(false), + enable_image(false), glslProgram(NULL), texture(NULL), isOpen(false), @@ -767,9 +770,11 @@ void Effect::startEffect() { void Effect::endEffect() { if (bound) glslProgram->release(); - bound = false; + bound = false; } +void Effect::process_image(double, uint8_t *, int) {} + Effect* Effect::copy(Clip* c) { Effect* copy = create_effect(c, meta); copy->set_enabled(is_enabled()); diff --git a/project/effect.h b/project/effect.h index 4f15a4123..08fcc13b4 100644 --- a/project/effect.h +++ b/project/effect.h @@ -62,7 +62,7 @@ extern QMutex effects_loaded; #define EFFECT_INTERNAL_TONE 6 #define EFFECT_INTERNAL_SHAKE 7 #define EFFECT_INTERNAL_TIMECODE 8 - +#define EFFECT_INTERNAL_MASK 9 #define EFFECT_INTERNAL_CORNERPIN 12 @@ -147,12 +147,14 @@ public: bool enable_shader; bool enable_coords; bool enable_superimpose; + bool enable_image; int getIterations(); void setIterations(int i); const char* ffmpeg_filter; + virtual void process_image(double timecode, uint8_t* data, int size); virtual void process_shader(double timecode, GLTextureCoords&); virtual void process_coords(double timecode, GLTextureCoords& coords, int data); virtual GLuint process_superimpose(double timecode); diff --git a/project/effectgizmo.h b/project/effectgizmo.h index befe4bcd3..ec10f4b09 100644 --- a/project/effectgizmo.h +++ b/project/effectgizmo.h @@ -3,8 +3,10 @@ #define GIZMO_TYPE_DOT 0 #define GIZMO_TYPE_POLY 1 +#define GIZMO_TYPE_TARGET 2 #define GIZMO_DOT_SIZE 2.5F +#define GIZMO_TARGET_SIZE 5.0F #include #include diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index 00094fac2..d39976bbd 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #define CLICK_RANGE 5 @@ -19,6 +19,16 @@ #define SUBLINE_MIN_PADDING 50 // TODO play with this #define MARKER_SIZE 4 +bool center_scroll_to_playhead(QScrollBar* bar, double zoom, long playhead) { + // returns true is the scroll was changed, false if not + int target_scroll = qMin(bar->maximum(), qMax(0, getScreenPointFromFrame(zoom, playhead)-(bar->width()>>1))); + if (target_scroll == bar->value()) { + return false; + } + bar->setValue(target_scroll); + return true; +} + TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent), snapping(true), @@ -87,6 +97,10 @@ void TimelineHeader::set_out_point(long new_out) { update_parents(); } +void TimelineHeader::set_scrollbar_max(QScrollBar* bar, long sequence_end_frame, int offset) { + bar->setMaximum(qMax(0, getScreenPointFromFrame(zoom, sequence_end_frame) - offset)); +} + void TimelineHeader::show_text(bool enable) { text_enabled = enable; if (enable) { @@ -255,7 +269,11 @@ void TimelineHeader::update_parents() { void TimelineHeader::update_zoom(double z) { zoom = z; - update(); + update(); +} + +double TimelineHeader::get_zoom() { + return zoom; } void TimelineHeader::delete_markers() { diff --git a/ui/timelineheader.h b/ui/timelineheader.h index 68cb38573..88adc3151 100644 --- a/ui/timelineheader.h +++ b/ui/timelineheader.h @@ -3,8 +3,10 @@ #include #include -class QScrollArea; class Viewer; +class QScrollBar; + +bool center_scroll_to_playhead(QScrollBar* bar, double zoom, long playhead); class TimelineHeader : public QWidget { @@ -20,7 +22,9 @@ public: void show_text(bool enable); void update_zoom(double z); + double get_zoom(); void delete_markers(); + void set_scrollbar_max(QScrollBar* bar, long sequence_end_frame, int offset); public slots: void set_scroll(int); diff --git a/ui/viewercontainer.cpp b/ui/viewercontainer.cpp index cd3e7cbfd..82b203bba 100644 --- a/ui/viewercontainer.cpp +++ b/ui/viewercontainer.cpp @@ -3,6 +3,8 @@ #include #include +#include "viewerwidget.h" + // enforces aspect ratio ViewerContainer::ViewerContainer(QWidget *parent) : QWidget(parent), @@ -11,26 +13,31 @@ ViewerContainer::ViewerContainer(QWidget *parent) : {} void ViewerContainer::adjust() { - if (child != NULL) { - QSize widget_size = size(); - int widget_x = 0; - int widget_y = 0; - int widget_width = widget_size.width(); - int widget_height = widget_size.height(); - float widget_ar = (float) widget_width /(float) widget_height; + if (child != NULL) { + if (child->waveform) { + child->move(0, 0); + child->resize(size()); + } else { + QSize widget_size = size(); + int widget_x = 0; + int widget_y = 0; + int widget_width = widget_size.width(); + int widget_height = widget_size.height(); + float widget_ar = (float) widget_width /(float) widget_height; - bool widget_is_larger_than_sequence = widget_ar > aspect_ratio; + bool widget_is_larger_than_sequence = widget_ar > aspect_ratio; - if (widget_is_larger_than_sequence) { - widget_width = widget_height * aspect_ratio; - widget_x = (widget_size.width() / 2) - (widget_width / 2); - } else { - widget_height = widget_width / aspect_ratio; - widget_y = (widget_size.height() / 2) - (widget_height / 2); - } + if (widget_is_larger_than_sequence) { + widget_width = widget_height * aspect_ratio; + widget_x = (widget_size.width() / 2) - (widget_width / 2); + } else { + widget_height = widget_width / aspect_ratio; + widget_y = (widget_size.height() / 2) - (widget_height / 2); + } - child->move(widget_x, widget_y); - child->resize(widget_width, widget_height); + child->move(widget_x, widget_y); + child->resize(widget_width, widget_height); + } } } diff --git a/ui/viewercontainer.h b/ui/viewercontainer.h index 2d2bdd0b6..c33a65ac6 100644 --- a/ui/viewercontainer.h +++ b/ui/viewercontainer.h @@ -2,6 +2,7 @@ #define VIEWERCONTAINER_H #include +class ViewerWidget; class ViewerContainer : public QWidget { @@ -9,7 +10,7 @@ class ViewerContainer : public QWidget public: explicit ViewerContainer(QWidget *parent = 0); float aspect_ratio; - QWidget* child; + ViewerWidget* child; void adjust(); protected: diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 5048d0fac..cf51ee2eb 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -44,7 +44,9 @@ ViewerWidget::ViewerWidget(QWidget *parent) : default_fbo(NULL), waveform(false), dragging(false), - selected_gizmo(NULL) + selected_gizmo(NULL), + waveform_zoom(1.0), + waveform_scroll(0) { setMouseTracking(true); setFocusPolicy(Qt::ClickFocus); @@ -70,6 +72,13 @@ void ViewerWidget::delete_function() { } } +void ViewerWidget::set_waveform_scroll(int s) { + if (waveform) { + waveform_scroll = s; + update(); + } +} + void ViewerWidget::show_context_menu() { QMenu menu(this); @@ -142,11 +151,7 @@ void ViewerWidget::paintEvent(QPaintEvent *e) { } void ViewerWidget::seek_from_click(int x) { - viewer->seek(getFrameFromScreenPoint((double) width() / (double) waveform_clip->timeline_out, x)); -} - -double get_timecode(Clip* c, long playhead) { - return ((double)(playhead-c->get_timeline_in_with_transition()+c->get_clip_in_with_transition())/(double)c->sequence->frame_rate); + viewer->seek(getFrameFromScreenPoint(waveform_zoom, x+waveform_scroll)); } EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { @@ -154,6 +159,7 @@ EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { double multiplier = (double) viewer->seq->width / (double) width(); QPoint mouse_pos(qRound(x*multiplier), qRound(y*multiplier)); int dot_size = 2 * qRound(GIZMO_DOT_SIZE * multiplier); + int target_size = 2 * qRound(GIZMO_TARGET_SIZE * multiplier); for (int i=0;igizmo_count();i++) { EffectGizmo* g = gizmos->gizmo(i); @@ -171,6 +177,14 @@ EffectGizmo* ViewerWidget::get_gizmo_from_mouse(int x, int y) { return g; } break; + case GIZMO_TYPE_TARGET: + if (mouse_pos.x() > g->screen_pos[0].x() - target_size + && mouse_pos.y() > g->screen_pos[0].y() - target_size + && mouse_pos.x() < g->screen_pos[0].x() + target_size + && mouse_pos.y() < g->screen_pos[0].y() + target_size) { + return g; + } + break; } } @@ -761,23 +775,23 @@ void ViewerWidget::paintGL() { compose_sequence(nests, render_audio); if (waveform) { - double waveform_zoom = (double) waveform_ms->audio_preview.size() / (double) width(); - double timeline_zoom = (double) width() / (double) waveform_clip->timeline_out; - QPainter p(this); if (viewer->seq->using_workarea) { - int in_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_in); - int out_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_out); + int in_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->workarea_in) - waveform_scroll; + int out_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->workarea_out) - waveform_scroll; p.fillRect(QRect(in_x, 0, out_x - in_x, height()), QColor(255, 255, 255, 64)); p.setPen(Qt::white); p.drawLine(in_x, 0, in_x, height()); p.drawLine(out_x, 0, out_x, height()); } + QRect wr = rect(); + wr.setX(wr.x() - waveform_scroll); + p.setPen(Qt::green); - draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, rect(), 0, width(), waveform_zoom); + draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, wr, waveform_scroll, width()+waveform_scroll, waveform_zoom); p.setPen(Qt::red); - int playhead_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->playhead); + int playhead_x = getScreenPointFromFrame(waveform_zoom, viewer->seq->playhead) - waveform_scroll; p.drawLine(playhead_x, 0, playhead_x, height()); } @@ -800,6 +814,7 @@ void ViewerWidget::paintGL() { glGetFloatv(GL_CURRENT_COLOR, color); float dot_size = GIZMO_DOT_SIZE / width() * viewer->seq->width; + float target_size = GIZMO_TARGET_SIZE / width() * viewer->seq->width; glPushMatrix(); glLoadIdentity(); @@ -827,6 +842,27 @@ void ViewerWidget::paintGL() { glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y(), gizmo_z); glEnd(); break; + case GIZMO_TYPE_TARGET: // draw target + glBegin(GL_LINES); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); + + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); + + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); + + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()+target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y()-target_size, gizmo_z); + + glVertex3f(g->screen_pos[0].x()-target_size, g->screen_pos[0].y(), gizmo_z); + glVertex3f(g->screen_pos[0].x()+target_size, g->screen_pos[0].y(), gizmo_z); + + glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y()-target_size, gizmo_z); + glVertex3f(g->screen_pos[0].x(), g->screen_pos[0].y()+target_size, gizmo_z); + glEnd(); + break; } } glPopMatrix(); diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h index 388582106..965e86f3d 100644 --- a/ui/viewerwidget.h +++ b/ui/viewerwidget.h @@ -33,10 +33,13 @@ public: bool waveform; Clip* waveform_clip; FootageStream* waveform_ms; + double waveform_zoom; + int waveform_scroll; bool force_quit; public slots: void delete_function(); + void set_waveform_scroll(int s); protected: void paintEvent(QPaintEvent *e); // void resizeGL(int w, int h);