diff --git a/app/common/timelinecommon.h b/app/common/timelinecommon.h index 03762c3a0..e1da93def 100644 --- a/app/common/timelinecommon.h +++ b/app/common/timelinecommon.h @@ -9,6 +9,8 @@ public: kTrimIn, kTrimOut }; + + static bool IsATrimMode(MovementMode mode) {return mode == kTrimIn || mode == kTrimOut;} }; #endif // TIMELINECOMMON_H diff --git a/app/render/backend/videorenderworker.cpp b/app/render/backend/videorenderworker.cpp index 75c8b295c..b939f9c00 100644 --- a/app/render/backend/videorenderworker.cpp +++ b/app/render/backend/videorenderworker.cpp @@ -41,6 +41,7 @@ NodeValueTable VideoRenderWorker::RenderInternal(const NodeDependency& path, con emit CompletedFrame(path, job_time, hash, texture); // If we actually have a texture, download it into the disk cache + qDebug() << "Texture was null:" << texture.isNull(); if (!texture.isNull()) { Download(path, hash, texture, frame_cache_->CachePathName(hash)); } diff --git a/app/ui/cursors/cursors.qrc b/app/ui/cursors/cursors.qrc index a7ff3b26d..491a89677 100644 --- a/app/ui/cursors/cursors.qrc +++ b/app/ui/cursors/cursors.qrc @@ -1,13 +1,15 @@ + + - 1_left.svg - 1_right.svg - 2.svg - 3_left.svg - 3_right.svg - 4.svg - 5.svg - 5b.svg - 5c.svg + trim-left.svg + trim-right.svg + slip.svg + ripple-left.svg + ripple-right.svg + rolling.svg + razor-a.svg + razor-b.svg + razor-c.svg diff --git a/app/ui/cursors/5.svg b/app/ui/cursors/razor-a.svg similarity index 100% rename from app/ui/cursors/5.svg rename to app/ui/cursors/razor-a.svg diff --git a/app/ui/cursors/5b.svg b/app/ui/cursors/razor-b.svg similarity index 100% rename from app/ui/cursors/5b.svg rename to app/ui/cursors/razor-b.svg diff --git a/app/ui/cursors/5c.svg b/app/ui/cursors/razor-c.svg similarity index 100% rename from app/ui/cursors/5c.svg rename to app/ui/cursors/razor-c.svg diff --git a/app/ui/cursors/3_left.svg b/app/ui/cursors/ripple-left.svg similarity index 100% rename from app/ui/cursors/3_left.svg rename to app/ui/cursors/ripple-left.svg diff --git a/app/ui/cursors/3_right.svg b/app/ui/cursors/ripple-right.svg similarity index 100% rename from app/ui/cursors/3_right.svg rename to app/ui/cursors/ripple-right.svg diff --git a/app/ui/cursors/2.svg b/app/ui/cursors/rolling.svg similarity index 100% rename from app/ui/cursors/2.svg rename to app/ui/cursors/rolling.svg diff --git a/app/ui/cursors/4.svg b/app/ui/cursors/slip.svg similarity index 100% rename from app/ui/cursors/4.svg rename to app/ui/cursors/slip.svg diff --git a/app/ui/cursors/1_left.svg b/app/ui/cursors/trim-left.svg similarity index 100% rename from app/ui/cursors/1_left.svg rename to app/ui/cursors/trim-left.svg diff --git a/app/ui/cursors/1_right.svg b/app/ui/cursors/trim-right.svg similarity index 100% rename from app/ui/cursors/1_right.svg rename to app/ui/cursors/trim-right.svg diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 2ea8d9f15..34f40a0a5 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -15,6 +15,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) : QWidget(parent), rubberband_(QRubberBand::Rectangle, this), + active_tool_(nullptr), timeline_node_(nullptr), playhead_(0) { @@ -652,8 +653,17 @@ void TimelineWidget::ViewMousePressed(TimelineViewMouseEvent *event) void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event) { - if (timeline_node_ != nullptr && active_tool_ != nullptr) { - active_tool_->MouseMove(event); + if (timeline_node_) { + if (active_tool_) { + active_tool_->MouseMove(event); + } else { + // Mouse is not down, attempt a hover event + Tool* hover_tool = GetActiveTool(); + + if (hover_tool) { + hover_tool->HoverMove(event); + } + } } } @@ -661,6 +671,7 @@ void TimelineWidget::ViewMouseReleased(TimelineViewMouseEvent *event) { if (timeline_node_ != nullptr && active_tool_ != nullptr) { active_tool_->MouseRelease(event); + active_tool_ = nullptr; } } @@ -668,6 +679,7 @@ void TimelineWidget::ViewMouseDoubleClicked(TimelineViewMouseEvent *event) { if (timeline_node_ != nullptr && active_tool_ != nullptr) { active_tool_->MouseDoubleClick(event); + active_tool_ = nullptr; } } diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index d553a7c5c..dda430586 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -81,6 +81,8 @@ private: virtual void MouseRelease(TimelineViewMouseEvent *){} virtual void MouseDoubleClick(TimelineViewMouseEvent *){} + virtual void HoverMove(TimelineViewMouseEvent *){} + virtual void DragEnter(TimelineViewMouseEvent *){} virtual void DragMove(TimelineViewMouseEvent *){} virtual void DragLeave(QDragLeaveEvent *){} @@ -144,6 +146,9 @@ private: virtual void MousePress(TimelineViewMouseEvent *event) override; virtual void MouseMove(TimelineViewMouseEvent *event) override; virtual void MouseRelease(TimelineViewMouseEvent *event) override; + + virtual void HoverMove(TimelineViewMouseEvent *event) override; + protected: void SetMovementAllowed(bool allowed); void SetTrackMovementAllowed(bool allowed); @@ -178,6 +183,8 @@ private: virtual void ProcessDrag(const TimelineCoordinate &mouse_pos); private: + Timeline::MovementMode IsCursorInTrimHandle(TimelineViewBlockItem* block, qreal cursor_x); + void InitiateDrag(const TimelineCoordinate &mouse_pos); void AddGhostInternal(TimelineViewGhostItem* ghost, Timeline::MovementMode mode); diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index e08b0da90..8f822c735 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -25,6 +25,7 @@ #include "common/clamp.h" #include "common/flipmodifiers.h" +#include "common/qtversionabstraction.h" #include "common/range.h" #include "common/timecodefunctions.h" #include "config/config.h" @@ -140,6 +141,27 @@ void TimelineWidget::PointerTool::MouseRelease(TimelineViewMouseEvent *event) dragging_ = false; } +void TimelineWidget::PointerTool::HoverMove(TimelineViewMouseEvent *event) +{ + // No dragging, but we still want to process cursors + TimelineViewBlockItem* block_at_cursor = GetItemAtScenePos(event->GetCoordinates()); + + if (block_at_cursor) { + switch (IsCursorInTrimHandle(block_at_cursor, event->GetSceneX())) { + case Timeline::kTrimIn: + parent()->setCursor(Qt::SizeHorCursor); + break; + case Timeline::kTrimOut: + parent()->setCursor(Qt::SizeHorCursor); + break; + default: + parent()->unsetCursor(); + } + } else { + parent()->unsetCursor(); + } +} + void TimelineWidget::PointerTool::SetMovementAllowed(bool allowed) { movement_allowed_ = allowed; @@ -211,7 +233,7 @@ void TimelineWidget::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *e Block* b = Node::ValueToPtr(ghost->data(TimelineViewGhostItem::kAttachedBlock)); // Normal blocks work in conjunction with the gap made above - if (ghost->mode() == Timeline::kTrimIn || ghost->mode() == Timeline::kTrimOut) { + if (Timeline::IsATrimMode(ghost->mode())) { // If we were trimming, we'll need to change the length // If we were trimming the in point, we'll need to adjust the media in too @@ -280,21 +302,13 @@ void TimelineWidget::PointerTool::InitiateDrag(const TimelineCoordinate &mouse_p // Record where the drag started in timeline coordinates track_start_ = mouse_pos.GetTrack(); - // Determine whether we're trimming or moving based on the position of the cursor - Timeline::MovementMode trim_mode = Timeline::kNone; - - // FIXME: Hardcoded number - double kTrimHandle = qMax(10.0, parent()->TimeToScene(parent()->timebase())); - qreal mouse_x = parent()->TimeToScene(mouse_pos.GetFrame()); + // Determine whether we're trimming or moving based on the position of the cursor + Timeline::MovementMode trim_mode = IsCursorInTrimHandle(clicked_item, mouse_x); - if (trimming_allowed_ && mouse_x <= clicked_item->x() + kTrimHandle) { - trim_mode = Timeline::kTrimIn; - } else if (trimming_allowed_ && mouse_x >= clicked_item->x() + clicked_item->rect().right() - kTrimHandle) { - trim_mode = Timeline::kTrimOut; - } else if (movement_allowed_) { - // Some derived classes don't allow movement + // Some derived classes don't allow movement + if (trim_mode == Timeline::kNone && movement_allowed_) { trim_mode = Timeline::kMove; } @@ -377,6 +391,24 @@ void TimelineWidget::PointerTool::ProcessDrag(const TimelineCoordinate &mouse_po parent()); } +Timeline::MovementMode TimelineWidget::PointerTool::IsCursorInTrimHandle(TimelineViewBlockItem *block, qreal cursor_x) +{ + double kTrimHandle = QFontMetricsWidth(parent()->fontMetrics(), "H"); + + // Block is too narrow, no trimming allowed + if (block->rect().width() <= kTrimHandle * 2) { + return Timeline::kNone; + } + + if (trimming_allowed_ && cursor_x <= block->x() + kTrimHandle) { + return Timeline::kTrimIn; + } else if (trimming_allowed_ && cursor_x >= block->x() + block->rect().right() - kTrimHandle) { + return Timeline::kTrimOut; + } else { + return Timeline::kNone; + } +} + void TimelineWidget::PointerTool::InitiateGhosts(TimelineViewBlockItem* clicked_item, Timeline::MovementMode trim_mode, bool allow_gap_trimming) @@ -389,8 +421,7 @@ void TimelineWidget::PointerTool::InitiateGhosts(TimelineViewBlockItem* clicked_ bool multitrim_enabled = true; // Determine if the clicked item is the earliest/latest in the track for in/out trimming respectively - if (trim_mode == Timeline::kTrimIn - || trim_mode == Timeline::kTrimOut) { + if (Timeline::IsATrimMode(trim_mode)) { multitrim_enabled = IsClipTrimmable(clicked_item, clips, trim_mode); } @@ -405,13 +436,12 @@ void TimelineWidget::PointerTool::InitiateGhosts(TimelineViewBlockItem* clicked_ bool include_this_clip = true; if (clip_item->block()->type() == Block::kGap - && trim_mode != Timeline::kTrimIn - && trim_mode != Timeline::kTrimOut) { + && !Timeline::IsATrimMode(trim_mode)) { continue; } if (clip_item != clicked_item - && (trim_mode == Timeline::kTrimIn || trim_mode == Timeline::kTrimOut)) { + && (Timeline::IsATrimMode(trim_mode))) { include_this_clip = multitrim_enabled ? IsClipTrimmable(clip_item, clips, trim_mode) : false; } diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index 8976b911b..7101114c5 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -45,6 +45,7 @@ TimelineView::TimelineView(const TrackType &type, Qt::Alignment vertical_alignme setBackgroundRole(QPalette::Window); setContextMenuPolicy(Qt::CustomContextMenu); SetLimitYAxis(true); + viewport()->setMouseTracking(true); } void TimelineView::SelectAll() @@ -207,6 +208,25 @@ void TimelineView::drawBackground(QPainter *painter, const QRectF &rect) } } +void TimelineView::ToolChangedEvent(Tool::Item tool) +{ + switch (tool) { + case Tool::kRazor: + setCursor(Qt::SplitHCursor); + break; + case Tool::kEdit: + setCursor(Qt::IBeamCursor); + break; + case Tool::kAdd: + case Tool::kTransition: + case Tool::kZoom: + setCursor(Qt::CrossCursor); + break; + default: + unsetCursor(); + } +} + Stream::Type TimelineView::TrackTypeToStreamType(TrackType track_type) { switch (track_type) { diff --git a/app/widget/timelinewidget/view/timelineview.h b/app/widget/timelinewidget/view/timelineview.h index d48ef41ab..3251049db 100644 --- a/app/widget/timelinewidget/view/timelineview.h +++ b/app/widget/timelinewidget/view/timelineview.h @@ -87,6 +87,8 @@ protected: virtual void drawBackground(QPainter *painter, const QRectF &rect) override; + virtual void ToolChangedEvent(Tool::Item tool) override; + private: TrackType ConnectedTrackType(); Stream::Type TrackTypeToStreamType(TrackType track_type); diff --git a/app/widget/timelinewidget/view/timelineviewbase.cpp b/app/widget/timelinewidget/view/timelineviewbase.cpp index 6e31f3a26..c0e50e9b9 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.cpp +++ b/app/widget/timelinewidget/view/timelineviewbase.cpp @@ -14,6 +14,7 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) : playhead_(0), playhead_scene_left_(-1), playhead_scene_right_(-1), + dragging_playhead_(false), dragging_hand_(false), limit_y_axis_(false) { @@ -136,7 +137,13 @@ bool TimelineViewBase::PlayheadMove(QMouseEvent *event) bool TimelineViewBase::PlayheadRelease(QMouseEvent *event) { - return dragging_playhead_; + if (dragging_playhead_) { + dragging_playhead_ = false; + + return true; + } + + return false; } bool TimelineViewBase::HandPress(QMouseEvent *event) @@ -199,6 +206,10 @@ bool TimelineViewBase::HandRelease(QMouseEvent *event) return false; } +void TimelineViewBase::ToolChangedEvent(Tool::Item tool) +{ +} + qreal TimelineViewBase::GetPlayheadX() { return TimeToScene(rational(playhead_ * timebase().numerator(), timebase().denominator())); @@ -324,4 +335,6 @@ void TimelineViewBase::ApplicationToolChanged(Tool::Item tool) } else { setDragMode(default_drag_mode_); } + + ToolChangedEvent(tool); } diff --git a/app/widget/timelinewidget/view/timelineviewbase.h b/app/widget/timelinewidget/view/timelineviewbase.h index 639fae607..2caadb8df 100644 --- a/app/widget/timelinewidget/view/timelineviewbase.h +++ b/app/widget/timelinewidget/view/timelineviewbase.h @@ -54,6 +54,8 @@ protected: bool HandMove(QMouseEvent* event); bool HandRelease(QMouseEvent* event); + virtual void ToolChangedEvent(Tool::Item tool); + private: qreal GetPlayheadX(); diff --git a/app/widget/timelinewidget/view/timelineviewblockitem.cpp b/app/widget/timelinewidget/view/timelineviewblockitem.cpp index 4288c8dd3..3b4610520 100644 --- a/app/widget/timelinewidget/view/timelineviewblockitem.cpp +++ b/app/widget/timelinewidget/view/timelineviewblockitem.cpp @@ -35,6 +35,7 @@ TimelineViewBlockItem::TimelineViewBlockItem(QGraphicsItem* parent) : block_(nullptr) { setBrush(Qt::white); + setCursor(Qt::DragMoveCursor); } Block *TimelineViewBlockItem::block() diff --git a/app/widget/timelinewidget/view/timelineviewmouseevent.cpp b/app/widget/timelinewidget/view/timelineviewmouseevent.cpp index e89d0994b..dc5bb4c32 100644 --- a/app/widget/timelinewidget/view/timelineviewmouseevent.cpp +++ b/app/widget/timelinewidget/view/timelineviewmouseevent.cpp @@ -74,6 +74,11 @@ void TimelineViewMouseEvent::SetEvent(QEvent *event) source_event_ = event; } +const qreal &TimelineViewMouseEvent::GetSceneX() const +{ + return scene_x_; +} + void TimelineViewMouseEvent::accept() { if (source_event_ != nullptr) diff --git a/app/widget/timelinewidget/view/timelineviewmouseevent.h b/app/widget/timelinewidget/view/timelineviewmouseevent.h index 32c86c10b..b79235756 100644 --- a/app/widget/timelinewidget/view/timelineviewmouseevent.h +++ b/app/widget/timelinewidget/view/timelineviewmouseevent.h @@ -57,6 +57,8 @@ public: void SetEvent(QEvent* event); + const qreal& GetSceneX() const; + void accept(); void ignore();