diff --git a/app/widget/handmovableview/handmovableview.h b/app/widget/handmovableview/handmovableview.h index 15fd8fc38..9fdaa5395 100644 --- a/app/widget/handmovableview/handmovableview.h +++ b/app/widget/handmovableview/handmovableview.h @@ -38,6 +38,8 @@ public: static qreal GetScrollZoomMultiplier(QWheelEvent* event); + virtual void CatchUpScrollEvent(){} + protected: virtual void ToolChangedEvent(Tool::Item tool){Q_UNUSED(tool)} diff --git a/app/widget/keyframeview/keyframeview.cpp b/app/widget/keyframeview/keyframeview.cpp index 5b0f745bd..2f6794e62 100644 --- a/app/widget/keyframeview/keyframeview.cpp +++ b/app/widget/keyframeview/keyframeview.cpp @@ -254,6 +254,15 @@ bool KeyframeView::Paste(std::function find_node_functi return false; } +void KeyframeView::CatchUpScrollEvent() +{ + super::CatchUpScrollEvent(); + + if (this->selection_manager_.IsRubberBanding()) { + this->selection_manager_.RubberBandMove(this->viewport()->mapFromGlobal(QCursor::pos())); + } +} + void KeyframeView::mousePressEvent(QMouseEvent *event) { NodeKeyframe *key_under_cursor = selection_manager_.GetObjectAtPoint(event->pos()); @@ -289,7 +298,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent *event) KeyframeDragMove(event, tip); selection_manager_.DragMove(event, tip); } else if (selection_manager_.IsRubberBanding()) { - selection_manager_.RubberBandMove(event); + selection_manager_.RubberBandMove(event->pos()); Redraw(); } @@ -618,6 +627,13 @@ void KeyframeView::ShowKeyframePropertiesDialog() } } +void KeyframeView::UpdateRubberBandForScroll() +{ + if (this->selection_manager_.IsRubberBanding()) { + this->selection_manager_.RubberBandMove(this->viewport()->mapFromGlobal(QCursor::pos())); + } +} + void KeyframeView::Redraw() { viewport()->update(); diff --git a/app/widget/keyframeview/keyframeview.h b/app/widget/keyframeview/keyframeview.h index 541b81583..b7c854777 100644 --- a/app/widget/keyframeview/keyframeview.h +++ b/app/widget/keyframeview/keyframeview.h @@ -83,6 +83,8 @@ public: bool Paste(std::function find_node_function); + virtual void CatchUpScrollEvent() override; + signals: void Dragged(int current_x, int current_y); @@ -164,6 +166,8 @@ private slots: void ShowKeyframePropertiesDialog(); + void UpdateRubberBandForScroll(); + }; } diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index c29006023..4a79ddfeb 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -123,8 +123,8 @@ NodeParamView::NodeParamView(bool create_keyframe_view, QWidget *parent) : keyframe_area_layout->addWidget(keyframe_view_); // Connect ruler and keyframe view together - connect(keyframe_view_, &KeyframeView::Dragged, this, &NodeParamView::KeyframeViewDragged); - connect(keyframe_view_, &KeyframeView::Released, this, &NodeParamView::KeyframeViewReleased); + connect(keyframe_view_, &KeyframeView::Dragged, this, static_cast(&NodeParamView::SetCatchUpScrollValue)); + connect(keyframe_view_, &KeyframeView::Released, this, static_cast(&NodeParamView::StopCatchUpScrollTimer)); splitter->addWidget(keyframe_area); @@ -898,18 +898,6 @@ void NodeParamView::PinNode(bool pin) } }*/ -void NodeParamView::KeyframeViewDragged(int x, int y) -{ - Q_UNUSED(y) - - SetCatchUpScrollValue(x); -} - -void NodeParamView::KeyframeViewReleased() -{ - StopCatchUpScrollTimer(); -} - void NodeParamView::UpdateElementY() { for (NodeParamViewContext *ctx : context_items_) { diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index da63e638a..3899f4e66 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -167,9 +167,6 @@ private slots: //void FocusChanged(QWidget *old, QWidget *now); - void KeyframeViewDragged(int x, int y); - void KeyframeViewReleased(); - void NodeAddedToContext(Node *n); void NodeRemovedFromContext(Node *n); diff --git a/app/widget/timebased/timebasedview.cpp b/app/widget/timebased/timebasedview.cpp index 8f83970fb..2929d9a61 100644 --- a/app/widget/timebased/timebasedview.cpp +++ b/app/widget/timebased/timebasedview.cpp @@ -157,6 +157,16 @@ void TimeBasedView::SetViewerNode(ViewerOutput *v) } } +QPointF TimeBasedView::ScalePoint(const QPointF &p) const +{ + return QPointF(p.x() * GetScale(), p.y() * GetYScale()); +} + +QPointF TimeBasedView::UnscalePoint(const QPointF &p) const +{ + return QPointF(p.x() / GetScale(), p.y() / GetYScale()); +} + void TimeBasedView::drawForeground(QPainter *painter, const QRectF &rect) { QGraphicsView::drawForeground(painter, rect); diff --git a/app/widget/timebased/timebasedview.h b/app/widget/timebased/timebasedview.h index cb149b445..5329570dc 100644 --- a/app/widget/timebased/timebasedview.h +++ b/app/widget/timebased/timebasedview.h @@ -64,6 +64,9 @@ public: void SetViewerNode(ViewerOutput *v); + QPointF ScalePoint(const QPointF &p) const; + QPointF UnscalePoint(const QPointF &p) const; + public slots: void SetEndTime(const rational& length); diff --git a/app/widget/timebased/timebasedviewselectionmanager.h b/app/widget/timebased/timebasedviewselectionmanager.h index 2169170b2..07ff10c3c 100644 --- a/app/widget/timebased/timebasedviewselectionmanager.h +++ b/app/widget/timebased/timebasedviewselectionmanager.h @@ -53,9 +53,10 @@ public: drawn_objects_.clear(); } - void DeclareDrawnObject(T *object, const QRectF &pos) + void DeclareDrawnObject(T *object, const QRectF &rect) { - drawn_objects_.push_back({object, pos}); + QRectF r(view_->UnscalePoint(rect.topLeft()), view_->UnscalePoint(rect.bottomRight())); + drawn_objects_.push_back({object, r}); } bool Select(T *key) @@ -345,23 +346,24 @@ public: void RubberBandStart(QMouseEvent *event) { if (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) { - rubberband_start_ = event->pos(); + rubberband_scene_start_ = view_->UnscalePoint(view_->mapToScene(event->pos())); rubberband_ = new QRubberBand(QRubberBand::Rectangle, view_); - rubberband_->setGeometry(QRect(rubberband_start_.x(), rubberband_start_.y(), 0, 0)); + rubberband_->setGeometry(QRect(event->pos().x(), event->pos().y(), 0, 0)); rubberband_->show(); rubberband_preselected_ = selected_; } } - void RubberBandMove(QMouseEvent *event) + void RubberBandMove(const QPoint &pos) { if (IsRubberBanding()) { - QRect band_rect = QRect(rubberband_start_, event->pos()).normalized(); - rubberband_->setGeometry(band_rect); + QRectF band_rect = QRectF(view_->mapFromScene(view_->ScalePoint(rubberband_scene_start_)), pos).normalized(); + rubberband_->setGeometry(band_rect.toRect()); - QRectF scene_rect = view_->mapToScene(band_rect).boundingRect(); + QPointF current = view_->UnscalePoint(view_->mapToScene(pos)); + QRectF scene_rect = QRectF(rubberband_scene_start_, current).normalized(); selected_ = rubberband_preselected_; foreach (const DrawnObject &kp, drawn_objects_) { @@ -445,7 +447,7 @@ private: rational timebase_; QRubberBand *rubberband_; - QPoint rubberband_start_; + QPointF rubberband_scene_start_; std::vector rubberband_preselected_; TimeBasedWidget::SnapMask snap_mask_; diff --git a/app/widget/timebased/timebasedwidget.cpp b/app/widget/timebased/timebasedwidget.cpp index 20fcb3734..80fa51612 100644 --- a/app/widget/timebased/timebasedwidget.cpp +++ b/app/widget/timebased/timebasedwidget.cpp @@ -49,6 +49,7 @@ TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_statu ruler_ = new TimeRuler(ruler_text_visible, ruler_cache_status_visible, this); ConnectTimelineView(ruler_); ruler()->SetSnapService(this); + connect(ruler(), &TimeRuler::DragMoved, this, static_cast(&TimeBasedWidget::SetCatchUpScrollValue)); connect(ruler(), &TimeRuler::DragReleased, this, static_cast(&TimeBasedWidget::StopCatchUpScrollTimer)); catchup_scroll_timer_ = new QTimer(this); @@ -230,6 +231,15 @@ void TimeBasedWidget::CatchUpTimerTimeout() const CatchUpScrollData &d = it.value(); PageScrollInternal(sb, d.maximum, sb->value() + d.value, false); } + + SendCatchUpScrollEvent(); +} + +void TimeBasedWidget::SendCatchUpScrollEvent() +{ + for (auto v : this->timeline_views_) { + v->CatchUpScrollEvent(); + } } void TimeBasedWidget::AutoUpdateTimebase() @@ -283,6 +293,8 @@ void TimeBasedWidget::ScaleChangedEvent(const double &scale) UpdateMaximumScroll(); + QMetaObject::invokeMethod(this, &TimeBasedWidget::SendCatchUpScrollEvent, Qt::QueuedConnection); + toggle_show_all_ = false; } diff --git a/app/widget/timeruler/seekablewidget.cpp b/app/widget/timeruler/seekablewidget.cpp index 6fb2a5765..b721bd017 100644 --- a/app/widget/timeruler/seekablewidget.cpp +++ b/app/widget/timeruler/seekablewidget.cpp @@ -206,7 +206,7 @@ void SeekableWidget::mouseMoveEvent(QMouseEvent *event) if (HandMove(event)) { return; } else if (selection_manager_.IsRubberBanding()) { - selection_manager_.RubberBandMove(event); + selection_manager_.RubberBandMove(event->pos()); viewport()->update(); } else if (selection_manager_.IsDragging()) { selection_manager_.DragMove(event); @@ -228,6 +228,11 @@ void SeekableWidget::mouseMoveEvent(QMouseEvent *event) ClearResizeHandle(); } } + + if (event->buttons()) { + // Signal cursor pos in case we should scroll to catch up to it + emit DragMoved(event->pos().x(), event->pos().y()); + } } void SeekableWidget::mouseReleaseEvent(QMouseEvent *event) @@ -413,6 +418,15 @@ void SeekableWidget::SelectionManagerDeselectEvent(void *obj) viewport()->update(); } +void SeekableWidget::CatchUpScrollEvent() +{ + super::CatchUpScrollEvent(); + + if (this->selection_manager_.IsRubberBanding()) { + this->selection_manager_.RubberBandMove(this->viewport()->mapFromGlobal(QCursor::pos())); + } +} + void SeekableWidget::DrawPlayhead(QPainter *p, int x, int y) { int half_width = playhead_width_ / 2; diff --git a/app/widget/timeruler/seekablewidget.h b/app/widget/timeruler/seekablewidget.h index bf0b248a6..3d0a5d985 100644 --- a/app/widget/timeruler/seekablewidget.h +++ b/app/widget/timeruler/seekablewidget.h @@ -77,6 +77,8 @@ public: virtual void SelectionManagerSelectEvent(void *obj) override; virtual void SelectionManagerDeselectEvent(void *obj) override; + virtual void CatchUpScrollEvent() override; + public slots: void SetScroll(int i) { @@ -86,6 +88,8 @@ public slots: virtual void TimebaseChangedEvent(const rational &) override; signals: + void DragMoved(int x, int y); + void DragReleased(); protected: