updated timeline tools to take custom mouse events

This commit is contained in:
itsmattkc
2019-10-11 09:35:11 +11:00
parent df9255ce0b
commit 405f4e5e00
29 changed files with 720 additions and 304 deletions
+2
View File
@@ -22,6 +22,8 @@ set(OLIVE_SOURCES
common/debug.cpp common/debug.cpp
common/filefunctions.h common/filefunctions.h
common/filefunctions.cpp common/filefunctions.cpp
common/flipmodifiers.h
common/flipmodifiers.cpp
common/lerp.h common/lerp.h
common/range.h common/range.h
common/rational.h common/rational.h
+37
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#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;
}
+28
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#ifndef FLIPMODIFIERS_H
#define FLIPMODIFIERS_H
#include <QtCore>
Qt::KeyboardModifiers FlipControlAndShiftModifiers(Qt::KeyboardModifiers e);
#endif // FLIPMODIFIERS_H
+3 -3
View File
@@ -39,7 +39,7 @@ TimelineOutput::TimelineOutput()
AddParameter(track_input); AddParameter(track_input);
track_inputs_[i] = track_input; track_inputs_[i] = track_input;
TrackList* list = new TrackList(this, track_input); TrackList* list = new TrackList(this, static_cast<TrackType>(i), track_input);
track_lists_[i] = list; track_lists_[i] = list;
connect(list, SIGNAL(TrackListChanged()), this, SLOT(UpdateTrackCache())); connect(list, SIGNAL(TrackListChanged()), this, SLOT(UpdateTrackCache()));
connect(list, SIGNAL(LengthChanged(const rational &)), this, SLOT(UpdateLength(const rational &))); 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); return track_inputs_.at(type);
} }
TrackList *TimelineOutput::track_list(TimelineOutput::TrackType type) TrackList *TimelineOutput::track_list(TrackType type)
{ {
return track_lists_.at(type); return track_lists_.at(type);
} }
+1 -8
View File
@@ -25,6 +25,7 @@
#include "node/block/block.h" #include "node/block/block.h"
#include "node/output/track/track.h" #include "node/output/track/track.h"
#include "tracklist.h" #include "tracklist.h"
#include "tracktypes.h"
/** /**
* @brief Node that represents the end of the Timeline as well as a time traversal Node * @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 Q_OBJECT
public: public:
enum TrackType {
kTrackTypeNone = -1,
kTrackTypeVideo,
kTrackTypeAudio,
kTrackTypeSubtitle,
kTrackTypeCount
};
TimelineOutput(); TimelineOutput();
virtual QString Name() override; virtual QString Name() override;
+8 -2
View File
@@ -23,9 +23,10 @@
#include "node/blend/alphaover/alphaover.h" #include "node/blend/alphaover/alphaover.h"
#include "timeline.h" #include "timeline.h"
TrackList::TrackList(TimelineOutput* parent, NodeInput *track_input) : TrackList::TrackList(TimelineOutput* parent, const enum TrackType &type, NodeInput *track_input) :
QObject(parent), QObject(parent),
track_input_(track_input) track_input_(track_input),
type_(type)
{ {
connect(parent, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(TrackConnectionAdded(NodeEdgePtr))); connect(parent, SIGNAL(EdgeAdded(NodeEdgePtr)), this, SLOT(TrackConnectionAdded(NodeEdgePtr)));
connect(parent, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackConnectionRemoved(NodeEdgePtr))); connect(parent, SIGNAL(EdgeRemoved(NodeEdgePtr)), this, SLOT(TrackConnectionRemoved(NodeEdgePtr)));
@@ -125,6 +126,11 @@ const rational &TrackList::TrackLength()
return total_length_; return total_length_;
} }
const enum TrackType &TrackList::TrackType()
{
return type_;
}
void TrackList::AddTrack() void TrackList::AddTrack()
{ {
TrackOutput* track = new TrackOutput(); TrackOutput* track = new TrackOutput();
+6 -1
View File
@@ -25,13 +25,14 @@
#include "node/graph.h" #include "node/graph.h"
#include "node/output/track/track.h" #include "node/output/track/track.h"
#include "tracktypes.h"
class TimelineOutput; class TimelineOutput;
class TrackList : public QObject { class TrackList : public QObject {
Q_OBJECT Q_OBJECT
public: public:
TrackList(TimelineOutput *parent, NodeInput* track_input); TrackList(TimelineOutput *parent, const enum TrackType& type, NodeInput* track_input);
TrackOutput* attached_track(); TrackOutput* attached_track();
@@ -53,6 +54,8 @@ public:
const rational& TrackLength(); const rational& TrackLength();
const enum TrackType& TrackType();
public slots:/** public slots:/**
* @brief Slot for when the track connection is added * @brief Slot for when the track connection is added
*/ */
@@ -114,6 +117,8 @@ private:
rational total_length_; rational total_length_;
enum TrackType type_;
private slots: private slots:
void UpdateTotalLength(); void UpdateTotalLength();
}; };
+12
View File
@@ -0,0 +1,12 @@
#ifndef TRACKTYPES_H
#define TRACKTYPES_H
enum TrackType {
kTrackTypeNone = -1,
kTrackTypeVideo,
kTrackTypeAudio,
kTrackTypeSubtitle,
kTrackTypeCount
};
#endif // TRACKTYPES_H
+2 -2
View File
@@ -84,8 +84,8 @@ void Sequence::AddDefaultNodes()
NodeParam::ConnectEdge(renderer_processor_->texture_output(), viewer_output_->texture_input()); NodeParam::ConnectEdge(renderer_processor_->texture_output(), viewer_output_->texture_input());
// Connect track to timeline // Connect track to timeline
NodeParam::ConnectEdge(video_track_output_->track_output(), timeline_output_->track_input(TimelineOutput::kTrackTypeVideo)); NodeParam::ConnectEdge(video_track_output_->track_output(), timeline_output_->track_input(kTrackTypeVideo));
NodeParam::ConnectEdge(audio_track_output_->track_output(), timeline_output_->track_input(TimelineOutput::kTrackTypeAudio)); NodeParam::ConnectEdge(audio_track_output_->track_output(), timeline_output_->track_input(kTrackTypeAudio));
// Connect timeline end point to renderer // Connect timeline end point to renderer
NodeParam::ConnectEdge(timeline_output_->length_output(), renderer_processor_->length_input()); NodeParam::ConnectEdge(timeline_output_->length_output(), renderer_processor_->length_input());
+3 -1
View File
@@ -66,7 +66,9 @@ enum Tool {
kRecord, kRecord,
/// Add tool /// Add tool
kAdd kAdd,
kCount
}; };
} }
+4
View File
@@ -19,12 +19,16 @@ add_subdirectory(undo)
set(OLIVE_SOURCES set(OLIVE_SOURCES
${OLIVE_SOURCES} ${OLIVE_SOURCES}
widget/timelineview/timelinecoordinate.h
widget/timelineview/timelinecoordinate.cpp
widget/timelineview/timelineplayhead.h widget/timelineview/timelineplayhead.h
widget/timelineview/timelineplayhead.cpp widget/timelineview/timelineplayhead.cpp
widget/timelineview/timelinescaledobject.h widget/timelineview/timelinescaledobject.h
widget/timelineview/timelinescaledobject.cpp widget/timelineview/timelinescaledobject.cpp
widget/timelineview/timelineview.h widget/timelineview/timelineview.h
widget/timelineview/timelineview.cpp widget/timelineview/timelineview.cpp
widget/timelineview/timelineviewmouseevent.h
widget/timelineview/timelineviewmouseevent.cpp
widget/timelineview/timelineviewrect.h widget/timelineview/timelineviewrect.h
widget/timelineview/timelineviewrect.cpp widget/timelineview/timelineviewrect.cpp
widget/timelineview/timelineviewblockitem.h widget/timelineview/timelineviewblockitem.h
@@ -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 <http://www.gnu.org/licenses/>.
***/
#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;
}
@@ -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 <http://www.gnu.org/licenses/>.
***/
#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
+162 -58
View File
@@ -27,6 +27,7 @@
#include <QtMath> #include <QtMath>
#include <QPen> #include <QPen>
#include "common/flipmodifiers.h"
#include "common/timecodefunctions.h" #include "common/timecodefunctions.h"
#include "core.h" #include "core.h"
#include "node/input/media/media.h" #include "node/input/media/media.h"
@@ -35,15 +36,6 @@
TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) : TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
QGraphicsView(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), timeline_node_(nullptr),
playhead_(0), playhead_(0),
use_tracklist_length_directly_(true) use_tracklist_length_directly_(true)
@@ -56,6 +48,25 @@ TimelineView::TimelineView(Qt::Alignment vertical_alignment, QWidget *parent) :
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setBackgroundRole(QPalette::Window); setBackgroundRole(QPalette::Window);
// Create tools
tools_.resize(olive::tool::kCount);
tools_.fill(nullptr);
tools_.replace(olive::tool::kPointer, std::make_shared<PointerTool>(this));
// tools_.replace(olive::tool::kEdit, new PointerTool(this)); FIXME: Implement
tools_.replace(olive::tool::kRipple, std::make_shared<RippleTool>(this));
tools_.replace(olive::tool::kRolling, std::make_shared<RollingTool>(this));
tools_.replace(olive::tool::kRazor, std::make_shared<RazorTool>(this));
tools_.replace(olive::tool::kSlip, std::make_shared<SlipTool>(this));
tools_.replace(olive::tool::kSlide, std::make_shared<SlideTool>(this));
tools_.replace(olive::tool::kHand, std::make_shared<HandTool>(this));
tools_.replace(olive::tool::kZoom, std::make_shared<ZoomTool>(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<ImportTool>(this);
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect())); connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect()));
// Create end item // Create end item
@@ -121,7 +132,7 @@ void TimelineView::SetScale(const double &scale)
{ {
scale_ = scale; scale_ = scale;
QMapIterator<Block*, TimelineViewRect*> iterator(block_items_); QMapIterator<Block*, TimelineViewBlockItem*> iterator(block_items_);
while (iterator.hasNext()) { while (iterator.hasNext()) {
iterator.next(); iterator.next();
@@ -145,11 +156,14 @@ void TimelineView::SetTimebase(const rational &timebase)
{ {
timebase_ = timebase; timebase_ = timebase;
timebase_dbl_ = timebase_.toDouble(); timebase_dbl_ = timebase_.toDouble();
// Timebase influences position/visibility of playhead
viewport()->update();
} }
void TimelineView::Clear() void TimelineView::Clear()
{ {
QMapIterator<Block*, TimelineViewRect*> iterator(block_items_); QMapIterator<Block*, TimelineViewBlockItem*> iterator(block_items_);
while (iterator.hasNext()) { while (iterator.hasNext()) {
iterator.next(); iterator.next();
@@ -239,50 +253,131 @@ void TimelineView::mousePressEvent(QMouseEvent *event)
{ {
active_tool_ = GetActiveTool(); 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) { 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) 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) { 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) 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) { 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) void TimelineView::dragEnterEvent(QDragEnterEvent *event)
{ {
if (timeline_node_ != nullptr) { 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) void TimelineView::dragMoveEvent(QDragMoveEvent *event)
{ {
if (timeline_node_ != nullptr) { 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) void TimelineView::dragLeaveEvent(QDragLeaveEvent *event)
{ {
if (timeline_node_ != nullptr) { if (timeline_node_ != nullptr) {
import_tool_.DragLeave(event); import_tool_->DragLeave(event);
} }
} }
void TimelineView::dropEvent(QDropEvent *event) void TimelineView::dropEvent(QDropEvent *event)
{ {
if (timeline_node_ != nullptr) { 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); QGraphicsView::drawForeground(painter, rect);
double x = TimeToScreenCoord(rational(playhead_ * timebase_.numerator(), timebase_.denominator())); if (!timebase_.isNull()) {
double width = TimeToScreenCoord(timebase_); 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->setPen(Qt::NoPen);
painter->setBrush(playhead_style_.PlayheadHighlightColor()); painter->setBrush(playhead_style_.PlayheadHighlightColor());
painter->drawRect(playhead_rect); painter->drawRect(playhead_rect);
painter->setPen(playhead_style_.PlayheadColor()); painter->setPen(playhead_style_.PlayheadColor());
painter->setBrush(Qt::NoBrush); painter->setBrush(Qt::NoBrush);
painter->drawLine(QLineF(playhead_rect.topLeft(), playhead_rect.bottomLeft())); 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() TimelineView::Tool *TimelineView::GetActiveTool()
{ {
switch (olive::core.tool()) { return tools_.at(olive::core.tool()).get();
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;
} }
int TimelineView::GetTrackY(int track_index) int TimelineView::GetTrackY(int track_index)
@@ -383,7 +487,7 @@ bool TimelineView::HasGhosts()
rational TimelineView::SceneToTime(const double &x) rational TimelineView::SceneToTime(const double &x)
{ {
// Adjust screen point by scale and timebase // 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 a time in the timebase
return rational(scaled_x_mvmt * timebase_.numerator(), timebase_.denominator()); return rational(scaled_x_mvmt * timebase_.numerator(), timebase_.denominator());
+53 -50
View File
@@ -31,6 +31,7 @@
#include "node/output/timeline/timeline.h" #include "node/output/timeline/timeline.h"
#include "timelineplayhead.h" #include "timelineplayhead.h"
#include "timelineviewblockitem.h" #include "timelineviewblockitem.h"
#include "timelineviewmouseevent.h"
#include "timelineviewenditem.h" #include "timelineviewenditem.h"
#include "timelineviewghostitem.h" #include "timelineviewghostitem.h"
#include "widget/timelineview/undo/undo.h" #include "widget/timelineview/undo/undo.h"
@@ -91,6 +92,7 @@ protected:
virtual void mousePressEvent(QMouseEvent *event) override; virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override; virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override; virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dragMoveEvent(QDragMoveEvent *event) override; virtual void dragMoveEvent(QDragMoveEvent *event) override;
@@ -109,27 +111,28 @@ private:
Tool(TimelineView* parent); Tool(TimelineView* parent);
virtual ~Tool(); virtual ~Tool();
virtual void MousePress(QMouseEvent *event); virtual void MousePress(TimelineViewMouseEvent *){}
virtual void MouseMove(QMouseEvent *event); virtual void MouseMove(TimelineViewMouseEvent *){}
virtual void MouseRelease(QMouseEvent *event); virtual void MouseRelease(TimelineViewMouseEvent *){}
virtual void MouseDoubleClick(TimelineViewMouseEvent *){}
virtual void DragEnter(QDragEnterEvent *event); virtual void DragEnter(TimelineViewMouseEvent *){}
virtual void DragMove(QDragMoveEvent *event); virtual void DragMove(TimelineViewMouseEvent *){}
virtual void DragLeave(QDragLeaveEvent *event); virtual void DragLeave(QDragLeaveEvent *){}
virtual void DragDrop(QDropEvent *event); virtual void DragDrop(TimelineViewMouseEvent *){}
TimelineView* parent(); TimelineView* parent();
static olive::timeline::MovementMode FlipTrimMode(const olive::timeline::MovementMode& trim_mode); static olive::timeline::MovementMode FlipTrimMode(const olive::timeline::MovementMode& trim_mode);
const DragMode& drag_mode();
bool enable_default_behavior();
protected: protected:
/** void set_drag_mode(const DragMode& mode);
* @brief Convert a integer screen point to a float scene point
* void set_enable_default_behavior(bool enable);
* 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);
/** /**
* @brief Retrieve the QGraphicsItem at a particular scene position * @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 * Requires a float-based scene position. If you have a screen position, use GetScenePos() first to convert it to a
* scene position * scene position
*/ */
QGraphicsItem* GetItemAtScenePos(const QPointF& scene_pos); TimelineViewBlockItem* GetItemAtScenePos(const TimelineCoordinate &coord);
/** /**
* @brief Validates Ghosts that are moving horizontally (time-based) * @brief Validates Ghosts that are moving horizontally (time-based)
@@ -169,11 +172,15 @@ private:
bool dragging_; bool dragging_;
QPointF drag_start_; TimelineCoordinate drag_start_;
private: private:
TimelineView* parent_; TimelineView* parent_;
DragMode drag_mode_;
bool enable_default_behavior_;
}; };
class PointerTool : public Tool class PointerTool : public Tool
@@ -181,14 +188,14 @@ private:
public: public:
PointerTool(TimelineView* parent); PointerTool(TimelineView* parent);
virtual void MousePress(QMouseEvent *event) override; virtual void MousePress(TimelineViewMouseEvent *event) override;
virtual void MouseMove(QMouseEvent *event) override; virtual void MouseMove(TimelineViewMouseEvent *event) override;
virtual void MouseRelease(QMouseEvent *event) override; virtual void MouseRelease(TimelineViewMouseEvent *event) override;
protected: protected:
void SetMovementAllowed(bool allowed); void SetMovementAllowed(bool allowed);
void SetTrackMovementAllowed(bool allowed); void SetTrackMovementAllowed(bool allowed);
void SetTrimmingAllowed(bool allowed); void SetTrimmingAllowed(bool allowed);
virtual void MouseReleaseInternal(QMouseEvent *event); virtual void MouseReleaseInternal(TimelineViewMouseEvent *event);
virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem *> &ghosts); virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem *> &ghosts);
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item, virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
@@ -215,9 +222,9 @@ private:
*/ */
rational ValidateOutTrimming(rational movement, const QVector<TimelineViewGhostItem*> ghosts, bool prevent_overwriting); rational ValidateOutTrimming(rational movement, const QVector<TimelineViewGhostItem*> ghosts, bool prevent_overwriting);
virtual void ProcessDrag(const QPoint &mouse_pos); virtual void ProcessDrag(const TimelineCoordinate &mouse_pos);
private: private:
void InitiateDrag(const QPoint &mouse_pos); void InitiateDrag(const TimelineCoordinate &mouse_pos);
void AddGhostInternal(TimelineViewGhostItem* ghost, olive::timeline::MovementMode mode); void AddGhostInternal(TimelineViewGhostItem* ghost, olive::timeline::MovementMode mode);
@@ -238,10 +245,10 @@ private:
public: public:
ImportTool(TimelineView* parent); ImportTool(TimelineView* parent);
virtual void DragEnter(QDragEnterEvent *event) override; virtual void DragEnter(TimelineViewMouseEvent *event) override;
virtual void DragMove(QDragMoveEvent *event) override; virtual void DragMove(TimelineViewMouseEvent *event) override;
virtual void DragLeave(QDragLeaveEvent *event) override; virtual void DragLeave(QDragLeaveEvent *event) override;
virtual void DragDrop(QDropEvent *event) override; virtual void DragDrop(TimelineViewMouseEvent *event) override;
private: private:
int import_pre_buffer_; int import_pre_buffer_;
}; };
@@ -251,9 +258,9 @@ private:
public: public:
RazorTool(TimelineView* parent); RazorTool(TimelineView* parent);
virtual void MousePress(QMouseEvent *event); virtual void MousePress(TimelineViewMouseEvent *event);
virtual void MouseMove(QMouseEvent *event); virtual void MouseMove(TimelineViewMouseEvent *event);
virtual void MouseRelease(QMouseEvent *event); virtual void MouseRelease(TimelineViewMouseEvent *event);
private: private:
QVector<int> split_tracks_; QVector<int> split_tracks_;
@@ -264,7 +271,7 @@ private:
public: public:
RippleTool(TimelineView* parent); RippleTool(TimelineView* parent);
protected: protected:
virtual void MouseReleaseInternal(QMouseEvent *event) override; virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem*>& ghosts) override; virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem*>& ghosts) override;
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item, virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
@@ -278,7 +285,7 @@ private:
RollingTool(TimelineView* parent); RollingTool(TimelineView* parent);
protected: protected:
virtual void MouseReleaseInternal(QMouseEvent *event) override; virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem*>& ghosts) override; virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem*>& ghosts) override;
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item, virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
@@ -292,7 +299,7 @@ private:
SlideTool(TimelineView* parent); SlideTool(TimelineView* parent);
protected: protected:
virtual void MouseReleaseInternal(QMouseEvent *event) override; virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem*>& ghosts) override; virtual rational FrameValidateInternal(rational time_movement, const QVector<TimelineViewGhostItem*>& ghosts) override;
virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item, virtual void InitiateGhosts(TimelineViewBlockItem* clicked_item,
olive::timeline::MovementMode trim_mode, olive::timeline::MovementMode trim_mode,
@@ -305,8 +312,8 @@ private:
SlipTool(TimelineView* parent); SlipTool(TimelineView* parent);
protected: protected:
virtual void ProcessDrag(const QPoint &mouse_pos) override; virtual void ProcessDrag(const TimelineCoordinate &mouse_pos) override;
virtual void MouseReleaseInternal(QMouseEvent *event) override; virtual void MouseReleaseInternal(TimelineViewMouseEvent *event) override;
}; };
class HandTool : public Tool class HandTool : public Tool
@@ -314,10 +321,6 @@ private:
public: public:
HandTool(TimelineView* parent); HandTool(TimelineView* parent);
virtual void MousePress(QMouseEvent *event);
virtual void MouseMove(QMouseEvent *event);
virtual void MouseRelease(QMouseEvent *event);
private: private:
QPoint screen_drag_start_; QPoint screen_drag_start_;
QPoint scrollbar_start_; QPoint scrollbar_start_;
@@ -328,25 +331,25 @@ private:
public: public:
ZoomTool(TimelineView* parent); ZoomTool(TimelineView* parent);
virtual void MousePress(QMouseEvent *event); virtual void MousePress(TimelineViewMouseEvent *event);
virtual void MouseMove(QMouseEvent *event); virtual void MouseMove(TimelineViewMouseEvent *event);
virtual void MouseRelease(QMouseEvent *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(); Tool* GetActiveTool();
int GetTrackY(int track_index); int GetTrackY(int track_index);
int GetTrackHeight(int track_index); int GetTrackHeight(int track_index);
PointerTool pointer_tool_; QVector< std::shared_ptr<Tool> > tools_;
ImportTool import_tool_;
RippleTool ripple_tool_; std::shared_ptr<ImportTool> import_tool_;
RollingTool rolling_tool_;
RazorTool razor_tool_;
SlideTool slide_tool_;
SlipTool slip_tool_;
HandTool hand_tool_;
ZoomTool zoom_tool_;
TrackList* timeline_node_; TrackList* timeline_node_;
@@ -369,7 +372,7 @@ private:
int64_t playhead_; int64_t playhead_;
QMap<Block*, TimelineViewRect*> block_items_; QMap<Block*, TimelineViewBlockItem*> block_items_;
QVector<TimelineViewGhostItem*> ghost_items_; QVector<TimelineViewGhostItem*> ghost_items_;
@@ -70,29 +70,41 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
{ {
Q_UNUSED(widget) Q_UNUSED(widget)
if (block_ == nullptr || block_->type() == Block::kGap) { if (block_ == nullptr) {
return; return;
} }
/*QLinearGradient grad; switch (block_->type()) {
grad.setStart(0, rect().top()); case Block::kClip:
grad.setFinalStop(0, rect().bottom()); /*QLinearGradient grad;
grad.setColorAt(0.0, QColor(160, 160, 240)); grad.setStart(0, rect().top());
grad.setColorAt(1.0, QColor(128, 128, 192)); grad.setFinalStop(0, rect().bottom());
painter->fillRect(rect(), grad);*/ grad.setColorAt(0.0, QColor(160, 160, 240));
painter->fillRect(rect(), QColor(128, 128, 192)); 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) { if (option->state & QStyle::State_Selected) {
painter->fillRect(rect(), QColor(0, 0, 0, 64)); 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<int>(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<int>(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()));
} }
@@ -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 <http://www.gnu.org/licenses/>.
***/
#include "timelineviewmouseevent.h"
#include <QEvent>
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();
}
@@ -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 <http://www.gnu.org/licenses/>.
***/
#ifndef TIMELINEVIEWMOUSEEVENT_H
#define TIMELINEVIEWMOUSEEVENT_H
#include <QMimeData>
#include <QPointF>
#include <QPoint>
#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
+1 -26
View File
@@ -25,30 +25,5 @@
TimelineView::HandTool::HandTool(TimelineView* parent) : TimelineView::HandTool::HandTool(TimelineView* parent) :
Tool(parent) Tool(parent)
{ {
set_drag_mode(ScrollHandDrag);
}
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;
} }
+40 -38
View File
@@ -38,16 +38,16 @@ TimelineView::ImportTool::ImportTool(TimelineView *parent) :
import_pre_buffer_ = QFontMetricsWidth(&fm, "HHHHHHHH"); 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 // Listen for MIME data from a ProjectViewModel
if (mime_formats.contains("application/x-oliveprojectitemdata")) { if (mime_formats.contains("application/x-oliveprojectitemdata")) {
// FIXME: Implement audio insertion // FIXME: Implement audio insertion
// Data is drag/drop data from a ProjectViewModel // 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 // Use QDataStream to deserialize the data
QDataStream stream(&model_data, QIODevice::ReadOnly); QDataStream stream(&model_data, QIODevice::ReadOnly);
@@ -57,10 +57,11 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
int r; int r;
// Set drag start position // Set drag start position
drag_start_ = GetScenePos(event->pos()); drag_start_ = event->GetCoordinates();
// Set ghosts to start where the cursor entered // 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(); 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 // If the Item is Footage, we can create a Ghost from it
Footage* footage = static_cast<Footage*>(item); Footage* footage = static_cast<Footage*>(item);
StreamPtr stream = footage->stream(0);
TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
rational footage_duration; rational footage_duration;
if (stream->type() == Stream::kImage) { // Loop through all streams in footage
// Stream is essentially length-less - use config's default image length foreach (StreamPtr stream, footage->streams()) {
footage_duration = Config::Current()["DefaultStillLength"].value<rational>(); // Check if this stream is compatible with this TrackList
} else { if (stream->type() == parent()->TrackTypeToStreamType(parent()->ConnectedTrackType())) {
// Use duration from file TimelineViewGhostItem* ghost = new TimelineViewGhostItem();
footage_duration = rational(stream->timebase().numerator() * stream->duration(),
stream->timebase().denominator()); if (stream->type() == Stream::kImage) {
// Stream is essentially length-less - use config's default image length
footage_duration = Config::Current()["DefaultStillLength"].value<rational>();
} 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 // Stack each ghost one after the other
ghost_start += footage_duration; 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()) { if (parent()->HasGhosts()) {
QPointF pos = GetScenePos(event->pos()); rational time_movement = event->GetCoordinates().GetFrame() - drag_start_.GetFrame();
QPointF movement = pos - drag_start_;
rational time_movement = parent()->SceneToTime(movement.x()); int ghost_track = event->GetCoordinates().GetTrack();
int ghost_track = parent()->SceneToTrack(pos.y());
int ghost_y = parent()->GetTrackY(ghost_track); int ghost_y = parent()->GetTrackY(ghost_track);
int ghost_height = parent()->GetTrackHeight(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 snapping is enabled, check for snap points
if (olive::core.snapping()) { if (olive::core.snapping()) {
SnapPoint(snap_points_, &time_movement); SnapPoint(snap_points_, &time_movement);
} }
time_movement = ValidateFrameMovement(time_movement, parent()->ghost_items_);
rational earliest_ghost = RATIONAL_MAX; rational earliest_ghost = RATIONAL_MAX;
// Move ghosts to the mouse cursor // 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()) { if (parent()->HasGhosts()) {
parent()->ClearGhosts(); 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()) { if (parent()->HasGhosts()) {
// We use QObject as the parent for the nodes we create. If there is no TimelineOutput node, this object going out // 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()); NodeParam::ConnectEdge(transform->matrix_output(), media->matrix_input());
if (event->keyboardModifiers() & Qt::ControlModifier) { if (event->GetModifiers() & Qt::ControlModifier) {
//emit parent()->RequestInsertBlockAtTime(clip, ghost->GetAdjustedIn()); //emit parent()->RequestInsertBlockAtTime(clip, ghost->GetAdjustedIn());
} else { } else {
new TrackPlaceBlockCommand(parent()->timeline_node_, ghost->Track(), clip, ghost->GetAdjustedIn(), command); new TrackPlaceBlockCommand(parent()->timeline_node_, ghost->Track(), clip, ghost->GetAdjustedIn(), command);
+22 -48
View File
@@ -24,6 +24,7 @@
#include <QToolTip> #include <QToolTip>
#include "common/clamp.h" #include "common/clamp.h"
#include "common/flipmodifiers.h"
#include "common/range.h" #include "common/range.h"
#include "common/timecodefunctions.h" #include "common/timecodefunctions.h"
#include "config/config.h" #include "config/config.h"
@@ -36,44 +37,25 @@ TimelineView::PointerTool::PointerTool(TimelineView *parent) :
trimming_allowed_(true), trimming_allowed_(true),
track_movement_allowed_(true) track_movement_allowed_(true)
{ {
set_drag_mode(RubberBandDrag);
set_enable_default_behavior(true);
} }
void FlipControlAndShiftModifiers(QMouseEvent* e) { void TimelineView::PointerTool::MousePress(TimelineViewMouseEvent *event)
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)
{ {
// 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 // 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 qDebug() << dragging_ << parent()->ghost_items_.isEmpty();
FlipControlAndShiftModifiers(event);
// Default QGraphicsView behavior (item selection)
parent()->QGraphicsView::mouseMoveEvent(event);
// Now that the cursor has moved, we will assume the intention is to drag // Now that the cursor has moved, we will assume the intention is to drag
if (!dragging_) { if (!dragging_) {
// If we haven't started dragging yet, we'll initiate a drag here // 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 // Set dragging to true here so no matter what, the drag isn't re-initiated until it's completed
dragging_ = true; dragging_ = true;
@@ -81,19 +63,13 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
} else if (!parent()->ghost_items_.isEmpty()) { } else if (!parent()->ghost_items_.isEmpty()) {
// We're already dragging AND we have ghosts to work with // 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()) { if (!parent()->ghost_items_.isEmpty()) {
MouseReleaseInternal(event); MouseReleaseInternal(event);
} }
@@ -121,7 +97,7 @@ void TimelineView::PointerTool::SetTrimmingAllowed(bool allowed)
trimming_allowed_ = allowed; trimming_allowed_ = allowed;
} }
void TimelineView::PointerTool::MouseReleaseInternal(QMouseEvent *event) void TimelineView::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
@@ -177,13 +153,13 @@ rational TimelineView::PointerTool::FrameValidateInternal(rational time_movement
return 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 // Record where the drag started in timeline coordinates
drag_start_ = GetScenePos(mouse_pos); drag_start_ = mouse_pos;
// Get the item that was clicked // Get the item that was clicked
TimelineViewBlockItem* clicked_item = dynamic_cast<TimelineViewBlockItem*>(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 // 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 // QGraphicsView default behavior would initiate a rubberband drag
@@ -193,7 +169,7 @@ void TimelineView::PointerTool::InitiateDrag(const QPoint& mouse_pos)
snap_points_.clear(); snap_points_.clear();
// Record where the drag started in timeline coordinates // 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 // Determine whether we're trimming or moving based on the position of the cursor
olive::timeline::MovementMode trim_mode = olive::timeline::kNone; olive::timeline::MovementMode trim_mode = olive::timeline::kNone;
@@ -201,9 +177,11 @@ void TimelineView::PointerTool::InitiateDrag(const QPoint& mouse_pos)
// FIXME: Hardcoded number // FIXME: Hardcoded number
const int kTrimHandle = 20; 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; 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; trim_mode = olive::timeline::kTrimOut;
} else if (movement_allowed_) { } else if (movement_allowed_) {
// Some derived classes don't allow movement // 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 // Determine track movement
int cursor_track = parent()->SceneToTrack(scene_pos.y()); int cursor_track = mouse_pos.GetTrack();
int track_movement = 0; int track_movement = 0;
if (track_movement_allowed_) { if (track_movement_allowed_) {
@@ -237,7 +211,7 @@ void TimelineView::PointerTool::ProcessDrag(const QPoint &mouse_pos)
} }
// Determine frame movement // 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) // Perform snapping if enabled (adjusts time_movement if it's close to any potential snap points)
if (olive::core.snapping()) { if (olive::core.snapping()) {
+6 -8
View File
@@ -25,36 +25,34 @@ TimelineView::RazorTool::RazorTool(TimelineView* parent) :
{ {
} }
void TimelineView::RazorTool::MousePress(QMouseEvent *event) void TimelineView::RazorTool::MousePress(TimelineViewMouseEvent *event)
{ {
split_tracks_.clear(); split_tracks_.clear();
MouseMove(event); MouseMove(event);
} }
void TimelineView::RazorTool::MouseMove(QMouseEvent *event) void TimelineView::RazorTool::MouseMove(TimelineViewMouseEvent *event)
{ {
if (!dragging_) { if (!dragging_) {
drag_start_ = GetScenePos(event->pos()); drag_start_ = event->GetCoordinates();
dragging_ = true; dragging_ = true;
} }
QPointF current_scene_pos = GetScenePos(event->pos());
// Split at the current cursor track // 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)) { if (!split_tracks_.contains(split_track)) {
split_tracks_.append(split_track); split_tracks_.append(split_track);
} }
} }
void TimelineView::RazorTool::MouseRelease(QMouseEvent *event) void TimelineView::RazorTool::MouseRelease(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
// Always split at the same time // Always split at the same time
rational split_time = parent()->SceneToTime(drag_start_.x()); rational split_time = drag_start_.GetFrame();
QUndoCommand* command = new QUndoCommand(); QUndoCommand* command = new QUndoCommand();
+1 -1
View File
@@ -28,7 +28,7 @@ TimelineView::RippleTool::RippleTool(TimelineView* parent) :
SetMovementAllowed(false); SetMovementAllowed(false);
} }
void TimelineView::RippleTool::MouseReleaseInternal(QMouseEvent *event) void TimelineView::RippleTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
+1 -1
View File
@@ -28,7 +28,7 @@ TimelineView::RollingTool::RollingTool(TimelineView* parent) :
SetMovementAllowed(false); SetMovementAllowed(false);
} }
void TimelineView::RollingTool::MouseReleaseInternal(QMouseEvent *event) void TimelineView::RollingTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
+1 -1
View File
@@ -29,7 +29,7 @@ TimelineView::SlideTool::SlideTool(TimelineView* parent) :
SetTrackMovementAllowed(false); SetTrackMovementAllowed(false);
} }
void TimelineView::SlideTool::MouseReleaseInternal(QMouseEvent *event) void TimelineView::SlideTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
+3 -7
View File
@@ -32,14 +32,10 @@ TimelineView::SlipTool::SlipTool(TimelineView *parent) :
SetTrackMovementAllowed(false); 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 // 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) // Validate slip (enforce all ghosts moving in legal ways)
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) { foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
@@ -65,7 +61,7 @@ void TimelineView::SlipTool::ProcessDrag(const QPoint &mouse_pos)
parent()); parent());
} }
void TimelineView::SlipTool::MouseReleaseInternal(QMouseEvent *event) void TimelineView::SlipTool::MouseReleaseInternal(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
+40 -20
View File
@@ -26,25 +26,15 @@
TimelineView::Tool::Tool(TimelineView *parent) : TimelineView::Tool::Tool(TimelineView *parent) :
dragging_(false), dragging_(false),
parent_(parent) parent_(parent),
drag_mode_(NoDrag),
enable_default_behavior_(false)
{ {
} }
TimelineView::Tool::~Tool(){} 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 *TimelineView::Tool::parent() TimelineView *TimelineView::Tool::parent()
{ {
@@ -64,14 +54,44 @@ olive::timeline::MovementMode TimelineView::Tool::FlipTrimMode(const olive::time
return trim_mode; 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<Block*, TimelineViewBlockItem*> 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<double>& proposed_pts, void AttemptSnap(const QList<double>& proposed_pts,
+13 -8
View File
@@ -25,26 +25,31 @@ TimelineView::ZoomTool::ZoomTool(TimelineView* parent) :
{ {
} }
void TimelineView::ZoomTool::MousePress(QMouseEvent *event) void TimelineView::ZoomTool::MousePress(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
} }
void TimelineView::ZoomTool::MouseMove(QMouseEvent *event) void TimelineView::ZoomTool::MouseMove(TimelineViewMouseEvent *event)
{ {
Q_UNUSED(event) Q_UNUSED(event)
} }
void TimelineView::ZoomTool::MouseRelease(QMouseEvent *event) void TimelineView::ZoomTool::MouseRelease(TimelineViewMouseEvent *event)
{ {
double scale = parent()->scale_; 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 // 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 // Zoom out if the user clicks while holding Alt
scale *= 0.5; scale *= 0.5;
} else { } else {
@@ -57,7 +62,7 @@ void TimelineView::ZoomTool::MouseRelease(QMouseEvent *event)
// Adjust zoom location for new scale // Adjust zoom location for new scale
scaled_x *= scale; scaled_x *= scale;
center_location.setX(scaled_x); scene_center.setX(scaled_x);
parent()->centerOn(center_location); parent()->centerOn(scene_center);
} }
+1 -1
View File
@@ -120,7 +120,7 @@ void TimelineWidget::ConnectTimelineNode(TimelineOutput *node)
int track_type = 0; int track_type = 0;
foreach (TimelineView* view, views_) { foreach (TimelineView* view, views_) {
view->ConnectTimelineNode(node->track_list(static_cast<TimelineOutput::TrackType>(track_type))); view->ConnectTimelineNode(node->track_list(static_cast<TrackType>(track_type)));
track_type++; track_type++;
} }