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();