wave effect axis, fixed folder bugs, timecode to frame number, drag from footage viewer, track resizing bug
This commit is contained in:
@@ -4,19 +4,26 @@
|
||||
uniform float frequency;
|
||||
uniform float intensity;
|
||||
uniform float evolution;
|
||||
uniform bool vertical;
|
||||
|
||||
uniform mediump float amount_val;
|
||||
uniform sampler2D myTexture;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main(void) {
|
||||
float offset = sin((vTexCoord.x-evolution)*frequency)*intensity;
|
||||
float x = vTexCoord.x;
|
||||
float y = vTexCoord.y;
|
||||
|
||||
float y = vTexCoord.y-offset;
|
||||
if (y < 0.0 || y > 1.0) {
|
||||
if (vertical) {
|
||||
x -= sin((vTexCoord.y-evolution)*frequency)*intensity;
|
||||
} else {
|
||||
y -= sin((vTexCoord.x-evolution)*frequency)*intensity;
|
||||
}
|
||||
|
||||
if (y < 0.0 || y > 1.0 || x < 0.0 || x > 1.0) {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
} else {
|
||||
vec4 textureColor = texture2D(myTexture, vec2(vTexCoord.x, y));
|
||||
vec4 textureColor = texture2D(myTexture, vec2(x, y));
|
||||
gl_FragColor = vec4(
|
||||
textureColor.r,
|
||||
textureColor.g,
|
||||
|
||||
@@ -13,9 +13,13 @@ WaveEffect::WaveEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_WAVE_EFFECT
|
||||
evolution_val = add_row("Evolution:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
evolution_val->set_double_default_value(0);
|
||||
|
||||
vertical_val = add_row("Vertical:")->add_field(EFFECT_FIELD_BOOL);
|
||||
vertical_val->set_bool_value(false);
|
||||
|
||||
connect(frequency_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(intensity_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(evolution_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(vertical_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
|
||||
vertPath = ":/shaders/common.vert";
|
||||
fragPath = ":/shaders/waveeffect.frag";
|
||||
@@ -25,4 +29,5 @@ void WaveEffect::process_shader(double timecode) {
|
||||
glslProgram->setUniformValue("frequency", (GLfloat) (frequency_val->get_double_value(timecode)));
|
||||
glslProgram->setUniformValue("intensity", (GLfloat) (intensity_val->get_double_value(timecode)*0.01));
|
||||
glslProgram->setUniformValue("evolution", (GLfloat) (evolution_val->get_double_value(timecode)*0.01));
|
||||
glslProgram->setUniformValue("vertical", vertical_val->get_bool_value(timecode));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ private:
|
||||
EffectField* frequency_val;
|
||||
EffectField* intensity_val;
|
||||
EffectField* evolution_val;
|
||||
|
||||
EffectField* vertical_val;
|
||||
};
|
||||
|
||||
#endif // WAVEEFFECT_H
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ bool ExportThread::setupVideo() {
|
||||
vcodec_ctx->codec_id = static_cast<AVCodecID>(video_codec);
|
||||
vcodec_ctx->width = video_width;
|
||||
vcodec_ctx->height = video_height;
|
||||
vcodec_ctx->sample_aspect_ratio = av_d2q(video_width/video_height, INT_MAX);
|
||||
vcodec_ctx->sample_aspect_ratio = {1, 1};
|
||||
vcodec_ctx->pix_fmt = vcodec->pix_fmts[0]; // maybe be breakable code
|
||||
vcodec_ctx->framerate = av_d2q(video_frame_rate, INT_MAX);
|
||||
if (video_compression_type == COMPRESSION_TYPE_CBR) vcodec_ctx->bit_rate = video_bitrate * 1000000;
|
||||
|
||||
+7
-2
@@ -1060,7 +1060,8 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
|
||||
int len = root ? ui->treeWidget->topLevelItemCount() : parent->childCount();
|
||||
for (int i=0;i<len;i++) {
|
||||
QTreeWidgetItem* item = root ? ui->treeWidget->topLevelItem(i) : parent->child(i);
|
||||
int item_type = get_type_from_tree(item);
|
||||
int item_type = get_type_from_tree(item);
|
||||
|
||||
if (type == item_type) {
|
||||
if (item_type == MEDIA_TYPE_FOLDER) {
|
||||
if (set_ids_only) {
|
||||
@@ -1078,7 +1079,7 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
|
||||
}
|
||||
stream.writeEndElement();
|
||||
}
|
||||
save_folder(stream, item, type, set_ids_only);
|
||||
// save_folder(stream, item, type, set_ids_only);
|
||||
} else {
|
||||
int folder = root ? 0 : parent->data(0, Qt::UserRole + 3).toInt();
|
||||
if (type == MEDIA_TYPE_FOOTAGE) {
|
||||
@@ -1202,6 +1203,10 @@ void Project::save_folder(QXmlStreamWriter& stream, QTreeWidgetItem* parent, int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item_type == MEDIA_TYPE_FOLDER) {
|
||||
save_folder(stream, item, type, set_ids_only);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ extern "C" {
|
||||
#include <QtMath>
|
||||
#include <QAudioOutput>
|
||||
#include <QPainter>
|
||||
#include <QStringList>
|
||||
|
||||
Viewer::Viewer(QWidget *parent) :
|
||||
QDockWidget(parent),
|
||||
@@ -87,6 +88,48 @@ void Viewer::reset_all_audio() {
|
||||
clear_audio_ibuffer();
|
||||
}
|
||||
|
||||
long timecode_to_frame(const QString& s, int view, double frame_rate) {
|
||||
QList<QString> list = s.split(QRegExp("[:;]"));
|
||||
|
||||
for (int i=0;i<list.size();i++) {
|
||||
qDebug() << "list" << i << list.at(i);
|
||||
}
|
||||
|
||||
if (view == TIMECODE_FRAMES || list.size() == 1) {
|
||||
return s.toLong();
|
||||
}
|
||||
|
||||
int frRound = qRound(frame_rate);
|
||||
int hours = ((list.size() > 0) ? list.at(0).toInt() : 0) * frRound * 3600;
|
||||
int minutes = ((list.size() > 1) ? list.at(1).toInt() : 0) * frRound * 60;
|
||||
int seconds = ((list.size() > 2) ? list.at(2).toInt() : 0) * frRound;
|
||||
int frames = (list.size() > 3) ? list.at(3).toInt() : 0;
|
||||
|
||||
int f = (frames + seconds + minutes + hours);
|
||||
|
||||
if (view == TIMECODE_DROP && frame_rate_is_droppable(frame_rate)) {
|
||||
// return drop
|
||||
int d;
|
||||
int m;
|
||||
|
||||
int dropFrames = round(frame_rate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate
|
||||
int framesPer10Minutes = round(frame_rate * 60 * 10); //Number of frames per ten minutes
|
||||
int framesPerMinute = (round(frame_rate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames
|
||||
|
||||
d = f / framesPer10Minutes;
|
||||
f -= dropFrames*9*d;
|
||||
|
||||
m = f % framesPer10Minutes;
|
||||
|
||||
if (m > dropFrames) {
|
||||
f -= (dropFrames * ((m - dropFrames) / framesPerMinute));
|
||||
}
|
||||
}
|
||||
|
||||
// return non-drop
|
||||
return f;
|
||||
}
|
||||
|
||||
QString frame_to_timecode(long f, int view, double frame_rate) {
|
||||
if (view == TIMECODE_FRAMES) {
|
||||
return QString::number(f);
|
||||
|
||||
@@ -13,6 +13,7 @@ class Viewer;
|
||||
}
|
||||
|
||||
bool frame_rate_is_droppable(float rate);
|
||||
long timecode_to_frame(const QString& s, int view, double frame_rate);
|
||||
QString frame_to_timecode(long f, int view, double frame_rate);
|
||||
|
||||
class Viewer : public QDockWidget
|
||||
|
||||
+11
-1
@@ -1210,6 +1210,8 @@ void MediaMove::undo() {
|
||||
} else {
|
||||
to->removeChild(items.at(i));
|
||||
}
|
||||
}
|
||||
for (int i=0;i<items.size();i++) {
|
||||
if (froms.at(i) == NULL) {
|
||||
table->addTopLevelItem(items.at(i));
|
||||
} else {
|
||||
@@ -1220,9 +1222,10 @@ void MediaMove::undo() {
|
||||
}
|
||||
|
||||
void MediaMove::redo() {
|
||||
froms.resize(items.size());
|
||||
for (int i=0;i<items.size();i++) {
|
||||
QTreeWidgetItem* parent = items.at(i)->parent();
|
||||
froms.append(parent);
|
||||
froms[i] = parent;
|
||||
if (parent == NULL) {
|
||||
table->takeTopLevelItem(table->indexOfTopLevelItem(items.at(i)));
|
||||
} else {
|
||||
@@ -1233,6 +1236,13 @@ void MediaMove::redo() {
|
||||
} else {
|
||||
to->addChild(items.at(i));
|
||||
}
|
||||
}
|
||||
for (int i=0;i<items.size();i++) {
|
||||
if (to == NULL) {
|
||||
table->addTopLevelItem(items.at(i));
|
||||
} else {
|
||||
to->addChild(items.at(i));
|
||||
}
|
||||
}
|
||||
mainWindow->setWindowModified(true);
|
||||
}
|
||||
|
||||
+26
-14
@@ -136,21 +136,33 @@ void LabelSlider::mouseReleaseEvent(QMouseEvent*) {
|
||||
drag_proc = false;
|
||||
previous_value = drag_start_value;
|
||||
emit valueChanged();
|
||||
} else {
|
||||
double d = QInputDialog::getDouble(
|
||||
this,
|
||||
"Set Value",
|
||||
"New value:",
|
||||
(display_type == LABELSLIDER_PERCENT) ? internal_value * 100 : internal_value,
|
||||
(min_enabled) ? min_value : INT_MIN,
|
||||
(max_enabled) ? max_value : INT_MAX,
|
||||
decimal_places
|
||||
);
|
||||
if (display_type == LABELSLIDER_PERCENT) d *= 0.01;
|
||||
if (d != internal_value) {
|
||||
} else {
|
||||
double d = internal_value;
|
||||
if (display_type == LABELSLIDER_FRAMENUMBER) {
|
||||
QString s = QInputDialog::getText(
|
||||
this,
|
||||
"Set Value",
|
||||
"New value:",
|
||||
QLineEdit::Normal,
|
||||
valueToString(internal_value)
|
||||
);
|
||||
d = timecode_to_frame(s, config.timecode_view, frame_rate); // string to frame number
|
||||
} else {
|
||||
d = QInputDialog::getDouble(
|
||||
this,
|
||||
"Set Value",
|
||||
"New value:",
|
||||
(display_type == LABELSLIDER_PERCENT) ? internal_value * 100 : internal_value,
|
||||
(min_enabled) ? min_value : INT_MIN,
|
||||
(max_enabled) ? max_value : INT_MAX,
|
||||
decimal_places
|
||||
);
|
||||
if (display_type == LABELSLIDER_PERCENT) d *= 0.01;
|
||||
}
|
||||
if (d != internal_value) {
|
||||
previous_value = internal_value;
|
||||
set_value(d, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-20
@@ -112,7 +112,7 @@ void SourceTable::rename_interval() {
|
||||
}
|
||||
}
|
||||
void SourceTable::item_click(QTreeWidgetItem* item, int column) {
|
||||
if (column == 0) {
|
||||
if (column == 0 && selectedItems().size() == 1) {
|
||||
editing_item = item;
|
||||
rename_timer.start();
|
||||
}
|
||||
@@ -186,30 +186,34 @@ void SourceTable::dropEvent(QDropEvent* event) {
|
||||
}
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
event->ignore();
|
||||
|
||||
// dragging files within project
|
||||
QVector<QTreeWidgetItem*> move_items;
|
||||
// if we dragged to the root OR dragged to a folder
|
||||
if (drop_item == NULL || (drop_item != NULL && get_type_from_tree(drop_item) == MEDIA_TYPE_FOLDER)) {
|
||||
QVector<QTreeWidgetItem*> move_items;
|
||||
QList<QTreeWidgetItem*> selected_items = selectedItems();
|
||||
for (int i=0;i<selected_items.size();i++) {
|
||||
QTreeWidgetItem* s = selected_items.at(i);
|
||||
bool ignore = false;
|
||||
if (s->parent() != NULL) {
|
||||
// if child belongs to a selected parent, assume the user is just moving the parent and ignore the child
|
||||
QTreeWidgetItem* par = s->parent();
|
||||
while (par != NULL) {
|
||||
for (int j=0;j<selected_items.size();j++) {
|
||||
if (par == selected_items.at(j)) {
|
||||
ignore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
par = par->parent();
|
||||
}
|
||||
}
|
||||
if (!ignore) {
|
||||
move_items.append(s);
|
||||
}
|
||||
if (s->parent() != drop_item && s != drop_item) {
|
||||
bool ignore = false;
|
||||
if (s->parent() != NULL) {
|
||||
// if child belongs to a selected parent, assume the user is just moving the parent and ignore the child
|
||||
QTreeWidgetItem* par = s->parent();
|
||||
while (par != NULL && !ignore) {
|
||||
for (int j=0;j<selected_items.size();j++) {
|
||||
if (par == selected_items.at(j)) {
|
||||
ignore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
par = par->parent();
|
||||
}
|
||||
}
|
||||
if (!ignore) {
|
||||
move_items.append(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (move_items.size() > 0) {
|
||||
MediaMove* mm = new MediaMove(this);
|
||||
@@ -217,6 +221,6 @@ void SourceTable::dropEvent(QDropEvent* event) {
|
||||
mm->items = move_items;
|
||||
undo_stack.push(mm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+144
-98
@@ -13,6 +13,7 @@
|
||||
#include "project/undo.h"
|
||||
#include "ui_timeline.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui/viewerwidget.h"
|
||||
|
||||
#include "effects/effect.h"
|
||||
#include "effects/transition.h"
|
||||
@@ -191,13 +192,59 @@ bool same_sign(int a, int b) {
|
||||
}
|
||||
|
||||
void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
if (event->source() == panel_project->source_table) {
|
||||
qDebug() << "DRAG ENTER CALLED";
|
||||
|
||||
bool import_init = false;
|
||||
|
||||
QVector<void*> media_list;
|
||||
QVector<int> type_list;
|
||||
|
||||
if (event->source() == panel_project->source_table) {
|
||||
QList<QTreeWidgetItem*> items = panel_project->source_table->selectedItems();
|
||||
media_list.resize(items.size());
|
||||
type_list.resize(items.size());
|
||||
for (int i=0;i<items.size();i++) {
|
||||
type_list[i] = get_type_from_tree(items.at(i));
|
||||
media_list[i] = get_media_from_tree(items.at(i));
|
||||
}
|
||||
import_init = true;
|
||||
}
|
||||
|
||||
if (event->source() == panel_footage_viewer->viewer_widget) {
|
||||
Sequence* proposed_seq = panel_footage_viewer->seq;
|
||||
if (proposed_seq != sequence) { // don't allow nesting the same sequence
|
||||
if (proposed_seq->wrapper_sequence) {
|
||||
type_list.append(MEDIA_TYPE_FOOTAGE);
|
||||
media_list.append(proposed_seq->clips.at(0)->media);
|
||||
} else {
|
||||
type_list.append(MEDIA_TYPE_SEQUENCE);
|
||||
media_list.append(proposed_seq);
|
||||
}
|
||||
import_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*if (config.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) {
|
||||
// TODO for this to work, we need a way to abort PreviewGenerator
|
||||
|
||||
|
||||
qDebug() << "TODO get data for:";
|
||||
QList<QUrl> urls = event->mimeData()->urls();
|
||||
if (!urls.isEmpty()) {
|
||||
for (int i=0;i<urls.size();i++) {
|
||||
qDebug() << (urls.at(i).toLocalFile());
|
||||
}
|
||||
}
|
||||
|
||||
import_init = true;
|
||||
}*/
|
||||
|
||||
if (import_init) {
|
||||
event->accept();
|
||||
|
||||
panel_timeline->video_ghosts = false;
|
||||
panel_timeline->audio_ghosts = false;
|
||||
QPoint pos = event->pos();
|
||||
QList<QTreeWidgetItem*> items = panel_project->source_table->selectedItems();
|
||||
QPoint pos = event->pos();
|
||||
long entry_point;
|
||||
if (sequence == NULL) {
|
||||
// if no sequence, we're going to create a new one using the clips as a reference
|
||||
@@ -212,12 +259,11 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
|
||||
bool got_video_values = false;
|
||||
bool got_audio_values = false;
|
||||
for (int i=0;i<items.size();i++) {
|
||||
QTreeWidgetItem* item = items.at(i);
|
||||
switch (get_type_from_tree(item)) {
|
||||
for (int i=0;i<media_list.size();i++) {
|
||||
switch (type_list.at(i)) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
{
|
||||
Media* m = get_footage_from_tree(item);
|
||||
Media* m = static_cast<Media*>(media_list.at(i));
|
||||
if (m->ready) {
|
||||
if (!got_video_values) {
|
||||
for (int j=0;j<m->video_tracks.size();j++) {
|
||||
@@ -246,7 +292,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
{
|
||||
Sequence* s = get_sequence_from_tree(item);
|
||||
Sequence* s = static_cast<Sequence*>(media_list.at(i));
|
||||
predicted_video_width = s->width;
|
||||
predicted_video_height = s->height;
|
||||
predicted_new_frame_rate = s->frame_rate;
|
||||
@@ -266,9 +312,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
panel_timeline->drag_track_start = (bottom_align) ? -1 : 0;
|
||||
predicted_new_frame_rate = sequence->frame_rate;
|
||||
}
|
||||
for (int i=0;i<items.size();i++) {
|
||||
QTreeWidgetItem* item = items.at(i);
|
||||
int item_type = get_type_from_tree(item);
|
||||
for (int i=0;i<media_list.size();i++) {
|
||||
bool can_import = true;
|
||||
|
||||
Media* m = NULL;
|
||||
@@ -278,9 +322,9 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
long default_clip_in = 0;
|
||||
long default_clip_out = 0;
|
||||
|
||||
switch (item_type) {
|
||||
switch (type_list.at(i)) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
m = get_footage_from_tree(item);
|
||||
m = static_cast<Media*>(media_list.at(i));
|
||||
media = m;
|
||||
can_import = m->ready;
|
||||
if (m->using_inout) {
|
||||
@@ -291,7 +335,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_SEQUENCE:
|
||||
s = get_sequence_from_tree(item);
|
||||
s = static_cast<Sequence*>(media_list.at(i));
|
||||
sequence_length = s->getEndFrame();
|
||||
if (sequence != NULL) sequence_length = refactor_frame_number(sequence_length, s->frame_rate, predicted_new_frame_rate);
|
||||
media = s;
|
||||
@@ -308,14 +352,14 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
if (can_import) {
|
||||
Ghost g;
|
||||
g.clip = -1;
|
||||
g.media_type = item_type;
|
||||
g.media_type = type_list.at(i);
|
||||
g.trimming = false;
|
||||
g.old_clip_in = g.clip_in = default_clip_in;
|
||||
g.media = media;
|
||||
g.in = entry_point;
|
||||
g.transition = NULL;
|
||||
|
||||
switch (item_type) {
|
||||
switch (type_list.at(i)) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
// is video source a still image?
|
||||
if (m->video_tracks.size() > 0 && m->video_tracks[0]->infinite_length && m->audio_tracks.size() == 0) {
|
||||
@@ -367,18 +411,7 @@ void TimelineWidget::dragEnterEvent(QDragEnterEvent *event) {
|
||||
g.old_track = g.track;
|
||||
}
|
||||
panel_timeline->importing = true;
|
||||
} else if (config.enable_drag_files_to_timeline && event->mimeData()->hasUrls()) {
|
||||
// TODO for this to work, we need a way to abort PreviewGenerator
|
||||
|
||||
/*event->accept();
|
||||
qDebug() << "TODO get data for:";
|
||||
QList<QUrl> urls = event->mimeData()->urls();
|
||||
if (!urls.isEmpty()) {
|
||||
for (int i=0;i<urls.size();i++) {
|
||||
qDebug() << (urls.at(i).toLocalFile());
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::dragMoveEvent(QDragMoveEvent *event) {
|
||||
@@ -1284,7 +1317,12 @@ void TimelineWidget::update_ghosts(QPoint& mouse_pos) {
|
||||
if (panel_timeline->importing) {
|
||||
QToolTip::showText(mapToGlobal(mouse_pos), frame_to_timecode(earliest_in_point, config.timecode_view, sequence->frame_rate));
|
||||
} else {
|
||||
QToolTip::showText(mapToGlobal(mouse_pos), ((frame_diff < 0) ? "-" : "+") + frame_to_timecode(qAbs(frame_diff), config.timecode_view, sequence->frame_rate));
|
||||
QToolTip::showText(mapToGlobal(mouse_pos),
|
||||
((frame_diff < 0) ? "-" : "+")
|
||||
+ frame_to_timecode(qAbs(frame_diff), config.timecode_view, sequence->frame_rate)
|
||||
+ " Duration: "
|
||||
+ frame_to_timecode((panel_timeline->ghosts.at(0).old_out-panel_timeline->ghosts.at(0).old_in)+frame_diff, config.timecode_view, sequence->frame_rate)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1666,71 +1704,77 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
bool found = false;
|
||||
bool cursor_contains_clip = false;
|
||||
int closeness = INT_MAX;
|
||||
int min_track = INT_MAX;
|
||||
int max_track = INT_MIN;
|
||||
panel_timeline->transition_select = TA_NO_TRANSITION;
|
||||
for (int i=0;i<sequence->clips.size();i++) {
|
||||
Clip* c = sequence->clips.at(i);
|
||||
if (c != NULL && c->track == mouse_track) {
|
||||
if (panel_timeline->cursor_frame >= c->timeline_in &&
|
||||
panel_timeline->cursor_frame <= c->timeline_out) {
|
||||
cursor_contains_clip = true;
|
||||
if (c != NULL) {
|
||||
min_track = qMin(min_track, c->track);
|
||||
max_track = qMax(max_track, c->track);
|
||||
if (c->track == mouse_track) {
|
||||
if (panel_timeline->cursor_frame >= c->timeline_in &&
|
||||
panel_timeline->cursor_frame <= c->timeline_out) {
|
||||
cursor_contains_clip = true;
|
||||
|
||||
tooltip_timer.start();
|
||||
tooltip_clip = i;
|
||||
tooltip_timer.start();
|
||||
tooltip_clip = i;
|
||||
|
||||
if (c->opening_transition != NULL && panel_timeline->cursor_frame <= c->timeline_in + c->opening_transition->length) {
|
||||
panel_timeline->transition_select = TA_OPENING_TRANSITION;
|
||||
} else if (c->closing_transition != NULL && panel_timeline->cursor_frame >= c->timeline_out - c->closing_transition->length) {
|
||||
panel_timeline->transition_select = TA_CLOSING_TRANSITION;
|
||||
}
|
||||
}
|
||||
if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) {
|
||||
int nc = qAbs(c->timeline_in + 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = true;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (c->timeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) {
|
||||
int nc = qAbs(c->timeline_out - 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = false;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
|
||||
if (c->opening_transition != NULL) {
|
||||
long transition_point = c->timeline_in + c->opening_transition->length;
|
||||
|
||||
if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) {
|
||||
int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = false;
|
||||
panel_timeline->transition_select = TA_OPENING_TRANSITION;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
if (c->opening_transition != NULL && panel_timeline->cursor_frame <= c->timeline_in + c->opening_transition->length) {
|
||||
panel_timeline->transition_select = TA_OPENING_TRANSITION;
|
||||
} else if (c->closing_transition != NULL && panel_timeline->cursor_frame >= c->timeline_out - c->closing_transition->length) {
|
||||
panel_timeline->transition_select = TA_CLOSING_TRANSITION;
|
||||
}
|
||||
}
|
||||
if (c->closing_transition != NULL) {
|
||||
long transition_point = c->timeline_out - c->closing_transition->length;
|
||||
if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) {
|
||||
int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = true;
|
||||
panel_timeline->transition_select = TA_CLOSING_TRANSITION;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
if (c->timeline_in > mouse_frame_lower && c->timeline_in < mouse_frame_upper) {
|
||||
int nc = qAbs(c->timeline_in + 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = true;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (c->timeline_out > mouse_frame_lower && c->timeline_out < mouse_frame_upper) {
|
||||
int nc = qAbs(c->timeline_out - 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = false;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_POINTER) {
|
||||
if (c->opening_transition != NULL) {
|
||||
long transition_point = c->timeline_in + c->opening_transition->length;
|
||||
|
||||
if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) {
|
||||
int nc = qAbs(transition_point - 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = false;
|
||||
panel_timeline->transition_select = TA_OPENING_TRANSITION;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c->closing_transition != NULL) {
|
||||
long transition_point = c->timeline_out - c->closing_transition->length;
|
||||
if (transition_point > mouse_frame_lower && transition_point < mouse_frame_upper) {
|
||||
int nc = qAbs(transition_point + 1 - panel_timeline->cursor_frame);
|
||||
if (nc < closeness) {
|
||||
panel_timeline->trim_target = i;
|
||||
panel_timeline->trim_in_point = true;
|
||||
panel_timeline->transition_select = TA_CLOSING_TRANSITION;
|
||||
closeness = nc;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*if (cursor_contains_clip) {
|
||||
QToolTip::showText(mapToGlobal(event->pos()), "HOVER OVER CLIP");
|
||||
@@ -1744,21 +1788,23 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
int track_y = 0;
|
||||
for (int i=0;i<panel_timeline->get_track_height_size(bottom_align);i++) {
|
||||
int track = (bottom_align) ? -1-i : i;
|
||||
int track_height = panel_timeline->calculate_track_height(track, -1);
|
||||
track_y += track_height;
|
||||
int y_test_value = (bottom_align) ? rect().bottom() - track_y : track_y;
|
||||
int test_range = 5;
|
||||
int mouse_pos = pos.y() + scroll;
|
||||
if (mouse_pos > y_test_value-test_range && mouse_pos < y_test_value+test_range) {
|
||||
// if track lines are hidden, only resize track if a clip is already there
|
||||
if (config.show_track_lines || cursor_contains_clip) {
|
||||
found = true;
|
||||
track_resizing = true;
|
||||
track_target = track;
|
||||
track_resize_old_value = track_height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (track >= min_track && track <= max_track) {
|
||||
int track_height = panel_timeline->calculate_track_height(track, -1);
|
||||
track_y += track_height;
|
||||
int y_test_value = (bottom_align) ? rect().bottom() - track_y : track_y;
|
||||
int test_range = 5;
|
||||
int mouse_pos = pos.y() + scroll;
|
||||
if (mouse_pos > y_test_value-test_range && mouse_pos < y_test_value+test_range) {
|
||||
// if track lines are hidden, only resize track if a clip is already there
|
||||
if (config.show_track_lines || cursor_contains_clip) {
|
||||
found = true;
|
||||
track_resizing = true;
|
||||
track_target = track;
|
||||
track_resize_old_value = track_height;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
|
||||
+42
-5
@@ -21,6 +21,9 @@
|
||||
#include <QtMath>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QMouseEvent>
|
||||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
|
||||
extern "C" {
|
||||
#include <libavformat/avformat.h>
|
||||
@@ -29,7 +32,8 @@ extern "C" {
|
||||
ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
QOpenGLWidget(parent),
|
||||
default_fbo(NULL),
|
||||
waveform(false)
|
||||
waveform(false),
|
||||
dragging(false)
|
||||
{
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
|
||||
@@ -67,7 +71,34 @@ void ViewerWidget::paintEvent(QPaintEvent *e) {
|
||||
if (!rendering) {
|
||||
makeCurrent();
|
||||
QOpenGLWidget::paintEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::seek_from_click(int x) {
|
||||
viewer->seek(getFrameFromScreenPoint((double) width() / (double) waveform_clip->timeline_out, x));
|
||||
}
|
||||
|
||||
void ViewerWidget::mousePressEvent(QMouseEvent* event) {
|
||||
if (waveform) seek_from_click(event->x());
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
|
||||
if (dragging) {
|
||||
if (waveform) {
|
||||
seek_from_click(event->x());
|
||||
} else {
|
||||
QDrag* drag = new QDrag(this);
|
||||
QMimeData* mimeData = new QMimeData;
|
||||
mimeData->setText("h");
|
||||
drag->setMimeData(mimeData);
|
||||
Qt::DropAction dropAction = drag->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::mouseReleaseEvent(QMouseEvent *) {
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
void ViewerWidget::drawTitleSafeArea() {
|
||||
@@ -238,7 +269,7 @@ GLuint ViewerWidget::compose_sequence(Clip* nest, bool render_audio) {
|
||||
}
|
||||
}
|
||||
|
||||
if (viewer->playing && s->playhead == endFrame) {
|
||||
if (viewer->playing && (s->playhead == endFrame || (s->using_workarea && s->playhead == s->workarea_out))) {
|
||||
viewer->pause();
|
||||
}
|
||||
|
||||
@@ -470,10 +501,16 @@ void ViewerWidget::paintGL() {
|
||||
double timeline_zoom = (double) width() / (double) waveform_clip->timeline_out;
|
||||
|
||||
QPainter p(this);
|
||||
p.setPen(QColor(0, 255, 0));
|
||||
if (viewer->seq->using_workarea) {
|
||||
p.fillRect(QRect(getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_in), 0, getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_out-viewer->seq->workarea_in), height()), QColor(255, 255, 255, 64));
|
||||
int in_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_in);
|
||||
int out_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->workarea_out);
|
||||
|
||||
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());
|
||||
}
|
||||
p.setPen(Qt::green);
|
||||
draw_waveform(waveform_clip, waveform_ms, waveform_clip->timeline_out, &p, rect(), 0, width(), waveform_zoom);
|
||||
p.setPen(Qt::red);
|
||||
int playhead_x = getScreenPointFromFrame(timeline_zoom, viewer->seq->playhead);
|
||||
|
||||
+7
-2
@@ -32,14 +32,19 @@ public:
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e);
|
||||
// void resizeGL(int w, int h);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
private:
|
||||
QTimer retry_timer;
|
||||
void drawTitleSafeArea();
|
||||
bool dragging;
|
||||
void seek_from_click(int x);
|
||||
GLuint compose_sequence(Clip *nest, bool render_audio);
|
||||
GLuint draw_clip(QOpenGLFramebufferObject *clip, GLuint texture);
|
||||
private slots:
|
||||
void retry();
|
||||
void deleteFunction();
|
||||
GLuint compose_sequence(Clip *nest, bool render_audio);
|
||||
GLuint draw_clip(QOpenGLFramebufferObject *clip, GLuint texture);
|
||||
};
|
||||
|
||||
#endif // VIEWERWIDGET_H
|
||||
|
||||
Reference in New Issue
Block a user