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; }