base pointer movement in timeline

This commit is contained in:
itsmattkc
2019-08-21 15:10:55 +10:00
parent 78d96ecd28
commit f03cc8fe07
14 changed files with 166 additions and 62 deletions
+5
View File
@@ -84,6 +84,11 @@ rational rational::flipped() const
return rational(denom, numer);
}
bool rational::isNull() const
{
return denominator() == 0;
}
//Function: get active instances
int rational::getActiveInstances()
+3
View File
@@ -96,6 +96,9 @@ public:
// Produce "flipped" version
rational flipped() const;
// Returns whether the rational is null or not
bool isNull() const;
//Function: print number to cout
void print(ostream &out = cout) const;
+9
View File
@@ -63,6 +63,7 @@ void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
//disconnect(view, SIGNAL(RequestInsertBlockAtIndex(Block*, int)), this, SLOT(InsertBlockAtIndex(Block*, int)));
disconnect(view, SIGNAL(RequestPlaceBlock(Block*, rational, int)), this, SLOT(PlaceBlock(Block*, rational, int)));
disconnect(view, SIGNAL(RequestReplaceBlock(Block*, Block*, int)), this, SLOT(ReplaceBlock(Block*, Block*, int)));
// Remove existing UI objects from TimelinePanel
attached_timeline_->Clear();
@@ -84,6 +85,7 @@ void TimelineOutput::AttachTimeline(TimelinePanel *timeline)
//connect(view, SIGNAL(RequestInsertBlockAtIndex(Block*, int)), this, SLOT(InsertBlockAtIndex(Block*, int)));
connect(view, SIGNAL(RequestPlaceBlock(Block*, rational, int)), this, SLOT(PlaceBlock(Block*, rational, int)));
connect(view, SIGNAL(RequestReplaceBlock(Block*, Block*, int)), this, SLOT(ReplaceBlock(Block*, Block*, int)));
}
}
@@ -240,9 +242,16 @@ void TimelineOutput::TrackEdgeRemoved(NodeEdgePtr edge)
void TimelineOutput::PlaceBlock(Block *block, rational start, int track)
{
Q_ASSERT(track >= 0);
while (track >= track_cache_.size()) {
AddTrack();
}
track_cache_.at(track)->PlaceBlock(block, start);
}
void TimelineOutput::ReplaceBlock(Block *old, Block *replace, int track)
{
track_cache_.at(track)->ReplaceBlock(old, replace);
}
+8
View File
@@ -101,9 +101,17 @@ private slots:
/**
* @brief Forwards a PlaceBlock signal to the requested track
*
* If the track index doesn't exist, tracks are automatically created until a track at that index does exist
* (provided the track index is positive). A negative track index fails immediately.
*/
void PlaceBlock(Block* block, rational start, int track);
/**
* @brief Forwards a ReplaceBlock signal to the appropriate track
*/
void ReplaceBlock(Block* old, Block* replace, int track);
};
#endif // TIMELINEOUTPUT_H
+22 -3
View File
@@ -245,12 +245,12 @@ void TrackOutput::AddBlockToGraph(Block *block)
void TrackOutput::PlaceBlock(Block *block, rational start)
{
AddBlockToGraph(block);
if (block->in() == start) {
if (block_cache_.contains(block) && block->in() == start) {
return;
}
AddBlockToGraph(block);
// Check if the placement location is past the end of the timeline
if (start >= in()) {
if (start > in()) {
@@ -408,3 +408,22 @@ void TrackOutput::RippleRemoveArea(rational in, rational out, Block *insert)
}
}
}
void TrackOutput::ReplaceBlock(Block *old, Block *replace)
{
Block* previous = old->previous();
Block* next = old->next();
AddBlockToGraph(replace);
// Disconnect old block from its surroundings
if (previous != nullptr) {
Block::DisconnectBlocks(previous, old);
Block::ConnectBlocks(previous, replace);
}
if (next != nullptr) {
Block::DisconnectBlocks(old, next);
Block::ConnectBlocks(replace, next);
}
}
+7
View File
@@ -125,6 +125,13 @@ public:
*/
void RippleRemoveArea(rational in, rational out, Block* insert = nullptr);
/**
* @brief Replaces Block `old` with Block `replace`
*
* Makes no modification to the lengths of either Blocks
*/
void ReplaceBlock(Block* old, Block* replace);
signals:
/**
* @brief Signal emitted when a Block is added to this Track
+2 -38
View File
@@ -43,9 +43,8 @@ TimelineView::TimelineView(QWidget *parent) :
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect()));
// Create playhead line and ensure it's always on top
// Create playhead line
playhead_line_ = new TimelineViewPlayheadItem();
playhead_line_->setZValue(100);
scene_.addItem(playhead_line_);
@@ -267,6 +266,7 @@ void TimelineView::UpdateSceneRect()
bounding_rect.setTopLeft(QPointF(0, 0));
// Ensure the scene height is always AT LEAST the height of the view
// The scrollbar appears to have a 1px margin on the top and bottom, hence the -2
int minimum_height = height() - horizontalScrollBar()->height() - 2;
if (bounding_rect.height() < minimum_height) {
bounding_rect.setHeight(minimum_height);
@@ -283,39 +283,3 @@ void TimelineView::UpdateSceneRect()
scene_.setSceneRect(bounding_rect);
}
TimelineView::Tool::Tool(TimelineView *parent) :
dragging_(false),
parent_(parent)
{
}
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()
{
return parent_;
}
QPointF TimelineView::Tool::GetScenePos(const QPoint &screen_pos)
{
return parent()->mapToScene(screen_pos);
}
QGraphicsItem *TimelineView::Tool::GetItemAtScenePos(const QPointF &scene_pos)
{
return parent()->scene_.itemAt(scene_pos, parent()->transform());
}
+3
View File
@@ -60,6 +60,7 @@ public slots:
signals:
void RequestPlaceBlock(Block* block, rational start, int track);
void RequestReplaceBlock(Block* old, Block* replace, int track);
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
@@ -97,6 +98,8 @@ private:
QGraphicsItem* GetItemAtScenePos(const QPointF& scene_pos);
rational ValidateMovement(rational movement, const QVector<TimelineViewGhostItem*> ghosts);
bool dragging_;
QPointF drag_start_;
@@ -29,7 +29,8 @@ TimelineViewPlayheadItem::TimelineViewPlayheadItem(QGraphicsItem *parent) :
TimelineViewRect(parent),
playhead_(0)
{
// Ensure this item is always on top
setZValue(100);
}
void TimelineViewPlayheadItem::SetPlayhead(const int64_t &playhead)
@@ -18,5 +18,6 @@ set(OLIVE_SOURCES
${OLIVE_SOURCES}
widget/timelineview/tool/import.cpp
widget/timelineview/tool/pointer.cpp
widget/timelineview/tool/tool.cpp
PARENT_SCOPE
)
+13 -10
View File
@@ -51,7 +51,8 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
drag_start_ = GetScenePos(event->pos());
// Set ghosts to start where the cursor entered
rational ghost_start = parent()->SceneToTime(drag_start_.x());
// FIXME: 100 = magic number so that imported clips are not right on the cursor when dragged in
rational ghost_start = parent()->SceneToTime(drag_start_.x() - 100);
while (!stream.atEnd()) {
stream >> r >> item_ptr;
@@ -92,22 +93,24 @@ void TimelineView::ImportTool::DragEnter(QDragEnterEvent *event)
void TimelineView::ImportTool::DragMove(QDragMoveEvent *event)
{
if (parent()->HasGhosts()) {
QPointF pos = GetScenePos(event->pos());
QPointF movement = pos - drag_start_;
rational time_movement = parent()->SceneToTime(movement.x());
int ghost_track = parent()->SceneToTrack(pos.y());
int ghost_y = parent()->GetTrackY(ghost_track);
int ghost_height = parent()->GetTrackHeight(ghost_track);
time_movement = ValidateMovement(time_movement, parent()->ghost_items_);
// Move ghosts to the mouse cursor
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
QPointF pos = GetScenePos(event->pos());
QPointF movement = pos - drag_start_;
rational time_movement = parent()->SceneToTime(movement.x());
ghost->SetInAdjustment(time_movement);
ghost->SetOutAdjustment(time_movement);
int ghost_track = parent()->SceneToTrack(pos.y());
ghost->SetTrack(ghost_track);
int ghost_y = parent()->GetTrackY(ghost_track);
int ghost_height = parent()->GetTrackHeight(ghost_track);
ghost->SetY(ghost_y);
ghost->SetHeight(ghost_height);
}
+20 -9
View File
@@ -20,6 +20,8 @@
#include "widget/timelineview/timelineview.h"
#include "node/block/gap/gap.h"
TimelineView::PointerTool::PointerTool(TimelineView *parent) :
Tool(parent)
{
@@ -71,6 +73,9 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
ghost->SetScale(parent()->scale_);
ghost->SetData(Node::PtrToValue(clip));
// FIXME: Very bad. Change immediately.
ghost->SetTrack(parent()->SceneToTrack(drag_start_.y()));
ghost->setPos(clip_item->pos());
parent()->ghost_items_.append(ghost);
@@ -89,12 +94,7 @@ void TimelineView::PointerTool::MouseMove(QMouseEvent *event)
rational time_movement = parent()->SceneToTime(movement.x());
// Validate movement
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
rational validator = ghost->In() + time_movement;
if (validator < 0) {
time_movement = rational(0) - ghost->In();
}
}
time_movement = ValidateMovement(time_movement, parent()->ghost_items_);
// Perform movement
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
@@ -110,13 +110,24 @@ void TimelineView::PointerTool::MouseRelease(QMouseEvent *event)
parent()->QGraphicsView::mouseReleaseEvent(event);
/*
QObject block_memory_manager;
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
Block* b = Node::ValueToPtr<Block>(ghost->data());
emit parent()->RequestPlaceBlock(b, ghost->In());
// Replace old Block with a new Gap
GapBlock* gap = new GapBlock();
gap->setParent(&block_memory_manager);
gap->set_length(b->length());
emit parent()->RequestReplaceBlock(b, gap, ghost->Track());
}
foreach (TimelineViewGhostItem* ghost, parent()->ghost_items_) {
Block* b = Node::ValueToPtr<Block>(ghost->data());
emit parent()->RequestPlaceBlock(b, ghost->GetAdjustedIn(), ghost->Track());
}
*/
parent()->ClearGhosts();
+70
View File
@@ -0,0 +1,70 @@
/***
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 "widget/timelineview/timelineview.h"
TimelineView::Tool::Tool(TimelineView *parent) :
dragging_(false),
parent_(parent)
{
}
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()
{
return parent_;
}
QPointF TimelineView::Tool::GetScenePos(const QPoint &screen_pos)
{
return parent()->mapToScene(screen_pos);
}
QGraphicsItem *TimelineView::Tool::GetItemAtScenePos(const QPointF &scene_pos)
{
return parent()->scene_.itemAt(scene_pos, parent()->transform());
}
rational TimelineView::Tool::ValidateMovement(rational movement, const QVector<TimelineViewGhostItem *> ghosts)
{
foreach (TimelineViewGhostItem* ghost, ghosts) {
rational validator = ghost->In() + movement;
if (validator < 0) {
movement = rational(0) - ghost->In();
}
}
return movement;
}
+1 -1
View File
@@ -109,7 +109,7 @@ void TimeRuler::SetScroll(int s)
void TimeRuler::paintEvent(QPaintEvent *)
{
// Nothing to paint if the timebase is invalid
if (timebase_.denominator() == 0) {
if (timebase_.isNull()) {
return;
}