From c74e3571ff1a5f66a5d70b7f43e2366a39f586a3 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 2 Aug 2019 11:33:45 +1200 Subject: [PATCH] added minor clip functionality to timelineview --- app/widget/timelineview/timelineview.cpp | 80 +++++++++++++++++-- app/widget/timelineview/timelineview.h | 13 +++ .../timelineview/timelineviewclipitem.cpp | 56 ++++++------- .../timelineview/timelineviewclipitem.h | 14 ++-- app/widget/timeruler/timeruler.cpp | 2 +- 5 files changed, 121 insertions(+), 44 deletions(-) diff --git a/app/widget/timelineview/timelineview.cpp b/app/widget/timelineview/timelineview.cpp index 29132db28..7fd554e18 100644 --- a/app/widget/timelineview/timelineview.cpp +++ b/app/widget/timelineview/timelineview.cpp @@ -20,7 +20,8 @@ #include "timelineview.h" -#include "timelineviewclipitem.h" +#include +#include TimelineView::TimelineView(QWidget *parent) : QGraphicsView(parent) @@ -28,32 +29,95 @@ TimelineView::TimelineView(QWidget *parent) : setScene(&scene_); setAlignment(Qt::AlignLeft | Qt::AlignVCenter); setDragMode(RubberBandDrag); + + // Set default scale + SetScale(1.0); } void TimelineView::AddClip(ClipBlock *clip) { TimelineViewClipItem* clip_item = new TimelineViewClipItem(); - clip_item->SetClip(clip); - scene_.addItem(clip_item); - // FIXME: Test code only - double framerate = timebase_.ToDouble(); - double clip_item_x = clip->in().ToDouble() / framerate; - clip_item->setRect(clip_item_x, 0, clip->out().ToDouble() / framerate - clip_item_x - 1, 100); - // End test code + // Set up clip with view parameters (clip item will automatically size its rect accordingly) + clip_item->SetClip(clip); + clip_item->SetTimebase(timebase_); + clip_item->SetScale(scale_); + + // Add to list of clip items that can be iterated through + clip_items_.append(clip_item); + + // Add item to graphics scene + scene_.addItem(clip_item); } void TimelineView::SetScale(const double &scale) { scale_ = scale; + + foreach (TimelineViewClipItem* item, clip_items_) { + item->SetScale(scale_); + } } void TimelineView::SetTimebase(const rational &timebase) { timebase_ = timebase; + + foreach (TimelineViewClipItem* item, clip_items_) { + item->SetTimebase(timebase_); + } } void TimelineView::Clear() { scene_.clear(); + clip_items_.clear(); + // FIXME: Does QGraphicsScene take ownership of these items or do I have to delete them manually after the scene + // clear? +} + +void TimelineView::mousePressEvent(QMouseEvent *event) +{ + QGraphicsView::mousePressEvent(event); + + 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); + + ghost->setRect(clip_item->rect()); + + ghost_items_.append(ghost); + + scene_.addItem(ghost); + } + } +} + +void TimelineView::mouseMoveEvent(QMouseEvent *event) +{ + QGraphicsView::mouseMoveEvent(event); + + if (!ghost_items_.isEmpty()) { + foreach (TimelineViewGhostItem* ghost, ghost_items_) { + QPointF scene_pos = mapToScene(event->pos()); + + ghost->setX(qMax(0.0, scene_pos.x())); + } + } +} + +void TimelineView::mouseReleaseEvent(QMouseEvent *event) +{ + QGraphicsView::mouseReleaseEvent(event); + + if (!ghost_items_.isEmpty()) { + foreach (TimelineViewGhostItem* ghost, ghost_items_) { + delete ghost; + } + + ghost_items_.clear(); + } } diff --git a/app/widget/timelineview/timelineview.h b/app/widget/timelineview/timelineview.h index fef025369..7c6bd6c6f 100644 --- a/app/widget/timelineview/timelineview.h +++ b/app/widget/timelineview/timelineview.h @@ -24,6 +24,8 @@ #include #include "node/block/clip/clip.h" +#include "timelineviewclipitem.h" +#include "timelineviewghostitem.h" class TimelineView : public QGraphicsView { @@ -38,12 +40,23 @@ public: void Clear(); +protected: + virtual void mousePressEvent(QMouseEvent *event) override; + virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void mouseReleaseEvent(QMouseEvent *event) override; + private: QGraphicsScene scene_; double scale_; rational timebase_; + + rational playhead_; + + QVector clip_items_; + + QVector ghost_items_; }; #endif // TIMELINEVIEW_H diff --git a/app/widget/timelineview/timelineviewclipitem.cpp b/app/widget/timelineview/timelineviewclipitem.cpp index 2d98fb3a3..fe401c7c5 100644 --- a/app/widget/timelineview/timelineviewclipitem.cpp +++ b/app/widget/timelineview/timelineviewclipitem.cpp @@ -29,7 +29,7 @@ TimelineViewClipItem::TimelineViewClipItem(QGraphicsItem* parent) : QGraphicsRectItem(parent), clip_(nullptr), - ghost_(nullptr) + scale_(1.0) { setBrush(Qt::white); setFlag(QGraphicsItem::ItemIsSelectable, true); @@ -38,6 +38,31 @@ TimelineViewClipItem::TimelineViewClipItem(QGraphicsItem* parent) : void TimelineViewClipItem::SetClip(ClipBlock *clip) { clip_ = clip; + UpdateRect(); +} + +void TimelineViewClipItem::SetTimebase(const rational &timebase) +{ + timebase_ = timebase; + UpdateRect(); +} + +void TimelineViewClipItem::SetScale(const double &scale) +{ + scale_ = scale; + UpdateRect(); +} + +void TimelineViewClipItem::UpdateRect() +{ + if (clip_ == nullptr || timebase_.denominator() == 0) { + return; + } + + double timebase_dbl = timebase_.ToDouble(); + double item_left = clip_->in().ToDouble() / timebase_dbl * scale_; + double item_right = clip_->out().ToDouble() / timebase_dbl * scale_; + setRect(item_left, 0, item_right - item_left - 1, 100); } void TimelineViewClipItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -64,32 +89,3 @@ void TimelineViewClipItem::paint(QPainter *painter, const QStyleOptionGraphicsIt painter->drawLine(QPointF(rect().left(), rect().bottom() - 1), QPointF(rect().right(), rect().bottom() - 1)); painter->drawLine(QPointF(rect().right(), rect().bottom() - 1), QPointF(rect().right(), rect().top())); } - -void TimelineViewClipItem::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsRectItem::mousePressEvent(event); - - ghost_ = new TimelineViewGhostItem(); - ghost_->setRect(rect()); - scene()->addItem(ghost_); -} - -void TimelineViewClipItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsRectItem::mouseMoveEvent(event); - - if (ghost_ != nullptr) { - ghost_->setPos(event->scenePos()); - } -} - -void TimelineViewClipItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsRectItem::mouseReleaseEvent(event); - - if (ghost_ != nullptr) { - scene()->removeItem(ghost_); - delete ghost_; - ghost_ = nullptr; - } -} diff --git a/app/widget/timelineview/timelineviewclipitem.h b/app/widget/timelineview/timelineviewclipitem.h index 3cebb932a..8c83a96e9 100644 --- a/app/widget/timelineview/timelineviewclipitem.h +++ b/app/widget/timelineview/timelineviewclipitem.h @@ -33,17 +33,21 @@ public: void SetClip(ClipBlock* clip); + void SetTimebase(const rational& timebase); + + void SetScale(const double& scale); + + void UpdateRect(); + protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override; - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; - private: ClipBlock* clip_; - TimelineViewGhostItem* ghost_; + rational timebase_; + + double scale_; }; #endif // TIMELINEVIEWCLIPITEM_H diff --git a/app/widget/timeruler/timeruler.cpp b/app/widget/timeruler/timeruler.cpp index 09c060844..6cfe05963 100644 --- a/app/widget/timeruler/timeruler.cpp +++ b/app/widget/timeruler/timeruler.cpp @@ -222,7 +222,7 @@ void TimeRuler::paintEvent(QPaintEvent *e) // If we found the playhead along here, draw it last if (playhead_pos >= 0) { p.setPen(Qt::NoPen); - p.setBrush(Qt::red); + p.setBrush(Qt::red); // FIXME: Make configurable in CSS DrawPlayhead(&p, playhead_pos, height()); } }