added cut/copy/paste

This commit is contained in:
itsmattkc
2018-06-08 18:20:50 -07:00
parent 5f2ed68f7b
commit cf18e52e90
13 changed files with 312 additions and 189 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ extern "C" {
int main(int argc, char *argv[])
{
// init ffmpeg subsystem
av_register_all();
av_register_all();
QApplication a(argc, argv);
MainWindow w;
+21
View File
@@ -182,3 +182,24 @@ void MainWindow::on_actionSplit_at_Playhead_triggered()
panel_timeline->split_at_playhead();
}
}
void MainWindow::on_actionCu_t_triggered()
{
if (panel_timeline->focused()) {
panel_timeline->copy(true);
}
}
void MainWindow::on_actionCop_y_triggered()
{
if (panel_timeline->focused()) {
panel_timeline->copy(false);
}
}
void MainWindow::on_action_Paste_triggered()
{
if (panel_timeline->focused()) {
panel_timeline->paste();
}
}
+6
View File
@@ -57,6 +57,12 @@ private slots:
void on_actionSplit_at_Playhead_triggered();
void on_actionCu_t_triggered();
void on_actionCop_y_triggered();
void on_action_Paste_triggered();
private:
Ui::MainWindow *ui;
void setup_layout();
+104 -30
View File
@@ -66,15 +66,17 @@ void Timeline::seek(long p) {
// reset all clip audio
for (int i=0;i<sequence->clip_count();i++) {
Clip& c = sequence->get_clip(i);
c.reset_audio = true;
c.frame_sample_index = 0;
c.audio_buffer_write = 0;
Clip* c = sequence->get_clip(i);
c->reset_audio = true;
c->frame_sample_index = 0;
c->audio_buffer_write = 0;
}
clear_audio_ibuffer();
audio_ibuffer_read = 0;
playhead = p;
repaint_timeline();
}
bool Timeline::toggle_play() {
@@ -105,9 +107,9 @@ void Timeline::set_sequence(Sequence *s) {
if (sequence != NULL) {
// clean up - close all open clips
for (int i=0;i<sequence->clip_count();i++) {
Clip& c = sequence->get_clip(i);
if (c.open) {
close_clip(&c);
Clip* c = sequence->get_clip(i);
if (c->open) {
close_clip(c);
}
}
}
@@ -139,6 +141,7 @@ bool Timeline::focused() {
void Timeline::undo() {
if (sequence != NULL) {
current_clips.clear();
sequence->undo();
ui->video_area->redraw_clips();
ui->audio_area->redraw_clips();
@@ -147,6 +150,7 @@ void Timeline::undo() {
void Timeline::redo() {
if (sequence != NULL) {
current_clips.clear();
sequence->redo();
ui->video_area->redraw_clips();
ui->audio_area->redraw_clips();
@@ -177,8 +181,8 @@ void Timeline::redraw_all_clips() {
void Timeline::select_all() {
selections.clear();
for (int i=0;i<sequence->clip_count();i++) {
Clip& c = sequence->get_clip(i);
selections.append({c.timeline_in, c.timeline_out, c.track});
Clip* c = sequence->get_clip(i);
selections.append({c->timeline_in, c->timeline_out, c->track});
}
}
@@ -204,12 +208,12 @@ void Timeline::delete_selection(bool ripple_delete) {
for (int i=0;i<sequence->clip_count();i++) {
// check every clip after and see if it'll collide
// NOTE, we could probably re-use the validation code for the ripple tool here for optimization (since it's technically better code I think)
Clip& c = sequence->get_clip(i);
if (c.timeline_in >= ripple_point) {
Clip* c = sequence->get_clip(i);
if (c->timeline_in >= ripple_point) {
for (int j=0;j<sequence->clip_count();j++) {
Clip& cc = sequence->get_clip(j);
if (cc.timeline_in < ripple_point) {
validator = c.timeline_in - ripple_length - cc.timeline_out;
Clip* cc = sequence->get_clip(j);
if (cc->timeline_in < ripple_point) {
validator = c->timeline_in - ripple_length - cc->timeline_out;
if (validator < 0) ripple_length += validator;
if (ripple_length <= 0) {
@@ -239,10 +243,10 @@ void Timeline::zoom_out() {
void Timeline::ripple(long ripple_point, long ripple_length) {
for (int i=0;i<sequence->clip_count();i++) {
Clip& c = sequence->get_clip(i);
if (c.timeline_in >= ripple_point) {
c.timeline_in += ripple_length;
c.timeline_out += ripple_length;
Clip* c = sequence->get_clip(i);
if (c->timeline_in >= ripple_point) {
c->timeline_in += ripple_length;
c->timeline_out += ripple_length;
}
}
for (int i=0;i<selections.size();i++) {
@@ -300,10 +304,10 @@ void Timeline::on_pushButton_5_clicked()
}
bool Timeline::is_clip_selected(int clip_index) {
Clip& clip = sequence->get_clip(clip_index);
Clip* clip = sequence->get_clip(clip_index);
for (int i=0;i<selections.size();i++) {
const Selection& s = selections.at(i);
if (clip.track == s.track && clip.timeline_in >= s.in && clip.timeline_out <= s.out) {
if (clip->track == s.track && clip->timeline_in >= s.in && clip->timeline_out <= s.out) {
return true;
}
}
@@ -342,6 +346,85 @@ void Timeline::on_snappingButton_toggled(bool checked)
snapping = checked;
}
void Timeline::copy(bool del) {
bool cleared = false;
bool copied = false;
long min_in = 0;
for (int i=0;i<sequence->clip_count();i++) {
Clip* c = sequence->get_clip(i);
for (int j=0;j<selections.size();j++) {
const Selection& s = selections.at(j);
if (s.track == c->track && !((c->timeline_in < s.in && c->timeline_out < s.in) || (c->timeline_in > s.out && c->timeline_out > s.out))) {
if (!cleared) {
clip_clipboard.clear();
cleared = true;
}
Clip* copied_clip = c->copy();
if (copied_clip->timeline_in < s.in) {
copied_clip->clip_in += (s.in - copied_clip->timeline_in);
copied_clip->timeline_in = s.in;
}
if (copied_clip->timeline_out > s.out) {
copied_clip->timeline_out = s.out;
}
if (copied) {
min_in = qMin(min_in, s.in);
} else {
min_in = s.in;
copied = true;
}
clip_clipboard.append(copied_clip);
}
}
}
for (int i=0;i<clip_clipboard.size();i++) {
// initialize all timeline_ins to 0 or offsets of
clip_clipboard[i]->timeline_in -= min_in;
clip_clipboard[i]->timeline_out -= min_in;
}
if (del && copied) {
delete_selection(false);
}
}
void Timeline::paste() {
if (clip_clipboard.size() > 0) {
for (int i=0;i<clip_clipboard.size();i++) {
Clip* c = clip_clipboard.at(i);
sequence->delete_area(c->timeline_in + playhead, c->timeline_out + playhead, c->track);
Clip* cc = c->copy();
cc->timeline_in += playhead;
cc->timeline_out += playhead;
sequence->add_clip(cc);
}
redraw_all_clips();
}
}
bool Timeline::split_selection() {
bool split = false;
for (int j=0;j<sequence->clip_count();j++) {
for (int i=0;i<selections.size();i++) {
const Selection& s = selections.at(i);
if (s.track == sequence->get_clip(j)->track) {
sequence->split_clip(j, s.in);
sequence->split_clip(j, s.out);
split = true;
}
}
}
return split;
}
void Timeline::split_at_playhead() {
bool split_selected = false;
@@ -356,16 +439,7 @@ void Timeline::split_at_playhead() {
// split a selection if not
if (!split_selected) {
for (int j=0;j<sequence->clip_count();j++) {
for (int i=0;i<selections.size();i++) {
const Selection& s = selections.at(i);
if (s.track == sequence->get_clip(j).track) {
sequence->split_clip(j, s.in);
sequence->split_clip(j, s.out);
split_selected = true;
}
}
}
split_selected = split_selection();
}
}
+4
View File
@@ -63,6 +63,9 @@ public:
void zoom_out();
void undo();
void redo();
void copy(bool del);
void paste();
bool split_selection();
void split_at_playhead();
void set_sequence(Sequence* s);
@@ -153,6 +156,7 @@ private:
void decheck_tool_buttons(QObject* sender);
void set_tool(int tool);
long last_frame;
QVector<Clip*> clip_clipboard;
};
#endif // TIMELINE_H
+3 -3
View File
@@ -313,14 +313,12 @@ void close_clip_worker(Clip* clip) {
av_frame_free(&clip->frame);
clip->reset();
// remove clip from current_clips
cc_lock.lock();
bool found = false;
for (int i=0;i<current_clips.count();i++) {
if (current_clips[i] == clip) {
current_clips.erase(current_clips.begin()+i);
current_clips.removeAt(i);
found = true;
i = current_clips.count();
}
@@ -328,6 +326,8 @@ void close_clip_worker(Clip* clip) {
cc_lock.unlock();
if (!found) qDebug() << "[WARNING] Could not remove clip from current clips";
clip->reset();
qDebug() << "[INFO] Clip closed on track" << clip->track;
}
+10 -10
View File
@@ -27,34 +27,34 @@ QMutex cc_lock;
void handle_media(Sequence* sequence, long playhead, bool multithreaded) {
for (int i=0;i<sequence->clip_count();i++) {
Clip& c = sequence->get_clip(i);
Clip* c = sequence->get_clip(i);
// if clip starts within one second and/or hasn't finished yet
if (is_clip_active(&c, playhead)) {
if (is_clip_active(c, playhead)) {
// if thread is already working, we don't want to touch this,
// but we also don't want to hang the UI thread
if (!c.open) {
if (c.lock.tryLock()) {
open_clip(&c, multithreaded);
if (!c->open) {
if (c->lock.tryLock()) {
open_clip(c, multithreaded);
// add to current_clips, (insertion) sorted by track so composite them in order
cc_lock.lock();
bool found = false;
for (int j=0;j<current_clips.size();j++) {
if (current_clips[j]->track < c.track) {
current_clips.insert(current_clips.begin()+j, &c);
if (current_clips[j]->track < c->track) {
current_clips.insert(current_clips.begin()+j, c);
found = true;
break;
}
}
if (!found) {
current_clips.push_back(&c);
current_clips.push_back(c);
}
cc_lock.unlock();
}
}
} else if (c.open) {
close_clip(&c);
} else if (c->open) {
close_clip(c);
}
}
}
+18 -24
View File
@@ -15,36 +15,30 @@ Clip::Clip() {
init();
}
Clip::Clip(const Clip &c) {
init();
copy(c);
}
Clip* Clip::copy() {
Clip* copy = new Clip();
Clip& Clip::operator= (const Clip& c) {
init();
copy(c);
return *this;
}
copy->name = name;
copy->clip_in = clip_in;
copy->timeline_in = timeline_in;
copy->timeline_out = timeline_out;
copy->track = track;
copy->color_r = color_r;
copy->color_g = color_g;
copy->color_b = color_b;
copy->sequence = sequence;
copy->media = media;
copy->media_stream = media_stream;
void Clip::copy(const Clip& c) {
name = c.name;
clip_in = c.clip_in;
timeline_in = c.timeline_in;
timeline_out = c.timeline_out;
track = c.track;
color_r = c.color_r;
color_g = c.color_g;
color_b = c.color_b;
sequence = c.sequence;
media = c.media;
media_stream = c.media_stream;
for (int i=0;i<c.effects.size();i++) {
effects.append(c.effects.at(i)->copy());
for (int i=0;i<effects.size();i++) {
copy->effects.append(effects.at(i)->copy());
}
return copy;
}
void Clip::init() {
qDebug() << "init was called";
reset();
clip_in = timeline_in = timeline_out = track = undeletable = 0;
texture = NULL;
+1 -3
View File
@@ -32,10 +32,8 @@ struct ClipCache {
struct Clip
{
Clip();
Clip(const Clip &c);
Clip& operator= (const Clip&); // explicitly defaulted copy assignment
~Clip();
void copy(const Clip& c);
Clip* copy();
void init();
void reset();
bool undeletable;
+69 -46
View File
@@ -9,24 +9,22 @@ Sequence::Sequence() {
}
Sequence::~Sequence() {
// dealloc all clips
for (int i=0;i<clips.size();i++) {
delete clips.at(i);
}
}
Clip& Sequence::new_clip() {
clips.append(Clip());
return clips[clips.size() - 1];
}
Clip& Sequence::insert_clip(const Clip& c) {
clips.append(c);
return clips[clips.size() - 1];
void Sequence::add_clip(Clip* c) {
clips.append(c);
}
int Sequence::clip_count() {
return clips.count();
return clips.size();
}
Clip& Sequence::get_clip(int i) {
return clips[i];
Clip* Sequence::get_clip(int i) {
return clips.at(i);
}
void Sequence::delete_clip(int i) {
@@ -41,15 +39,16 @@ void Sequence::delete_clip(int i) {
// }
// finally remove from vector
delete clips.at(i);
clips.removeAt(i);
}
long Sequence::getEndFrame() {
long end = 0;
for (int j=0;j<clip_count();j++) {
Clip& c = get_clip(j);
if (c.timeline_out > end) {
end = c.timeline_out;
Clip* c = get_clip(j);
if (c->timeline_out > end) {
end = c->timeline_out;
}
}
return end;
@@ -59,11 +58,11 @@ void Sequence::get_track_limits(int* video_tracks, int* audio_tracks) {
int vt = 0;
int at = 0;
for (int j=0;j<clip_count();j++) {
Clip& c = get_clip(j);
if (c.track < 0 && c.track < vt) { // video clip
vt = c.track;
} else if (c.track > at) {
at = c.track;
Clip* c = get_clip(j);
if (c->track < 0 && c->track < vt) { // video clip
vt = c->track;
} else if (c->track > at) {
at = c->track;
}
}
if (video_tracks != NULL) *video_tracks = vt;
@@ -72,61 +71,85 @@ void Sequence::get_track_limits(int* video_tracks, int* audio_tracks) {
void Sequence::delete_area(long in, long out, int track) {
for (int i=0;i<clip_count();i++) {
Clip& c = get_clip(i);
if (c.track == track && !c.undeletable) {
if (c.timeline_in >= in && c.timeline_out <= out) {
Clip* c = get_clip(i);
if (c->track == track && !c->undeletable) {
if (c->timeline_in >= in && c->timeline_out <= out) {
// clips falls entirely within deletion area
delete_clip(i);
i--;
} else if (c.timeline_in < in && c.timeline_out > out) {
// middle of clip is within deletion area
clips.append(clips.at(i)); // copy clip
} else if (c->timeline_in < in && c->timeline_out > out) {
// middle of clip is within deletion area
Clip& pre = get_clip(i);
Clip& post = get_clip(clips.size()-1);
// duplicate clip
Clip* pre = get_clip(i);
Clip* post = pre->copy();
pre.timeline_out = in;
post.timeline_in = out;
post.clip_in = pre.clip_in + pre.getLength() + (out - in);
} else if (c.timeline_in < in && c.timeline_out > in) {
pre->timeline_out = in;
post->timeline_in = out;
post->clip_in = pre->clip_in + pre->getLength() + (out - in);
add_clip(post);
} else if (c->timeline_in < in && c->timeline_out > in) {
// only out point is in deletion area
c.timeline_out = in;
} else if (c.timeline_in < out && c.timeline_out > out) {
c->timeline_out = in;
} else if (c->timeline_in < out && c->timeline_out > out) {
// only in point is in deletion area
c.clip_in += out - c.timeline_in;
c.timeline_in = out;
c->clip_in += out - c->timeline_in;
c->timeline_in = out;
}
}
}
}
void Sequence::split_clip(int i, long frame) {
Clip& pre = get_clip(i);
if (pre.timeline_in < frame && pre.timeline_out > frame) { // guard against attempts to split at in/out points
clips.append(pre); // copy clip
Clip* pre = get_clip(i);
if (pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points
Clip* post = pre->copy();
Clip& post = get_clip(clips.size()-1);
pre->timeline_out = frame;
post->timeline_in = frame;
post->clip_in = pre->clip_in + pre->getLength();
pre.timeline_out = frame;
post.timeline_in = frame;
post.clip_in = pre.clip_in + pre.getLength();
add_clip(post);
}
}
void Sequence::undo_add_current() {
if (undo_stack.size() == UNDO_LIMIT) {
delete undo_stack.at(0);
undo_stack.removeFirst();
} else {
undo_pointer++;
undo_stack.resize(undo_pointer);
for (int i=undo_stack.size()-1;i>undo_pointer;i--) {
delete undo_stack[i];
undo_stack.removeLast();
}
}
// copy clips
QVector<Clip*>* copied_clips = new QVector<Clip*>();
for (int i=0;i<clip_count();i++) {
copied_clips->append(get_clip(i)->copy());
}
undo_stack.append(copied_clips);
}
void Sequence::set_undo(int i) {
for (int i=0;i<clip_count();i++) {
delete clips.at(i);
}
clips.clear();
QVector<Clip*>* copy_from_list = undo_stack[undo_pointer];
for (int i=0;i<copy_from_list->size();i++) {
add_clip(copy_from_list->at(i));
}
undo_stack.append(clips);
}
void Sequence::undo() {
if (undo_pointer > 0) {
undo_pointer--;
clips = undo_stack[undo_pointer];
set_undo(undo_pointer);
} else {
qDebug() << "[INFO] No more undos";
}
@@ -136,6 +159,6 @@ void Sequence::redo() {
qDebug() << "[INFO] No more redos";
} else {
undo_pointer++;
clips = undo_stack[undo_pointer];
set_undo(undo_pointer);
}
}
+5 -5
View File
@@ -12,10 +12,9 @@ public:
Sequence();
~Sequence();
QString name;
Clip& new_clip();
Clip& insert_clip(const Clip& c);
void add_clip(Clip* c);
int clip_count();
Clip& get_clip(int i);
Clip* get_clip(int i);
void delete_clip(int i);
void delete_area(long in, long out, int track);
void split_clip(int i, long frame);
@@ -31,9 +30,10 @@ public:
void undo();
void redo();
private:
QList<Clip> clips;
QVector<Clip*> clips;
QVector<QList<Clip>> undo_stack;
void set_undo(int i);
QVector<QVector<Clip*>*> undo_stack;
int undo_pointer;
int undo_stack_start;
};
+68 -66
View File
@@ -96,27 +96,29 @@ void TimelineWidget::dropEvent(QDropEvent* event) {
panel_timeline->sequence->delete_area(g.in, g.out, g.track);
Clip& c = panel_timeline->sequence->new_clip();
c.media = g.media;
c.media_stream = g.media_stream;
c.timeline_in = g.in;
c.timeline_out = g.out;
c.clip_in = g.clip_in;
c.color_r = 128;
c.color_g = 128;
c.color_b = 192;
c.sequence = panel_timeline->sequence;
c.track = g.track;
c.name = c.media->name;
Clip* c = new Clip();
c->media = g.media;
c->media_stream = g.media_stream;
c->timeline_in = g.in;
c->timeline_out = g.out;
c->clip_in = g.clip_in;
c->color_r = 128;
c->color_g = 128;
c->color_b = 192;
c->sequence = panel_timeline->sequence;
c->track = g.track;
c->name = c->media->name;
if (c.track < 0) {
if (c->track < 0) {
// add default video effects
c.effects.append(create_effect(VIDEO_TRANSFORM_EFFECT, &c));
c->effects.append(create_effect(VIDEO_TRANSFORM_EFFECT, c));
} else {
// add default audio effects
c.effects.append(create_effect(AUDIO_VOLUME_EFFECT, &c));
c.effects.append(create_effect(AUDIO_PAN_EFFECT, &c));
}
c->effects.append(create_effect(AUDIO_VOLUME_EFFECT, c));
c->effects.append(create_effect(AUDIO_PAN_EFFECT, c));
}
panel_timeline->sequence->add_clip(c);
}
panel_timeline->ghosts.clear();
@@ -154,8 +156,8 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) {
panel_timeline->selections.clear();
}
Clip& clip = panel_timeline->sequence->get_clip(clip_index);
panel_timeline->selections.append({clip.timeline_in, clip.timeline_out, clip.track});
Clip* clip = panel_timeline->sequence->get_clip(clip_index);
panel_timeline->selections.append({clip->timeline_in, clip->timeline_out, clip->track});
}
panel_timeline->moving_init = true;
} else {
@@ -166,8 +168,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) {
break;
case TIMELINE_TOOL_EDIT:
panel_timeline->seek(panel_timeline->drag_frame_start);
panel_timeline->selecting = true;
panel_timeline->repaint_timeline();
panel_timeline->selecting = true;
break;
case TIMELINE_TOOL_RAZOR:
{
@@ -186,18 +187,17 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
if (event->modifiers() & Qt::AltModifier) { // if holding alt, duplicate rather than move
// duplicate clips
for (int i=0;i<panel_timeline->ghosts.size();i++) {
Ghost& g = panel_timeline->ghosts[i];
Clip& c = panel_timeline->sequence->insert_clip(*g.clip);
Ghost& g = panel_timeline->ghosts[i];
Clip* c = g.clip->copy();
c.timeline_in = g.in;
c.timeline_out = g.out;
c.track = g.track;
c.undeletable = true;
c->timeline_in = g.in;
c->timeline_out = g.out;
c->track = g.track;
// step 2 - delete anything that exists in area that clip is moving to
panel_timeline->sequence->delete_area(g.in, g.out, g.track);
c.undeletable = false;
panel_timeline->sequence->add_clip(c);
}
} else {
// move clips
@@ -284,7 +284,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
}
}
if (single_select) {
panel_effect_controls->set_clip(&panel_timeline->sequence->get_clip(selected_clip));
panel_effect_controls->set_clip(panel_timeline->sequence->get_clip(selected_clip));
} else {
panel_effect_controls->set_clip(NULL);
}
@@ -336,9 +336,9 @@ void validate_snapping(Ghost& g, long* frame_diff) {
if (panel_timeline->snapping) {
if (!subvalidate_snapping(g, frame_diff, panel_timeline->playhead)) {
for (int j=0;j<panel_timeline->sequence->clip_count();j++) {
Clip& c = panel_timeline->sequence->get_clip(j);
if (!subvalidate_snapping(g, frame_diff, c.timeline_in)) {
subvalidate_snapping(g, frame_diff, c.timeline_out);
Clip* c = panel_timeline->sequence->get_clip(j);
if (!subvalidate_snapping(g, frame_diff, c->timeline_in)) {
subvalidate_snapping(g, frame_diff, c->timeline_out);
}
if (panel_timeline->snapped) break;
}
@@ -539,7 +539,10 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
int limit = panel_timeline->getFrameFromScreenPoint(10);
if (panel_timeline->snapping && panel_timeline->cursor_frame > panel_timeline->playhead-limit-1 && panel_timeline->cursor_frame < panel_timeline->playhead+limit+1) {
if (panel_timeline->snapping &&
!panel_timeline->selecting &&
panel_timeline->cursor_frame > panel_timeline->playhead-limit-1 &&
panel_timeline->cursor_frame < panel_timeline->playhead+limit+1) {
panel_timeline->cursor_frame = panel_timeline->playhead;
}
}
@@ -557,8 +560,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
s->in = qMin(in, out);
s->out = qMax(in, out);
}
panel_timeline->playhead = qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame);
panel_timeline->repaint_timeline();
panel_timeline->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame));
} else if (panel_timeline->moving_init) {
if (panel_timeline->moving_proc) {
update_ghosts((QPoint&) event->pos());
@@ -567,8 +569,8 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
// create ghosts
for (int i=0;i<panel_timeline->sequence->clip_count();i++) {
if (panel_timeline->is_clip_selected(i)) {
Clip& c = panel_timeline->sequence->get_clip(i);
panel_timeline->ghosts.append({&c, c.timeline_in, c.timeline_out, c.track, c.clip_in});
Clip* c = panel_timeline->sequence->get_clip(i);
panel_timeline->ghosts.append({c, c->timeline_in, c->timeline_out, c->track, c->clip_in});
}
}
@@ -579,49 +581,49 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
for (int j=0;j<panel_timeline->sequence->clip_count();j++) {
// don't cache any currently selected clips
Clip* c = panel_timeline->ghosts.at(i).clip;
Clip& cc = panel_timeline->sequence->get_clip(j);
Clip* cc = panel_timeline->sequence->get_clip(j);
bool is_selected = false;
for (int k=0;k<panel_timeline->ghosts.size();k++) {
if (panel_timeline->ghosts.at(k).clip == &cc) {
if (panel_timeline->ghosts.at(k).clip == cc) {
is_selected = true;
break;
}
}
if (!is_selected) {
if (cc.timeline_in < c->timeline_in) {
if (cc->timeline_in < c->timeline_in) {
// add clip to pre-cache UNLESS there is already a clip on that track closer to the ripple point
bool found = false;
for (int k=0;k<pre_clips.size();k++) {
Clip* ccc = pre_clips.at(k);
if (ccc->track == cc.track) {
if (ccc->timeline_in < cc.timeline_in) {
if (ccc->track == cc->track) {
if (ccc->timeline_in < cc->timeline_in) {
// clip is closer to ripple point than the one in cache, replace it
ccc = &cc;
ccc = cc;
}
found = true;
}
}
if (!found) {
// no clip from that track in the cache, add it
pre_clips.append(&cc);
pre_clips.append(cc);
}
} else {
// add clip to post-cache UNLESS there is already a clip on that track closer to the ripple point
bool found = false;
for (int k=0;k<post_clips.size();k++) {
Clip* ccc = post_clips.at(k);
if (ccc->track == cc.track) {
if (ccc->timeline_in > cc.timeline_in) {
if (ccc->track == cc->track) {
if (ccc->timeline_in > cc->timeline_in) {
// clip is closer to ripple point than the one in cache, replace it
ccc = &cc;
ccc = cc;
}
found = true;
}
}
if (!found) {
// no clip from that track in the cache, add it
post_clips.append(&cc);
post_clips.append(cc);
}
}
}
@@ -641,7 +643,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
int track = panel_timeline->cursor_track;
bool repaint = false;
for (int i=0;i<panel_timeline->sequence->clip_count();i++) {
if (panel_timeline->sequence->get_clip(i).track == track) {
if (panel_timeline->sequence->get_clip(i)->track == track) {
panel_timeline->sequence->split_clip(i, panel_timeline->drag_frame_start);
repaint = true;
}
@@ -658,14 +660,14 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
long mouse_frame_upper = panel_timeline->getFrameFromScreenPoint(pos.x()+lim)+1;
bool found = false;
for (int i=0;i<panel_timeline->sequence->clip_count();i++) {
Clip& c = panel_timeline->sequence->get_clip(i);
if (c.track == mouse_track) {
if (c.timeline_in > mouse_frame_lower && c.timeline_in < mouse_frame_upper) {
Clip* c = panel_timeline->sequence->get_clip(i);
if (c->track == mouse_track) {
if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) {
panel_timeline->trim_target = i;
panel_timeline->trim_in = true;
found = true;
break;
} else if (c.timeline_out > mouse_frame_lower && c.timeline_out < mouse_frame_upper) {
} else if (c->timeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) {
panel_timeline->trim_target = i;
panel_timeline->trim_in = false;
found = true;
@@ -706,16 +708,16 @@ void TimelineWidget::redraw_clips() {
int video_track_limit = 0;
int audio_track_limit = 0;
for (int i=0;i<panel_timeline->sequence->clip_count();i++) {
Clip& clip = panel_timeline->sequence->get_clip(i);
if (is_track_visible(clip.track)) {
if (clip.track < 0 && clip.track < video_track_limit) { // video clip
video_track_limit = clip.track;
} else if (clip.track > audio_track_limit) {
audio_track_limit = clip.track;
Clip* clip = panel_timeline->sequence->get_clip(i);
if (is_track_visible(clip->track)) {
if (clip->track < 0 && clip->track < video_track_limit) { // video clip
video_track_limit = clip->track;
} else if (clip->track > audio_track_limit) {
audio_track_limit = clip->track;
}
QRect clip_rect(panel_timeline->getScreenPointFromFrame(clip.timeline_in), getScreenPointFromTrack(clip.track), clip.getLength() * panel_timeline->zoom, track_height);
clip_painter.fillRect(clip_rect, QColor(clip.color_r, clip.color_g, clip.color_b));
QRect clip_rect(panel_timeline->getScreenPointFromFrame(clip->timeline_in), getScreenPointFromTrack(clip->track), clip->getLength() * panel_timeline->zoom, track_height);
clip_painter.fillRect(clip_rect, QColor(clip->color_r, clip->color_g, clip->color_b));
clip_painter.setPen(Qt::white);
clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.topLeft());
clip_painter.drawLine(clip_rect.topLeft(), clip_rect.topRight());
@@ -723,13 +725,13 @@ void TimelineWidget::redraw_clips() {
clip_painter.drawLine(clip_rect.bottomLeft(), clip_rect.bottomRight());
clip_painter.drawLine(clip_rect.bottomRight(), clip_rect.topRight());
if (color_brightness(clip.color_r, clip.color_g, clip.color_b) > 160) {
if (color_brightness(clip->color_r, clip->color_g, clip->color_b) > 160) {
clip_painter.setPen(Qt::black);
} else {
clip_painter.setPen(Qt::white);
}
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);
clip_painter.drawText(text_rect, 0, clip->name, &text_rect);
}
}
@@ -853,9 +855,9 @@ int TimelineWidget::getScreenPointFromTrack(int track) {
int TimelineWidget::getClipIndexFromCoords(long frame, int track) {
for (int i=0;i<panel_timeline->sequence->clip_count();i++) {
Clip& c = panel_timeline->sequence->get_clip(i);
if (c.track == track) {
if (frame >= c.timeline_in && frame < c.timeline_out) {
Clip* c = panel_timeline->sequence->get_clip(i);
if (c->track == track) {
if (frame >= c->timeline_in && frame < c->timeline_out) {
return i;
}
}
+2 -1
View File
@@ -66,6 +66,7 @@ void ViewerWidget::paintGL()
bool render_audio = (panel_timeline->playing || force_audio);
cc_lock.lock();
for (int i=0;i<current_clips.size();i++) {
Clip* c = current_clips.at(i);
@@ -110,7 +111,7 @@ void ViewerWidget::paintGL()
glEnd();
c->texture->release();
}
}
} else if (render_audio &&
c->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
playhead >= c->timeline_in &&