diff --git a/rendering/cacher.cpp b/rendering/cacher.cpp index ec7727e5e..380b1c996 100644 --- a/rendering/cacher.cpp +++ b/rendering/cacher.cpp @@ -20,8 +20,14 @@ #include "cacher.h" -#define __STDC_FORMAT_MACROS +#ifndef __STDC_FORMAT_MACROS +// For some reason the Windows AppVeyor build fails to find PRIx64 without this definition and including +// Maybe something to do with the GCC version being used? Either way, that's why it's here. +#define __STDC_FORMAT_MACROS 1 +#endif + #include + #include #include #include diff --git a/ui/timelineheader.cpp b/ui/timelineheader.cpp index 24ec538f5..b3e3711c2 100644 --- a/ui/timelineheader.cpp +++ b/ui/timelineheader.cpp @@ -47,428 +47,429 @@ #define TEXT_PADDING_FROM_LINE 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; + // 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), - dragging(false), - resizing_workarea(false), - zoom(1), - in_visible(0), - fm(font()), - dragging_markers(false), - scroll(0) + QWidget(parent), + snapping(true), + dragging(false), + resizing_workarea(false), + zoom(1), + in_visible(0), + fm(font()), + dragging_markers(false), + scroll(0) { - height_actual = fm.height(); - setCursor(Qt::ArrowCursor); - setMouseTracking(true); - setFocusPolicy(Qt::ClickFocus); - show_text(true); + height_actual = fm.height(); + setCursor(Qt::ArrowCursor); + setMouseTracking(true); + setFocusPolicy(Qt::ClickFocus); + show_text(true); - setContextMenuPolicy(Qt::CustomContextMenu); - connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(show_context_menu(const QPoint &))); + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(show_context_menu(const QPoint &))); } void TimelineHeader::set_scroll(int s) { - scroll = s; - update(); + scroll = s; + update(); } long TimelineHeader::getHeaderFrameFromScreenPoint(int x) { - return getFrameFromScreenPoint(zoom, x + scroll) + in_visible; + return getFrameFromScreenPoint(zoom, x + scroll) + in_visible; } int TimelineHeader::getHeaderScreenPointFromFrame(long frame) { - return getScreenPointFromFrame(zoom, frame - in_visible) - scroll; + return getScreenPointFromFrame(zoom, frame - in_visible) - scroll; } void TimelineHeader::set_playhead(int mouse_x) { - long frame = getHeaderFrameFromScreenPoint(mouse_x); - if (snapping) panel_timeline->snap_to_timeline(&frame, false, true, true); - if (frame != viewer->seq->playhead) { - viewer->seek(frame); - } + long frame = getHeaderFrameFromScreenPoint(mouse_x); + if (snapping) panel_timeline->snap_to_timeline(&frame, false, true, true); + if (frame != viewer->seq->playhead) { + viewer->seek(frame); + } } int TimelineHeader::get_marker_offset() { - return (text_enabled) ? height()/2 : 0; + return (text_enabled) ? height()/2 : 0; } void TimelineHeader::set_visible_in(long i) { - in_visible = i; - update(); + in_visible = i; + update(); } void TimelineHeader::set_in_point(long new_in) { - long new_out = viewer->seq->workarea_out; - if (new_out == new_in) { - new_in--; - } else if (new_out < new_in) { - new_out = viewer->seq->getEndFrame(); - } + long new_out = viewer->seq->workarea_out; + if (new_out == new_in) { + new_in--; + } else if (new_out < new_in) { + new_out = viewer->seq->getEndFrame(); + } - olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); - update_parents(); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); + update_parents(); } void TimelineHeader::set_out_point(long new_out) { - long new_in = viewer->seq->workarea_in; - if (new_out == new_in) { - new_out++; - } else if (new_in > new_out || new_in < 0) { - new_in = 0; - } + long new_in = viewer->seq->workarea_in; + if (new_out == new_in) { + new_out++; + } else if (new_in > new_out || new_in < 0) { + new_in = 0; + } - olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, new_out)); - update_parents(); + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, new_in, 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)); + bar->setMaximum(qMax(0, getScreenPointFromFrame(zoom, sequence_end_frame) - offset)); } void TimelineHeader::show_text(bool enable) { - text_enabled = enable; - if (enable) { - setFixedHeight(height_actual*2); - } else { - setFixedHeight(height_actual); - } - update(); + text_enabled = enable; + if (enable) { + setFixedHeight(height_actual*2); + } else { + setFixedHeight(height_actual); + } + update(); } void TimelineHeader::mousePressEvent(QMouseEvent* event) { - if (viewer->seq != nullptr && event->buttons() & Qt::LeftButton) { - if (resizing_workarea) { - sequence_end = viewer->seq->getEndFrame(); - } else { - /*int - QPoint start(in_x, height()+2); - QPainterPath path; - path.moveTo(start + QPoint(1,0)); - path.lineTo(in_x-PLAYHEAD_SIZE, yoff); - path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff);*/ + if (viewer->seq != nullptr && event->buttons() & Qt::LeftButton) { + if (resizing_workarea) { + sequence_end = viewer->seq->getEndFrame(); + } else { + /*int + QPoint start(in_x, height()+2); + QPainterPath path; + path.moveTo(start + QPoint(1,0)); + path.lineTo(in_x-PLAYHEAD_SIZE, yoff); + path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff);*/ - bool shift = (event->modifiers() & Qt::ShiftModifier); - bool clicked_on_marker = false; - int playhead_x = getHeaderScreenPointFromFrame(viewer->seq->playhead); + bool shift = (event->modifiers() & Qt::ShiftModifier); + bool clicked_on_marker = false; + int playhead_x = getHeaderScreenPointFromFrame(viewer->seq->playhead); - if (event->pos().y() > get_marker_offset() - && (event->pos().x() < playhead_x-PLAYHEAD_SIZE - || event->pos().x() > playhead_x+PLAYHEAD_SIZE)) { - for (int i=0;imarker_ref->size();i++) { - int marker_pos = getHeaderScreenPointFromFrame(viewer->marker_ref->at(i).frame); - if (event->pos().x() > marker_pos - MARKER_SIZE && event->pos().x() < marker_pos + MARKER_SIZE) { - bool found = false; - for (int j=0;jpos().y() > get_marker_offset() + && (event->pos().x() < playhead_x-PLAYHEAD_SIZE + || event->pos().x() > playhead_x+PLAYHEAD_SIZE)) { + for (int i=0;imarker_ref->size();i++) { + int marker_pos = getHeaderScreenPointFromFrame(viewer->marker_ref->at(i).frame); + if (event->pos().x() > marker_pos - MARKER_SIZE && event->pos().x() < marker_pos + MARKER_SIZE) { + bool found = false; + for (int j=0;jmarker_ref->at(selected_markers.at(i)).frame; - } - drag_start = event->pos().x(); - dragging_markers = true; - } else { - if (selected_markers.size() > 0 && !shift) { - selected_markers.clear(); - update(); - } - set_playhead(event->pos().x()); - } - } - dragging = true; - } + if (clicked_on_marker) { + selected_marker_original_times.resize(selected_markers.size()); + for (int i=0;imarker_ref->at(selected_markers.at(i)).frame; + } + drag_start = event->pos().x(); + dragging_markers = true; + } else { + if (selected_markers.size() > 0 && !shift) { + selected_markers.clear(); + update(); + } + set_playhead(event->pos().x()); + } + } + dragging = true; + } } void TimelineHeader::mouseMoveEvent(QMouseEvent* event) { - if (viewer->seq != nullptr) { - if (dragging) { - if (resizing_workarea) { - long frame = getHeaderFrameFromScreenPoint(event->pos().x()); - if (snapping) panel_timeline->snap_to_timeline(&frame, true, true, false); + if (viewer->seq != nullptr) { + if (dragging) { + if (resizing_workarea) { + long frame = getHeaderFrameFromScreenPoint(event->pos().x()); + if (snapping) panel_timeline->snap_to_timeline(&frame, true, true, false); - if (resizing_workarea_in) { - temp_workarea_in = qMax(qMin(temp_workarea_out-1, frame), 0L); - } else { - temp_workarea_out = qMin(qMax(temp_workarea_in+1, frame), sequence_end); - } + if (resizing_workarea_in) { + temp_workarea_in = qMax(qMin(temp_workarea_out-1, frame), 0L); + } else { + temp_workarea_out = qMin(qMax(temp_workarea_in+1, frame), sequence_end); + } - update_parents(); - } else if (dragging_markers) { - long frame_movement = getHeaderFrameFromScreenPoint(event->pos().x()) - getHeaderFrameFromScreenPoint(drag_start); + update_parents(); + } else if (dragging_markers) { + long frame_movement = getHeaderFrameFromScreenPoint(event->pos().x()) - getHeaderFrameFromScreenPoint(drag_start); - // snap markers - for (int i=0;isnap_to_timeline(&fm, true, false, true)) { - frame_movement = fm - selected_marker_original_times.at(i); - break; - } - } + // snap markers + for (int i=0;isnap_to_timeline(&fm, true, false, true)) { + frame_movement = fm - selected_marker_original_times.at(i); + break; + } + } - // validate markers (ensure none go below 0) - long validator; - for (int i=0;imarker_ref[0][selected_markers.at(i)].frame = selected_marker_original_times.at(i) + frame_movement; - } + // move markers + for (int i=0;imarker_ref[0][selected_markers.at(i)].frame = selected_marker_original_times.at(i) + frame_movement; + } - update_parents(); - } else { - set_playhead(event->pos().x()); - } - } else { - resizing_workarea = false; - unsetCursor(); - if (viewer->seq != nullptr && viewer->seq->using_workarea) { - long min_frame = getHeaderFrameFromScreenPoint(event->pos().x() - CLICK_RANGE) - 1; - long max_frame = getHeaderFrameFromScreenPoint(event->pos().x() + CLICK_RANGE) + 1; - if (viewer->seq->workarea_in > min_frame && viewer->seq->workarea_in < max_frame) { - resizing_workarea = true; - resizing_workarea_in = true; - } else if (viewer->seq->workarea_out > min_frame && viewer->seq->workarea_out < max_frame) { - resizing_workarea = true; - resizing_workarea_in = false; - } - if (resizing_workarea) { - temp_workarea_in = viewer->seq->workarea_in; - temp_workarea_out = viewer->seq->workarea_out; - setCursor(Qt::SizeHorCursor); - } - } - } - } + update_parents(); + } else { + set_playhead(event->pos().x()); + } + } else { + resizing_workarea = false; + unsetCursor(); + if (viewer->seq != nullptr && viewer->seq->using_workarea) { + long min_frame = getHeaderFrameFromScreenPoint(event->pos().x() - CLICK_RANGE) - 1; + long max_frame = getHeaderFrameFromScreenPoint(event->pos().x() + CLICK_RANGE) + 1; + if (viewer->seq->workarea_in > min_frame && viewer->seq->workarea_in < max_frame) { + resizing_workarea = true; + resizing_workarea_in = true; + } else if (viewer->seq->workarea_out > min_frame && viewer->seq->workarea_out < max_frame) { + resizing_workarea = true; + resizing_workarea_in = false; + } + if (resizing_workarea) { + temp_workarea_in = viewer->seq->workarea_in; + temp_workarea_out = viewer->seq->workarea_out; + setCursor(Qt::SizeHorCursor); + } + } + } + } } void TimelineHeader::mouseReleaseEvent(QMouseEvent*) { - if (viewer->seq != nullptr) { - dragging = false; - if (resizing_workarea) { - olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, temp_workarea_in, temp_workarea_out)); - } else if (dragging_markers && selected_markers.size() > 0) { - bool moved = false; - ComboAction* ca = new ComboAction(); - for (int i=0;imarker_ref[0][selected_markers.at(i)]; - if (selected_marker_original_times.at(i) != m->frame) { - ca->append(new MoveMarkerAction(m, selected_marker_original_times.at(i), m->frame)); - moved = true; - } - } - if (moved) { - olive::UndoStack.push(ca); - } else { - delete ca; - } - } + if (viewer->seq != nullptr) { + dragging = false; + if (resizing_workarea) { + olive::UndoStack.push(new SetTimelineInOutCommand(viewer->seq, true, temp_workarea_in, temp_workarea_out)); + } else if (dragging_markers && selected_markers.size() > 0) { + bool moved = false; + ComboAction* ca = new ComboAction(); + for (int i=0;imarker_ref[0][selected_markers.at(i)]; + if (selected_marker_original_times.at(i) != m->frame) { + ca->append(new MoveMarkerAction(m, selected_marker_original_times.at(i), m->frame)); + moved = true; + } + } + if (moved) { + olive::UndoStack.push(ca); + } else { + delete ca; + } + } - resizing_workarea = false; - dragging = false; - dragging_markers = false; - panel_timeline->snapped = false; - update_parents(); - } + resizing_workarea = false; + dragging = false; + dragging_markers = false; + panel_timeline->snapped = false; + update_parents(); + } } void TimelineHeader::focusOutEvent(QFocusEvent*) { - selected_markers.clear(); - update(); + selected_markers.clear(); + update(); } void TimelineHeader::update_parents() { - viewer->update_parents(); + viewer->update_parents(); } void TimelineHeader::update_zoom(double z) { - zoom = z; - update(); + zoom = z; + update(); } double TimelineHeader::get_zoom() { - return zoom; + return zoom; } void TimelineHeader::delete_markers() { - if (selected_markers.size() > 0) { - DeleteMarkerAction* dma = new DeleteMarkerAction(viewer->marker_ref); - for (int i=0;imarkers.append(selected_markers.at(i)); - } - olive::UndoStack.push(dma); - update_parents(); - } + if (selected_markers.size() > 0) { + DeleteMarkerAction* dma = new DeleteMarkerAction(viewer->marker_ref); + for (int i=0;imarkers.append(selected_markers.at(i)); + } + olive::UndoStack.push(dma); + update_parents(); + } } void TimelineHeader::paintEvent(QPaintEvent*) { - if (viewer->seq != nullptr && zoom > 0) { - QPainter p(this); - int yoff = get_marker_offset(); + if (viewer->seq != nullptr && zoom > 0) { + QPainter p(this); + int yoff = get_marker_offset(); - double interval = viewer->seq->frame_rate; - int textWidth = 0; - int lastTextBoundary = INT_MIN; + double interval = viewer->seq->frame_rate; + int textWidth = 0; + int lastTextBoundary = INT_MIN; - int lastLineX = INT_MIN; + int lastLineX = INT_MIN; - int sublineCount = 1; - int sublineTest = qRound(interval*zoom); - int sublineInterval = 1; - while (sublineTest > SUBLINE_MIN_PADDING - && sublineInterval >= 1) { - sublineCount *= 2; - sublineInterval = (interval/sublineCount); - sublineTest = qRound(sublineInterval*zoom); - } - sublineCount = qMin(sublineCount, qRound(interval)); + int sublineCount = 1; + int sublineTest = qRound(interval*zoom); + int sublineInterval = 1; + while (sublineTest > SUBLINE_MIN_PADDING + && sublineInterval >= 1) { + sublineCount *= 2; + sublineInterval = (interval/sublineCount); + sublineTest = qRound(sublineInterval*zoom); + } + sublineCount = qMin(sublineCount, qRound(interval)); - int text_x, fullTextWidth; - QString timecode; + int text_x, fullTextWidth; + QString timecode; - // find where to start drawing lines (lineX algorithm reversed if lineX = 0) - int i = qFloor(double(scroll)/zoom/interval); + // find where to start drawing lines (lineX algorithm reversed if lineX = 0) + int i = qFloor(double(scroll)/zoom/interval); - while (true) { - long frame = qRound(interval*i); - int lineX = qRound(frame*zoom) - scroll; + while (true) { + long frame = qRound(interval*i); + int lineX = qRound(frame*zoom) - scroll; - if (lineX > width()) break; + if (lineX > width()) break; - // draw text - bool draw_text = false; - if (text_enabled && lineX-textWidth > lastTextBoundary) { - timecode = frame_to_timecode(frame + in_visible, olive::CurrentConfig.timecode_view, viewer->seq->frame_rate); - fullTextWidth = fm.width(timecode); - textWidth = fullTextWidth>>1; + // draw text + bool draw_text = false; + if (text_enabled && lineX-textWidth > lastTextBoundary) { + timecode = frame_to_timecode(frame + in_visible, olive::CurrentConfig.timecode_view, viewer->seq->frame_rate); + fullTextWidth = fm.width(timecode); + textWidth = fullTextWidth>>1; - text_x = lineX; + text_x = lineX; - // centers the text to that point on the timeline, LEFT aligns it if not - if (olive::CurrentConfig.center_timeline_timecodes) { - text_x -= textWidth; - } else { - text_x += TEXT_PADDING_FROM_LINE; - } + // centers the text to that point on the timeline, LEFT aligns it if not + if (olive::CurrentConfig.center_timeline_timecodes) { + text_x -= textWidth; + } else { + text_x += TEXT_PADDING_FROM_LINE; + } - lastTextBoundary = lineX+textWidth; - if (lastTextBoundary >= 0) { - draw_text = true; - } - } + lastTextBoundary = lineX+textWidth; + if (lastTextBoundary >= 0) { + draw_text = true; + } + } - if (lineX > lastLineX+LINE_MIN_PADDING) { - if (draw_text) { - p.setPen(Qt::white); - p.drawText(QRect(text_x, 0, fullTextWidth, yoff), timecode); - } + if (lineX > lastLineX+LINE_MIN_PADDING) { + if (draw_text) { + p.setPen(Qt::white); + p.drawText(QRect(text_x, 0, fullTextWidth, yoff), timecode); + } - // draw line markers - p.setPen(Qt::gray); - p.drawLine(lineX, (!olive::CurrentConfig.center_timeline_timecodes && draw_text) ? 0 : yoff, lineX, height()); + // draw line markers + p.setPen(Qt::gray); + p.drawLine(lineX, (!olive::CurrentConfig.center_timeline_timecodes && draw_text) ? 0 : yoff, lineX, height()); - // draw sub-line markers - for (int j=1;jseq->using_workarea) { - in_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_in : viewer->seq->workarea_in)); - int out_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_out : viewer->seq->workarea_out)); - p.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128)); - p.setPen(Qt::white); - p.drawLine(in_x, 0, in_x, height()); - p.drawLine(out_x, 0, out_x, height()); - } + // draw in/out selection + int in_x; + if (viewer->seq->using_workarea) { + in_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_in : viewer->seq->workarea_in)); + int out_x = getHeaderScreenPointFromFrame((resizing_workarea ? temp_workarea_out : viewer->seq->workarea_out)); + p.fillRect(QRect(in_x, 0, out_x-in_x, height()), QColor(0, 192, 255, 128)); + p.setPen(Qt::white); + p.drawLine(in_x, 0, in_x, height()); + p.drawLine(out_x, 0, out_x, height()); + } - // draw markers - for (int i=0;imarker_ref->size();i++) { - const Marker& m = viewer->marker_ref->at(i); + // draw markers + for (int i=0;imarker_ref->size();i++) { + const Marker& m = viewer->marker_ref->at(i); - int marker_x = getHeaderScreenPointFromFrame(m.frame); + int marker_x = getHeaderScreenPointFromFrame(m.frame); - bool selected = false; - for (int j=0;jseq->playhead); - QPoint start(in_x, height()+2); - QPainterPath path; - path.moveTo(start + QPoint(1,0)); - path.lineTo(in_x-PLAYHEAD_SIZE, yoff); - path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff); - path.lineTo(start); - p.fillPath(path, Qt::red); - } + // draw playhead triangle + p.setRenderHint(QPainter::Antialiasing); + in_x = getHeaderScreenPointFromFrame(viewer->seq->playhead); + QPoint start(in_x, height()+2); + QPainterPath path; + path.moveTo(start + QPoint(1,0)); + path.lineTo(in_x-PLAYHEAD_SIZE, yoff); + path.lineTo(in_x+PLAYHEAD_SIZE+1, yoff); + path.lineTo(start); + p.fillPath(path, Qt::red); + } } void TimelineHeader::show_context_menu(const QPoint &pos) { - QMenu menu(this); + QMenu menu(this); - olive::MenuHelper.make_inout_menu(&menu); + // Add items for setting the in/out points of a QMenu + olive::MenuHelper.make_inout_menu(&menu); - menu.addSeparator(); + menu.addSeparator(); - QAction* center_timecodes = menu.addAction(tr("Center Timecodes"), olive::MainWindow, SLOT(toggle_bool_action())); - center_timecodes->setCheckable(true); - center_timecodes->setChecked(olive::CurrentConfig.center_timeline_timecodes); - center_timecodes->setData(reinterpret_cast(&olive::CurrentConfig.center_timeline_timecodes)); + QAction* center_timecodes = menu.addAction(tr("Center Timecodes"), &olive::MenuHelper, SLOT(toggle_bool_action())); + center_timecodes->setCheckable(true); + center_timecodes->setChecked(olive::CurrentConfig.center_timeline_timecodes); + center_timecodes->setData(reinterpret_cast(&olive::CurrentConfig.center_timeline_timecodes)); - menu.exec(mapToGlobal(pos)); + menu.exec(mapToGlobal(pos)); } void TimelineHeader::resized_scroll_listener(double d) { - update_zoom(zoom * d); + update_zoom(zoom * d); }