From edc38ad8a2caa2efc90e63b21a157416f01ec55b Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 6 Apr 2020 00:05:09 +1000 Subject: [PATCH] timeline: implemented adding objects in the timeline (e.g. solid, title) --- app/core.cpp | 15 +++++- app/core.h | 21 ++++++-- app/panel/tool/tool.cpp | 10 ++-- app/tool/tool.h | 46 +++++++++++++++++ app/widget/timelinewidget/tool/add.cpp | 70 ++++++++++++++++++++++---- app/widget/toolbar/toolbar.cpp | 25 ++++++++- app/widget/toolbar/toolbar.h | 18 +++++++ 7 files changed, 186 insertions(+), 19 deletions(-) diff --git a/app/core.cpp b/app/core.cpp index 0d8fdc42b..2eabcf9ba 100644 --- a/app/core.cpp +++ b/app/core.cpp @@ -63,6 +63,7 @@ Core Core::instance_; Core::Core() : main_window_(nullptr), tool_(Tool::kPointer), + addable_object_(Tool::kAddableEmpty), snapping_(true), queue_autorecovery_(false) { @@ -187,12 +188,22 @@ void Core::ImportFiles(const QStringList &urls, ProjectViewModel* model, Folder* task_dialog->open(); } -const Tool::Item &Core::tool() +const Tool::Item &Core::tool() const { return tool_; } -const bool &Core::snapping() +const Tool::AddableObject &Core::selected_addable_object() const +{ + return addable_object_; +} + +void Core::SetSelectedAddableObject(const Tool::AddableObject &obj) +{ + addable_object_ = obj; +} + +const bool &Core::snapping() const { return snapping_; } diff --git a/app/core.h b/app/core.h index 2ebcdf001..7ca3708e5 100644 --- a/app/core.h +++ b/app/core.h @@ -105,12 +105,17 @@ public: /** * @brief Get the currently active tool */ - const Tool::Item& tool(); + const Tool::Item& tool() const; + + /** + * @brief Get the currently selected object that the add tool should make (if the add tool is active) + */ + const Tool::AddableObject& selected_addable_object() const; /** * @brief Get current snapping value */ - const bool& snapping(); + const bool& snapping() const; /** * @brief Get the currently active project @@ -264,6 +269,11 @@ public slots: */ void CreateNewSequence(); + /** + * @brief Set the currently selected object that the add tool should make + */ + void SetSelectedAddableObject(const Tool::AddableObject& obj); + signals: /** * @brief Signal emitted when a project is opened @@ -345,7 +355,12 @@ private: Tool::Item tool_; /** - * @brief Current snapping toggle + * @brief Currently active addable object + */ + Tool::AddableObject addable_object_; + + /** + * @brief Current snapping setting */ bool snapping_; diff --git a/app/panel/tool/tool.cpp b/app/panel/tool/tool.cpp index d05e8ea40..4992a61b2 100644 --- a/app/panel/tool/tool.cpp +++ b/app/panel/tool/tool.cpp @@ -36,11 +36,13 @@ ToolPanel::ToolPanel(QWidget *parent) : setWidget(t); - connect(t, SIGNAL(ToolChanged(const Tool::Item&)), Core::instance(), SLOT(SetTool(const Tool::Item&))); - connect(Core::instance(), SIGNAL(ToolChanged(const Tool::Item&)), t, SLOT(SetTool(const Tool::Item&))); + connect(t, &Toolbar::ToolChanged, Core::instance(), &Core::SetTool); + connect(Core::instance(), &Core::ToolChanged, t, &Toolbar::SetTool); - connect(t, SIGNAL(SnappingChanged(const bool&)), Core::instance(), SLOT(SetSnapping(const bool&))); - connect(Core::instance(), SIGNAL(SnappingChanged(const bool&)), t, SLOT(SetSnapping(const bool&))); + connect(t, &Toolbar::SnappingChanged, Core::instance(), &Core::SetSnapping); + connect(Core::instance(), &Core::SnappingChanged, t, &Toolbar::SetSnapping); + + connect(t, &Toolbar::AddableObjectChanged, Core::instance(), &Core::SetSelectedAddableObject); Retranslate(); } diff --git a/app/tool/tool.h b/app/tool/tool.h index 56bb115ae..781c73f6e 100644 --- a/app/tool/tool.h +++ b/app/tool/tool.h @@ -21,6 +21,9 @@ #ifndef TOOL_H #define TOOL_H +#include +#include + class Tool { public: /** @@ -69,6 +72,49 @@ public: kCount }; + + /** + * @brief Tools that can be added using the kAdd tool + */ + enum AddableObject { + /// An empty clip + kAddableEmpty, + + /// A video clip showing a generic video placeholder + kAddableBars, + + /// A video clip with a solid connected + kAddableSolid, + + /// A video clip with a title connected + kAddableTitle, + + /// An audio clip with a sine connected to it + kAddableTone, + + kAddableCount + }; + + static QString GetAddableObjectName(const AddableObject& a) + { + switch (a) { + case kAddableEmpty: + return QCoreApplication::translate("Tool", "Empty"); + case kAddableBars: + return QCoreApplication::translate("Tool", "Bars"); + case kAddableSolid: + return QCoreApplication::translate("Tool", "Solid"); + case kAddableTitle: + return QCoreApplication::translate("Tool", "Title"); + case kAddableTone: + return QCoreApplication::translate("Tool", "Tone"); + case kAddableCount: + break; + } + + return QCoreApplication::translate("Tool", "Unknown"); + } + }; #endif // TOOL_H diff --git a/app/widget/timelinewidget/tool/add.cpp b/app/widget/timelinewidget/tool/add.cpp index cde223fbf..1e6cb8126 100644 --- a/app/widget/timelinewidget/tool/add.cpp +++ b/app/widget/timelinewidget/tool/add.cpp @@ -1,6 +1,7 @@ #include "widget/timelinewidget/timelinewidget.h" #include "core.h" +#include "node/factory.h" #include "widget/nodeview/nodeviewundo.h" TimelineWidget::AddTool::AddTool(TimelineWidget *parent) : @@ -18,16 +19,37 @@ void TimelineWidget::AddTool::MousePress(TimelineViewMouseEvent *event) return; } - drag_start_point_ = event->GetFrame(); + Timeline::TrackType add_type = Timeline::kTrackTypeNone; - ghost_ = new TimelineViewGhostItem(); - ghost_->SetIn(drag_start_point_); - ghost_->SetOut(drag_start_point_); - ghost_->SetTrack(track); - ghost_->SetYCoords(parent()->GetTrackY(track), parent()->GetTrackHeight(track)); - parent()->AddGhost(ghost_); + switch (Core::instance()->selected_addable_object()) { + case ::Tool::kAddableBars: + case ::Tool::kAddableSolid: + case ::Tool::kAddableTitle: + add_type = Timeline::kTrackTypeVideo; + break; + case ::Tool::kAddableTone: + add_type = Timeline::kTrackTypeAudio; + break; + case ::Tool::kAddableEmpty: + // Leave as "none", which means this block can be placed on any track + break; + case ::Tool::kAddableCount: + return; + } - snap_points_.append(drag_start_point_); + if (add_type == Timeline::kTrackTypeNone + || add_type == track.type()) { + drag_start_point_ = event->GetFrame(); + + ghost_ = new TimelineViewGhostItem(); + ghost_->SetIn(drag_start_point_); + ghost_->SetOut(drag_start_point_); + ghost_->SetTrack(track); + ghost_->SetYCoords(parent()->GetTrackY(track), parent()->GetTrackHeight(track)); + parent()->AddGhost(ghost_); + + snap_points_.append(drag_start_point_); + } } void TimelineWidget::AddTool::MouseMove(TimelineViewMouseEvent *event) @@ -51,7 +73,11 @@ void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event) ClipBlock* clip = new ClipBlock(); clip->set_length_and_media_out(ghost_->AdjustedLength()); - new NodeAddCommand(static_cast(parent()->GetConnectedNode()->parent()), + clip->set_block_name(::Tool::GetAddableObjectName(Core::instance()->selected_addable_object())); + + NodeGraph* graph = static_cast(parent()->GetConnectedNode()->parent()); + + new NodeAddCommand(graph, clip, command); @@ -61,6 +87,32 @@ void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event) ghost_->GetAdjustedIn(), command); + switch (Core::instance()->selected_addable_object()) { + case ::Tool::kAddableEmpty: + // Empty, nothing to be done + break; + case ::Tool::kAddableSolid: + { + Node* solid = NodeFactory::CreateFromID(QStringLiteral("org.olivevideoeditor.Olive.solidgenerator")); + + new NodeAddCommand(graph, + solid, + command); + + new NodeEdgeAddCommand(solid->output(), clip->texture_input(), command); + break; + } + case ::Tool::kAddableBars: + case ::Tool::kAddableTitle: + case ::Tool::kAddableTone: + // Not implemented yet + qWarning() << "Unimplemented add object:" << Core::instance()->selected_addable_object(); + break; + case ::Tool::kAddableCount: + // Invalid value, do nothing + break; + } + Core::instance()->undo_stack()->push(command); } diff --git a/app/widget/toolbar/toolbar.cpp b/app/widget/toolbar/toolbar.cpp index bef30a4a7..15641d6e4 100644 --- a/app/widget/toolbar/toolbar.cpp +++ b/app/widget/toolbar/toolbar.cpp @@ -25,6 +25,7 @@ #include #include +#include "widget/menu/menu.h" #include "ui/icons/icons.h" Toolbar::Toolbar(QWidget *parent) : @@ -49,7 +50,10 @@ Toolbar::Toolbar(QWidget *parent) : // Create snapping button, which is not actually a tool, it's a toggle option btn_snapping_toggle_ = CreateNonToolButton(); - connect(btn_snapping_toggle_, SIGNAL(clicked(bool)), this, SLOT(SnappingButtonClicked(bool))); + connect(btn_snapping_toggle_, &QPushButton::clicked, this, &Toolbar::SnappingButtonClicked); + + // Connect add button to menu signal + connect(btn_add_, &QPushButton::clicked, this, &Toolbar::AddButtonClicked); Retranslate(); UpdateIcons(); @@ -160,3 +164,22 @@ void Toolbar::SnappingButtonClicked(bool b) { emit SnappingChanged(b); } + +void Toolbar::AddButtonClicked() +{ + QMenu m(this); + + for (int i=0;i(i))); + action->setData(i); + } + + connect(&m, &QMenu::triggered, this, &Toolbar::AddMenuItemTriggered); + + m.exec(QCursor::pos()); +} + +void Toolbar::AddMenuItemTriggered(QAction* a) +{ + emit AddableObjectChanged(static_cast(a->data().toInt())); +} diff --git a/app/widget/toolbar/toolbar.h b/app/widget/toolbar/toolbar.h index 1444b5d80..b39e3e67d 100644 --- a/app/widget/toolbar/toolbar.h +++ b/app/widget/toolbar/toolbar.h @@ -106,6 +106,11 @@ signals: */ void SnappingChanged(const bool& b); + /** + * @brief Emitted when the addable object is changed from the add tool menu + */ + void AddableObjectChanged(const Tool::AddableObject& obj); + private: /** * @brief Reset all strings based on the currently selected language @@ -195,6 +200,19 @@ private slots: * The new snapping value received from the sender's clicked signal */ void SnappingButtonClicked(bool b); + + /** + * @brief Receiver for the add button + * + * The add button pops up a list for which object to create. + */ + void AddButtonClicked(); + + /** + * @brief Receiver for the menu created by AddButtonClicked() + */ + void AddMenuItemTriggered(QAction* a); + }; #endif // TOOLBAR_H