From 6b24ac69d6f071a354ba3f2cf1387e6b599bafdb Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 22 Aug 2019 14:52:52 +1000 Subject: [PATCH] validations added for moving and trimming --- app/node/block/clip/clip.cpp | 2 - app/panel/timeline/timeline.cpp | 2 +- app/widget/timelineview/timelineview.h | 40 +++++++++++++ .../timelineview/timelineviewghostitem.cpp | 18 ++---- .../timelineview/timelineviewghostitem.h | 5 -- app/widget/timelineview/tool/import.cpp | 5 +- app/widget/timelineview/tool/pointer.cpp | 18 +++--- app/widget/timelineview/tool/tool.cpp | 57 +++++++++++++++++-- 8 files changed, 114 insertions(+), 33 deletions(-) diff --git a/app/node/block/clip/clip.cpp b/app/node/block/clip/clip.cpp index 60d8e0039..c6619d8f6 100644 --- a/app/node/block/clip/clip.cpp +++ b/app/node/block/clip/clip.cpp @@ -20,8 +20,6 @@ #include "clip.h" -#include - ClipBlock::ClipBlock() { texture_input_ = new NodeInput("tex_in"); diff --git a/app/panel/timeline/timeline.cpp b/app/panel/timeline/timeline.cpp index a4e38375a..477aa762c 100644 --- a/app/panel/timeline/timeline.cpp +++ b/app/panel/timeline/timeline.cpp @@ -42,7 +42,7 @@ TimelinePanel::TimelinePanel(QWidget *parent) : connect(view_->horizontalScrollBar(), SIGNAL(valueChanged(int)), ruler_, SLOT(SetScroll(int))); connect(ruler_, SIGNAL(TimeChanged(const int64_t&)), view_, SLOT(SetTime(const int64_t&))); - // FIXME Magic number + // FIXME: Magic number SetScale(90.0); Retranslate(); diff --git a/app/widget/timelineview/timelineview.h b/app/widget/timelineview/timelineview.h index 5bf2c871a..57af1831b 100644 --- a/app/widget/timelineview/timelineview.h +++ b/app/widget/timelineview/timelineview.h @@ -94,13 +94,53 @@ private: TimelineView* parent(); protected: + /** + * @brief Convert a integer screen point to a float scene point + * + * Useful for converting a mouse coordinate provided by a QMouseEvent to a inner-timeline scene position (the + * coordinates that the graphics items use) + */ QPointF GetScenePos(const QPoint& screen_pos); + /** + * @brief Retrieve the QGraphicsItem at a particular scene position + * + * Requires a float-based scene position. If you have a screen position, use GetScenePos() first to convert it to a + * scene position + */ QGraphicsItem* GetItemAtScenePos(const QPointF& scene_pos); + /** + * @brief Validates Ghosts that are moving horizontally (time-based) + * + * Validation is the process of ensuring that whatever movements the user is making are "valid" and "legal". This + * function's validation ensures that no Ghost's in point ends up in a negative timecode. + */ rational ValidateFrameMovement(rational movement, const QVector ghosts); + + /** + * @brief Validates Ghosts that are moving vertically (track-based) + * + * This function's validation ensures that no Ghost's track ends up in a negative (non-existent) track. + */ int ValidateTrackMovement(int movement, const QVector ghosts); + /** + * @brief Validates Ghosts that are getting their in points trimmed + * + * Assumes ghost->data() is a Block. Ensures no Ghost's in point becomes a negative timecode. Also ensures no + * Ghost's length becomes 0 or negative. + */ + rational ValidateInTrimming(rational movement, const QVector ghosts); + + /** + * @brief Validates Ghosts that are getting their out points trimmed + * + * Assumes ghost->data() is a Block. Ensures no Ghost's in point becomes a negative timecode. Also ensures no + * Ghost's length becomes 0 or negative. + */ + rational ValidateOutTrimming(rational movement, const QVector ghosts); + bool dragging_; QPointF drag_start_; diff --git a/app/widget/timelineview/timelineviewghostitem.cpp b/app/widget/timelineview/timelineviewghostitem.cpp index 5d3fdbb9b..48a8668f4 100644 --- a/app/widget/timelineview/timelineviewghostitem.cpp +++ b/app/widget/timelineview/timelineviewghostitem.cpp @@ -24,7 +24,11 @@ TimelineViewGhostItem::TimelineViewGhostItem(QGraphicsItem *parent) : TimelineViewRect(parent), - stream_(nullptr) + in_adj_(0), + out_adj_(0), + track_adj_(0), + stream_(nullptr), + mode_(kNone) { setBrush(Qt::NoBrush); setPen(QPen(Qt::yellow, 2)); // FIXME: Make customizable via CSS @@ -43,7 +47,7 @@ TimelineViewGhostItem *TimelineViewGhostItem::FromClip(TimelineViewClipItem *cli ghost->SetIn(clip->in()); ghost->SetOut(clip->out()); - ghost->SetData(Node::PtrToValue(clip)); + ghost->setData(0, Node::PtrToValue(clip)); return ghost; } @@ -141,16 +145,6 @@ void TimelineViewGhostItem::SetMode(const TimelineViewGhostItem::Mode &mode) mode_ = mode; } -const QVariant &TimelineViewGhostItem::data() const -{ - return data_; -} - -void TimelineViewGhostItem::SetData(const QVariant &data) -{ - data_ = data; -} - void TimelineViewGhostItem::UpdateRect() { rational length = GetAdjustedOut() - GetAdjustedIn(); diff --git a/app/widget/timelineview/timelineviewghostitem.h b/app/widget/timelineview/timelineviewghostitem.h index df579cbfd..43109b7d9 100644 --- a/app/widget/timelineview/timelineviewghostitem.h +++ b/app/widget/timelineview/timelineviewghostitem.h @@ -68,9 +68,6 @@ public: const Mode& mode() const; void SetMode(const Mode& mode); - const QVariant& data() const; - void SetData(const QVariant& data); - virtual void UpdateRect() override; protected: @@ -86,8 +83,6 @@ private: StreamPtr stream_; - QVariant data_; - Mode mode_; }; diff --git a/app/widget/timelineview/tool/import.cpp b/app/widget/timelineview/tool/import.cpp index 3b296d7a3..6a924b8a2 100644 --- a/app/widget/timelineview/tool/import.cpp +++ b/app/widget/timelineview/tool/import.cpp @@ -77,7 +77,8 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event) ghost->SetIn(ghost_start); ghost->SetOut(ghost_start + footage_duration); - ghost->SetData(QVariant::fromValue(stream)); + ghost->setData(0, QVariant::fromValue(stream)); + ghost->SetMode(TimelineViewGhostItem::kMove); parent()->AddGhost(ghost); @@ -151,7 +152,7 @@ void TimelineView::ImportTool::DragDrop(QDropEvent *event) media->setParent(&node_memory_manager); clip->set_length(ghost->Length()); - media->SetFootage(ghost->data().value()->footage()); + media->SetFootage(ghost->data(0).value()->footage()); NodeParam::ConnectEdge(media->texture_output(), clip->texture_input()); diff --git a/app/widget/timelineview/tool/pointer.cpp b/app/widget/timelineview/tool/pointer.cpp index d8ba7e832..252fcf0cc 100644 --- a/app/widget/timelineview/tool/pointer.cpp +++ b/app/widget/timelineview/tool/pointer.cpp @@ -112,6 +112,8 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event) // Validate movement time_movement = ValidateFrameMovement(time_movement, parent()->ghost_items_); + time_movement = ValidateInTrimming(time_movement, parent()->ghost_items_); + time_movement = ValidateOutTrimming(time_movement, parent()->ghost_items_); track_movement = ValidateTrackMovement(track_movement, parent()->ghost_items_); // Perform movement @@ -126,15 +128,17 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event) ghost->SetOutAdjustment(time_movement); break; case TimelineViewGhostItem::kMove: + { ghost->SetInAdjustment(time_movement); ghost->SetOutAdjustment(time_movement); + + ghost->SetTrackAdjustment(track_movement); + int track = ghost->GetAdjustedTrack(); + ghost->SetY(parent()->GetTrackY(track)); + ghost->SetHeight(parent()->GetTrackHeight(track)); break; } - - ghost->SetTrackAdjustment(track_movement); - int track = ghost->GetAdjustedTrack(); - ghost->SetY(parent()->GetTrackY(track)); - ghost->SetHeight(parent()->GetTrackHeight(track)); + } } } } @@ -148,7 +152,7 @@ void TimelineView::PointerTool::MouseRelease(QMouseEvent *event) QObject block_memory_manager; foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) { - Block* b = Node::ValueToPtr(ghost->data()); + Block* b = Node::ValueToPtr(ghost->data(0)); // Replace old Block with a new Gap GapBlock* gap = new GapBlock(); @@ -159,7 +163,7 @@ void TimelineView::PointerTool::MouseRelease(QMouseEvent *event) } foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) { - Block* b = Node::ValueToPtr(ghost->data()); + Block* b = Node::ValueToPtr(ghost->data(0)); if (ghost->mode() == TimelineViewGhostItem::kTrimIn || ghost->mode() == TimelineViewGhostItem::kTrimOut) { // If we were trimming, we'll need to change the length diff --git a/app/widget/timelineview/tool/tool.cpp b/app/widget/timelineview/tool/tool.cpp index 73a6328f3..6bace9ae1 100644 --- a/app/widget/timelineview/tool/tool.cpp +++ b/app/widget/timelineview/tool/tool.cpp @@ -60,9 +60,12 @@ QGraphicsItem *TimelineView::Tool::GetItemAtScenePos(const QPointF &scene_pos) rational TimelineView::Tool::ValidateFrameMovement(rational movement, const QVector ghosts) { foreach (TimelineViewGhostItem* ghost, ghosts) { + if (ghost->mode() != TimelineViewGhostItem::kMove) { + continue; + } + // Prevents any ghosts from going below 0:00:00 time - rational validator = ghost->In() + movement; - if (validator < 0) { + if (ghost->In() + movement < 0) { movement = -ghost->In(); } } @@ -74,11 +77,57 @@ int TimelineView::Tool::ValidateTrackMovement(int movement, const QVectorTrack() + movement; - if (validator < 0) { + if (ghost->Track() + movement < 0) { + if (ghost->mode() != TimelineViewGhostItem::kMove) { + continue; + } + movement = -ghost->Track(); } } return movement; } + +rational TimelineView::Tool::ValidateInTrimming(rational movement, const QVector ghosts) +{ + foreach (TimelineViewGhostItem* ghost, ghosts) { + if (ghost->mode() != TimelineViewGhostItem::kTrimIn) { + continue; + } + + Block* block = Node::ValueToPtr(ghost->data(0)); + + // Prevents any media_in points from becoming negative + if (block->media_in() + movement < 0) { + movement = -block->media_in(); + } + + // Prevents any clip length's becoming infinitely small (or negative length) + if (ghost->In() + movement >= ghost->Out()) { + // Since the timebase is considered more or less the "minimum unit", we adjust the movement to make the proposed + // length precisely one timebase unit in size + movement = ghost->Out() - parent()->timebase_ - ghost->In(); + } + } + + return movement; +} + +rational TimelineView::Tool::ValidateOutTrimming(rational movement, const QVector ghosts) +{ + foreach (TimelineViewGhostItem* ghost, ghosts) { + if (ghost->mode() != TimelineViewGhostItem::kTrimOut) { + continue; + } + + // Prevents any clip length's becoming infinitely small (or negative length) + if (ghost->Out() + movement <= ghost->In()) { + // Since the timebase is considered more or less the "minimum unit", we adjust the movement to make the proposed + // length precisely one timebase unit in size + movement = ghost->In() + parent()->timebase_ - ghost->Out(); + } + } + + return movement; +}