diff --git a/icons/hand-disabled.png b/icons/hand-disabled.png
new file mode 100644
index 000000000..ec80df67a
Binary files /dev/null and b/icons/hand-disabled.png differ
diff --git a/icons/hand.png b/icons/hand.png
new file mode 100644
index 000000000..31cfea6fb
Binary files /dev/null and b/icons/hand.png differ
diff --git a/icons/icons.qrc b/icons/icons.qrc
index 8271d98bc..57624c16c 100644
--- a/icons/icons.qrc
+++ b/icons/icons.qrc
@@ -56,5 +56,7 @@
tri-left.png
tri-right.png
tri-up.png
+ hand.png
+ hand-disabled.png
diff --git a/mainwindow.cpp b/mainwindow.cpp
index adc24850e..43a9d7cbe 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -607,7 +607,11 @@ void MainWindow::on_actionToggle_Snapping_triggered()
void MainWindow::on_actionPointer_Tool_triggered()
{
- if (panel_timeline->focused()) panel_timeline->ui->toolArrowButton->click();
+ if (panel_timeline->focused()
+ || panel_effect_controls->keyframe_focus()
+ || panel_footage_viewer->is_focused()
+ || panel_sequence_viewer->is_focused())
+ panel_timeline->ui->toolArrowButton->click();
}
void MainWindow::on_actionRazor_Tool_triggered()
@@ -1061,3 +1065,11 @@ void MainWindow::on_actionMilliseconds_triggered() {
void MainWindow::on_actionEnable_Hover_Focus_triggered() {
config.hover_focus = !config.hover_focus;
}
+
+void MainWindow::on_actionHand_Tool_triggered() {
+ if (panel_timeline->focused()
+ || panel_effect_controls->keyframe_focus()
+ || panel_footage_viewer->is_focused()
+ || panel_sequence_viewer->is_focused())
+ panel_timeline->ui->toolHandButton->click();
+}
diff --git a/mainwindow.h b/mainwindow.h
index 048c30a7b..a1b380542 100644
--- a/mainwindow.h
+++ b/mainwindow.h
@@ -213,6 +213,8 @@ private slots:
void on_actionEnable_Hover_Focus_triggered();
+ void on_actionHand_Tool_triggered();
+
private:
Ui::MainWindow *ui;
void setup_layout(bool reset);
diff --git a/mainwindow.ui b/mainwindow.ui
index 6533a2453..fe24d5e23 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -176,6 +176,7 @@
+
@@ -948,6 +949,14 @@
F11
+
+
+ Hand Tool
+
+
+ H
+
+
diff --git a/panels/timeline.cpp b/panels/timeline.cpp
index b4c1abf0c..33fd1c9b9 100644
--- a/panels/timeline.cpp
+++ b/panels/timeline.cpp
@@ -69,6 +69,8 @@ Timeline::Timeline(QWidget *parent) :
transition_tool_proc(false),
transition_tool_pre_clip(-1),
transition_tool_post_clip(-1),
+ hand_moving(false),
+ block_repaints(false),
ui(new Ui::Timeline),
last_frame(0),
scroll(0)
@@ -102,6 +104,7 @@ Timeline::Timeline(QWidget *parent) :
tool_buttons.append(ui->toolRollingButton);
tool_buttons.append(ui->toolSlideButton);
tool_buttons.append(ui->toolTransitionButton);
+ tool_buttons.append(ui->toolHandButton);
ui->toolArrowButton->click();
@@ -420,42 +423,44 @@ bool Timeline::focused() {
}
void Timeline::repaint_timeline() {
- bool draw = true;
+ if (!block_repaints) {
+ bool draw = true;
- if (sequence != NULL
- && !ui->horizontalScrollBar->isSliderDown()
- && !ui->horizontalScrollBar->is_resizing()
- && panel_sequence_viewer->playing
- && !zoom_just_changed) {
- // auto scroll
- if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) {
- int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead);
- if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) {
- ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead));
- draw = false;
- }
- } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) {
- if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) {
- draw = false;
+ if (sequence != NULL
+ && !ui->horizontalScrollBar->isSliderDown()
+ && !ui->horizontalScrollBar->is_resizing()
+ && panel_sequence_viewer->playing
+ && !zoom_just_changed) {
+ // auto scroll
+ if (config.autoscroll == AUTOSCROLL_PAGE_SCROLL) {
+ int playhead_x = panel_timeline->getTimelineScreenPointFromFrame(sequence->playhead);
+ if (playhead_x < 0 || playhead_x > (ui->editAreas->width() - ui->videoScrollbar->width())) {
+ ui->horizontalScrollBar->setValue(getScreenPointFromFrame(zoom, sequence->playhead));
+ draw = false;
+ }
+ } else if (config.autoscroll == AUTOSCROLL_SMOOTH_SCROLL) {
+ if (center_scroll_to_playhead(ui->horizontalScrollBar, zoom, sequence->playhead)) {
+ draw = false;
+ }
}
}
- }
- zoom_just_changed = false;
+ zoom_just_changed = false;
- if (draw) {
- ui->headers->update();
- ui->video_area->update();
- ui->audio_area->update();
+ if (draw) {
+ ui->headers->update();
+ ui->video_area->update();
+ ui->audio_area->update();
- if (sequence != NULL) {
- long sequenceEndFrame = sequence->getEndFrame();
+ if (sequence != NULL) {
+ long sequenceEndFrame = sequence->getEndFrame();
- set_sb_max();
+ set_sb_max();
- if (last_frame != sequence->playhead) {
- ui->audio_monitor->update();
- last_frame = sequence->playhead;
+ if (last_frame != sequence->playhead) {
+ ui->audio_monitor->update();
+ last_frame = sequence->playhead;
+ }
}
}
}
@@ -1605,3 +1610,10 @@ void move_clip(ComboAction* ca, Clip *c, long iin, long iout, long iclip_in, int
}
}
}
+
+void Timeline::on_toolHandButton_clicked() {
+ decheck_tool_buttons(sender());
+ ui->timeline_area->setCursor(Qt::OpenHandCursor);
+ tool = TIMELINE_TOOL_HAND;
+ creating = false;
+}
diff --git a/panels/timeline.h b/panels/timeline.h
index a9633e723..d3ae3a7d1 100644
--- a/panels/timeline.h
+++ b/panels/timeline.h
@@ -185,6 +185,13 @@ public:
const EffectMeta* transition_tool_meta;
int transition_tool_side;
+ // hand tool variables
+ bool hand_moving;
+ int drag_x_start;
+ int drag_y_start;
+
+ bool block_repaints;
+
Ui::Timeline *ui;
void resizeEvent(QResizeEvent *event);
@@ -227,6 +234,8 @@ private slots:
void resize_move(double d);
+ void on_toolHandButton_clicked();
+
private:
void set_zoom_value(double v);
QVector tool_buttons;
diff --git a/panels/timeline.ui b/panels/timeline.ui
index aadfdb639..03c6daf0b 100644
--- a/panels/timeline.ui
+++ b/panels/timeline.ui
@@ -194,6 +194,22 @@
+ -
+
+
+
+
+
+
+ :/icons/hand.png
+ :/icons/hand-disabled.png
+
+
+
+ true
+
+
+
-
diff --git a/ui/keyframeview.cpp b/ui/keyframeview.cpp
index 88d10713f..c46dcb0c2 100644
--- a/ui/keyframeview.cpp
+++ b/ui/keyframeview.cpp
@@ -34,7 +34,8 @@ KeyframeView::KeyframeView(QWidget *parent) :
keys_selected(false),
select_rect(false),
x_scroll(0),
- y_scroll(0)
+ y_scroll(0),
+ scroll_drag(false)
{
setFocusPolicy(Qt::ClickFocus);
setMouseTracking(true);
@@ -193,12 +194,20 @@ void KeyframeView::resize_move(double d) {
header->update_zoom(header->get_zoom()*d);
}
-void KeyframeView::mousePressEvent(QMouseEvent *event) {
+void KeyframeView::mousePressEvent(QMouseEvent *event) {
+ rect_select_x = event->x();
+ rect_select_y = event->y();
+
+ if (panel_timeline->tool == TIMELINE_TOOL_HAND || event->buttons() & Qt::MiddleButton) {
+ scroll_drag = true;
+ return;
+ }
+
+ int mouse_x = event->x() + x_scroll;
+ int mouse_y = event->y();
int row_index = -1;
int keyframe_index = -1;
long frame_diff = 0;
- int mouse_x = event->x() + x_scroll;
- int mouse_y = event->y();
long frame_min = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x-KEYFRAME_SIZE);
drag_frame_start = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x);
long frame_max = getFrameFromScreenPoint(panel_effect_controls->zoom, mouse_x+KEYFRAME_SIZE);
@@ -235,9 +244,6 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
if (selected_rows.size() > 0) {
keys_selected = true;
- } else {
- rect_select_x = event->x();
- rect_select_y = event->y();
}
update();
@@ -248,7 +254,17 @@ void KeyframeView::mousePressEvent(QMouseEvent *event) {
}
void KeyframeView::mouseMoveEvent(QMouseEvent* event) {
- if (mousedown) {
+ if (panel_timeline->tool == TIMELINE_TOOL_HAND) {
+ setCursor(Qt::OpenHandCursor);
+ } else {
+ unsetCursor();
+ }
+ if (scroll_drag) {
+ panel_effect_controls->ui->horizontalScrollBar->setValue(panel_effect_controls->ui->horizontalScrollBar->value() + rect_select_x - event->pos().x());
+ panel_effect_controls->ui->verticalScrollBar->setValue(panel_effect_controls->ui->verticalScrollBar->value() + rect_select_y - event->pos().y());
+ rect_select_x = event->pos().x();
+ rect_select_y = event->pos().y();
+ } else if (mousedown) {
int mouse_x = event->x() + x_scroll;
if (keys_selected) {
// move keyframes
@@ -332,6 +348,7 @@ void KeyframeView::mouseReleaseEvent(QMouseEvent*) {
select_rect = false;
dragging = false;
mousedown = false;
+ scroll_drag = false;
panel_timeline->snapped = false;
update();
}
diff --git a/ui/keyframeview.h b/ui/keyframeview.h
index e565d6e61..6c3a72f31 100644
--- a/ui/keyframeview.h
+++ b/ui/keyframeview.h
@@ -39,7 +39,8 @@ private:
bool mousedown;
bool dragging;
bool keys_selected;
- bool select_rect;
+ bool select_rect;
+ bool scroll_drag;
bool keyframeIsSelected(EffectRow* row, int keyframe);
diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp
index 0506995af..e96b87fc2 100644
--- a/ui/timelinewidget.cpp
+++ b/ui/timelinewidget.cpp
@@ -698,7 +698,12 @@ void TimelineWidget::mousePressEvent(QMouseEvent *event) {
update_ui(false);
}
}
- break;
+ break;
+ case TIMELINE_TOOL_HAND:
+ panel_timeline->hand_moving = true;
+ panel_timeline->drag_x_start = pos.x();
+ panel_timeline->drag_y_start = pos.y();
+ break;
case TIMELINE_TOOL_EDIT:
if (config.edit_tool_also_seeks) panel_sequence_viewer->seek(panel_timeline->drag_frame_start);
panel_timeline->selecting = true;
@@ -1134,6 +1139,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
panel_timeline->rect_select_proc = false;
panel_timeline->transition_tool_init = false;
panel_timeline->transition_tool_proc = false;
+ panel_timeline->hand_moving = false;
pre_clips.clear();
post_clips.clear();
@@ -1630,6 +1636,16 @@ void TimelineWidget::mouseMoveEvent(QMouseEvent *event) {
} else {
panel_timeline->repaint_timeline();
}
+ } else if (panel_timeline->hand_moving) {
+ panel_timeline->block_repaints = true;
+ panel_timeline->ui->horizontalScrollBar->setValue(panel_timeline->ui->horizontalScrollBar->value() + panel_timeline->drag_x_start - event->pos().x());
+ scrollBar->setValue(scrollBar->value() + panel_timeline->drag_y_start - event->pos().y());
+ panel_timeline->block_repaints = false;
+
+ panel_timeline->repaint_timeline();
+
+ panel_timeline->drag_x_start = event->pos().x();
+ panel_timeline->drag_y_start = event->pos().y();
} else if (panel_timeline->moving_init) {
if (track_resizing) {
int diff = track_resize_mouse_cache - event->pos().y();
@@ -2603,7 +2619,11 @@ void TimelineWidget::paintEvent(QPaintEvent*) {
p.setPen(Qt::gray);
p.drawLine(cursor_x, cursor_y, cursor_x, cursor_y + panel_timeline->calculate_track_height(panel_timeline->cursor_track, -1));
}
- }
+ }
+}
+
+void TimelineWidget::resizeEvent(QResizeEvent *event) {
+ scrollBar->setPageStep(height());
}
bool TimelineWidget::is_track_visible(int track) {
diff --git a/ui/timelinewidget.h b/ui/timelinewidget.h
index 20e4bfea9..63d7ee067 100644
--- a/ui/timelinewidget.h
+++ b/ui/timelinewidget.h
@@ -33,6 +33,8 @@ public:
protected:
void paintEvent(QPaintEvent*);
+ void resizeEvent(QResizeEvent *event);
+
void mouseDoubleClickEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp
index 05156f77f..f84c27b6f 100644
--- a/ui/viewerwidget.cpp
+++ b/ui/viewerwidget.cpp
@@ -258,7 +258,7 @@ void ViewerWidget::move_gizmos(QMouseEvent *event, bool done) {
void ViewerWidget::mousePressEvent(QMouseEvent* event) {
if (waveform) {
seek_from_click(event->x());
- } else if (event->buttons() & Qt::MiddleButton) {
+ } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) {
container->dragScrollPress(event->pos());
} else {
drag_start_x = event->pos().x();
@@ -277,10 +277,14 @@ void ViewerWidget::mousePressEvent(QMouseEvent* event) {
}
void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
+ unsetCursor();
+ if (panel_timeline->tool == TIMELINE_TOOL_HAND) {
+ setCursor(Qt::OpenHandCursor);
+ }
if (dragging) {
if (waveform) {
seek_from_click(event->x());
- } else if (event->buttons() & Qt::MiddleButton) {
+ } else if (event->buttons() & Qt::MiddleButton || panel_timeline->tool == TIMELINE_TOOL_HAND) {
container->dragScrollMove(event->pos());
} else if (gizmos == NULL) {
QDrag* drag = new QDrag(this);
@@ -293,7 +297,6 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
move_gizmos(event, false);
}
} else {
- unsetCursor();
EffectGizmo* g = get_gizmo_from_mouse(event->pos().x(), event->pos().y());
if (g != NULL) {
if (g->get_cursor() > -1) {
@@ -304,7 +307,7 @@ void ViewerWidget::mouseMoveEvent(QMouseEvent* event) {
}
void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) {
- move_gizmos(event, true);
+ if (dragging) move_gizmos(event, true);
dragging = false;
}