From 7ceb5c091473c7510b9920f28ff50fd247dc8893 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Mon, 11 Apr 2022 19:49:50 -0700 Subject: [PATCH] timeline: implement track select tool Fixes #866 --- app/tool/tool.h | 3 + app/widget/timelinewidget/timelinewidget.cpp | 2 + app/widget/timelinewidget/tool/CMakeLists.txt | 2 + app/widget/timelinewidget/tool/pointer.cpp | 4 +- app/widget/timelinewidget/tool/pointer.h | 14 +-- .../timelinewidget/tool/trackselect.cpp | 96 +++++++++++++++++++ app/widget/timelinewidget/tool/trackselect.h | 42 ++++++++ .../timelinewidget/view/timelineview.cpp | 3 + app/widget/toolbar/toolbar.cpp | 3 + app/widget/toolbar/toolbar.h | 1 + app/window/mainwindow/mainmenu.cpp | 6 ++ app/window/mainwindow/mainmenu.h | 1 + 12 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 app/widget/timelinewidget/tool/trackselect.cpp create mode 100644 app/widget/timelinewidget/tool/trackselect.h diff --git a/app/tool/tool.h b/app/tool/tool.h index 90482062d..f6422e806 100644 --- a/app/tool/tool.h +++ b/app/tool/tool.h @@ -74,6 +74,9 @@ public: /// Add tool kAdd, + /// Track select tool + kTrackSelect, + kCount }; diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index af0844486..39850defc 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -41,6 +41,7 @@ #include "tool/rolling.h" #include "tool/slide.h" #include "tool/slip.h" +#include "tool/trackselect.h" #include "tool/transition.h" #include "tool/zoom.h" #include "tool/tool.h" @@ -100,6 +101,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : tools_.fill(nullptr); tools_.replace(olive::Tool::kPointer, new PointerTool(this)); + tools_.replace(olive::Tool::kTrackSelect, new TrackSelectTool(this)); tools_.replace(olive::Tool::kEdit, new EditTool(this)); tools_.replace(olive::Tool::kRipple, new RippleTool(this)); tools_.replace(olive::Tool::kRolling, new RollingTool(this)); diff --git a/app/widget/timelinewidget/tool/CMakeLists.txt b/app/widget/timelinewidget/tool/CMakeLists.txt index ca5a88918..8175a66cf 100644 --- a/app/widget/timelinewidget/tool/CMakeLists.txt +++ b/app/widget/timelinewidget/tool/CMakeLists.txt @@ -38,6 +38,8 @@ set(OLIVE_SOURCES widget/timelinewidget/tool/slide.h widget/timelinewidget/tool/slip.cpp widget/timelinewidget/tool/slip.h + widget/timelinewidget/tool/trackselect.cpp + widget/timelinewidget/tool/trackselect.h widget/timelinewidget/tool/transition.cpp widget/timelinewidget/tool/transition.h widget/timelinewidget/tool/tool.cpp diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index b82a8b83d..5b6be9e14 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -44,6 +44,7 @@ PointerTool::PointerTool(TimelineWidget *parent) : trimming_allowed_(true), track_movement_allowed_(true), gap_trimming_allowed_(false), + can_rubberband_select_(false), rubberband_selecting_(false) { } @@ -715,8 +716,7 @@ Timeline::MovementMode PointerTool::IsCursorInTrimHandle(Block *block, qreal cur } } -void PointerTool::InitiateDrag(Block *clicked_item, - Timeline::MovementMode trim_mode) +void PointerTool::InitiateDrag(Block *clicked_item, Timeline::MovementMode trim_mode) { InitiateDragInternal(clicked_item, trim_mode, false, false, false); } diff --git a/app/widget/timelinewidget/tool/pointer.h b/app/widget/timelinewidget/tool/pointer.h index ca23b7fd9..f64bd9b34 100644 --- a/app/widget/timelinewidget/tool/pointer.h +++ b/app/widget/timelinewidget/tool/pointer.h @@ -39,8 +39,7 @@ public: protected: virtual void FinishDrag(TimelineViewMouseEvent *event); - virtual void InitiateDrag(Block* clicked_item, - Timeline::MovementMode trim_mode); + virtual void InitiateDrag(Block* clicked_item, Timeline::MovementMode trim_mode); TimelineViewGhostItem* AddGhostFromBlock(Block *block, Timeline::MovementMode mode, bool check_if_exists = false); @@ -69,10 +68,8 @@ protected: bool dont_roll_trims, bool allow_nongap_rolling, bool slide_instead_of_moving); - const Timeline::MovementMode& drag_movement_mode() const - { - return drag_movement_mode_; - } + const Timeline::MovementMode& drag_movement_mode() const { return drag_movement_mode_; } + void set_drag_movement_mode(const Timeline::MovementMode &d) { drag_movement_mode_ = d; } void SetMovementAllowed(bool e) { @@ -94,6 +91,11 @@ protected: gap_trimming_allowed_ = e; } + void SetClickedItem(Block *b) + { + clicked_item_ = b; + } + private: Timeline::MovementMode IsCursorInTrimHandle(Block* block, qreal cursor_x); diff --git a/app/widget/timelinewidget/tool/trackselect.cpp b/app/widget/timelinewidget/tool/trackselect.cpp new file mode 100644 index 000000000..57a948ef3 --- /dev/null +++ b/app/widget/timelinewidget/tool/trackselect.cpp @@ -0,0 +1,96 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2021 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "trackselect.h" + +#include "node/block/gap/gap.h" +#include "node/output/track/track.h" +#include "widget/timelinewidget/timelinewidget.h" + +namespace olive { + +TrackSelectTool::TrackSelectTool(TimelineWidget *parent) : + PointerTool(parent) +{ +} + +void TrackSelectTool::MousePress(TimelineViewMouseEvent *event) +{ + QVector blocks; + bool forward = !(event->GetModifiers() & Qt::ControlModifier); + + parent()->DeselectAll(); + + if (event->GetModifiers() & Qt::ShiftModifier) { + // Track only + Track *track = parent()->GetTrackFromReference(event->GetTrack()); + if (track) { + SelectBlocksOnTrack(track, event, &blocks, forward); + } + } else { + // All tracks + foreach (Track *track, parent()->sequence()->GetTracks()) { + SelectBlocksOnTrack(track, event, &blocks, forward); + } + } + + if (!blocks.isEmpty()) { + parent()->SignalSelectedBlocks(blocks); + set_drag_movement_mode(Timeline::kMove); + SetClickedItem(blocks.first()); + drag_start_ = event->GetCoordinates(); + } else { + set_drag_movement_mode(Timeline::kNone); + } +} + +void TrackSelectTool::SelectBlocksOnTrack(Track *track, TimelineViewMouseEvent *event, QVector *blocks, bool forward) +{ + Block *b = track->NearestBlockBeforeOrAt(event->GetFrame()); + + if (!b && !track->Blocks().isEmpty() && !forward) { + // Fallback to first or last block in track + b = track->Blocks().last(); + } + + while (b) { + if (!dynamic_cast(b)) { + if (!blocks->contains(b)) { + parent()->AddSelection(b); + blocks->append(b); + } + + if (!(event->GetModifiers() & Qt::AltModifier)) { + if (ClipBlock *clip = dynamic_cast(b)) { + foreach (Block *link, clip->block_links()) { + if (!blocks->contains(link)) { + parent()->AddSelection(link); + blocks->append(link); + } + } + } + } + } + + b = forward ? b->next() : b->previous(); + } +} + +} diff --git a/app/widget/timelinewidget/tool/trackselect.h b/app/widget/timelinewidget/tool/trackselect.h new file mode 100644 index 000000000..1ff4e4a9f --- /dev/null +++ b/app/widget/timelinewidget/tool/trackselect.h @@ -0,0 +1,42 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2021 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef TRACKSELECTTOOL_H +#define TRACKSELECTTOOL_H + +#include "pointer.h" + +namespace olive { + +class TrackSelectTool : public PointerTool +{ +public: + TrackSelectTool(TimelineWidget *parent); + + virtual void MousePress(TimelineViewMouseEvent *event) override; + +private: + void SelectBlocksOnTrack(Track *track, TimelineViewMouseEvent *event, QVector *blocks, bool forward); + +}; + +} + +#endif // TRACKSELECTTOOL_H diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 97424c59a..3488a8e80 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -347,6 +347,9 @@ void TimelineView::ToolChangedEvent(Tool::Item tool) case Tool::kZoom: setCursor(Qt::CrossCursor); break; + case Tool::kTrackSelect: + setCursor(Qt::SizeHorCursor); // FIXME: Not the ideal cursor + break; default: unsetCursor(); } diff --git a/app/widget/toolbar/toolbar.cpp b/app/widget/toolbar/toolbar.cpp index 5b08edce7..ca3a04056 100644 --- a/app/widget/toolbar/toolbar.cpp +++ b/app/widget/toolbar/toolbar.cpp @@ -42,6 +42,7 @@ Toolbar::Toolbar(QWidget *parent) : // Create standard tool buttons btn_pointer_tool_ = CreateToolButton(Tool::kPointer); + btn_trackselect_tool_ = CreateToolButton(Tool::kTrackSelect); btn_edit_tool_ = CreateToolButton(Tool::kEdit); btn_ripple_tool_ = CreateToolButton(Tool::kRipple); btn_rolling_tool_ = CreateToolButton(Tool::kRolling); @@ -107,6 +108,7 @@ void Toolbar::resizeEvent(QResizeEvent *e) void Toolbar::Retranslate() { btn_pointer_tool_->setToolTip(tr("Pointer Tool")); + btn_trackselect_tool_->setToolTip(tr("Track Select Tool")); btn_edit_tool_->setToolTip(tr("Edit Tool")); btn_ripple_tool_->setToolTip(tr("Ripple Tool")); btn_rolling_tool_->setToolTip(tr("Rolling Tool")); @@ -124,6 +126,7 @@ void Toolbar::Retranslate() void Toolbar::UpdateIcons() { btn_pointer_tool_->setIcon(icon::ToolPointer); + btn_trackselect _tool_->setIcon(icon::TriRight); // FIXME: Procure real icon btn_edit_tool_->setIcon(icon::ToolEdit); btn_ripple_tool_->setIcon(icon::ToolRipple); btn_rolling_tool_->setIcon(icon::ToolRolling); diff --git a/app/widget/toolbar/toolbar.h b/app/widget/toolbar/toolbar.h index 271af43d6..16c1989f1 100644 --- a/app/widget/toolbar/toolbar.h +++ b/app/widget/toolbar/toolbar.h @@ -173,6 +173,7 @@ private: QList toolbar_btns_; ToolbarButton* btn_pointer_tool_; + ToolbarButton* btn_trackselect_tool_; ToolbarButton* btn_edit_tool_; ToolbarButton* btn_ripple_tool_; ToolbarButton* btn_rolling_tool_; diff --git a/app/window/mainwindow/mainmenu.cpp b/app/window/mainwindow/mainmenu.cpp index 276c698a2..c4ba08d5e 100644 --- a/app/window/mainwindow/mainmenu.cpp +++ b/app/window/mainwindow/mainmenu.cpp @@ -207,6 +207,11 @@ MainMenu::MainMenu(MainWindow *parent) : tools_pointer_item_->setData(Tool::kPointer); tools_group_->addAction(tools_pointer_item_); + tools_trackselect_item_ = tools_menu_->AddItem("trackselecttool", this, &MainMenu::ToolItemTriggered, tr("D")); + tools_trackselect_item_->setCheckable(true); + tools_trackselect_item_->setData(Tool::kTrackSelect); + tools_group_->addAction(tools_trackselect_item_); + tools_edit_item_ = tools_menu_->AddItem("edittool", this, &MainMenu::ToolItemTriggered, tr("X")); tools_edit_item_->setCheckable(true); tools_edit_item_->setData(Tool::kEdit); @@ -763,6 +768,7 @@ void MainMenu::Retranslate() // Tools menu tools_menu_->setTitle(tr("&Tools")); tools_pointer_item_->setText(tr("Pointer Tool")); + tools_trackselect_item_->setText(tr("Track Select Tool")); tools_edit_item_->setText(tr("Edit Tool")); tools_ripple_item_->setText(tr("Ripple Tool")); tools_rolling_item_->setText(tr("Rolling Tool")); diff --git a/app/window/mainwindow/mainmenu.h b/app/window/mainwindow/mainmenu.h index 748e7159f..ba5740f0b 100644 --- a/app/window/mainwindow/mainmenu.h +++ b/app/window/mainwindow/mainmenu.h @@ -272,6 +272,7 @@ private: Menu* tools_menu_; QActionGroup* tools_group_; QAction* tools_pointer_item_; + QAction* tools_trackselect_item_; QAction* tools_edit_item_; QAction* tools_ripple_item_; QAction* tools_rolling_item_;