most clip marker work completed #333
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#define SAVE_VERSION 190120 // YYMMDD
|
||||
#define SAVE_VERSION 190201 // YYMMDD
|
||||
#define MIN_SAVE_VERSION 190104 // lowest compatible project version
|
||||
|
||||
#define TIMECODE_DROP 0
|
||||
|
||||
+16
-2
@@ -427,10 +427,24 @@ bool LoadThread::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
}
|
||||
}
|
||||
if (cancelled) return false;
|
||||
} else if (stream.isStartElement() && (stream.name() == "effect" || stream.name() == "opening" || stream.name() == "closing")) {
|
||||
} else if (stream.isStartElement()
|
||||
&& (stream.name() == "effect"
|
||||
|| stream.name() == "opening"
|
||||
|| stream.name() == "closing")) {
|
||||
// "opening" and "closing" are backwards compatibility code
|
||||
load_effect(stream, c);
|
||||
}
|
||||
} else if (stream.name() == "marker" && stream.isStartElement()) {
|
||||
Marker m;
|
||||
for (int j=0;j<stream.attributes().size();j++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(j);
|
||||
if (attr.name() == "frame") {
|
||||
m.frame = attr.value().toLong();
|
||||
} else if (attr.name() == "name") {
|
||||
m.name = attr.value().toString();
|
||||
}
|
||||
}
|
||||
c->markers.append(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cancelled) return false;
|
||||
|
||||
+13
-4
@@ -915,6 +915,13 @@ void Project::load_project(bool autorecovery) {
|
||||
ld.exec();
|
||||
}
|
||||
|
||||
void save_marker(QXmlStreamWriter& stream, const Marker& m) {
|
||||
stream.writeStartElement("marker");
|
||||
stream.writeAttribute("frame", QString::number(m.frame));
|
||||
stream.writeAttribute("name", m.name);
|
||||
stream.writeEndElement();
|
||||
}
|
||||
|
||||
void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only, const QModelIndex& parent) {
|
||||
for (int i=0;i<project_model.rowCount(parent);i++) {
|
||||
const QModelIndex& item = project_model.index(i, 0, parent);
|
||||
@@ -1045,6 +1052,11 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
}
|
||||
}
|
||||
|
||||
// save markers
|
||||
for (int k=0;k<c->markers.size();k++) {
|
||||
save_marker(stream, c->markers.at(k));
|
||||
}
|
||||
|
||||
stream.writeStartElement("linked"); // linked
|
||||
for (int k=0;k<c->linked.size();k++) {
|
||||
stream.writeStartElement("link"); // link
|
||||
@@ -1063,10 +1075,7 @@ void Project::save_folder(QXmlStreamWriter& stream, int type, bool set_ids_only,
|
||||
}
|
||||
}
|
||||
for (int j=0;j<s->markers.size();j++) {
|
||||
stream.writeStartElement("marker");
|
||||
stream.writeAttribute("frame", QString::number(s->markers.at(j).frame));
|
||||
stream.writeAttribute("name", s->markers.at(j).name);
|
||||
stream.writeEndElement();
|
||||
save_marker(stream, s->markers.at(j));
|
||||
}
|
||||
stream.writeEndElement();
|
||||
}
|
||||
|
||||
+30
-3
@@ -1426,7 +1426,14 @@ bool Timeline::snap_to_timeline(long* l, bool use_playhead, bool use_markers, bo
|
||||
} else if (c->get_closing_transition() != nullptr
|
||||
&& snap_to_point(c->timeline_out - c->get_closing_transition()->get_true_length(), l)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// try to snap to clip markers
|
||||
for (int j=0;j<c->markers.size();j++) {
|
||||
if (snap_to_point(c->markers.at(j).frame + c->timeline_in - c->clip_in, l)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1446,9 +1453,29 @@ void Timeline::set_marker() {
|
||||
marker_name = d.textValue();
|
||||
}
|
||||
|
||||
|
||||
if (add_marker) {
|
||||
undo_stack.push(new AddMarkerAction(sequence, sequence->playhead, marker_name));
|
||||
ComboAction* ca = new ComboAction();
|
||||
|
||||
// see if any clips are selected, and if so add a marker to them
|
||||
bool clip_mode = false;
|
||||
for (int i=0;i<sequence->clips.size();i++) {
|
||||
Clip* c = sequence->clips.at(i);
|
||||
if (c != nullptr
|
||||
&& is_clip_selected(c, true)) {
|
||||
ca->append(new AddMarkerAction(false,
|
||||
c,
|
||||
sequence->playhead - c->timeline_in + c->clip_in,
|
||||
marker_name));
|
||||
clip_mode = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if no clips are selected, we're adding a marker to the sequence
|
||||
if (!clip_mode) {
|
||||
ca->append(new AddMarkerAction(true, sequence, sequence->playhead, marker_name));
|
||||
}
|
||||
|
||||
undo_stack.push(ca);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <QMutex>
|
||||
#include <QVector>
|
||||
|
||||
#include "marker.h"
|
||||
|
||||
#define SKIP_TYPE_DISCARD 0
|
||||
#define SKIP_TYPE_SEEK 1
|
||||
|
||||
@@ -73,6 +75,9 @@ struct Clip
|
||||
bool maintain_audio_pitch;
|
||||
bool autoscale;
|
||||
|
||||
// markers
|
||||
QVector<Marker> markers;
|
||||
|
||||
// other variables (should be deep copied/duplicated in copy())
|
||||
QList<Effect*> effects;
|
||||
QVector<int> linked;
|
||||
|
||||
@@ -1 +1,18 @@
|
||||
#include "marker.h"
|
||||
|
||||
void draw_marker(QPainter &p, int x, int y, int bottom, bool selected, bool flipped) {
|
||||
const QPoint points[5] = {
|
||||
QPoint(x, bottom),
|
||||
QPoint(x + MARKER_SIZE, bottom - MARKER_SIZE),
|
||||
QPoint(x + MARKER_SIZE, y),
|
||||
QPoint(x - MARKER_SIZE, y),
|
||||
QPoint(x - MARKER_SIZE, bottom - MARKER_SIZE)
|
||||
};
|
||||
p.setPen(Qt::black);
|
||||
if (selected) {
|
||||
p.setBrush(QColor(208, 255, 208));
|
||||
} else {
|
||||
p.setBrush(QColor(128, 224, 128));
|
||||
}
|
||||
p.drawPolygon(points, 5);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
#ifndef MARKER_H
|
||||
#define MARKER_H
|
||||
|
||||
#define MARKER_SIZE 4
|
||||
|
||||
#include <QString>
|
||||
#include <QPainter>
|
||||
|
||||
struct Marker {
|
||||
long frame;
|
||||
QString name;
|
||||
};
|
||||
|
||||
void draw_marker(QPainter& p, int x, int y, int bottom, bool selected, bool flipped);
|
||||
|
||||
#endif // MARKER_H
|
||||
|
||||
+19
-9
@@ -803,18 +803,23 @@ void SetAutoscaleAction::redo() {
|
||||
mainWindow->setWindowModified(true);
|
||||
}
|
||||
|
||||
AddMarkerAction::AddMarkerAction(Sequence* s, long t, QString n) :
|
||||
seq(s),
|
||||
AddMarkerAction::AddMarkerAction(bool is_sequence, void* s, long t, QString n) :
|
||||
is_sequence_internal(is_sequence),
|
||||
target(s),
|
||||
time(t),
|
||||
name(n),
|
||||
old_project_changed(mainWindow->isWindowModified())
|
||||
{}
|
||||
|
||||
void AddMarkerAction::undo() {
|
||||
QVector<Marker>& markers = is_sequence_internal ?
|
||||
static_cast<Sequence*>(target)->markers :
|
||||
static_cast<Clip*>(target)->markers;
|
||||
|
||||
if (index == -1) {
|
||||
seq->markers.removeLast();
|
||||
markers.removeLast();
|
||||
} else {
|
||||
seq->markers[index].name = old_name;
|
||||
markers[index].name = old_name;
|
||||
}
|
||||
|
||||
mainWindow->setWindowModified(old_project_changed);
|
||||
@@ -822,8 +827,13 @@ void AddMarkerAction::undo() {
|
||||
|
||||
void AddMarkerAction::redo() {
|
||||
index = -1;
|
||||
for (int i=0;i<seq->markers.size();i++) {
|
||||
if (seq->markers.at(i).frame == time) {
|
||||
|
||||
QVector<Marker>& markers = is_sequence_internal ?
|
||||
static_cast<Sequence*>(target)->markers :
|
||||
static_cast<Clip*>(target)->markers;
|
||||
|
||||
for (int i=0;i<markers.size();i++) {
|
||||
if (markers.at(i).frame == time) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
@@ -832,10 +842,10 @@ void AddMarkerAction::redo() {
|
||||
if (index == -1) {
|
||||
Marker m;
|
||||
m.frame = time;
|
||||
seq->markers.append(m);
|
||||
markers.append(m);
|
||||
} else {
|
||||
old_name = seq->markers.at(index).name;
|
||||
seq->markers[index].name = name;
|
||||
old_name = markers.at(index).name;
|
||||
markers[index].name = name;
|
||||
}
|
||||
|
||||
mainWindow->setWindowModified(true);
|
||||
|
||||
+3
-2
@@ -384,11 +384,12 @@ private:
|
||||
|
||||
class AddMarkerAction : public QUndoCommand {
|
||||
public:
|
||||
AddMarkerAction(Sequence* s, long t, QString n);
|
||||
AddMarkerAction(bool is_sequence, void* s, long t, QString n);
|
||||
void undo();
|
||||
void redo();
|
||||
private:
|
||||
Sequence* seq;
|
||||
bool is_sequence_internal;
|
||||
void* target;
|
||||
long time;
|
||||
QString name;
|
||||
QString old_name;
|
||||
|
||||
+11
-29
@@ -20,7 +20,6 @@
|
||||
#define PLAYHEAD_SIZE 6
|
||||
#define LINE_MIN_PADDING 50
|
||||
#define SUBLINE_MIN_PADDING 50 // TODO play with this
|
||||
#define MARKER_SIZE 4
|
||||
|
||||
// used only if center_timeline_timecodes is FALSE
|
||||
#define TEXT_PADDING_FROM_LINE 4
|
||||
@@ -406,35 +405,18 @@ void TimelineHeader::paintEvent(QPaintEvent*) {
|
||||
// draw markers
|
||||
for (int i=0;i<viewer->seq->markers.size();i++) {
|
||||
const Marker& m = viewer->seq->markers.at(i);
|
||||
|
||||
int marker_x = getHeaderScreenPointFromFrame(m.frame);
|
||||
const QPoint points[5] = {
|
||||
QPoint(marker_x, height()-1),
|
||||
QPoint(marker_x + MARKER_SIZE, height() - MARKER_SIZE - 1),
|
||||
QPoint(marker_x + MARKER_SIZE, yoff),
|
||||
QPoint(marker_x - MARKER_SIZE, yoff),
|
||||
QPoint(marker_x - MARKER_SIZE, height() - MARKER_SIZE - 1)
|
||||
};
|
||||
/*const QPoint points[5] = {
|
||||
QPoint(marker_x, height()-1),
|
||||
QPoint(marker_x + MARKER_SIZE, height() - MARKER_SIZE - 1),
|
||||
QPoint(marker_x + MARKER_SIZE, yoff),
|
||||
QPoint(marker_x - MARKER_SIZE, yoff),
|
||||
QPoint(marker_x - MARKER_SIZE, height() - MARKER_SIZE - 1)
|
||||
};*/
|
||||
p.setPen(Qt::black);
|
||||
bool selected = false;
|
||||
for (int j=0;j<selected_markers.size();j++) {
|
||||
if (selected_markers.at(j) == i) {
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
p.setBrush(QColor(208, 255, 208));
|
||||
} else {
|
||||
p.setBrush(QColor(128, 224, 128));
|
||||
}
|
||||
p.drawPolygon(points, 5);
|
||||
|
||||
bool selected = false;
|
||||
for (int j=0;j<selected_markers.size();j++) {
|
||||
if (selected_markers.at(j) == i) {
|
||||
selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
draw_marker(p, marker_x, yoff, height()-1, selected, false);
|
||||
}
|
||||
|
||||
// draw playhead triangle
|
||||
|
||||
@@ -1244,6 +1244,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) {
|
||||
// slipping doesn't move the clips so we don't bother snapping for it
|
||||
for (int i=0;i<panel_timeline->ghosts.size();i++) {
|
||||
const Ghost& g = panel_timeline->ghosts.at(i);
|
||||
|
||||
// snap ghost's in point
|
||||
if (panel_timeline->trim_target == -1 || g.trim_in) {
|
||||
fm = g.old_in + frame_diff;
|
||||
if (panel_timeline->snap_to_timeline(&fm, true, true, true)) {
|
||||
@@ -1251,6 +1253,8 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// snap ghost's out point
|
||||
if (panel_timeline->trim_target == -1 || !g.trim_in) {
|
||||
fm = g.old_out + frame_diff;
|
||||
if (panel_timeline->snap_to_timeline(&fm, true, true, true)) {
|
||||
@@ -1258,6 +1262,19 @@ void TimelineWidget::update_ghosts(const QPoint& mouse_pos, bool lock_frame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the ghost is attached to a clip, snap its markers too
|
||||
if (panel_timeline->trim_target == -1 && g.clip >= 0) {
|
||||
Clip* c = sequence->clips.at(g.clip);
|
||||
for (int j=0;j<c->markers.size();j++) {
|
||||
long marker_real_time = c->markers.at(j).frame + c->timeline_in - c->clip_in;
|
||||
fm = marker_real_time + frame_diff;
|
||||
if (panel_timeline->snap_to_timeline(&fm, true, true, true)) {
|
||||
frame_diff = fm - marker_real_time;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2394,6 +2411,18 @@ void TimelineWidget::paintEvent(QPaintEvent*) {
|
||||
}
|
||||
}
|
||||
|
||||
// draw clip markers
|
||||
for (int j=0;j<clip->markers.size();j++) {
|
||||
const Marker& m = clip->markers.at(j);
|
||||
|
||||
// convert marker time (in clip time) to sequence time
|
||||
long marker_time = m.frame + clip->timeline_in - clip->clip_in;
|
||||
int marker_x = panel_timeline->getTimelineScreenPointFromFrame(marker_time);
|
||||
if (marker_x > clip_rect.x() && marker_x < clip_rect.right()) {
|
||||
draw_marker(p, marker_x, clip_rect.bottom()-p.fontMetrics().height(), clip_rect.bottom(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
// draw clip transitions
|
||||
draw_transition(p, clip, clip_rect, text_rect, TA_OPENING_TRANSITION);
|
||||
draw_transition(p, clip, clip_rect, text_rect, TA_CLOSING_TRANSITION);
|
||||
|
||||
Reference in New Issue
Block a user