added text/solid/bar objects and fixed several keyframe bugs
This commit is contained in:
@@ -264,7 +264,6 @@ void Effect::load(QXmlStreamReader& stream) {
|
||||
qDebug() << "[ERROR] Too many fields for effect" << id << "row" << row_count << ". Project might be corrupt. (Got" << field_count << ", expected <" << row->fieldCount()-1 << ")";
|
||||
}
|
||||
field_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -39,5 +39,7 @@
|
||||
<file>add-transition.png</file>
|
||||
<file>add-effect.png</file>
|
||||
<file>olive-splash.png</file>
|
||||
<file>add-button.png</file>
|
||||
<file>add-button-disabled.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -177,16 +177,18 @@ void EffectControls::load_effects() {
|
||||
// load in new clips
|
||||
for (int i=0;i<selected_clips.size();i++) {
|
||||
Clip* c = sequence->get_clip(selected_clips.at(i));
|
||||
QVBoxLayout* layout;
|
||||
if (c->track < 0) {
|
||||
ui->vcontainer->setVisible(true);
|
||||
layout = static_cast<QVBoxLayout*>(ui->video_effect_area->layout());
|
||||
} else {
|
||||
ui->acontainer->setVisible(true);
|
||||
layout = static_cast<QVBoxLayout*>(ui->audio_effect_area->layout());
|
||||
}
|
||||
for (int j=0;j<c->effects.size();j++) {
|
||||
Effect* e = c->effects.at(j);
|
||||
CollapsibleWidget* container = e->container;
|
||||
if (c->track < 0) {
|
||||
static_cast<QVBoxLayout*>(ui->video_effect_area->layout())->addWidget(container);
|
||||
ui->vcontainer->setVisible(true);
|
||||
} else {
|
||||
static_cast<QVBoxLayout*>(ui->audio_effect_area->layout())->addWidget(container);
|
||||
ui->acontainer->setVisible(true);
|
||||
}
|
||||
layout->addWidget(container);
|
||||
connect(container, SIGNAL(deselect_others(QWidget*)), this, SLOT(deselect_all_effects(QWidget*)));
|
||||
}
|
||||
}
|
||||
|
||||
+17
-19
@@ -778,6 +778,8 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
//<clip id="0" name="Brock_Drying_Pan.gif" clipin="0" in="44" out="144" track="-1" r="192" g="128" b="128" media="2" stream="0">
|
||||
int media_id, stream_id;
|
||||
Clip* c = new Clip(s);
|
||||
c->media_type = MEDIA_TYPE_SOLID;
|
||||
c->media = NULL;
|
||||
for (int j=0;j<stream.attributes().size();j++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(j);
|
||||
if (attr.name() == "name") {
|
||||
@@ -814,26 +816,22 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
}
|
||||
|
||||
// set media and media stream
|
||||
/*switch (c->media_type) {
|
||||
switch (c->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
|
||||
|
||||
break;
|
||||
}*/
|
||||
if (c->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
if (media_id == 0) {
|
||||
c->media = NULL;
|
||||
} else {
|
||||
for (int j=0;j<loaded_media.size();j++) {
|
||||
Media* m = loaded_media.at(j);
|
||||
if (m->save_id == media_id) {
|
||||
c->media = m;
|
||||
c->media_stream = stream_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (media_id == 0) {
|
||||
c->media = NULL;
|
||||
} else {
|
||||
for (int j=0;j<loaded_media.size();j++) {
|
||||
Media* m = loaded_media.at(j);
|
||||
if (m->save_id == media_id) {
|
||||
c->media = m;
|
||||
c->media_stream = stream_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// load links and effects
|
||||
while (!(stream.name() == "clip" && stream.isEndElement()) && !stream.atEnd()) {
|
||||
|
||||
+43
-1
@@ -23,6 +23,7 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <QPainter>
|
||||
#include <QMenu>
|
||||
|
||||
long refactor_frame_number(long framenumber, double source_frame_rate, double target_frame_rate) {
|
||||
if (source_frame_rate == target_frame_rate) return framenumber;
|
||||
@@ -56,7 +57,8 @@ Timeline::Timeline(QWidget *parent) :
|
||||
importing(false),
|
||||
zoomChanged(false),
|
||||
ui(new Ui::Timeline),
|
||||
last_frame(0)
|
||||
last_frame(0),
|
||||
creating(false)
|
||||
{
|
||||
default_track_height = (QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96) * TRACK_DEFAULT_HEIGHT;
|
||||
|
||||
@@ -253,6 +255,7 @@ void Timeline::update_sequence() {
|
||||
ui->snappingButton->setEnabled(!null_sequence);
|
||||
ui->pushButton_4->setEnabled(!null_sequence);
|
||||
ui->pushButton_5->setEnabled(!null_sequence);
|
||||
ui->addButton->setEnabled(!null_sequence);
|
||||
ui->headers->setEnabled(!null_sequence);
|
||||
|
||||
if (null_sequence) {
|
||||
@@ -1155,3 +1158,42 @@ void Timeline::on_toolSlideButton_clicked()
|
||||
ui->timeline_area->setCursor(Qt::ArrowCursor);
|
||||
tool = TIMELINE_TOOL_SLIDE;
|
||||
}
|
||||
|
||||
void Timeline::on_addButton_clicked() {
|
||||
QMenu add_menu(this);
|
||||
|
||||
QAction* titleMenuItem = new QAction(&add_menu);
|
||||
titleMenuItem->setText("Title...");
|
||||
titleMenuItem->setData(ADD_OBJ_TITLE);
|
||||
add_menu.addAction(titleMenuItem);
|
||||
|
||||
QAction* solidMenuItem = new QAction(&add_menu);
|
||||
solidMenuItem->setText("Solid Color...");
|
||||
solidMenuItem->setData(ADD_OBJ_SOLID);
|
||||
add_menu.addAction(solidMenuItem);
|
||||
|
||||
QAction* barsMenuItem = new QAction(&add_menu);
|
||||
barsMenuItem->setText("Bars and Tone...");
|
||||
barsMenuItem->setData(ADD_OBJ_BARS);
|
||||
add_menu.addAction(barsMenuItem);
|
||||
|
||||
connect(&add_menu, SIGNAL(triggered(QAction*)), this, SLOT(addMenuItem(QAction*)));
|
||||
|
||||
add_menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void Timeline::addMenuItem(QAction* action) {
|
||||
creating = true;
|
||||
creatingObject = action->data().toInt();
|
||||
/*switch (action->data()) {
|
||||
case ADD_OBJ_TITLE:
|
||||
|
||||
break;
|
||||
case ADD_OBJ_SOLID:
|
||||
|
||||
break;
|
||||
case ADD_OBJ_BARS:
|
||||
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
#define TRACK_DEFAULT_HEIGHT 40
|
||||
|
||||
#define ADD_OBJ_TITLE 0
|
||||
#define ADD_OBJ_SOLID 1
|
||||
#define ADD_OBJ_BARS 2
|
||||
|
||||
class QPushButton;
|
||||
class SourceTable;
|
||||
class ViewerWidget;
|
||||
@@ -183,6 +187,10 @@ public:
|
||||
// zoom variables
|
||||
bool zoomChanged;
|
||||
|
||||
// creating variables
|
||||
bool creating;
|
||||
int creatingObject;
|
||||
|
||||
Ui::Timeline *ui;
|
||||
public slots:
|
||||
void repaint_timeline();
|
||||
@@ -209,6 +217,10 @@ private slots:
|
||||
|
||||
void on_toolSlipButton_clicked();
|
||||
|
||||
void on_addButton_clicked();
|
||||
|
||||
void addMenuItem(QAction*);
|
||||
|
||||
private:
|
||||
QVector<QPushButton*> tool_buttons;
|
||||
void decheck_tool_buttons(QObject* sender);
|
||||
|
||||
@@ -245,6 +245,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addButton">
|
||||
<property name="toolTip">
|
||||
<string>Add title, solid, bars, etc.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normalon>:/icons/add-button.png</normalon>
|
||||
<disabledon>:/icons/add-button-disabled.png</disabledon>
|
||||
</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
+12
-4
@@ -27,7 +27,8 @@ extern "C" {
|
||||
bool texture_failed = false;
|
||||
|
||||
void open_clip(Clip* clip, bool multithreaded) {
|
||||
if (clip->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
switch (clip->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
clip->multithreaded = multithreaded;
|
||||
if (multithreaded) {
|
||||
if (clip->open_lock.tryLock()) {
|
||||
@@ -47,8 +48,11 @@ void open_clip(Clip* clip, bool multithreaded) {
|
||||
|
||||
open_clip_worker(clip);
|
||||
}
|
||||
} else if (clip->media_type == MEDIA_TYPE_SEQUENCE) {
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
case MEDIA_TYPE_SOLID:
|
||||
clip->open = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,16 +74,20 @@ void close_clip(Clip* clip) {
|
||||
clip->fbo = NULL;
|
||||
}
|
||||
|
||||
if (clip->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
switch (clip->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
if (clip->multithreaded) {
|
||||
clip->cacher->caching = false;
|
||||
clip->can_cache.wakeAll();
|
||||
} else {
|
||||
close_clip_worker(clip);
|
||||
}
|
||||
} else if (clip->media_type == MEDIA_TYPE_SEQUENCE) {
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
closeActiveClips(static_cast<Sequence*>(clip->media), false);
|
||||
case MEDIA_TYPE_SOLID:
|
||||
clip->open = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -181,7 +181,10 @@ long Clip::getMediaLength(double framerate) {
|
||||
return refactor_frame_number(s->getEndFrame(), s->frame_rate, framerate);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEDIA_TYPE_SOLID:
|
||||
return timeline_out - timeline_in;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+24
-28
@@ -808,17 +808,17 @@ KeyframeDelete::KeyframeDelete() : old_project_changed(project_changed), disable
|
||||
void KeyframeDelete::undo() {
|
||||
if (disable_keyframes_on_row != NULL) disable_keyframes_on_row->setKeyframing(true);
|
||||
|
||||
int data_index = 0;
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
int data_index = deleted_keyframe_data.size()-1;
|
||||
for (int i=rows.size()-1;i>=0;i--) {
|
||||
EffectRow* row = rows.at(i);
|
||||
int keyframe_index = keyframes.at(i);
|
||||
|
||||
row->keyframe_times.insert(keyframe_index, deleted_keyframe_times.at(i));
|
||||
row->keyframe_types.insert(keyframe_index, deleted_keyframe_types.at(i));
|
||||
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
for (int j=row->fieldCount()-1;j>=0;j--) {
|
||||
row->field(j)->keyframe_data.insert(keyframe_index, deleted_keyframe_data.at(data_index));
|
||||
data_index++;
|
||||
data_index--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,45 +827,41 @@ void KeyframeDelete::undo() {
|
||||
|
||||
void KeyframeDelete::redo() {
|
||||
if (!sorted) {
|
||||
for (int i=0;i<keyframes.size();i++) {
|
||||
for (int j=i+1;j<keyframes.size();j++) {
|
||||
if (keyframes.at(i) > keyframes.at(j)) {
|
||||
int temp = keyframes.at(i);
|
||||
EffectRow* temp_row = rows.at(i);
|
||||
|
||||
keyframes[i] = keyframes.at(j);
|
||||
rows[i] = rows.at(j);
|
||||
|
||||
keyframes[j] = temp;
|
||||
rows[j] = temp_row;
|
||||
}
|
||||
}
|
||||
}
|
||||
sorted = true;
|
||||
deleted_keyframe_times.resize(rows.size());
|
||||
deleted_keyframe_types.resize(rows.size());
|
||||
deleted_keyframe_data.clear();
|
||||
}
|
||||
|
||||
deleted_keyframe_times.resize(rows.size());
|
||||
deleted_keyframe_types.resize(rows.size());
|
||||
deleted_keyframe_data.clear();
|
||||
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
for (int i=0;i<keyframes.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
int keyframe_index = keyframes.at(i) - i;
|
||||
int keyframe_index = keyframes.at(i);
|
||||
|
||||
deleted_keyframe_times[i] = (row->keyframe_times.at(keyframe_index));
|
||||
deleted_keyframe_types[i] = (row->keyframe_types.at(keyframe_index));
|
||||
if (!sorted) {
|
||||
deleted_keyframe_times[i] = (row->keyframe_times.at(keyframe_index));
|
||||
deleted_keyframe_types[i] = (row->keyframe_types.at(keyframe_index));
|
||||
}
|
||||
|
||||
row->keyframe_times.removeAt(keyframe_index);
|
||||
row->keyframe_types.removeAt(keyframe_index);
|
||||
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
deleted_keyframe_data.append(row->field(j)->keyframe_data.at(keyframe_index));
|
||||
if (!sorted) deleted_keyframe_data.append(row->field(j)->keyframe_data.at(keyframe_index));
|
||||
row->field(j)->keyframe_data.removeAt(keyframe_index);
|
||||
}
|
||||
|
||||
// correct following indices
|
||||
if (!sorted) {
|
||||
for (int j=i+1;j<keyframes.size();j++) {
|
||||
if (rows.at(j) == row && keyframes.at(j) > keyframe_index) {
|
||||
keyframes[j]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (disable_keyframes_on_row != NULL) disable_keyframes_on_row->setKeyframing(false);
|
||||
project_changed = true;
|
||||
sorted = true;
|
||||
}
|
||||
|
||||
KeyframeSet::KeyframeSet(EffectRow* r, int i, long t, bool justMadeKeyframe) :
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ bool KeyframeView::keyframeIsSelected(EffectRow *row, int keyframe) {
|
||||
void KeyframeView::delete_selected_keyframes() {
|
||||
KeyframeDelete* kd = new KeyframeDelete();
|
||||
bool del = false;
|
||||
for (int i=0;i<selected_keyframes.size();i++) {
|
||||
for (int i=0;i<selected_keyframes.size();i++) {
|
||||
selected_rows.at(i)->delete_keyframe(kd, selected_keyframes.at(i));
|
||||
del = true;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent), dragging(fals
|
||||
}
|
||||
|
||||
void TimelineHeader::set_playhead(int mouse_x) {
|
||||
long frame = getFrameFromScreenPoint(zoom, mouse_x);
|
||||
long frame = getFrameFromScreenPoint(zoom, mouse_x) + in_visible;
|
||||
if (snapping) panel_timeline->snap_to_clip(&frame, false);
|
||||
panel_timeline->seek(frame);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ void TimelineHeader::mousePressEvent(QMouseEvent* event) {
|
||||
if (resizing_workarea) {
|
||||
sequence_end = sequence->getEndFrame();
|
||||
} else {
|
||||
set_playhead(event->pos().x());
|
||||
set_playhead(event->pos().x());
|
||||
}
|
||||
dragging = true;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ void TimelineHeader::mouseMoveEvent(QMouseEvent* event) {
|
||||
}
|
||||
panel_timeline->repaint_timeline();
|
||||
} else {
|
||||
set_playhead(event->pos().x());
|
||||
set_playhead(event->pos().x());
|
||||
}
|
||||
} else {
|
||||
resizing_workarea = false;
|
||||
|
||||
+171
-112
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "effects/transition.h"
|
||||
#include "effects/video/solideffect.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QColor>
|
||||
@@ -362,14 +363,18 @@ void TimelineWidget::mouseDoubleClickEvent(QMouseEvent *event) {
|
||||
}
|
||||
}
|
||||
|
||||
bool isLiveEditing() {
|
||||
return (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR || panel_timeline->creating);
|
||||
}
|
||||
|
||||
void TimelineWidget::mousePressEvent(QMouseEvent *event) {
|
||||
if (sequence != NULL) {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
|
||||
QPoint pos = event->pos();
|
||||
if (isLiveEditing()) {
|
||||
panel_timeline->drag_frame_start = panel_timeline->cursor_frame;
|
||||
panel_timeline->drag_track_start = panel_timeline->cursor_track;
|
||||
} else {
|
||||
QPoint pos = event->pos();
|
||||
} else {
|
||||
panel_timeline->drag_frame_start = panel_timeline->getTimelineFrameFromScreenPoint(pos.x());
|
||||
panel_timeline->drag_track_start = getTrackFromScreenPoint(pos.y());
|
||||
}
|
||||
@@ -386,118 +391,130 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) {
|
||||
panel_timeline->selection_offset = 0;
|
||||
}
|
||||
|
||||
switch (panel_timeline->tool) {
|
||||
case TIMELINE_TOOL_POINTER:
|
||||
case TIMELINE_TOOL_RIPPLE:
|
||||
case TIMELINE_TOOL_SLIP:
|
||||
case TIMELINE_TOOL_ROLLING:
|
||||
case TIMELINE_TOOL_SLIDE:
|
||||
{
|
||||
if (track_resizing) {
|
||||
track_resize_mouse_cache = event->pos().y();
|
||||
panel_timeline->moving_init = true;
|
||||
} else {
|
||||
if (clip_index >= 0) {
|
||||
Clip* clip = sequence->get_clip(clip_index);
|
||||
if (clip != NULL) {
|
||||
if (panel_timeline->is_clip_selected(clip, true)) {
|
||||
if (shift) {
|
||||
panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track);
|
||||
if (panel_timeline->creating) {
|
||||
Ghost g;
|
||||
g.in = g.old_in = g.out = g.old_out = panel_timeline->drag_frame_start;
|
||||
g.track = g.old_track = panel_timeline->drag_track_start;
|
||||
g.transition = NULL;
|
||||
g.clip = -1;
|
||||
panel_timeline->ghosts.append(g);
|
||||
|
||||
if (!alt) {
|
||||
for (int i=0;i<clip->linked.size();i++) {
|
||||
Clip* link = sequence->get_clip(clip->linked.at(i));
|
||||
panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track);
|
||||
panel_timeline->moving_init = true;
|
||||
panel_timeline->moving_proc = true;
|
||||
} else {
|
||||
switch (panel_timeline->tool) {
|
||||
case TIMELINE_TOOL_POINTER:
|
||||
case TIMELINE_TOOL_RIPPLE:
|
||||
case TIMELINE_TOOL_SLIP:
|
||||
case TIMELINE_TOOL_ROLLING:
|
||||
case TIMELINE_TOOL_SLIDE:
|
||||
{
|
||||
if (track_resizing) {
|
||||
track_resize_mouse_cache = event->pos().y();
|
||||
panel_timeline->moving_init = true;
|
||||
} else {
|
||||
if (clip_index >= 0) {
|
||||
Clip* clip = sequence->get_clip(clip_index);
|
||||
if (clip != NULL) {
|
||||
if (panel_timeline->is_clip_selected(clip, true)) {
|
||||
if (shift) {
|
||||
panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track);
|
||||
|
||||
if (!alt) {
|
||||
for (int i=0;i<clip->linked.size();i++) {
|
||||
Clip* link = sequence->get_clip(clip->linked.at(i));
|
||||
panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (panel_timeline->transition_select != TA_NO_TRANSITION) {
|
||||
panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track);
|
||||
|
||||
for (int i=0;i<clip->linked.size();i++) {
|
||||
Clip* link = sequence->get_clip(clip->linked.at(i));
|
||||
panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track);
|
||||
}
|
||||
|
||||
Selection s;
|
||||
s.track = clip->track;
|
||||
if (panel_timeline->transition_select == TA_OPENING_TRANSITION && clip->opening_transition != NULL) {
|
||||
s.in = clip->timeline_in;
|
||||
s.out = clip->timeline_in + clip->opening_transition->length;
|
||||
} else if (panel_timeline->transition_select == TA_CLOSING_TRANSITION && clip->closing_transition != NULL) {
|
||||
s.in = clip->timeline_out - clip->closing_transition->length;
|
||||
s.out = clip->timeline_out;
|
||||
}
|
||||
panel_timeline->selections.append(s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (panel_timeline->transition_select != TA_NO_TRANSITION) {
|
||||
panel_timeline->deselect_area(clip->timeline_in, clip->timeline_out, clip->track);
|
||||
// if "shift" is not down
|
||||
if (!shift) {
|
||||
panel_timeline->selections.clear();
|
||||
}
|
||||
|
||||
Selection s;
|
||||
|
||||
s.in = clip->timeline_in;
|
||||
s.out = clip->timeline_out;
|
||||
|
||||
if (panel_timeline->transition_select == TA_OPENING_TRANSITION) {
|
||||
s.out = clip->timeline_in + clip->opening_transition->length;
|
||||
}
|
||||
|
||||
if (panel_timeline->transition_select == TA_CLOSING_TRANSITION) {
|
||||
s.in = clip->timeline_out - clip->closing_transition->length;
|
||||
}
|
||||
|
||||
s.track = clip->track;
|
||||
panel_timeline->selections.append(s);
|
||||
|
||||
if (config.select_also_seeks) {
|
||||
panel_timeline->seek(clip->timeline_in);
|
||||
}
|
||||
|
||||
// if alt is not down, select links
|
||||
if (!alt && panel_timeline->transition_select == TA_NO_TRANSITION) {
|
||||
for (int i=0;i<clip->linked.size();i++) {
|
||||
Clip* link = sequence->get_clip(clip->linked.at(i));
|
||||
panel_timeline->deselect_area(link->timeline_in, link->timeline_out, link->track);
|
||||
if (!panel_timeline->is_clip_selected(link, true)) {
|
||||
Selection ss;
|
||||
ss.in = link->timeline_in;
|
||||
ss.out = link->timeline_out;
|
||||
ss.track = link->track;
|
||||
panel_timeline->selections.append(ss);
|
||||
}
|
||||
}
|
||||
|
||||
Selection s;
|
||||
s.track = clip->track;
|
||||
if (panel_timeline->transition_select == TA_OPENING_TRANSITION && clip->opening_transition != NULL) {
|
||||
s.in = clip->timeline_in;
|
||||
s.out = clip->timeline_in + clip->opening_transition->length;
|
||||
} else if (panel_timeline->transition_select == TA_CLOSING_TRANSITION && clip->closing_transition != NULL) {
|
||||
s.in = clip->timeline_out - clip->closing_transition->length;
|
||||
s.out = clip->timeline_out;
|
||||
}
|
||||
panel_timeline->selections.append(s);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if "shift" is not down
|
||||
if (!shift) {
|
||||
panel_timeline->selections.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Selection s;
|
||||
panel_timeline->moving_init = true;
|
||||
} else {
|
||||
// if "shift" is not down
|
||||
if (!shift) {
|
||||
panel_timeline->selections.clear();
|
||||
}
|
||||
|
||||
s.in = clip->timeline_in;
|
||||
s.out = clip->timeline_out;
|
||||
|
||||
if (panel_timeline->transition_select == TA_OPENING_TRANSITION) {
|
||||
s.out = clip->timeline_in + clip->opening_transition->length;
|
||||
}
|
||||
|
||||
if (panel_timeline->transition_select == TA_CLOSING_TRANSITION) {
|
||||
s.in = clip->timeline_out - clip->closing_transition->length;
|
||||
}
|
||||
|
||||
s.track = clip->track;
|
||||
panel_timeline->selections.append(s);
|
||||
|
||||
if (config.select_also_seeks) {
|
||||
panel_timeline->seek(clip->timeline_in);
|
||||
}
|
||||
|
||||
// if alt is not down, select links
|
||||
if (!alt && panel_timeline->transition_select == TA_NO_TRANSITION) {
|
||||
for (int i=0;i<clip->linked.size();i++) {
|
||||
Clip* link = sequence->get_clip(clip->linked.at(i));
|
||||
if (!panel_timeline->is_clip_selected(link, true)) {
|
||||
Selection ss;
|
||||
ss.in = link->timeline_in;
|
||||
ss.out = link->timeline_out;
|
||||
ss.track = link->track;
|
||||
panel_timeline->selections.append(ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panel_timeline->moving_init = true;
|
||||
} else {
|
||||
// if "shift" is not down
|
||||
if (!shift) {
|
||||
panel_timeline->selections.clear();
|
||||
}
|
||||
|
||||
panel_timeline->rect_select_init = true;
|
||||
}
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TIMELINE_TOOL_EDIT:
|
||||
if (config.edit_tool_also_seeks) panel_timeline->seek(panel_timeline->drag_frame_start);
|
||||
panel_timeline->selecting = true;
|
||||
break;
|
||||
case TIMELINE_TOOL_RAZOR:
|
||||
{
|
||||
panel_timeline->splitting = true;
|
||||
panel_timeline->split_tracks.append(panel_timeline->drag_track_start);
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
break;
|
||||
}
|
||||
panel_timeline->rect_select_init = true;
|
||||
}
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TIMELINE_TOOL_EDIT:
|
||||
if (config.edit_tool_also_seeks) panel_timeline->seek(panel_timeline->drag_frame_start);
|
||||
panel_timeline->selecting = true;
|
||||
break;
|
||||
case TIMELINE_TOOL_RAZOR:
|
||||
{
|
||||
panel_timeline->splitting = true;
|
||||
panel_timeline->split_tracks.append(panel_timeline->drag_track_start);
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -509,7 +526,46 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
bool repaint = false;
|
||||
|
||||
if (panel_timeline->moving_proc) {
|
||||
if (panel_timeline->creating) {
|
||||
const Ghost& g = panel_timeline->ghosts.at(0);
|
||||
|
||||
TimelineAction* ta = new TimelineAction();
|
||||
|
||||
Clip* c = new Clip(sequence);
|
||||
c->media = NULL;
|
||||
c->media_type = MEDIA_TYPE_SOLID;
|
||||
c->timeline_in = qMin(g.in, g.out);
|
||||
c->timeline_out = qMax(g.in, g.out);
|
||||
c->clip_in = 0;
|
||||
c->color_r = 192;
|
||||
c->color_g = 192;
|
||||
c->color_b = 64;
|
||||
c->track = g.track;
|
||||
|
||||
QVector<Clip*> add;
|
||||
add.append(c);
|
||||
ta->add_clips(sequence, add);
|
||||
|
||||
ta->add_effect(sequence, sequence->clip_count(), VIDEO_TRANSFORM_EFFECT);
|
||||
switch (panel_timeline->creatingObject) {
|
||||
case ADD_OBJ_TITLE:
|
||||
c->name = "Title";
|
||||
ta->add_effect(sequence, sequence->clip_count(), VIDEO_TEXT_EFFECT);
|
||||
break;
|
||||
case ADD_OBJ_SOLID:
|
||||
c->name = "Solid Color";
|
||||
ta->add_effect(sequence, sequence->clip_count(), VIDEO_SOLID_EFFECT);
|
||||
break;
|
||||
case ADD_OBJ_BARS:
|
||||
c->name = "Bars and Tone";
|
||||
ta->add_effect(sequence, sequence->clip_count(), VIDEO_SOLID_EFFECT);
|
||||
break;
|
||||
}
|
||||
|
||||
undo_stack.push(ta);
|
||||
|
||||
panel_timeline->redraw_all_clips(true);
|
||||
} else if (panel_timeline->moving_proc) {
|
||||
repaint = true;
|
||||
if (panel_timeline->ghosts.size() > 0) {
|
||||
const Ghost& first_ghost = panel_timeline->ghosts.at(0);
|
||||
@@ -718,6 +774,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
// clear split tracks
|
||||
panel_timeline->split_tracks.clear();
|
||||
|
||||
panel_timeline->creating = false;
|
||||
panel_timeline->selecting = false;
|
||||
panel_timeline->moving_proc = false;
|
||||
panel_timeline->moving_init = false;
|
||||
@@ -896,7 +953,9 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
|
||||
}
|
||||
|
||||
// validate ghosts for trimming
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_SLIP) {
|
||||
if (panel_timeline->creating) {
|
||||
|
||||
} else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) {
|
||||
if (c->media_type == MEDIA_TYPE_SEQUENCE
|
||||
|| (c->media_type == MEDIA_TYPE_FOOTAGE && !static_cast<Media*>(c->media)->get_stream_from_file_index(c->track < 0, c->media_stream)->infinite_length)) {
|
||||
// prevent slip moving a clip below 0 clip_in
|
||||
@@ -1075,7 +1134,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
panel_timeline->cursor_frame = panel_timeline->getTimelineFrameFromScreenPoint(event->pos().x());
|
||||
panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y());
|
||||
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
|
||||
if (isLiveEditing()) {
|
||||
panel_timeline->snap_to_clip(&panel_timeline->cursor_frame, !config.edit_tool_also_seeks || !panel_timeline->selecting);
|
||||
}
|
||||
if (panel_timeline->selecting) {
|
||||
@@ -1422,6 +1481,9 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
panel_timeline->rect_select_h = 0;
|
||||
panel_timeline->rect_select_proc = true;
|
||||
}
|
||||
} else if (isLiveEditing()) {
|
||||
// redraw because we have a cursor
|
||||
panel_timeline->repaint_timeline();
|
||||
} else if (panel_timeline->tool == TIMELINE_TOOL_POINTER ||
|
||||
panel_timeline->tool == TIMELINE_TOOL_RIPPLE ||
|
||||
panel_timeline->tool == TIMELINE_TOOL_ROLLING) {
|
||||
@@ -1529,10 +1591,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
} else {
|
||||
unsetCursor();
|
||||
}
|
||||
}
|
||||
} else if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
|
||||
// redraw because we have a cursor
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
} else if (panel_timeline->tool == TIMELINE_TOOL_SLIP) {
|
||||
if (getClipIndexFromCoords(panel_timeline->cursor_frame, panel_timeline->cursor_track) > -1) {
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
@@ -1820,7 +1879,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) {
|
||||
int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->drag_frame_start);
|
||||
int cursor_y = getScreenPointFromTrack(panel_timeline->split_tracks.at(i));
|
||||
|
||||
p.setPen(QColor(64, 64, 64));
|
||||
p.setPen(QColor(64, 64, 64));
|
||||
p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->split_tracks.at(i), -1));
|
||||
}
|
||||
}
|
||||
@@ -1844,7 +1903,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) {
|
||||
}
|
||||
|
||||
// Draw edit cursor
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
|
||||
if (isLiveEditing()) {
|
||||
if (is_track_visible(panel_timeline->cursor_track)) {
|
||||
int cursor_x = panel_timeline->getTimelineScreenPointFromFrame(panel_timeline->cursor_frame);
|
||||
int cursor_y = getScreenPointFromTrack(panel_timeline->cursor_track);
|
||||
|
||||
+17
-11
@@ -135,6 +135,7 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
case MEDIA_TYPE_SOLID:
|
||||
if (is_clip_active(c, playhead)) {
|
||||
if (!c->open) open_clip(c, !rendering);
|
||||
clip_is_active = true;
|
||||
@@ -170,30 +171,27 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
glOrtho(-half_width, half_width, half_height, -half_height, -1, 1);
|
||||
|
||||
for (int i=0;i<current_clips.size();i++) {
|
||||
Clip* c = current_clips.at(i);
|
||||
Clip* c = current_clips.at(i);
|
||||
|
||||
if (c->media_type == MEDIA_TYPE_FOOTAGE && !c->finished_opening) {
|
||||
qDebug() << "[WARNING] Tried to display clip" << i << "but it's closed";
|
||||
texture_failed = true;
|
||||
} else {
|
||||
if (c->track < 0) {
|
||||
glPushMatrix();
|
||||
|
||||
GLuint textureID = 0;
|
||||
int video_width, video_height;
|
||||
int video_width = c->getWidth();
|
||||
int video_height = c->getHeight();
|
||||
|
||||
if (c->media_type == MEDIA_TYPE_FOOTAGE) {
|
||||
get_clip_frame(c, playhead);
|
||||
MediaStream* ms = static_cast<Media*>(c->media)->get_stream_from_file_index(c->track < 0, c->media_stream);
|
||||
video_width = ms->video_width;
|
||||
video_height = ms->video_height;
|
||||
if (c->texture != NULL) textureID = c->texture->textureId();
|
||||
} else if (c->media_type == MEDIA_TYPE_SEQUENCE) {
|
||||
Sequence* cs = static_cast<Sequence*>(c->media);
|
||||
video_width = cs->width;
|
||||
video_height = cs->height;
|
||||
textureID = -1;
|
||||
}
|
||||
|
||||
if (textureID == 0) {
|
||||
if (textureID == 0 && c->media_type != MEDIA_TYPE_SOLID) {
|
||||
qDebug() << "[WARNING] Texture hasn't been created yet";
|
||||
texture_failed = true;
|
||||
} else if (playhead >= c->timeline_in) {
|
||||
@@ -213,11 +211,17 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
c->fbo[1]->release();
|
||||
|
||||
// for nested sequences
|
||||
if (textureID == -1) textureID = compose_sequence(c, render_audio);
|
||||
if (c->media_type == MEDIA_TYPE_SEQUENCE) textureID = compose_sequence(c, render_audio);
|
||||
|
||||
glViewport(0, 0, video_width, video_height);
|
||||
|
||||
GLuint composite_texture = draw_clip(c->fbo[0], textureID);
|
||||
GLuint composite_texture;
|
||||
if (c->media_type == MEDIA_TYPE_SOLID) {
|
||||
composite_texture = c->fbo[0]->texture();
|
||||
} else {
|
||||
composite_texture = draw_clip(c->fbo[0], textureID);
|
||||
}
|
||||
|
||||
bool fbo_switcher = true;
|
||||
|
||||
GLTextureCoords coords;
|
||||
@@ -302,6 +306,8 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
if (default_fbo != NULL) default_fbo->bind();
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
} else {
|
||||
if (c->media_type == MEDIA_TYPE_FOOTAGE
|
||||
&& render_audio
|
||||
|
||||
Reference in New Issue
Block a user