diff --git a/app/widget/timelineview/CMakeLists.txt b/app/widget/timelineview/CMakeLists.txt index 02642a2cb..db2aaaa44 100644 --- a/app/widget/timelineview/CMakeLists.txt +++ b/app/widget/timelineview/CMakeLists.txt @@ -14,6 +14,8 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +add_subdirectory(tool) + set(OLIVE_SOURCES ${OLIVE_SOURCES} widget/timelineview/timelineplayhead.h diff --git a/app/widget/timelineview/timelineplayhead.cpp b/app/widget/timelineview/timelineplayhead.cpp index e9eac8c9e..4b45e6e82 100644 --- a/app/widget/timelineview/timelineplayhead.cpp +++ b/app/widget/timelineview/timelineplayhead.cpp @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "timelineplayhead.h" TimelinePlayhead::TimelinePlayhead() diff --git a/app/widget/timelineview/timelineplayhead.h b/app/widget/timelineview/timelineplayhead.h index 0ceaa99d3..30a8ff285 100644 --- a/app/widget/timelineview/timelineplayhead.h +++ b/app/widget/timelineview/timelineplayhead.h @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 TIMELINEPLAYHEADSTYLE_H #define TIMELINEPLAYHEADSTYLE_H diff --git a/app/widget/timelineview/timelineview.cpp b/app/widget/timelineview/timelineview.cpp index 57f94e045..6d5e2dd03 100644 --- a/app/widget/timelineview/timelineview.cpp +++ b/app/widget/timelineview/timelineview.cpp @@ -31,6 +31,8 @@ TimelineView::TimelineView(QWidget *parent) : QGraphicsView(parent), + pointer_tool_(this), + import_tool_(this), playhead_(0), dragging_(false) { @@ -102,152 +104,49 @@ void TimelineView::SetTime(const int64_t time) void TimelineView::mousePressEvent(QMouseEvent *event) { - QGraphicsView::mousePressEvent(event); + pointer_tool_.MousePress(event); } void TimelineView::mouseMoveEvent(QMouseEvent *event) { - QGraphicsView::mouseMoveEvent(event); - - if (!dragging_) { - // Let's see if there's anything selected to drag - if (itemAt(event->pos()) != nullptr) { - QList selected_items = scene_.selectedItems(); - - foreach (QGraphicsItem* item, selected_items) { - TimelineViewGhostItem* ghost = new TimelineViewGhostItem(); - TimelineViewClipItem* clip_item = static_cast(item); - - ClipBlock* clip = clip_item->clip(); - - ghost->SetIn(clip->in()); - ghost->SetOut(clip->out()); - ghost->SetScale(scale_); - - ghost->setPos(clip_item->pos()); - - ghost_items_.append(ghost); - - scene_.addItem(ghost); - } - - drag_start_ = event->pos(); - } - - dragging_ = true; - } else if (!ghost_items_.isEmpty()) { - QPoint movement = event->pos() - drag_start_; - - rational time_movement = ScreenToTime(movement.x()); - - // Validate movement - foreach (TimelineViewGhostItem* ghost, ghost_items_) { - rational validator = ghost->In() + time_movement; - if (validator < 0) { - time_movement = rational(0) - ghost->In(); - } - } - - // Perform movement - foreach (TimelineViewGhostItem* ghost, ghost_items_) { - ghost->SetInAdjustment(time_movement); - ghost->SetOutAdjustment(time_movement); - } - } + pointer_tool_.MouseMove(event); } void TimelineView::mouseReleaseEvent(QMouseEvent *event) { - QGraphicsView::mouseReleaseEvent(event); - - ClearGhosts(); - - dragging_ = false; + pointer_tool_.MouseRelease(event); } void TimelineView::dragEnterEvent(QDragEnterEvent *event) { - QStringList mime_formats = event->mimeData()->formats(); - - // Listen for MIME data from a ProjectViewModel - if (mime_formats.contains("application/x-oliveprojectitemdata")) { - // FIXME: Implement audio insertion - - // Data is drag/drop data from a ProjectViewModel - QByteArray model_data = event->mimeData()->data("application/x-oliveprojectitemdata"); - - // Use QDataStream to deserialize the data - QDataStream stream(&model_data, QIODevice::ReadOnly); - - // Variables to deserialize into - quintptr item_ptr; - int r; - - while (!stream.atEnd()) { - stream >> r >> item_ptr; - - // Get Item object - Item* item = reinterpret_cast(item_ptr); - - // Check if Item is Footage - if (item->type() == Item::kFootage) { - // If the Item is Footage, we can create a Ghost from it - Footage* footage = static_cast(item); - - StreamPtr stream = footage->stream(0); - - TimelineViewGhostItem* ghost = new TimelineViewGhostItem(); - - rational footage_duration(stream->timebase().numerator() * stream->duration(), - stream->timebase().denominator()); - - ghost->SetIn(0); - ghost->SetOut(footage_duration); - ghost->SetScale(scale_); - ghost->SetStream(stream); - - ghost_items_.append(ghost); - - scene_.addItem(ghost); - } - } - - event->accept(); - } else { - // FIXME: Implement dropping from file - event->ignore(); - } + import_tool_.DragEnter(event); } void TimelineView::dragMoveEvent(QDragMoveEvent *event) { - if (ghost_items_.isEmpty()) { - event->ignore(); - } else { - event->accept(); - } + import_tool_.DragMove(event); } void TimelineView::dragLeaveEvent(QDragLeaveEvent *event) { - if (ghost_items_.isEmpty()) { - event->ignore(); - } else { - ClearGhosts(); - - event->accept(); - } + import_tool_.DragLeave(event); } void TimelineView::dropEvent(QDropEvent *event) { - if (ghost_items_.isEmpty()) { - event->ignore(); - } else { - ClearGhosts(); + import_tool_.DragDrop(event); +} - event->accept(); - } +void TimelineView::AddGhost(TimelineViewGhostItem *ghost) +{ + ghost->SetScale(scale_); + ghost_items_.append(ghost); + scene_.addItem(ghost); +} + +bool TimelineView::HasGhosts() +{ + return !ghost_items_.isEmpty(); } rational TimelineView::ScreenToTime(const int &x) @@ -269,3 +168,29 @@ void TimelineView::ClearGhosts() ghost_items_.clear(); } } + +TimelineView::Tool::Tool(TimelineView *parent) : + parent_(parent) +{ +} + +TimelineView::Tool::~Tool(){} + +void TimelineView::Tool::MousePress(QMouseEvent *){} + +void TimelineView::Tool::MouseMove(QMouseEvent *){} + +void TimelineView::Tool::MouseRelease(QMouseEvent *){} + +void TimelineView::Tool::DragEnter(QDragEnterEvent *){} + +void TimelineView::Tool::DragMove(QDragMoveEvent *){} + +void TimelineView::Tool::DragLeave(QDragLeaveEvent *){} + +void TimelineView::Tool::DragDrop(QDropEvent *){} + +TimelineView *TimelineView::Tool::parent() +{ + return parent_; +} diff --git a/app/widget/timelineview/timelineview.h b/app/widget/timelineview/timelineview.h index 615d78ae8..79c0a0036 100644 --- a/app/widget/timelineview/timelineview.h +++ b/app/widget/timelineview/timelineview.h @@ -22,6 +22,10 @@ #define TIMELINEVIEW_H #include +#include +#include +#include +#include #include "node/block/clip/clip.h" #include "timelineviewclipitem.h" @@ -56,6 +60,56 @@ protected: virtual void dropEvent(QDropEvent *event) override; private: + + class Tool + { + public: + Tool(TimelineView* parent); + virtual ~Tool(); + + virtual void MousePress(QMouseEvent *event); + virtual void MouseMove(QMouseEvent *event); + virtual void MouseRelease(QMouseEvent *event); + + virtual void DragEnter(QDragEnterEvent *event); + virtual void DragMove(QDragMoveEvent *event); + virtual void DragLeave(QDragLeaveEvent *event); + virtual void DragDrop(QDropEvent *event); + + TimelineView* parent(); + + private: + TimelineView* parent_; + }; + + class PointerTool : public Tool + { + public: + PointerTool(TimelineView* parent); + + virtual void MousePress(QMouseEvent *event); + virtual void MouseMove(QMouseEvent *event); + virtual void MouseRelease(QMouseEvent *event); + }; + + class ImportTool : public Tool + { + public: + ImportTool(TimelineView* parent); + + virtual void DragEnter(QDragEnterEvent *event) override; + virtual void DragMove(QDragMoveEvent *event) override; + virtual void DragLeave(QDragLeaveEvent *event) override; + virtual void DragDrop(QDropEvent *event) override; + }; + + PointerTool pointer_tool_; + ImportTool import_tool_; + + void AddGhost(TimelineViewGhostItem* ghost); + + bool HasGhosts(); + rational ScreenToTime(const int& x); void ClearGhosts(); diff --git a/app/widget/timelineview/timelineviewplayheaditem.cpp b/app/widget/timelineview/timelineviewplayheaditem.cpp index dabbcf6e4..66fce5ba9 100644 --- a/app/widget/timelineview/timelineviewplayheaditem.cpp +++ b/app/widget/timelineview/timelineviewplayheaditem.cpp @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "timelineviewplayheaditem.h" #include diff --git a/app/widget/timelineview/timelineviewplayheaditem.h b/app/widget/timelineview/timelineviewplayheaditem.h index d7f325c9d..75a6e7504 100644 --- a/app/widget/timelineview/timelineviewplayheaditem.h +++ b/app/widget/timelineview/timelineviewplayheaditem.h @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 TIMELINEVIEWPLAYHEADITEM_H #define TIMELINEVIEWPLAYHEADITEM_H diff --git a/app/widget/timelineview/timelineviewrect.cpp b/app/widget/timelineview/timelineviewrect.cpp index 4e6355eb4..90a22df8c 100644 --- a/app/widget/timelineview/timelineviewrect.cpp +++ b/app/widget/timelineview/timelineviewrect.cpp @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "timelineviewrect.h" TimelineViewRect::TimelineViewRect(QGraphicsItem* parent) : diff --git a/app/widget/timelineview/timelineviewrect.h b/app/widget/timelineview/timelineviewrect.h index e1dcdf1d4..97e9862a2 100644 --- a/app/widget/timelineview/timelineviewrect.h +++ b/app/widget/timelineview/timelineviewrect.h @@ -1,3 +1,23 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 TIMELINEVIEWRECT_H #define TIMELINEVIEWRECT_H diff --git a/app/widget/timelineview/tool/CMakeLists.txt b/app/widget/timelineview/tool/CMakeLists.txt new file mode 100644 index 000000000..9eadd9514 --- /dev/null +++ b/app/widget/timelineview/tool/CMakeLists.txt @@ -0,0 +1,22 @@ +# Olive - Non-Linear Video Editor +# Copyright (C) 2019 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 . + +set(OLIVE_SOURCES + ${OLIVE_SOURCES} + widget/timelineview/tool/import.cpp + widget/timelineview/tool/pointer.cpp + PARENT_SCOPE +) diff --git a/app/widget/timelineview/tool/import.cpp b/app/widget/timelineview/tool/import.cpp new file mode 100644 index 000000000..c6851adf9 --- /dev/null +++ b/app/widget/timelineview/tool/import.cpp @@ -0,0 +1,110 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "widget/timelineview/timelineview.h" + +#include + +TimelineView::ImportTool::ImportTool(TimelineView *parent) : + Tool(parent) +{ +} + +void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event) +{ + QStringList mime_formats = event->mimeData()->formats(); + + // Listen for MIME data from a ProjectViewModel + if (mime_formats.contains("application/x-oliveprojectitemdata")) { + // FIXME: Implement audio insertion + + // Data is drag/drop data from a ProjectViewModel + QByteArray model_data = event->mimeData()->data("application/x-oliveprojectitemdata"); + + // Use QDataStream to deserialize the data + QDataStream stream(&model_data, QIODevice::ReadOnly); + + // Variables to deserialize into + quintptr item_ptr; + int r; + + while (!stream.atEnd()) { + stream >> r >> item_ptr; + + // Get Item object + Item* item = reinterpret_cast(item_ptr); + + // Check if Item is Footage + if (item->type() == Item::kFootage) { + // If the Item is Footage, we can create a Ghost from it + Footage* footage = static_cast(item); + + StreamPtr stream = footage->stream(0); + + TimelineViewGhostItem* ghost = new TimelineViewGhostItem(); + + rational footage_duration(stream->timebase().numerator() * stream->duration(), + stream->timebase().denominator()); + + ghost->SetIn(0); + ghost->SetOut(footage_duration); + ghost->SetStream(stream); + + parent()->AddGhost(ghost); + } + } + + event->accept(); + } else { + // FIXME: Implement dropping from file + event->ignore(); + } +} + +void TimelineView::ImportTool::DragMove(QDragMoveEvent *event) +{ + if (parent()->HasGhosts()) { + event->accept(); + } else { + event->ignore(); + } +} + +void TimelineView::ImportTool::DragLeave(QDragLeaveEvent *event) +{ + if (parent()->HasGhosts()) { + parent()->ClearGhosts(); + + event->accept(); + } else { + event->ignore(); + } +} + +void TimelineView::ImportTool::DragDrop(QDropEvent *event) +{ + if (parent()->HasGhosts()) { + parent()->ClearGhosts(); + + event->accept(); + } else { + event->ignore(); + } +} diff --git a/app/widget/timelineview/tool/pointer.cpp b/app/widget/timelineview/tool/pointer.cpp new file mode 100644 index 000000000..511f99839 --- /dev/null +++ b/app/widget/timelineview/tool/pointer.cpp @@ -0,0 +1,109 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 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 "widget/timelineview/timelineview.h" + +TimelineView::PointerTool::PointerTool(TimelineView *parent) : + Tool(parent) +{ +} + +void FlipControlAndShiftModifiers(QMouseEvent* e) { + if (e->modifiers() & Qt::ControlModifier & Qt::ShiftModifier) { + return; + } + + if (e->modifiers() & Qt::ShiftModifier) { + e->setModifiers((e->modifiers() | Qt::ControlModifier) & ~Qt::ShiftModifier); + } else if (e->modifiers() & Qt::ControlModifier) { + e->setModifiers((e->modifiers() | Qt::ShiftModifier) & ~Qt::ControlModifier); + } +} + +void TimelineView::PointerTool::MousePress(QMouseEvent *event) +{ + FlipControlAndShiftModifiers(event); + + parent()->QGraphicsView::mousePressEvent(event); +} + +void TimelineView::PointerTool::MouseMove(QMouseEvent *event) +{ + FlipControlAndShiftModifiers(event); + + parent()->QGraphicsView::mouseMoveEvent(event); + + if (!parent()->dragging_) { + // Let's see if there's anything selected to drag + if (parent()->itemAt(event->pos()) != nullptr) { + QList selected_items = parent()->scene_.selectedItems(); + + foreach (QGraphicsItem* item, selected_items) { + TimelineViewGhostItem* ghost = new TimelineViewGhostItem(); + TimelineViewClipItem* clip_item = static_cast(item); + + ClipBlock* clip = clip_item->clip(); + + ghost->SetIn(clip->in()); + ghost->SetOut(clip->out()); + ghost->SetScale(parent()->scale_); + + ghost->setPos(clip_item->pos()); + + parent()->ghost_items_.append(ghost); + + parent()->scene_.addItem(ghost); + } + + parent()->drag_start_ = event->pos(); + } + + parent()->dragging_ = true; + } else if (!parent()->ghost_items_.isEmpty()) { + QPoint movement = event->pos() - parent()->drag_start_; + + rational time_movement = parent()->ScreenToTime(movement.x()); + + // Validate movement + foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) { + rational validator = ghost->In() + time_movement; + if (validator < 0) { + time_movement = rational(0) - ghost->In(); + } + } + + // Perform movement + foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) { + ghost->SetInAdjustment(time_movement); + ghost->SetOutAdjustment(time_movement); + } + } +} + +void TimelineView::PointerTool::MouseRelease(QMouseEvent *event) +{ + FlipControlAndShiftModifiers(event); + + parent()->QGraphicsView::mouseReleaseEvent(event); + + parent()->ClearGhosts(); + + parent()->dragging_ = false; +}