diff --git a/app/common/CMakeLists.txt b/app/common/CMakeLists.txt
index f3cb1ca7e..930eb2d53 100644
--- a/app/common/CMakeLists.txt
+++ b/app/common/CMakeLists.txt
@@ -22,6 +22,8 @@ set(OLIVE_SOURCES
common/debug.cpp
common/filefunctions.h
common/filefunctions.cpp
+ common/flipmodifiers.h
+ common/flipmodifiers.cpp
common/lerp.h
common/range.h
common/rational.h
diff --git a/app/common/flipmodifiers.cpp b/app/common/flipmodifiers.cpp
new file mode 100644
index 000000000..3652babcf
--- /dev/null
+++ b/app/common/flipmodifiers.cpp
@@ -0,0 +1,37 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#include "flipmodifiers.h"
+
+Qt::KeyboardModifiers FlipControlAndShiftModifiers(Qt::KeyboardModifiers e) {
+ if (e & Qt::ControlModifier & Qt::ShiftModifier) {
+ return e;
+ }
+
+ if (e & Qt::ShiftModifier) {
+ e |= Qt::ControlModifier;
+ e &= ~Qt::ShiftModifier;
+ } else if (e & Qt::ControlModifier) {
+ e |= Qt::ShiftModifier;
+ e &= ~Qt::ControlModifier;
+ }
+
+ return e;
+}
diff --git a/app/common/flipmodifiers.h b/app/common/flipmodifiers.h
new file mode 100644
index 000000000..8fb754eda
--- /dev/null
+++ b/app/common/flipmodifiers.h
@@ -0,0 +1,28 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#ifndef FLIPMODIFIERS_H
+#define FLIPMODIFIERS_H
+
+#include
+
+Qt::KeyboardModifiers FlipControlAndShiftModifiers(Qt::KeyboardModifiers e);
+
+#endif // FLIPMODIFIERS_H
diff --git a/app/node/output/timeline/timeline.cpp b/app/node/output/timeline/timeline.cpp
index f31f4db98..ffdbdcf75 100644
--- a/app/node/output/timeline/timeline.cpp
+++ b/app/node/output/timeline/timeline.cpp
@@ -39,7 +39,7 @@ TimelineOutput::TimelineOutput()
AddParameter(track_input);
track_inputs_[i] = track_input;
- TrackList* list = new TrackList(this, track_input);
+ TrackList* list = new TrackList(this, static_cast(i), track_input);
track_lists_[i] = list;
connect(list, SIGNAL(TrackListChanged()), this, SLOT(UpdateTrackCache()));
connect(list, SIGNAL(LengthChanged(const rational &)), this, SLOT(UpdateLength(const rational &)));
@@ -141,12 +141,12 @@ void TimelineOutput::SetTimebase(const rational &timebase)
}
}
-NodeInput *TimelineOutput::track_input(TimelineOutput::TrackType type)
+NodeInput *TimelineOutput::track_input(TrackType type)
{
return track_inputs_.at(type);
}
-TrackList *TimelineOutput::track_list(TimelineOutput::TrackType type)
+TrackList *TimelineOutput::track_list(TrackType type)
{
return track_lists_.at(type);
}
diff --git a/app/node/output/timeline/timeline.h b/app/node/output/timeline/timeline.h
index 60418ad98..ff233bd11 100644
--- a/app/node/output/timeline/timeline.h
+++ b/app/node/output/timeline/timeline.h
@@ -25,6 +25,7 @@
#include "node/block/block.h"
#include "node/output/track/track.h"
#include "tracklist.h"
+#include "tracktypes.h"
/**
* @brief Node that represents the end of the Timeline as well as a time traversal Node
@@ -33,14 +34,6 @@ class TimelineOutput : public Node
{
Q_OBJECT
public:
- enum TrackType {
- kTrackTypeNone = -1,
- kTrackTypeVideo,
- kTrackTypeAudio,
- kTrackTypeSubtitle,
- kTrackTypeCount
- };
-
TimelineOutput();
virtual QString Name() override;
diff --git a/app/node/output/timeline/tracklist.cpp b/app/node/output/timeline/tracklist.cpp
index c65c413e3..e373d9a6b 100644
--- a/app/node/output/timeline/tracklist.cpp
+++ b/app/node/output/timeline/tracklist.cpp
@@ -23,9 +23,10 @@
#include "node/blend/alphaover/alphaover.h"
#include "timeline.h"
-TrackList::TrackList(TimelineOutput* parent, NodeInput *track_input) :
+TrackList::TrackList(TimelineOutput* parent, const enum TrackType &type, NodeInput *track_input) :
QObject(parent),
- track_input_(track_input)
+ track_input_(track_input),
+ type_(type)
{
connect(parent, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(TrackConnectionAdded(NodeEdgePtr)));
connect(parent, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackConnectionRemoved(NodeEdgePtr)));
@@ -125,6 +126,11 @@ const rational &TrackList::TrackLength()
return total_length_;
}
+const enum TrackType &TrackList::TrackType()
+{
+ return type_;
+}
+
void TrackList::AddTrack()
{
TrackOutput* track = new TrackOutput();
diff --git a/app/node/output/timeline/tracklist.h b/app/node/output/timeline/tracklist.h
index ae670092c..7b0858d13 100644
--- a/app/node/output/timeline/tracklist.h
+++ b/app/node/output/timeline/tracklist.h
@@ -25,13 +25,14 @@
#include "node/graph.h"
#include "node/output/track/track.h"
+#include "tracktypes.h"
class TimelineOutput;
class TrackList : public QObject {
Q_OBJECT
public:
- TrackList(TimelineOutput *parent, NodeInput* track_input);
+ TrackList(TimelineOutput *parent, const enum TrackType& type, NodeInput* track_input);
TrackOutput* attached_track();
@@ -53,6 +54,8 @@ public:
const rational& TrackLength();
+ const enum TrackType& TrackType();
+
public slots:/**
* @brief Slot for when the track connection is added
*/
@@ -114,6 +117,8 @@ private:
rational total_length_;
+ enum TrackType type_;
+
private slots:
void UpdateTotalLength();
};
diff --git a/app/node/output/timeline/tracktypes.h b/app/node/output/timeline/tracktypes.h
new file mode 100644
index 000000000..f3cb28a50
--- /dev/null
+++ b/app/node/output/timeline/tracktypes.h
@@ -0,0 +1,12 @@
+#ifndef TRACKTYPES_H
+#define TRACKTYPES_H
+
+enum TrackType {
+ kTrackTypeNone = -1,
+ kTrackTypeVideo,
+ kTrackTypeAudio,
+ kTrackTypeSubtitle,
+ kTrackTypeCount
+};
+
+#endif // TRACKTYPES_H
diff --git a/app/project/item/sequence/sequence.cpp b/app/project/item/sequence/sequence.cpp
index 3af8939ce..3dd0c77c3 100644
--- a/app/project/item/sequence/sequence.cpp
+++ b/app/project/item/sequence/sequence.cpp
@@ -84,8 +84,8 @@ void Sequence::AddDefaultNodes()
NodeParam::ConnectEdge(renderer_processor_->texture_output(), viewer_output_->texture_input());
// Connect track to timeline
- NodeParam::ConnectEdge(video_track_output_->track_output(), timeline_output_->track_input(TimelineOutput::kTrackTypeVideo));
- NodeParam::ConnectEdge(audio_track_output_->track_output(), timeline_output_->track_input(TimelineOutput::kTrackTypeAudio));
+ NodeParam::ConnectEdge(video_track_output_->track_output(), timeline_output_->track_input(kTrackTypeVideo));
+ NodeParam::ConnectEdge(audio_track_output_->track_output(), timeline_output_->track_input(kTrackTypeAudio));
// Connect timeline end point to renderer
NodeParam::ConnectEdge(timeline_output_->length_output(), renderer_processor_->length_input());
diff --git a/app/tool/tool.h b/app/tool/tool.h
index 079a9839f..5e4734b7a 100644
--- a/app/tool/tool.h
+++ b/app/tool/tool.h
@@ -66,7 +66,9 @@ enum Tool {
kRecord,
/// Add tool
- kAdd
+ kAdd,
+
+ kCount
};
}
diff --git a/app/widget/timelineview/CMakeLists.txt b/app/widget/timelineview/CMakeLists.txt
index a52e59a95..515a529bf 100644
--- a/app/widget/timelineview/CMakeLists.txt
+++ b/app/widget/timelineview/CMakeLists.txt
@@ -19,12 +19,16 @@ add_subdirectory(undo)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
+ widget/timelineview/timelinecoordinate.h
+ widget/timelineview/timelinecoordinate.cpp
widget/timelineview/timelineplayhead.h
widget/timelineview/timelineplayhead.cpp
widget/timelineview/timelinescaledobject.h
widget/timelineview/timelinescaledobject.cpp
widget/timelineview/timelineview.h
widget/timelineview/timelineview.cpp
+ widget/timelineview/timelineviewmouseevent.h
+ widget/timelineview/timelineviewmouseevent.cpp
widget/timelineview/timelineviewrect.h
widget/timelineview/timelineviewrect.cpp
widget/timelineview/timelineviewblockitem.h
diff --git a/app/widget/timelineview/timelinecoordinate.cpp b/app/widget/timelineview/timelinecoordinate.cpp
new file mode 100644
index 000000000..8a41d84f5
--- /dev/null
+++ b/app/widget/timelineview/timelinecoordinate.cpp
@@ -0,0 +1,52 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#include "timelinecoordinate.h"
+
+TimelineCoordinate::TimelineCoordinate() :
+ track_(0)
+{
+}
+
+TimelineCoordinate::TimelineCoordinate(const rational &frame, const int &track) :
+ frame_(frame),
+ track_(track)
+{
+}
+
+const rational &TimelineCoordinate::GetFrame() const
+{
+ return frame_;
+}
+
+const int &TimelineCoordinate::GetTrack() const
+{
+ return track_;
+}
+
+void TimelineCoordinate::SetFrame(const rational &frame)
+{
+ frame_ = frame;
+}
+
+void TimelineCoordinate::SetTrack(const int &track)
+{
+ track_ = track;
+}
diff --git a/app/widget/timelineview/timelinecoordinate.h b/app/widget/timelineview/timelinecoordinate.h
new file mode 100644
index 000000000..605135684
--- /dev/null
+++ b/app/widget/timelineview/timelinecoordinate.h
@@ -0,0 +1,45 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#ifndef TIMELINECOORDINATE_H
+#define TIMELINECOORDINATE_H
+
+#include "common/rational.h"
+
+class TimelineCoordinate
+{
+public:
+ TimelineCoordinate();
+ TimelineCoordinate(const rational& frame, const int& track);
+
+ const rational& GetFrame() const;
+ const int& GetTrack() const;
+
+ void SetFrame(const rational& frame);
+ void SetTrack(const int& track);
+
+private:
+ rational frame_;
+
+ int track_;
+
+};
+
+#endif // TIMELINECOORDINATE_H
diff --git a/app/widget/timelineview/timelineview.cpp b/app/widget/timelineview/timelineview.cpp
index 66aba1dfb..00fbefa87 100644
--- a/app/widget/timelineview/timelineview.cpp
+++ b/app/widget/timelineview/timelineview.cpp
@@ -27,6 +27,7 @@
#include
#include
+#include "common/flipmodifiers.h"
#include "common/timecodefunctions.h"
#include "core.h"
#include "node/input/media/media.h"
@@ -35,15 +36,6 @@
TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
QGraphicsView(parent),
- pointer_tool_(this),
- import_tool_(this),
- ripple_tool_(this),
- rolling_tool_(this),
- razor_tool_(this),
- slide_tool_(this),
- slip_tool_(this),
- hand_tool_(this),
- zoom_tool_(this),
timeline_node_(nullptr),
playhead_(0),
use_tracklist_length_directly_(true)
@@ -56,6 +48,25 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setBackgroundRole(QPalette::Window);
+ // Create tools
+ tools_.resize(olive::tool::kCount);
+ tools_.fill(nullptr);
+
+ tools_.replace(olive::tool::kPointer, std::make_shared(this));
+ // tools_.replace(olive::tool::kEdit, new PointerTool(this)); FIXME: Implement
+ tools_.replace(olive::tool::kRipple, std::make_shared(this));
+ tools_.replace(olive::tool::kRolling, std::make_shared(this));
+ tools_.replace(olive::tool::kRazor, std::make_shared(this));
+ tools_.replace(olive::tool::kSlip, std::make_shared(this));
+ tools_.replace(olive::tool::kSlide, std::make_shared(this));
+ tools_.replace(olive::tool::kHand, std::make_shared(this));
+ tools_.replace(olive::tool::kZoom, std::make_shared(this));
+ //tools_.replace(olive::tool::kTransition, new (this)); FIXME: Implement
+ //tools_.replace(olive::tool::kRecord, new PointerTool(this)); FIXME: Implement
+ //tools_.replace(olive::tool::kAdd, new PointerTool(this)); FIXME: Implement
+
+ import_tool_ = std::make_shared(this);
+
connect(&scene_, SIGNAL(changed(const QList&)), this, SLOT(UpdateSceneRect()));
// Create end item
@@ -121,7 +132,7 @@ void TimelineView::SetScale(const double &scale)
{
scale_ = scale;
- QMapIterator iterator(block_items_);
+ QMapIterator iterator(block_items_);
while (iterator.hasNext()) {
iterator.next();
@@ -145,11 +156,14 @@ void TimelineView::SetTimebase(const rational &timebase)
{
timebase_ = timebase;
timebase_dbl_ = timebase_.toDouble();
+
+ // Timebase influences position/visibility of playhead
+ viewport()->update();
}
void TimelineView::Clear()
{
- QMapIterator iterator(block_items_);
+ QMapIterator iterator(block_items_);
while (iterator.hasNext()) {
iterator.next();
@@ -239,50 +253,131 @@ void TimelineView::mousePressEvent(QMouseEvent *event)
{
active_tool_ = GetActiveTool();
+ // Cache these since we modify the event's later on
+ Qt::KeyboardModifiers mods = event->modifiers();
+
+ if (active_tool_ != nullptr) {
+ setDragMode(active_tool_->drag_mode());
+ }
+
+ if (active_tool_ == nullptr || active_tool_->enable_default_behavior()) {
+ // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
+ event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
+
+ QGraphicsView::mousePressEvent(event);
+ }
+
if (timeline_node_ != nullptr && active_tool_ != nullptr) {
- active_tool_->MousePress(event);
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ mods);
+
+ active_tool_->MousePress(&timeline_event);
}
}
void TimelineView::mouseMoveEvent(QMouseEvent *event)
{
+ // Cache these since we modify the event's later on
+ Qt::KeyboardModifiers mods = event->modifiers();
+
+ if (active_tool_ == nullptr || active_tool_->enable_default_behavior()) {
+ // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
+ event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
+
+ QGraphicsView::mouseMoveEvent(event);
+ }
+
if (timeline_node_ != nullptr && active_tool_ != nullptr) {
- active_tool_->MouseMove(event);
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ mods);
+
+ active_tool_->MouseMove(&timeline_event);
}
}
void TimelineView::mouseReleaseEvent(QMouseEvent *event)
{
+ // Cache these since we modify the event's later on
+ Qt::KeyboardModifiers mods = event->modifiers();
+
+ if (active_tool_ == nullptr || active_tool_->enable_default_behavior()) {
+ // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
+ event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
+
+ QGraphicsView::mouseReleaseEvent(event);
+ }
+
if (timeline_node_ != nullptr && active_tool_ != nullptr) {
- active_tool_->MouseRelease(event);
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ mods);
+
+ active_tool_->MouseRelease(&timeline_event);
+ }
+}
+
+void TimelineView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ // Cache these since we modify the event's later on
+ Qt::KeyboardModifiers mods = event->modifiers();
+
+ if (active_tool_ == nullptr || active_tool_->enable_default_behavior()) {
+ // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
+ event->setModifiers(FlipControlAndShiftModifiers(event->modifiers()));
+
+ QGraphicsView::mouseDoubleClickEvent(event);
+ }
+
+ if (timeline_node_ != nullptr && active_tool_ != nullptr) {
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ mods);
+
+ active_tool_->MouseDoubleClick(&timeline_event);
}
}
void TimelineView::dragEnterEvent(QDragEnterEvent *event)
{
if (timeline_node_ != nullptr) {
- import_tool_.DragEnter(event);
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ event->keyboardModifiers());
+
+ timeline_event.SetMimeData(event->mimeData());
+ timeline_event.SetEvent(event);
+
+ import_tool_->DragEnter(&timeline_event);
}
}
void TimelineView::dragMoveEvent(QDragMoveEvent *event)
{
if (timeline_node_ != nullptr) {
- import_tool_.DragMove(event);
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ event->keyboardModifiers());
+
+ timeline_event.SetMimeData(event->mimeData());
+ timeline_event.SetEvent(event);
+
+ import_tool_->DragMove(&timeline_event);
}
}
void TimelineView::dragLeaveEvent(QDragLeaveEvent *event)
{
if (timeline_node_ != nullptr) {
- import_tool_.DragLeave(event);
+ import_tool_->DragLeave(event);
}
}
void TimelineView::dropEvent(QDropEvent *event)
{
if (timeline_node_ != nullptr) {
- import_tool_.DragDrop(event);
+ TimelineViewMouseEvent timeline_event(ScreenToCoordinate(event->pos()),
+ event->keyboardModifiers());
+
+ timeline_event.SetMimeData(event->mimeData());
+ timeline_event.SetEvent(event);
+
+ import_tool_->DragDrop(&timeline_event);
}
}
@@ -297,52 +392,61 @@ void TimelineView::drawForeground(QPainter *painter, const QRectF &rect)
{
QGraphicsView::drawForeground(painter, rect);
- double x = TimeToScreenCoord(rational(playhead_ * timebase_.numerator(), timebase_.denominator()));
- double width = TimeToScreenCoord(timebase_);
+ if (!timebase_.isNull()) {
+ double x = TimeToScreenCoord(rational(playhead_ * timebase_.numerator(), timebase_.denominator()));
+ double width = TimeToScreenCoord(timebase_);
- QRectF playhead_rect(x, rect.top(), width, rect.height());
+ QRectF playhead_rect(x, rect.top(), width, rect.height());
- painter->setPen(Qt::NoPen);
- painter->setBrush(playhead_style_.PlayheadHighlightColor());
- painter->drawRect(playhead_rect);
+ 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()));
+ painter->setPen(playhead_style_.PlayheadColor());
+ painter->setBrush(Qt::NoBrush);
+ painter->drawLine(QLineF(playhead_rect.topLeft(), playhead_rect.bottomLeft()));
+ }
+}
+
+TrackType TimelineView::ConnectedTrackType()
+{
+ if (timeline_node_ != nullptr) {
+ return timeline_node_->TrackType();
+ }
+
+ return kTrackTypeNone;
+}
+
+Stream::Type TimelineView::TrackTypeToStreamType(TrackType track_type)
+{
+ switch (track_type) {
+ case kTrackTypeNone:
+ case kTrackTypeCount:
+ break;
+ case kTrackTypeVideo:
+ return Stream::kVideo;
+ case kTrackTypeAudio:
+ return Stream::kAudio;
+ case kTrackTypeSubtitle:
+ return Stream::kSubtitle;
+ }
+
+ return Stream::kUnknown;
+}
+
+TimelineCoordinate TimelineView::ScreenToCoordinate(const QPoint& pt)
+{
+ return SceneToCoordinate(mapToScene(pt));
+}
+
+TimelineCoordinate TimelineView::SceneToCoordinate(const QPointF& pt)
+{
+ return TimelineCoordinate(SceneToTime(pt.x()), SceneToTrack(pt.y()));
}
TimelineView::Tool *TimelineView::GetActiveTool()
{
- switch (olive::core.tool()) {
- case olive::tool::kNone:
- return nullptr;
- case olive::tool::kPointer:
- return &pointer_tool_;
- case olive::tool::kEdit:
- return nullptr; // FIXME: Implement
- case olive::tool::kRipple:
- return &ripple_tool_;
- case olive::tool::kRolling:
- return &rolling_tool_;
- case olive::tool::kRazor:
- return &razor_tool_;
- case olive::tool::kSlip:
- return &slip_tool_;
- case olive::tool::kSlide:
- return &slide_tool_;
- case olive::tool::kHand:
- return &hand_tool_;
- case olive::tool::kZoom:
- return &zoom_tool_;
- case olive::tool::kTransition:
- return nullptr; // FIXME: Implement
- case olive::tool::kRecord:
- return nullptr; // FIXME: Implement
- case olive::tool::kAdd:
- return nullptr; // FIXME: Implement
- }
-
- return nullptr;
+ return tools_.at(olive::core.tool()).get();
}
int TimelineView::GetTrackY(int track_index)
@@ -383,7 +487,7 @@ bool TimelineView::HasGhosts()
rational TimelineView::SceneToTime(const double &x)
{
// Adjust screen point by scale and timebase
- int scaled_x_mvmt = qRound(x / scale_ / timebase_dbl_);
+ qint64 scaled_x_mvmt = qRound64(x / scale_ / timebase_dbl_);
// Return a time in the timebase
return rational(scaled_x_mvmt * timebase_.numerator(), timebase_.denominator());
diff --git a/app/widget/timelineview/timelineview.h b/app/widget/timelineview/timelineview.h
index 2442d8615..29b4d4217 100644
--- a/app/widget/timelineview/timelineview.h
+++ b/app/widget/timelineview/timelineview.h
@@ -31,6 +31,7 @@
#include "node/output/timeline/timeline.h"
#include "timelineplayhead.h"
#include "timelineviewblockitem.h"
+#include "timelineviewmouseevent.h"
#include "timelineviewenditem.h"
#include "timelineviewghostitem.h"
#include "widget/timelineview/undo/undo.h"
@@ -91,6 +92,7 @@ protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
+ virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dragMoveEvent(QDragMoveEvent *event) override;
@@ -109,27 +111,28 @@ private:
Tool(TimelineView* parent);
virtual ~Tool();
- virtual void MousePress(QMouseEvent *event);
- virtual void MouseMove(QMouseEvent *event);
- virtual void MouseRelease(QMouseEvent *event);
+ virtual void MousePress(TimelineViewMouseEvent *){}
+ virtual void MouseMove(TimelineViewMouseEvent *){}
+ virtual void MouseRelease(TimelineViewMouseEvent *){}
+ virtual void MouseDoubleClick(TimelineViewMouseEvent *){}
- virtual void DragEnter(QDragEnterEvent *event);
- virtual void DragMove(QDragMoveEvent *event);
- virtual void DragLeave(QDragLeaveEvent *event);
- virtual void DragDrop(QDropEvent *event);
+ virtual void DragEnter(TimelineViewMouseEvent *){}
+ virtual void DragMove(TimelineViewMouseEvent *){}
+ virtual void DragLeave(QDragLeaveEvent *){}
+ virtual void DragDrop(TimelineViewMouseEvent *){}
TimelineView* parent();
static olive::timeline::MovementMode FlipTrimMode(const olive::timeline::MovementMode& trim_mode);
+ const DragMode& drag_mode();
+
+ bool enable_default_behavior();
+
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);
+ void set_drag_mode(const DragMode& mode);
+
+ void set_enable_default_behavior(bool enable);
/**
* @brief Retrieve the QGraphicsItem at a particular scene position
@@ -137,7 +140,7 @@ private:
* 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);
+ TimelineViewBlockItem* GetItemAtScenePos(const TimelineCoordinate &coord);
/**
* @brief Validates Ghosts that are moving horizontally (time-based)
@@ -169,11 +172,15 @@ private:
bool dragging_;
- QPointF drag_start_;
+ TimelineCoordinate drag_start_;
private:
TimelineView* parent_;
+ DragMode drag_mode_;
+
+ bool enable_default_behavior_;
+
};
class PointerTool : public Tool
@@ -181,14 +188,14 @@ private:
public:
PointerTool(TimelineView* parent);
- virtual void MousePress(QMouseEvent *event) override;
- virtual void MouseMove(QMouseEvent *event) override;
- virtual void MouseRelease(QMouseEvent *event) override;
+ virtual void MousePress(TimelineViewMouseEvent *event) override;
+ virtual void MouseMove(TimelineViewMouseEvent *event) override;
+ virtual void MouseRelease(TimelineViewMouseEvent *event) override;
protected:
void SetMovementAllowed(bool allowed);
void SetTrackMovementAllowed(bool allowed);
void SetTrimmingAllowed(bool allowed);
- virtual void MouseReleaseInternal(QMouseEvent *event);
+ virtual void MouseReleaseInternal(TimelineViewMouseEvent *event);
virtual rational FrameValidateInternal(rational time_movement, const QVector &ghosts);
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
@@ -215,9 +222,9 @@ private:
*/
rational ValidateOutTrimming(rational movement, const QVector ghosts, bool prevent_overwriting);
- virtual void ProcessDrag(const QPoint &mouse_pos);
+ virtual void ProcessDrag(const TimelineCoordinate &mouse_pos);
private:
- void InitiateDrag(const QPoint &mouse_pos);
+ void InitiateDrag(const TimelineCoordinate &mouse_pos);
void AddGhostInternal(TimelineViewGhostItem* ghost, olive::timeline::MovementMode mode);
@@ -238,10 +245,10 @@ private:
public:
ImportTool(TimelineView* parent);
- virtual void DragEnter(QDragEnterEvent *event) override;
- virtual void DragMove(QDragMoveEvent *event) override;
+ virtual void DragEnter(TimelineViewMouseEvent *event) override;
+ virtual void DragMove(TimelineViewMouseEvent *event) override;
virtual void DragLeave(QDragLeaveEvent *event) override;
- virtual void DragDrop(QDropEvent *event) override;
+ virtual void DragDrop(TimelineViewMouseEvent *event) override;
private:
int import_pre_buffer_;
};
@@ -251,9 +258,9 @@ private:
public:
RazorTool(TimelineView* parent);
- virtual void MousePress(QMouseEvent *event);
- virtual void MouseMove(QMouseEvent *event);
- virtual void MouseRelease(QMouseEvent *event);
+ virtual void MousePress(TimelineViewMouseEvent *event);
+ virtual void MouseMove(TimelineViewMouseEvent *event);
+ virtual void MouseRelease(TimelineViewMouseEvent *event);
private:
QVector split_tracks_;
@@ -264,7 +271,7 @@ private:
public:
RippleTool(TimelineView* parent);
protected:
- virtual void MouseReleaseInternal(QMouseEvent *event) override;
+ virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
virtual rational FrameValidateInternal(rational time_movement, const QVector& ghosts) override;
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
@@ -278,7 +285,7 @@ private:
RollingTool(TimelineView* parent);
protected:
- virtual void MouseReleaseInternal(QMouseEvent *event) override;
+ virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
virtual rational FrameValidateInternal(rational time_movement, const QVector& ghosts) override;
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
@@ -292,7 +299,7 @@ private:
SlideTool(TimelineView* parent);
protected:
- virtual void MouseReleaseInternal(QMouseEvent *event) override;
+ virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
virtual rational FrameValidateInternal(rational time_movement, const QVector& ghosts) override;
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
olive::timeline::MovementMode trim_mode,
@@ -305,8 +312,8 @@ private:
SlipTool(TimelineView* parent);
protected:
- virtual void ProcessDrag(const QPoint &mouse_pos) override;
- virtual void MouseReleaseInternal(QMouseEvent *event) override;
+ virtual void ProcessDrag(const TimelineCoordinate &mouse_pos) override;
+ virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
};
class HandTool : public Tool
@@ -314,10 +321,6 @@ private:
public:
HandTool(TimelineView* parent);
- virtual void MousePress(QMouseEvent *event);
- virtual void MouseMove(QMouseEvent *event);
- virtual void MouseRelease(QMouseEvent *event);
-
private:
QPoint screen_drag_start_;
QPoint scrollbar_start_;
@@ -328,25 +331,25 @@ private:
public:
ZoomTool(TimelineView* parent);
- virtual void MousePress(QMouseEvent *event);
- virtual void MouseMove(QMouseEvent *event);
- virtual void MouseRelease(QMouseEvent *event);
+ virtual void MousePress(TimelineViewMouseEvent *event);
+ virtual void MouseMove(TimelineViewMouseEvent *event);
+ virtual void MouseRelease(TimelineViewMouseEvent *event);
};
+ TrackType ConnectedTrackType();
+ Stream::Type TrackTypeToStreamType(TrackType track_type);
+
+ TimelineCoordinate ScreenToCoordinate(const QPoint& pt);
+ TimelineCoordinate SceneToCoordinate(const QPointF& pt);
+
Tool* GetActiveTool();
int GetTrackY(int track_index);
int GetTrackHeight(int track_index);
- PointerTool pointer_tool_;
- ImportTool import_tool_;
- RippleTool ripple_tool_;
- RollingTool rolling_tool_;
- RazorTool razor_tool_;
- SlideTool slide_tool_;
- SlipTool slip_tool_;
- HandTool hand_tool_;
- ZoomTool zoom_tool_;
+ QVector< std::shared_ptr > tools_;
+
+ std::shared_ptr import_tool_;
TrackList* timeline_node_;
@@ -369,7 +372,7 @@ private:
int64_t playhead_;
- QMap block_items_;
+ QMap block_items_;
QVector ghost_items_;
diff --git a/app/widget/timelineview/timelineviewblockitem.cpp b/app/widget/timelineview/timelineviewblockitem.cpp
index 8d0c326f1..b1690b544 100644
--- a/app/widget/timelineview/timelineviewblockitem.cpp
+++ b/app/widget/timelineview/timelineviewblockitem.cpp
@@ -70,29 +70,41 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
{
Q_UNUSED(widget)
- if (block_ == nullptr || block_->type() == Block::kGap) {
+ if (block_ == nullptr) {
return;
}
- /*QLinearGradient grad;
- grad.setStart(0, rect().top());
- grad.setFinalStop(0, rect().bottom());
- grad.setColorAt(0.0, QColor(160, 160, 240));
- grad.setColorAt(1.0, QColor(128, 128, 192));
- painter->fillRect(rect(), grad);*/
- painter->fillRect(rect(), QColor(128, 128, 192));
+ switch (block_->type()) {
+ case Block::kClip:
+ /*QLinearGradient grad;
+ grad.setStart(0, rect().top());
+ grad.setFinalStop(0, rect().bottom());
+ grad.setColorAt(0.0, QColor(160, 160, 240));
+ grad.setColorAt(1.0, QColor(128, 128, 192));
+ painter->fillRect(rect(), grad);*/
+ painter->fillRect(rect(), QColor(128, 128, 192));
- if (option->state & QStyle::State_Selected) {
- painter->fillRect(rect(), QColor(0, 0, 0, 64));
+ if (option->state & QStyle::State_Selected) {
+ painter->fillRect(rect(), QColor(0, 0, 0, 64));
+ }
+
+ painter->setPen(Qt::white);
+ painter->drawLine(rect().topLeft(), QPointF(rect().right(), rect().top()));
+ painter->drawLine(rect().topLeft(), QPointF(rect().left(), rect().bottom() - 1));
+
+ painter->drawText(rect(), static_cast(Qt::AlignLeft | Qt::AlignTop), block_->block_name());
+
+ painter->setPen(QColor(64, 64, 64));
+ 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()));
+ break;
+ case Block::kGap:
+ if (option->state & QStyle::State_Selected) {
+ // FIXME: Make this palette or CSS
+ painter->fillRect(rect(), Qt::white);
+ }
+ break;
+ case Block::kEnd:
+ break;
}
-
- painter->setPen(Qt::white);
- painter->drawLine(rect().topLeft(), QPointF(rect().right(), rect().top()));
- painter->drawLine(rect().topLeft(), QPointF(rect().left(), rect().bottom() - 1));
-
- painter->drawText(rect(), static_cast(Qt::AlignLeft | Qt::AlignTop), block_->block_name());
-
- painter->setPen(QColor(64, 64, 64));
- 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()));
}
diff --git a/app/widget/timelineview/timelineviewmouseevent.cpp b/app/widget/timelineview/timelineviewmouseevent.cpp
new file mode 100644
index 000000000..592fda769
--- /dev/null
+++ b/app/widget/timelineview/timelineviewmouseevent.cpp
@@ -0,0 +1,79 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#include "timelineviewmouseevent.h"
+
+#include
+
+TimelineViewMouseEvent::TimelineViewMouseEvent(const TimelineCoordinate &coord,
+ const Qt::KeyboardModifiers &modifiers) :
+ coord_(coord),
+ modifiers_(modifiers),
+ source_event_(nullptr),
+ mime_data_(nullptr)
+{
+}
+
+TimelineViewMouseEvent::TimelineViewMouseEvent(const rational &frame,
+ const int &track,
+ const Qt::KeyboardModifiers &modifiers) :
+ coord_(frame, track),
+ modifiers_(modifiers),
+ source_event_(nullptr),
+ mime_data_(nullptr)
+{
+}
+
+const TimelineCoordinate &TimelineViewMouseEvent::GetCoordinates()
+{
+ return coord_;
+}
+
+const Qt::KeyboardModifiers TimelineViewMouseEvent::GetModifiers()
+{
+ return modifiers_;
+}
+
+const QMimeData* TimelineViewMouseEvent::GetMimeData()
+{
+ return mime_data_;
+}
+
+void TimelineViewMouseEvent::SetMimeData(const QMimeData *data)
+{
+ mime_data_ = data;
+}
+
+void TimelineViewMouseEvent::SetEvent(QEvent *event)
+{
+ source_event_ = event;
+}
+
+void TimelineViewMouseEvent::accept()
+{
+ if (source_event_ != nullptr)
+ source_event_->accept();
+}
+
+void TimelineViewMouseEvent::ignore()
+{
+ if (source_event_ != nullptr)
+ source_event_->ignore();
+}
diff --git a/app/widget/timelineview/timelineviewmouseevent.h b/app/widget/timelineview/timelineviewmouseevent.h
new file mode 100644
index 000000000..61afbb7ba
--- /dev/null
+++ b/app/widget/timelineview/timelineviewmouseevent.h
@@ -0,0 +1,62 @@
+/***
+
+ Olive - Non-Linear Video Editor
+ Copyright (C) 2019 Olive Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+***/
+
+#ifndef TIMELINEVIEWMOUSEEVENT_H
+#define TIMELINEVIEWMOUSEEVENT_H
+
+#include
+#include
+#include
+
+#include "timelinecoordinate.h"
+
+class TimelineViewMouseEvent
+{
+public:
+ TimelineViewMouseEvent(const TimelineCoordinate& coord,
+ const Qt::KeyboardModifiers& modifiers = Qt::NoModifier);
+
+ TimelineViewMouseEvent(const rational& frame,
+ const int& track,
+ const Qt::KeyboardModifiers& modifiers = Qt::NoModifier);
+
+ const TimelineCoordinate& GetCoordinates();
+ const Qt::KeyboardModifiers GetModifiers();
+
+ const QMimeData *GetMimeData();
+ void SetMimeData(const QMimeData *data);
+
+ void SetEvent(QEvent* event);
+
+ void accept();
+ void ignore();
+
+private:
+ TimelineCoordinate coord_;
+
+ Qt::KeyboardModifiers modifiers_;
+
+ QEvent* source_event_;
+
+ const QMimeData* mime_data_;
+
+};
+
+#endif // TIMELINEVIEWMOUSEEVENT_H
diff --git a/app/widget/timelineview/tool/hand.cpp b/app/widget/timelineview/tool/hand.cpp
index b7486dc1b..89d1076a6 100644
--- a/app/widget/timelineview/tool/hand.cpp
+++ b/app/widget/timelineview/tool/hand.cpp
@@ -25,30 +25,5 @@
TimelineView::HandTool::HandTool(TimelineView* parent) :
Tool(parent)
{
-
-}
-
-void TimelineView::HandTool::MousePress(QMouseEvent *event)
-{
- screen_drag_start_ = event->pos();
- scrollbar_start_.setX(parent()->horizontalScrollBar()->value());
- scrollbar_start_.setY(parent()->verticalScrollBar()->value());
- dragging_ = true;
-}
-
-void TimelineView::HandTool::MouseMove(QMouseEvent *event)
-{
- if (dragging_) {
- QPoint drag_diff = event->pos() - screen_drag_start_;
-
- parent()->horizontalScrollBar()->setValue(scrollbar_start_.x() - drag_diff.x());
- parent()->verticalScrollBar()->setValue(scrollbar_start_.y() - drag_diff.y());
- }
-}
-
-void TimelineView::HandTool::MouseRelease(QMouseEvent *event)
-{
- Q_UNUSED(event)
-
- dragging_ = false;
+ set_drag_mode(ScrollHandDrag);
}
diff --git a/app/widget/timelineview/tool/import.cpp b/app/widget/timelineview/tool/import.cpp
index 470f65363..68e4386c5 100644
--- a/app/widget/timelineview/tool/import.cpp
+++ b/app/widget/timelineview/tool/import.cpp
@@ -38,16 +38,16 @@ TimelineView::ImportTool::ImportTool(TimelineView *parent) :
import_pre_buffer_ = QFontMetricsWidth(&fm, "HHHHHHHH");
}
-void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
+void TimelineView::ImportTool::DragEnter(TimelineViewMouseEvent *event)
{
- QStringList mime_formats = event->mimeData()->formats();
+ QStringList mime_formats = event->GetMimeData()->formats();
// Listen for MIME data from a ProjectViewModel
if (mime_formats.contains("application/x-oliveprojectitemdata")) {
// FIXME: Implement audio insertion
// Data is drag/drop data from a ProjectViewModel
- QByteArray model_data = event->mimeData()->data("application/x-oliveprojectitemdata");
+ QByteArray model_data = event->GetMimeData()->data("application/x-oliveprojectitemdata");
// Use QDataStream to deserialize the data
QDataStream stream(&model_data, QIODevice::ReadOnly);
@@ -57,10 +57,11 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
int r;
// Set drag start position
- drag_start_ = GetScenePos(event->pos());
+ drag_start_ = event->GetCoordinates();
// Set ghosts to start where the cursor entered
- rational ghost_start = parent()->SceneToTime(drag_start_.x() - import_pre_buffer_);
+
+ rational ghost_start = drag_start_.GetFrame() - parent()->SceneToTime(import_pre_buffer_);
snap_points_.clear();
@@ -75,32 +76,36 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
// If the Item is Footage, we can create a Ghost from it
Footage* footage = static_cast(item);
- StreamPtr stream = footage->stream(0);
-
- TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
-
rational footage_duration;
- if (stream->type() == Stream::kImage) {
- // Stream is essentially length-less - use config's default image length
- footage_duration = Config::Current()["DefaultStillLength"].value();
- } else {
- // Use duration from file
- footage_duration = rational(stream->timebase().numerator() * stream->duration(),
- stream->timebase().denominator());
+ // Loop through all streams in footage
+ foreach (StreamPtr stream, footage->streams()) {
+ // Check if this stream is compatible with this TrackList
+ if (stream->type() == parent()->TrackTypeToStreamType(parent()->ConnectedTrackType())) {
+ TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
+
+ if (stream->type() == Stream::kImage) {
+ // Stream is essentially length-less - use config's default image length
+ footage_duration = Config::Current()["DefaultStillLength"].value();
+ } else {
+ // Use duration from file
+ footage_duration = rational(stream->timebase().numerator() * stream->duration(),
+ stream->timebase().denominator());
+ }
+
+ ghost->SetIn(ghost_start);
+ ghost->SetOut(ghost_start + footage_duration);
+
+ snap_points_.append(ghost->In());
+ snap_points_.append(ghost->Out());
+
+ ghost->setData(TimelineViewGhostItem::kAttachedFootage, QVariant::fromValue(stream));
+ ghost->SetMode(olive::timeline::kMove);
+
+ parent()->AddGhost(ghost);
+ }
}
- ghost->SetIn(ghost_start);
- ghost->SetOut(ghost_start + footage_duration);
-
- snap_points_.append(ghost->In());
- snap_points_.append(ghost->Out());
-
- ghost->setData(TimelineViewGhostItem::kAttachedFootage, QVariant::fromValue(stream));
- ghost->SetMode(olive::timeline::kMove);
-
- parent()->AddGhost(ghost);
-
// Stack each ghost one after the other
ghost_start += footage_duration;
}
@@ -113,25 +118,22 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
}
}
-void TimelineView::ImportTool::DragMove(QDragMoveEvent *event)
+void TimelineView::ImportTool::DragMove(TimelineViewMouseEvent *event)
{
if (parent()->HasGhosts()) {
- QPointF pos = GetScenePos(event->pos());
- QPointF movement = pos - drag_start_;
+ rational time_movement = event->GetCoordinates().GetFrame() - drag_start_.GetFrame();
- rational time_movement = parent()->SceneToTime(movement.x());
-
- int ghost_track = parent()->SceneToTrack(pos.y());
+ int ghost_track = event->GetCoordinates().GetTrack();
int ghost_y = parent()->GetTrackY(ghost_track);
int ghost_height = parent()->GetTrackHeight(ghost_track);
- time_movement = ValidateFrameMovement(time_movement, parent()->ghost_items_);
-
// If snapping is enabled, check for snap points
if (olive::core.snapping()) {
SnapPoint(snap_points_, &time_movement);
}
+ time_movement = ValidateFrameMovement(time_movement, parent()->ghost_items_);
+
rational earliest_ghost = RATIONAL_MAX;
// Move ghosts to the mouse cursor
@@ -162,7 +164,7 @@ void TimelineView::ImportTool::DragMove(QDragMoveEvent *event)
}
}
-void TimelineView::ImportTool::DragLeave(QDragLeaveEvent *event)
+void TimelineView::ImportTool::DragLeave(QDragLeaveEvent* event)
{
if (parent()->HasGhosts()) {
parent()->ClearGhosts();
@@ -173,7 +175,7 @@ void TimelineView::ImportTool::DragLeave(QDragLeaveEvent *event)
}
}
-void TimelineView::ImportTool::DragDrop(QDropEvent *event)
+void TimelineView::ImportTool::DragDrop(TimelineViewMouseEvent *event)
{
if (parent()->HasGhosts()) {
// We use QObject as the parent for the nodes we create. If there is no TimelineOutput node, this object going out
@@ -204,7 +206,7 @@ void TimelineView::ImportTool::DragDrop(QDropEvent *event)
NodeParam::ConnectEdge(transform->matrix_output(), media->matrix_input());
- if (event->keyboardModifiers() & Qt::ControlModifier) {
+ if (event->GetModifiers() & Qt::ControlModifier) {
//emit parent()->RequestInsertBlockAtTime(clip, ghost->GetAdjustedIn());
} else {
new TrackPlaceBlockCommand(parent()->timeline_node_, ghost->Track(), clip, ghost->GetAdjustedIn(), command);
diff --git a/app/widget/timelineview/tool/pointer.cpp b/app/widget/timelineview/tool/pointer.cpp
index eaa013fae..545674dcf 100644
--- a/app/widget/timelineview/tool/pointer.cpp
+++ b/app/widget/timelineview/tool/pointer.cpp
@@ -24,6 +24,7 @@
#include
#include "common/clamp.h"
+#include "common/flipmodifiers.h"
#include "common/range.h"
#include "common/timecodefunctions.h"
#include "config/config.h"
@@ -36,44 +37,25 @@ TimelineView::PointerTool::PointerTool(TimelineView *parent) :
trimming_allowed_(true),
track_movement_allowed_(true)
{
+ set_drag_mode(RubberBandDrag);
+ set_enable_default_behavior(true);
}
-void FlipControlAndShiftModifiers(QMouseEvent* e) {
- if (e->modifiers() & Qt::ControlModifier & Qt::ShiftModifier) {
- return;
- }
-
- if (e->modifiers() & Qt::ShiftModifier) {
- e->setModifiers((e->modifiers() | Qt::ControlModifier) & ~Qt::ShiftModifier);
- } else if (e->modifiers() & Qt::ControlModifier) {
- e->setModifiers((e->modifiers() | Qt::ShiftModifier) & ~Qt::ControlModifier);
- }
-}
-
-void TimelineView::PointerTool::MousePress(QMouseEvent *event)
+void TimelineView::PointerTool::MousePress(TimelineViewMouseEvent *event)
{
- // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
- FlipControlAndShiftModifiers(event);
-
- // Default QGraphicsView behavior (item selection)
- parent()->QGraphicsView::mousePressEvent(event);
-
// We don't initiate dragging here since clicking could easily be just for selecting
+ Q_UNUSED(event)
}
-void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
+void TimelineView::PointerTool::MouseMove(TimelineViewMouseEvent *event)
{
- // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
- FlipControlAndShiftModifiers(event);
-
- // Default QGraphicsView behavior (item selection)
- parent()->QGraphicsView::mouseMoveEvent(event);
+ qDebug() << dragging_ << parent()->ghost_items_.isEmpty();
// Now that the cursor has moved, we will assume the intention is to drag
if (!dragging_) {
// If we haven't started dragging yet, we'll initiate a drag here
- InitiateDrag(event->pos());
+ InitiateDrag(event->GetCoordinates());
// Set dragging to true here so no matter what, the drag isn't re-initiated until it's completed
dragging_ = true;
@@ -81,19 +63,13 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
} else if (!parent()->ghost_items_.isEmpty()) {
// We're already dragging AND we have ghosts to work with
- ProcessDrag(event->pos());
+ ProcessDrag(event->GetCoordinates());
}
}
-void TimelineView::PointerTool::MouseRelease(QMouseEvent *event)
+void TimelineView::PointerTool::MouseRelease(TimelineViewMouseEvent *event)
{
- // We use Shift for multiple selection while Qt uses Ctrl, we flip those modifiers here to compensate
- FlipControlAndShiftModifiers(event);
-
- // Default QGraphicsView behavior (item selection)
- parent()->QGraphicsView::mouseReleaseEvent(event);
-
if (!parent()->ghost_items_.isEmpty()) {
MouseReleaseInternal(event);
}
@@ -121,7 +97,7 @@ void TimelineView::PointerTool::SetTrimmingAllowed(bool allowed)
trimming_allowed_ = allowed;
}
-void TimelineView::PointerTool::MouseReleaseInternal(QMouseEvent *event)
+void TimelineView::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
@@ -177,13 +153,13 @@ rational TimelineView::PointerTool::FrameValidateInternal(rational time_movement
return time_movement;
}
-void TimelineView::PointerTool::InitiateDrag(const QPoint& mouse_pos)
+void TimelineView::PointerTool::InitiateDrag(const TimelineCoordinate &mouse_pos)
{
// Record where the drag started in timeline coordinates
- drag_start_ = GetScenePos(mouse_pos);
+ drag_start_ = mouse_pos;
// Get the item that was clicked
- TimelineViewBlockItem* clicked_item = dynamic_cast(GetItemAtScenePos(drag_start_));
+ TimelineViewBlockItem* clicked_item = GetItemAtScenePos(drag_start_);
// We only initiate a pointer drag if the user actually dragged an item, otherwise if they dragged on empty space
// QGraphicsView default behavior would initiate a rubberband drag
@@ -193,7 +169,7 @@ void TimelineView::PointerTool::InitiateDrag(const QPoint& mouse_pos)
snap_points_.clear();
// Record where the drag started in timeline coordinates
- track_start_ = parent()->SceneToTrack(drag_start_.y());
+ track_start_ = mouse_pos.GetTrack();
// Determine whether we're trimming or moving based on the position of the cursor
olive::timeline::MovementMode trim_mode = olive::timeline::kNone;
@@ -201,9 +177,11 @@ void TimelineView::PointerTool::InitiateDrag(const QPoint& mouse_pos)
// FIXME: Hardcoded number
const int kTrimHandle = 20;
- if (trimming_allowed_ && drag_start_.x() < clicked_item->x() + kTrimHandle) {
+ qreal mouse_x = parent()->TimeToScreenCoord(mouse_pos.GetFrame());
+
+ if (trimming_allowed_ && mouse_x < clicked_item->x() + kTrimHandle) {
trim_mode = olive::timeline::kTrimIn;
- } else if (trimming_allowed_ && drag_start_.x() > clicked_item->x() + clicked_item->rect().right() - kTrimHandle) {
+ } else if (trimming_allowed_ && mouse_x > clicked_item->x() + clicked_item->rect().right() - kTrimHandle) {
trim_mode = olive::timeline::kTrimOut;
} else if (movement_allowed_) {
// Some derived classes don't allow movement
@@ -222,14 +200,10 @@ void TimelineView::PointerTool::InitiateDrag(const QPoint& mouse_pos)
}
}
-void TimelineView::PointerTool::ProcessDrag(const QPoint &mouse_pos)
+void TimelineView::PointerTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
{
- // Retrieve cursor position difference
- QPointF scene_pos = GetScenePos(mouse_pos);
- QPointF movement = scene_pos - drag_start_;
-
// Determine track movement
- int cursor_track = parent()->SceneToTrack(scene_pos.y());
+ int cursor_track = mouse_pos.GetTrack();
int track_movement = 0;
if (track_movement_allowed_) {
@@ -237,7 +211,7 @@ void TimelineView::PointerTool::ProcessDrag(const QPoint &mouse_pos)
}
// Determine frame movement
- rational time_movement = parent()->SceneToTime(movement.x());
+ rational time_movement = mouse_pos.GetFrame() - drag_start_.GetFrame();
// Perform snapping if enabled (adjusts time_movement if it's close to any potential snap points)
if (olive::core.snapping()) {
diff --git a/app/widget/timelineview/tool/razor.cpp b/app/widget/timelineview/tool/razor.cpp
index 1eab31cf6..b6e02f206 100644
--- a/app/widget/timelineview/tool/razor.cpp
+++ b/app/widget/timelineview/tool/razor.cpp
@@ -25,36 +25,34 @@ TimelineView::RazorTool::RazorTool(TimelineView* parent) :
{
}
-void TimelineView::RazorTool::MousePress(QMouseEvent *event)
+void TimelineView::RazorTool::MousePress(TimelineViewMouseEvent *event)
{
split_tracks_.clear();
MouseMove(event);
}
-void TimelineView::RazorTool::MouseMove(QMouseEvent *event)
+void TimelineView::RazorTool::MouseMove(TimelineViewMouseEvent *event)
{
if (!dragging_) {
- drag_start_ = GetScenePos(event->pos());
+ drag_start_ = event->GetCoordinates();
dragging_ = true;
}
- QPointF current_scene_pos = GetScenePos(event->pos());
-
// Split at the current cursor track
- int split_track = parent()->SceneToTrack(current_scene_pos.y());
+ int split_track = event->GetCoordinates().GetTrack();
if (!split_tracks_.contains(split_track)) {
split_tracks_.append(split_track);
}
}
-void TimelineView::RazorTool::MouseRelease(QMouseEvent *event)
+void TimelineView::RazorTool::MouseRelease(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
// Always split at the same time
- rational split_time = parent()->SceneToTime(drag_start_.x());
+ rational split_time = drag_start_.GetFrame();
QUndoCommand* command = new QUndoCommand();
diff --git a/app/widget/timelineview/tool/ripple.cpp b/app/widget/timelineview/tool/ripple.cpp
index d030fe435..a42345ad0 100644
--- a/app/widget/timelineview/tool/ripple.cpp
+++ b/app/widget/timelineview/tool/ripple.cpp
@@ -28,7 +28,7 @@ TimelineView::RippleTool::RippleTool(TimelineView* parent) :
SetMovementAllowed(false);
}
-void TimelineView::RippleTool::MouseReleaseInternal(QMouseEvent *event)
+void TimelineView::RippleTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
diff --git a/app/widget/timelineview/tool/rolling.cpp b/app/widget/timelineview/tool/rolling.cpp
index f6e839c90..2db6f8bc6 100644
--- a/app/widget/timelineview/tool/rolling.cpp
+++ b/app/widget/timelineview/tool/rolling.cpp
@@ -28,7 +28,7 @@ TimelineView::RollingTool::RollingTool(TimelineView* parent) :
SetMovementAllowed(false);
}
-void TimelineView::RollingTool::MouseReleaseInternal(QMouseEvent *event)
+void TimelineView::RollingTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
diff --git a/app/widget/timelineview/tool/slide.cpp b/app/widget/timelineview/tool/slide.cpp
index 8f466fb10..46d89e313 100644
--- a/app/widget/timelineview/tool/slide.cpp
+++ b/app/widget/timelineview/tool/slide.cpp
@@ -29,7 +29,7 @@ TimelineView::SlideTool::SlideTool(TimelineView* parent) :
SetTrackMovementAllowed(false);
}
-void TimelineView::SlideTool::MouseReleaseInternal(QMouseEvent *event)
+void TimelineView::SlideTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
diff --git a/app/widget/timelineview/tool/slip.cpp b/app/widget/timelineview/tool/slip.cpp
index d70aa1916..a095ac99b 100644
--- a/app/widget/timelineview/tool/slip.cpp
+++ b/app/widget/timelineview/tool/slip.cpp
@@ -32,14 +32,10 @@ TimelineView::SlipTool::SlipTool(TimelineView *parent) :
SetTrackMovementAllowed(false);
}
-void TimelineView::SlipTool::ProcessDrag(const QPoint &mouse_pos)
+void TimelineView::SlipTool::ProcessDrag(const TimelineCoordinate &mouse_pos)
{
- // Retrieve cursor position difference
- QPointF scene_pos = GetScenePos(mouse_pos);
- QPointF movement = scene_pos - drag_start_;
-
// Determine frame movement
- rational time_movement = -parent()->SceneToTime(movement.x());
+ rational time_movement = drag_start_.GetFrame() - mouse_pos.GetFrame();
// Validate slip (enforce all ghosts moving in legal ways)
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
@@ -65,7 +61,7 @@ void TimelineView::SlipTool::ProcessDrag(const QPoint &mouse_pos)
parent());
}
-void TimelineView::SlipTool::MouseReleaseInternal(QMouseEvent *event)
+void TimelineView::SlipTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
diff --git a/app/widget/timelineview/tool/tool.cpp b/app/widget/timelineview/tool/tool.cpp
index 77a99b322..6b5219e12 100644
--- a/app/widget/timelineview/tool/tool.cpp
+++ b/app/widget/timelineview/tool/tool.cpp
@@ -26,25 +26,15 @@
TimelineView::Tool::Tool(TimelineView *parent) :
dragging_(false),
- parent_(parent)
+ parent_(parent),
+ drag_mode_(NoDrag),
+ enable_default_behavior_(false)
{
}
-TimelineView::Tool::~Tool(){}
-
-void TimelineView::Tool::MousePress(QMouseEvent *){}
-
-void TimelineView::Tool::MouseMove(QMouseEvent *){}
-
-void TimelineView::Tool::MouseRelease(QMouseEvent *){}
-
-void TimelineView::Tool::DragEnter(QDragEnterEvent *){}
-
-void TimelineView::Tool::DragMove(QDragMoveEvent *){}
-
-void TimelineView::Tool::DragLeave(QDragLeaveEvent *){}
-
-void TimelineView::Tool::DragDrop(QDropEvent *){}
+TimelineView::Tool::~Tool()
+{
+}
TimelineView *TimelineView::Tool::parent()
{
@@ -64,14 +54,44 @@ olive::timeline::MovementMode TimelineView::Tool::FlipTrimMode(const olive::time
return trim_mode;
}
-QPointF TimelineView::Tool::GetScenePos(const QPoint &screen_pos)
+const QGraphicsView::DragMode &TimelineView::Tool::drag_mode()
{
- return parent()->mapToScene(screen_pos);
+ return drag_mode_;
}
-QGraphicsItem *TimelineView::Tool::GetItemAtScenePos(const QPointF &scene_pos)
+bool TimelineView::Tool::enable_default_behavior()
{
- return parent()->scene_.itemAt(scene_pos, parent()->transform());
+ return enable_default_behavior_;
+}
+
+void TimelineView::Tool::set_drag_mode(const QGraphicsView::DragMode &mode)
+{
+ drag_mode_ = mode;
+}
+
+void TimelineView::Tool::set_enable_default_behavior(bool enable)
+{
+ enable_default_behavior_ = enable;
+}
+
+TimelineViewBlockItem *TimelineView::Tool::GetItemAtScenePos(const TimelineCoordinate& coord)
+{
+ QMapIterator iterator(parent()->block_items_);
+
+ while (iterator.hasNext()) {
+ iterator.next();
+
+ Block* b = iterator.key();
+ TimelineViewBlockItem* item = iterator.value();
+
+ if (b->in() <= coord.GetFrame()
+ && b->out() > coord.GetFrame()
+ && item->Track() == coord.GetTrack()) {
+ return item;
+ }
+ }
+
+ return nullptr;
}
void AttemptSnap(const QList& proposed_pts,
diff --git a/app/widget/timelineview/tool/zoom.cpp b/app/widget/timelineview/tool/zoom.cpp
index da9f786fe..6215fba8b 100644
--- a/app/widget/timelineview/tool/zoom.cpp
+++ b/app/widget/timelineview/tool/zoom.cpp
@@ -25,26 +25,31 @@ TimelineView::ZoomTool::ZoomTool(TimelineView* parent) :
{
}
-void TimelineView::ZoomTool::MousePress(QMouseEvent *event)
+void TimelineView::ZoomTool::MousePress(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
}
-void TimelineView::ZoomTool::MouseMove(QMouseEvent *event)
+void TimelineView::ZoomTool::MouseMove(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
}
-void TimelineView::ZoomTool::MouseRelease(QMouseEvent *event)
+void TimelineView::ZoomTool::MouseRelease(TimelineViewMouseEvent *event)
{
double scale = parent()->scale_;
- QPointF center_location = parent()->mapToScene(event->pos());
+ // Get center of viewport
+ QPoint viewport_center = parent()->viewport()->rect().center();
+ QPointF scene_center = parent()->mapToScene(viewport_center);
+
+ // Set X to time
+ scene_center.setX(parent()->TimeToScreenCoord(event->GetCoordinates().GetFrame()));
// Normalize zoom location for 1.0 scale
- double scaled_x = center_location.x() / scale;
+ double scaled_x = scene_center.x() / scale;
- if (event->modifiers() & Qt::AltModifier) {
+ if (event->GetModifiers() & Qt::AltModifier) {
// Zoom out if the user clicks while holding Alt
scale *= 0.5;
} else {
@@ -57,7 +62,7 @@ void TimelineView::ZoomTool::MouseRelease(QMouseEvent *event)
// Adjust zoom location for new scale
scaled_x *= scale;
- center_location.setX(scaled_x);
+ scene_center.setX(scaled_x);
- parent()->centerOn(center_location);
+ parent()->centerOn(scene_center);
}
diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp
index b9d3dc078..8ee886c32 100644
--- a/app/widget/timelinewidget/timelinewidget.cpp
+++ b/app/widget/timelinewidget/timelinewidget.cpp
@@ -120,7 +120,7 @@ void TimelineWidget::ConnectTimelineNode(TimelineOutput *node)
int track_type = 0;
foreach (TimelineView* view, views_) {
- view->ConnectTimelineNode(node->track_list(static_cast(track_type)));
+ view->ConnectTimelineNode(node->track_list(static_cast(track_type)));
track_type++;
}