diff --git a/app/widget/timelinewidget/view/CMakeLists.txt b/app/widget/timelinewidget/view/CMakeLists.txt index fa09dae9f..f1aa3a9a1 100644 --- a/app/widget/timelinewidget/view/CMakeLists.txt +++ b/app/widget/timelinewidget/view/CMakeLists.txt @@ -24,6 +24,8 @@ set(OLIVE_SOURCES widget/timelinewidget/view/timelineviewmouseevent.cpp widget/timelinewidget/view/timelineviewrect.h widget/timelinewidget/view/timelineviewrect.cpp + widget/timelinewidget/view/timelineviewbase.h + widget/timelinewidget/view/timelineviewbase.cpp widget/timelinewidget/view/timelineviewblockitem.h widget/timelinewidget/view/timelineviewblockitem.cpp widget/timelinewidget/view/timelineviewenditem.h diff --git a/app/widget/timelinewidget/view/timelineplayhead.cpp b/app/widget/timelinewidget/view/timelineplayhead.cpp index 4b45e6e82..0b9ea95a9 100644 --- a/app/widget/timelinewidget/view/timelineplayhead.cpp +++ b/app/widget/timelinewidget/view/timelineplayhead.cpp @@ -20,17 +20,14 @@ #include "timelineplayhead.h" -TimelinePlayhead::TimelinePlayhead() -{ +#include -} - -QColor TimelinePlayhead::PlayheadColor() +const QColor &TimelinePlayhead::PlayheadColor() const { return playhead_color_; } -QColor TimelinePlayhead::PlayheadHighlightColor() +const QColor &TimelinePlayhead::PlayheadHighlightColor() const { return playhead_highlight_color_; } @@ -44,3 +41,14 @@ void TimelinePlayhead::SetPlayheadHighlightColor(QColor c) { playhead_highlight_color_ = c; } + +void TimelinePlayhead::Draw(QPainter* painter, const QRectF& playhead_rect) const +{ + painter->setPen(Qt::NoPen); + painter->setBrush(PlayheadHighlightColor()); + painter->drawRect(playhead_rect); + + painter->setPen(PlayheadColor()); + painter->setBrush(Qt::NoBrush); + painter->drawLine(QLineF(playhead_rect.topLeft(), playhead_rect.bottomLeft())); +} diff --git a/app/widget/timelinewidget/view/timelineplayhead.h b/app/widget/timelinewidget/view/timelineplayhead.h index dd69b114e..bbdf1f934 100644 --- a/app/widget/timelinewidget/view/timelineplayhead.h +++ b/app/widget/timelinewidget/view/timelineplayhead.h @@ -34,14 +34,16 @@ class TimelinePlayhead : public QWidget Q_PROPERTY(QColor playheadColor READ PlayheadColor WRITE SetPlayheadColor DESIGNABLE true) Q_PROPERTY(QColor playheadHighlightColor READ PlayheadHighlightColor WRITE SetPlayheadHighlightColor DESIGNABLE true) public: - TimelinePlayhead(); + TimelinePlayhead() = default; - QColor PlayheadColor(); - QColor PlayheadHighlightColor(); + const QColor& PlayheadColor() const; + const QColor& PlayheadHighlightColor() const; void SetPlayheadColor(QColor c); void SetPlayheadHighlightColor(QColor c); + void Draw(QPainter *painter, const QRectF &rect) const; + private: QColor playhead_color_; QColor playhead_highlight_color_; diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 26e7c499d..101418112 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -34,9 +34,8 @@ #include "project/item/footage/footage.h" TimelineView::TimelineView(const TrackType &type, Qt::Alignment vertical_alignment, QWidget *parent) : - QGraphicsView(parent), + TimelineViewBase(parent), connected_track_list_(nullptr), - playhead_(0), type_(type) { Q_ASSERT(vertical_alignment == Qt::AlignTop || vertical_alignment == Qt::AlignBottom); @@ -68,14 +67,6 @@ void TimelineView::SetScale(const double &scale) end_item_->SetScale(scale_); } -void TimelineView::SetTimebase(const rational &timebase) -{ - SetTimebaseInternal(timebase); - - // Timebase influences position/visibility of playhead - viewport()->update(); -} - void TimelineView::SelectAll() { QList all_items = items(); @@ -94,26 +85,26 @@ void TimelineView::DeselectAll() } } -void TimelineView::SetTime(const int64_t time) -{ - playhead_ = time; - - // Force redraw for playhead - viewport()->update(); -} - void TimelineView::mousePressEvent(QMouseEvent *event) { + if (PlayheadPress(event)) { + // Let the parent handle this + return; + } + TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), event->modifiers()); emit MousePressed(&timeline_event); - - } void TimelineView::mouseMoveEvent(QMouseEvent *event) { + if (PlayheadMove(event)) { + // Let the parent handle this + return; + } + TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), event->modifiers()); @@ -122,6 +113,11 @@ void TimelineView::mouseMoveEvent(QMouseEvent *event) void TimelineView::mouseReleaseEvent(QMouseEvent *event) { + if (PlayheadRelease(event)) { + // Let the parent handle this + return; + } + TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()), event->modifiers()); @@ -181,26 +177,6 @@ void TimelineView::resizeEvent(QResizeEvent *event) UpdateSceneRect(); } -void TimelineView::drawForeground(QPainter *painter, const QRectF &rect) -{ - QGraphicsView::drawForeground(painter, rect); - - if (!timebase().isNull()) { - double x = TimeToScene(rational(playhead_ * timebase().numerator(), timebase().denominator())); - double width = TimeToScene(timebase()); - - QRectF playhead_rect(x, rect.top(), width, rect.height()); - - painter->setPen(Qt::NoPen); - painter->setBrush(playhead_style_.PlayheadHighlightColor()); - painter->drawRect(playhead_rect); - - painter->setPen(playhead_style_.PlayheadColor()); - painter->setBrush(Qt::NoBrush); - painter->drawLine(QLineF(playhead_rect.topLeft(), playhead_rect.bottomLeft())); - } -} - Stream::Type TimelineView::TrackTypeToStreamType(TrackType track_type) { switch (track_type) { @@ -295,11 +271,6 @@ void TimelineView::UserSetTime(const int64_t &time) emit TimeChanged(time); } -rational TimelineView::GetPlayheadTime() -{ - return rational(playhead_ * timebase().numerator(), timebase().denominator()); -} - void TimelineView::UpdateSceneRect() { QRectF bounding_rect = scene_.itemsBoundingRect(); diff --git a/app/widget/timelinewidget/view/timelineview.h b/app/widget/timelinewidget/view/timelineview.h index 649508532..00578b6f4 100644 --- a/app/widget/timelinewidget/view/timelineview.h +++ b/app/widget/timelinewidget/view/timelineview.h @@ -29,7 +29,7 @@ #include "node/block/clip/clip.h" #include "node/output/timeline/timeline.h" -#include "timelineplayhead.h" +#include "timelineviewbase.h" #include "timelineviewblockitem.h" #include "timelineviewmouseevent.h" #include "timelineviewenditem.h" @@ -42,7 +42,7 @@ * * This widget primarily exposes users to viewing and modifying Block nodes, usually through a TimelineOutput node. */ -class TimelineView : public QGraphicsView, public TimelineScaledObject +class TimelineView : public TimelineViewBase { Q_OBJECT public: @@ -66,16 +66,9 @@ public: void ConnectTrackList(TrackList* list); -public slots: - void SetTimebase(const rational& timebase); - - void SetTime(const int64_t time); - signals: void ScaleChanged(double scale); - void TimeChanged(const int64_t& time); - void MousePressed(TimelineViewMouseEvent* event); void MouseMoved(TimelineViewMouseEvent* event); void MouseReleased(TimelineViewMouseEvent* event); @@ -99,8 +92,6 @@ protected: virtual void resizeEvent(QResizeEvent *event) override; - virtual void drawForeground(QPainter *painter, const QRectF &rect) override; - private: TrackType ConnectedTrackType(); Stream::Type TrackTypeToStreamType(TrackType track_type); @@ -112,22 +103,14 @@ private: void UserSetTime(const int64_t& time); - rational GetPlayheadTime(); - void UpdatePlayheadRect(); TrackList* connected_track_list_; QGraphicsScene scene_; - int64_t playhead_; - TimelineViewEndItem* end_item_; - TimelinePlayhead playhead_style_; - - QRect playhead_rect_; - TrackType type_; private slots: diff --git a/app/widget/timelinewidget/view/timelineviewbase.cpp b/app/widget/timelinewidget/view/timelineviewbase.cpp new file mode 100644 index 000000000..70916ff20 --- /dev/null +++ b/app/widget/timelinewidget/view/timelineviewbase.cpp @@ -0,0 +1,80 @@ +#include "timelineviewbase.h" + +#include +#include + +#include "common/timecodefunctions.h" + +TimelineViewBase::TimelineViewBase(QWidget *parent) : + QGraphicsView(parent), + playhead_(0), + playhead_scene_left_(-1), + playhead_scene_right_(-1) +{ +} + +void TimelineViewBase::SetTimebase(const rational &timebase) +{ + SetTimebaseInternal(timebase); + + // Timebase influences position/visibility of playhead + viewport()->update(); +} + +void TimelineViewBase::SetTime(const int64_t time) +{ + playhead_ = time; + + // Force redraw for playhead + viewport()->update(); +} + +void TimelineViewBase::drawForeground(QPainter *painter, const QRectF &rect) +{ + QGraphicsView::drawForeground(painter, rect); + + if (!timebase().isNull()) { + double width = TimeToScene(timebase()); + + playhead_scene_left_ = TimeToScene(rational(playhead_ * timebase().numerator(), timebase().denominator())); + playhead_scene_right_ = playhead_scene_left_ + width; + + playhead_style_.Draw(painter, QRectF(playhead_scene_left_, rect.top(), width, rect.height())); + } +} + +rational TimelineViewBase::GetPlayheadTime() +{ + return rational(playhead_ * timebase().numerator(), timebase().denominator()); +} + +bool TimelineViewBase::PlayheadPress(QMouseEvent *event) +{ + QPointF scene_pos = mapToScene(event->pos()); + + dragging_playhead_ = (scene_pos.x() >= playhead_scene_left_ && scene_pos.x() < playhead_scene_right_); + + return dragging_playhead_; +} + +bool TimelineViewBase::PlayheadMove(QMouseEvent *event) +{ + if (!dragging_playhead_) { + return false; + } + + QPointF scene_pos = mapToScene(event->pos()); + rational mouse_time = SceneToTime(scene_pos.x()); + + int64_t target_ts = olive::time_to_timestamp(mouse_time, timebase()); + + SetTime(target_ts); + emit TimeChanged(target_ts); + + return true; +} + +bool TimelineViewBase::PlayheadRelease(QMouseEvent *event) +{ + return dragging_playhead_; +} diff --git a/app/widget/timelinewidget/view/timelineviewbase.h b/app/widget/timelinewidget/view/timelineviewbase.h new file mode 100644 index 000000000..c29042a70 --- /dev/null +++ b/app/widget/timelinewidget/view/timelineviewbase.h @@ -0,0 +1,44 @@ +#ifndef TIMELINEVIEWBASE_H +#define TIMELINEVIEWBASE_H + +#include + +#include "timelineplayhead.h" +#include "widget/timelinewidget/timelinescaledobject.h" + +class TimelineViewBase : public QGraphicsView, public TimelineScaledObject +{ + Q_OBJECT +public: + TimelineViewBase(QWidget* parent = nullptr); + + virtual void drawForeground(QPainter *painter, const QRectF &rect) override; + +public slots: + void SetTimebase(const rational& timebase); + + void SetTime(const int64_t time); + +signals: + void TimeChanged(const int64_t& time); + +protected: + rational GetPlayheadTime(); + + bool PlayheadPress(QMouseEvent* event); + bool PlayheadMove(QMouseEvent* event); + bool PlayheadRelease(QMouseEvent* event); + +private: + int64_t playhead_; + + TimelinePlayhead playhead_style_; + + double playhead_scene_left_; + double playhead_scene_right_; + + bool dragging_playhead_; + +}; + +#endif // TIMELINEVIEWBASE_H