implemented rubberband zoom in timeline

This commit is contained in:
itsmattkc
2020-01-07 20:24:07 +11:00
parent 5bdc631da8
commit c8baf4aa3e
13 changed files with 99 additions and 50 deletions
-1
View File
@@ -42,7 +42,6 @@ public:
enum Type {
kClip,
kGap,
kTrack,
kTransition
};
+1 -1
View File
@@ -60,7 +60,7 @@ const Timeline::TrackType& TrackOutput::track_type()
Block::Type TrackOutput::type() const
{
return kTrack;
return kClip;
}
Block *TrackOutput::copy() const
+4 -2
View File
@@ -145,10 +145,12 @@ const double &CurveWidget::GetScale()
return ruler_->scale();
}
void CurveWidget::SetScale(const double &scale)
void CurveWidget::SetScale(double scale)
{
scale = qMin(scale, TimelineViewBase::kMaximumScale);
ruler_->SetScale(scale);
view_->SetScale(scale);
view_->SetScale(scale, true);
}
const double &CurveWidget::GetVerticalScale()
+1 -1
View File
@@ -31,7 +31,7 @@ public:
void SetVerticalScale(const double& vscale);
public slots:
void SetScale(const double& scale);
void SetScale(double scale);
signals:
void TimeChanged(const int64_t& timestamp);
+4 -2
View File
@@ -179,10 +179,12 @@ const double &NodeParamView::GetScale() const
return ruler_->scale();
}
void NodeParamView::SetScale(const double& scale)
void NodeParamView::SetScale(double scale)
{
scale = qMin(scale, TimelineViewBase::kMaximumScale);
ruler_->SetScale(scale);
keyframe_view_->SetScale(scale);
keyframe_view_->SetScale(scale, true);
}
void NodeParamView::SetTime(const int64_t &timestamp)
+1 -1
View File
@@ -41,7 +41,7 @@ public:
const double& GetScale() const;
public slots:
void SetScale(const double &scale);
void SetScale(double scale);
void SetTime(const int64_t& timestamp);
+17 -11
View File
@@ -616,9 +616,9 @@ void TimelineWidget::CenterOn(qreal scene_pos)
horizontal_scroll_->setValue(qRound(scene_pos - horizontal_scroll_->width()/2));
}
void TimelineWidget::SetScale(double scale)
void TimelineWidget::SetScale(double scale, bool center_on_playhead)
{
scale_ = scale;
scale_ = qMin(scale, TimelineViewBase::kMaximumScale);
ruler_->SetScale(scale_);
@@ -637,7 +637,7 @@ void TimelineWidget::SetScale(double scale)
}
foreach (TimelineAndTrackView* view, views_) {
view->view()->SetScale(scale_);
view->view()->SetScale(scale_, center_on_playhead);
}
}
@@ -768,9 +768,6 @@ void TimelineWidget::AddBlock(Block *block, TrackReference track)
connect(block, SIGNAL(Refreshed()), this, SLOT(BlockChanged()));
break;
}
case Block::kTrack:
// Do nothing
break;
}
}
@@ -870,6 +867,11 @@ void TimelineWidget::ShowSpeedDurationDialog()
speed_diag.exec();
}
void TimelineWidget::DeferredScrollAction()
{
horizontal_scroll_->setValue(deferred_scroll_value_);
}
void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost)
{
ghost->SetScale(scale_);
@@ -888,20 +890,24 @@ void TimelineWidget::SetBlockLinksSelected(Block* block, bool selected)
}
}
void TimelineWidget::StartRubberBandSelect(bool select_links)
void TimelineWidget::StartRubberBandSelect(bool enable_selecting, bool select_links)
{
drag_origin_ = QCursor::pos();
rubberband_.show();
MoveRubberBandSelect(select_links);
MoveRubberBandSelect(enable_selecting, select_links);
}
void TimelineWidget::MoveRubberBandSelect(bool select_links)
void TimelineWidget::MoveRubberBandSelect(bool enable_selecting, bool select_links)
{
QPoint rubberband_now = QCursor::pos();
rubberband_.setGeometry(QRect(mapFromGlobal(drag_origin_), mapFromGlobal(rubberband_now)).normalized());
if (!enable_selecting) {
return;
}
QList<QGraphicsItem*> new_selected_list;
foreach (TimelineAndTrackView* tview, views_) {
@@ -954,9 +960,9 @@ void TimelineWidget::MoveRubberBandSelect(bool select_links)
rubberband_now_selected_ = new_selected_list;
}
void TimelineWidget::EndRubberBandSelect(bool select_links)
void TimelineWidget::EndRubberBandSelect(bool enable_selecting, bool select_links)
{
MoveRubberBandSelect(select_links);
MoveRubberBandSelect(enable_selecting, select_links);
rubberband_.hide();
rubberband_now_selected_.clear();
}
+9 -4
View File
@@ -300,6 +300,7 @@ private:
virtual void MousePress(TimelineViewMouseEvent *event) override;
virtual void MouseMove(TimelineViewMouseEvent *event) override;
virtual void MouseRelease(TimelineViewMouseEvent *event) override;
};
class AddTool : public Tool
@@ -337,9 +338,9 @@ private:
QPoint drag_origin_;
void StartRubberBandSelect(bool select_links);
void MoveRubberBandSelect(bool select_links);
void EndRubberBandSelect(bool select_links);
void StartRubberBandSelect(bool enable_selecting, bool select_links);
void MoveRubberBandSelect(bool enable_selecting, bool select_links);
void EndRubberBandSelect(bool enable_selecting, bool select_links);
QRubberBand rubberband_;
QList<QGraphicsItem*> rubberband_now_selected_;
@@ -377,6 +378,8 @@ private:
TimeSlider* timecode_label_;
int deferred_scroll_value_;
int GetTrackY(const TrackReference& ref);
int GetTrackHeight(const TrackReference& ref);
@@ -385,7 +388,7 @@ private:
void AddGhost(TimelineViewGhostItem* ghost);
private slots:
void SetScale(double scale);
void SetScale(double scale, bool center_on_playhead = true);
void UpdateInternalTime(const int64_t& timestamp);
@@ -425,6 +428,8 @@ private slots:
void ShowSpeedDurationDialog();
void DeferredScrollAction();
};
#endif // TIMELINEWIDGET_H
+3 -3
View File
@@ -91,7 +91,7 @@ void TimelineWidget::PointerTool::MousePress(TimelineViewMouseEvent *event)
}
} else {
// Start rubberband drag
parent()->StartRubberBandSelect(!(event->GetModifiers() & Qt::AltModifier));
parent()->StartRubberBandSelect(true, !(event->GetModifiers() & Qt::AltModifier));
rubberband_selecting_ = true;
}
@@ -102,7 +102,7 @@ void TimelineWidget::PointerTool::MouseMove(TimelineViewMouseEvent *event)
if (rubberband_selecting_) {
// Process rubberband select
parent()->MoveRubberBandSelect(!(event->GetModifiers() & Qt::AltModifier));
parent()->MoveRubberBandSelect(true, !(event->GetModifiers() & Qt::AltModifier));
} else if (!dragging_) {
// Now that the cursor has moved, we will assume the intention is to drag
@@ -124,7 +124,7 @@ void TimelineWidget::PointerTool::MouseMove(TimelineViewMouseEvent *event)
void TimelineWidget::PointerTool::MouseRelease(TimelineViewMouseEvent *event)
{
if (rubberband_selecting_) {
parent()->EndRubberBandSelect(!(event->GetModifiers() & Qt::AltModifier));
parent()->EndRubberBandSelect(true, !(event->GetModifiers() & Qt::AltModifier));
rubberband_selecting_ = false;
return;
+46 -15
View File
@@ -32,28 +32,59 @@ void TimelineWidget::ZoomTool::MousePress(TimelineViewMouseEvent *event)
void TimelineWidget::ZoomTool::MouseMove(TimelineViewMouseEvent *event)
{
Q_UNUSED(event)
if (dragging_) {
parent()->MoveRubberBandSelect(false, false);
} else {
parent()->StartRubberBandSelect(false, false);
dragging_ = true;
}
}
void TimelineWidget::ZoomTool::MouseRelease(TimelineViewMouseEvent *event)
{
double scale = parent()->scale_;
if (dragging_) {
// Zoom into the rubberband selection
QRect screen_coords = parent()->rubberband_.geometry();
// Normalize zoom location for 1.0 scale
double frame_x = parent()->TimeToScene(event->GetFrame());
parent()->EndRubberBandSelect(false, false);
if (event->GetModifiers() & Qt::AltModifier) {
// Zoom out if the user clicks while holding Alt
scale *= 0.5;
TimelineView* reference_view = parent()->views_.first()->view();
QPointF scene_topleft = reference_view->mapToScene(reference_view->mapFrom(parent(), screen_coords.topLeft()));
QPointF scene_bottomright = reference_view->mapToScene(reference_view->mapFrom(parent(), screen_coords.bottomRight()));
double scene_left = scene_topleft.x();
double scene_right = scene_bottomright.x();
// Normalize scale to 1.0 scale
double scene_width = (scene_right - scene_left) / parent()->scale_;
double new_scale = qMin(TimelineViewBase::kMaximumScale, static_cast<double>(reference_view->viewport()->width()) / scene_width);
parent()->deferred_scroll_value_ = qMax(0, qRound(scene_left / parent()->scale_ * new_scale));
parent()->SetScale(new_scale, false);
dragging_ = false;
} else {
// Otherwise zoom in
scale *= 2;
// Simple zoom in/out at the cursor position
double scale = parent()->scale_;
if (event->GetModifiers() & Qt::AltModifier) {
// Zoom out if the user clicks while holding Alt
scale *= 0.5;
} else {
// Otherwise zoom in
scale *= 2.0;
}
parent()->SetScale(scale, false);
// Adjust scroll location for new scale
double frame_x = event->GetFrame().toDouble() * scale;
parent()->deferred_scroll_value_ = qMax(0, qRound(frame_x - parent()->views_.first()->view()->viewport()->width()/2));
}
parent()->SetScale(scale);
// Adjust zoom location for new scale
frame_x *= scale;
parent()->CenterOn(frame_x);
// (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated)
QTimer::singleShot(0, parent(), &TimelineWidget::DeferredScrollAction);
}
@@ -9,6 +9,8 @@
#include "common/timecodefunctions.h"
#include "config/config.h"
const double TimelineViewBase::kMaximumScale = 8192;
TimelineViewBase::TimelineViewBase(QWidget *parent) :
QGraphicsView(parent),
playhead_(0),
@@ -25,7 +27,7 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) :
scene_.addItem(end_item_);
// Set default scale
SetScale(1.0);
SetScale(1.0, true);
SetDefaultDragMode(NoDrag);
@@ -35,9 +37,9 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) :
connect(Core::instance(), &Core::ToolChanged, this, &TimelineViewBase::ApplicationToolChanged);
}
void TimelineViewBase::SetScale(const double &scale)
void TimelineViewBase::SetScale(const double &scale, bool center_on_playhead)
{
scale_ = scale;
scale_ = qMin(scale, kMaximumScale);
end_item_->SetScale(scale_);
@@ -46,9 +48,11 @@ void TimelineViewBase::SetScale(const double &scale)
// Force redraw for playhead
viewport()->update();
// Zoom towards the playhead
// (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated)
QTimer::singleShot(0, this, &TimelineViewBase::CenterScrollOnPlayhead);
if (center_on_playhead) {
// Zoom towards the playhead
// (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated)
QTimer::singleShot(0, this, &TimelineViewBase::CenterScrollOnPlayhead);
}
}
void TimelineViewBase::SetTimebase(const rational &timebase)
@@ -14,10 +14,12 @@ class TimelineViewBase : public QGraphicsView, public TimelineScaledObject
public:
TimelineViewBase(QWidget* parent = nullptr);
void SetScale(const double& scale);
void SetScale(const double& scale, bool center_on_playhead);
void SetEndTime(const rational& length);
static const double kMaximumScale;
public slots:
void SetTimebase(const rational& timebase);
@@ -176,7 +176,5 @@ void TimelineViewBlockItem::paint(QPainter *painter, const QStyleOptionGraphicsI
}
break;
}
case Block::kTrack:
break;
}
}