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