improved snapping
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
#include "preferencesdialog.h"
|
||||
#include "ui_preferencesdialog.h"
|
||||
|
||||
PreferencesDialog::PreferencesDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::PreferencesDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
PreferencesDialog::~PreferencesDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef PREFERENCESDIALOG_H
|
||||
#define PREFERENCESDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class PreferencesDialog;
|
||||
}
|
||||
|
||||
class PreferencesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PreferencesDialog(QWidget *parent = 0);
|
||||
~PreferencesDialog();
|
||||
|
||||
private:
|
||||
Ui::PreferencesDialog *ui;
|
||||
};
|
||||
|
||||
#endif // PREFERENCESDIALOG_H
|
||||
@@ -0,0 +1,71 @@
|
||||
<ui version="4.0">
|
||||
<author/>
|
||||
<comment/>
|
||||
<exportmacro/>
|
||||
<class>PreferencesDialog</class>
|
||||
<widget class="QDialog" name="PreferencesDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>240</y>
|
||||
<width>341</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<pixmapfunction/>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>PreferencesDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>PreferencesDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "dialogs/aboutdialog.h"
|
||||
#include "dialogs/newsequencedialog.h"
|
||||
#include "dialogs/exportdialog.h"
|
||||
#include "dialogs/preferencesdialog.h"
|
||||
|
||||
#include "ui_timeline.h"
|
||||
|
||||
@@ -421,3 +422,14 @@ void MainWindow::on_actionGo_to_Next_Cut_triggered()
|
||||
panel_timeline->next_cut();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionEdit_Tool_Also_Seeks_triggered(bool checked)
|
||||
{
|
||||
panel_timeline->edit_tool_also_seeks = checked;
|
||||
}
|
||||
|
||||
void MainWindow::on_actionPreferences_triggered()
|
||||
{
|
||||
PreferencesDialog pd(this);
|
||||
pd.exec();
|
||||
}
|
||||
|
||||
@@ -107,6 +107,10 @@ private slots:
|
||||
|
||||
void autorecover_interval();
|
||||
|
||||
void on_actionEdit_Tool_Also_Seeks_triggered(bool checked);
|
||||
|
||||
void on_actionPreferences_triggered();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
void setup_layout();
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
<addaction name="actionSlip_Tool"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionToggle_Snapping"/>
|
||||
<addaction name="actionEdit_Tool_Also_Seeks"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPreferences"/>
|
||||
<addaction name="separator"/>
|
||||
@@ -465,6 +466,14 @@
|
||||
<string>Down</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEdit_Tool_Also_Seeks">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Edit Tool Also Seeks</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
||||
@@ -54,7 +54,8 @@ SOURCES += \
|
||||
io/exportthread.cpp \
|
||||
ui/timelineheader.cpp \
|
||||
io/previewgenerator.cpp \
|
||||
ui/labelslider.cpp
|
||||
ui/labelslider.cpp \
|
||||
dialogs/preferencesdialog.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
@@ -84,7 +85,8 @@ HEADERS += \
|
||||
ui/timelinetools.h \
|
||||
ui/timelineheader.h \
|
||||
io/previewgenerator.h \
|
||||
ui/labelslider.h
|
||||
ui/labelslider.h \
|
||||
dialogs/preferencesdialog.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
@@ -94,7 +96,8 @@ FORMS += \
|
||||
panels/timeline.ui \
|
||||
dialogs/aboutdialog.ui \
|
||||
dialogs/newsequencedialog.ui \
|
||||
dialogs/exportdialog.ui
|
||||
dialogs/exportdialog.ui \
|
||||
dialogs/preferencesdialog.ui
|
||||
|
||||
win32 {
|
||||
LIBS += -L../ffmpeg/lib -lavutil -lavformat -lavcodec -lswscale -lswresample -lopengl32
|
||||
|
||||
+27
-16
@@ -23,6 +23,7 @@ Timeline::Timeline(QWidget *parent) :
|
||||
ui(new Ui::Timeline)
|
||||
{
|
||||
selecting = moving_init = moving_proc = splitting = importing = playing = trim_in = snapped = false;
|
||||
edit_tool_also_seeks = false;
|
||||
snapping = true;
|
||||
last_frame = playhead = snap_point = cursor_frame = cursor_track = 0;
|
||||
trim_target = -1;
|
||||
@@ -165,6 +166,10 @@ void Timeline::update_sequence() {
|
||||
}
|
||||
}
|
||||
|
||||
int Timeline::get_snap_range() {
|
||||
return getFrameFromScreenPoint(10);
|
||||
}
|
||||
|
||||
bool Timeline::focused() {
|
||||
return (ui->headers->hasFocus() || ui->video_area->hasFocus() || ui->audio_area->hasFocus());
|
||||
}
|
||||
@@ -635,23 +640,29 @@ void Timeline::split_at_playhead() {
|
||||
if (split_selected) redraw_all_clips();
|
||||
}
|
||||
|
||||
void Timeline::snap_to_clip(long* l) {
|
||||
int limit = 10;
|
||||
bool Timeline::snap_to_point(long point, long* l) {
|
||||
int limit = get_snap_range();
|
||||
if (*l > point-limit-1 && *l < point+limit+1) {
|
||||
snap_point = point;
|
||||
*l = point;
|
||||
snapped = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Timeline::snap_to_clip(long* l, bool playhead_inclusive) {
|
||||
snapped = false;
|
||||
for (int i=0;i<sequence->clip_count();i++) {
|
||||
Clip* c = sequence->get_clip(i);
|
||||
if (*l > c->timeline_in-limit-1 &&
|
||||
*l < c->timeline_in+limit+1) {
|
||||
*l = c->timeline_in;
|
||||
snapped = true;
|
||||
snap_point = c->timeline_in;
|
||||
break;
|
||||
} else if (*l > c->timeline_out-limit-1 &&
|
||||
*l < c->timeline_out+limit+1) {
|
||||
*l = c->timeline_out;
|
||||
snapped = true;
|
||||
snap_point = c->timeline_out;
|
||||
break;
|
||||
if (snapping) {
|
||||
if (!playhead_inclusive || !snap_to_point(playhead, l)) {
|
||||
for (int i=0;i<sequence->clip_count();i++) {
|
||||
Clip* c = sequence->get_clip(i);
|
||||
if (snap_to_point(c->timeline_in, l)) {
|
||||
break;
|
||||
} else if (snap_to_point(c->timeline_out, l)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -71,10 +71,12 @@ public:
|
||||
void delete_areas_and_relink(QVector<Selection> areas);
|
||||
void update_sequence();
|
||||
|
||||
int get_snap_range();
|
||||
int getScreenPointFromFrame(long frame);
|
||||
long getFrameFromScreenPoint(int x);
|
||||
|
||||
void snap_to_clip(long* l);
|
||||
bool snap_to_point(long point, long* l);
|
||||
void snap_to_clip(long* l, bool playhead_inclusive);
|
||||
|
||||
long playhead;
|
||||
|
||||
@@ -95,6 +97,7 @@ public:
|
||||
QTimer playback_updater;
|
||||
|
||||
// shared information
|
||||
bool edit_tool_also_seeks;
|
||||
int tool;
|
||||
long cursor_frame;
|
||||
int cursor_track;
|
||||
|
||||
@@ -17,9 +17,7 @@ TimelineHeader::TimelineHeader(QWidget *parent) : QWidget(parent)
|
||||
|
||||
void set_playhead(QMouseEvent* event) {
|
||||
long frame = panel_timeline->getFrameFromScreenPoint(event->pos().x());
|
||||
if (panel_timeline->snapping) {
|
||||
panel_timeline->snap_to_clip(&frame);
|
||||
}
|
||||
panel_timeline->snap_to_clip(&frame, false);
|
||||
panel_timeline->seek(frame);
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
|
||||
+8
-15
@@ -214,7 +214,7 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) {
|
||||
}
|
||||
break;
|
||||
case TIMELINE_TOOL_EDIT:
|
||||
panel_timeline->seek(panel_timeline->drag_frame_start);
|
||||
if (panel_timeline->edit_tool_also_seeks) panel_timeline->seek(panel_timeline->drag_frame_start);
|
||||
panel_timeline->selecting = true;
|
||||
break;
|
||||
case TIMELINE_TOOL_RAZOR:
|
||||
@@ -374,7 +374,7 @@ void TimelineWidget::init_ghosts() {
|
||||
}
|
||||
|
||||
bool subvalidate_snapping(Ghost& g, long* frame_diff, long snap_point) {
|
||||
int snap_range = panel_timeline->getFrameFromScreenPoint(10);
|
||||
int snap_range = panel_timeline->get_snap_range();
|
||||
long in_validator = g.old_in + *frame_diff - snap_point;
|
||||
long out_validator = g.old_out + *frame_diff - snap_point;
|
||||
|
||||
@@ -598,18 +598,7 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
panel_timeline->cursor_track = getTrackFromScreenPoint(event->pos().y());
|
||||
|
||||
if (panel_timeline->tool == TIMELINE_TOOL_EDIT || panel_timeline->tool == TIMELINE_TOOL_RAZOR) {
|
||||
int limit = panel_timeline->getFrameFromScreenPoint(10);
|
||||
if (panel_timeline->snapping) {
|
||||
if (!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;
|
||||
panel_timeline->snapped = true;
|
||||
panel_timeline->snap_point = panel_timeline->playhead;
|
||||
} else {
|
||||
panel_timeline->snap_to_clip(&panel_timeline->cursor_frame);
|
||||
}
|
||||
}
|
||||
panel_timeline->snap_to_clip(&panel_timeline->cursor_frame, !panel_timeline->edit_tool_also_seeks || !panel_timeline->selecting);
|
||||
}
|
||||
if (panel_timeline->selecting) {
|
||||
int selection_count = 1 + qMax(panel_timeline->cursor_track, panel_timeline->drag_track_start) - qMin(panel_timeline->cursor_track, panel_timeline->drag_track_start);
|
||||
@@ -625,7 +614,11 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
|
||||
s->in = qMin(in, out);
|
||||
s->out = qMax(in, out);
|
||||
}
|
||||
panel_timeline->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame));
|
||||
if (panel_timeline->edit_tool_also_seeks) {
|
||||
panel_timeline->seek(qMin(panel_timeline->drag_frame_start, panel_timeline->cursor_frame));
|
||||
} else {
|
||||
panel_timeline->repaint_timeline();
|
||||
}
|
||||
} else if (panel_timeline->moving_init) {
|
||||
if (panel_timeline->moving_proc) {
|
||||
QPoint pos = event->pos();
|
||||
|
||||
Reference in New Issue
Block a user