use catch up scrolling when dragging items
This commit is contained in:
@@ -101,6 +101,7 @@ CurveWidget::CurveWidget(QWidget *parent) :
|
||||
connect(view_, &CurveView::TimeChanged, this, &CurveWidget::SetTimeAndSignal);
|
||||
connect(view_->scene(), &QGraphicsScene::selectionChanged, this, &CurveWidget::SelectionChanged);
|
||||
connect(view_, &CurveView::ScaleChanged, this, &CurveWidget::SetScale);
|
||||
connect(view_, &CurveView::Dragged, this, &CurveWidget::KeyframeViewDragged);
|
||||
|
||||
// TimeBasedWidget's scrollbar has extra functionality that we can take advantage of
|
||||
view_->setHorizontalScrollBar(scrollbar());
|
||||
@@ -389,4 +390,17 @@ void CurveWidget::InputDoubleClicked(NodeInput *input, int element, int track)
|
||||
view_->ZoomToFitInput(input, element, track);
|
||||
}
|
||||
|
||||
void CurveWidget::KeyframeViewDragged(int x, int y)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "CatchUpScrollToPoint", Qt::QueuedConnection,
|
||||
Q_ARG(int, x));
|
||||
QMetaObject::invokeMethod(this, "CatchUpYScrollToPoint", Qt::QueuedConnection,
|
||||
Q_ARG(int, y));
|
||||
}
|
||||
|
||||
void CurveWidget::CatchUpYScrollToPoint(int point)
|
||||
{
|
||||
PageScrollInternal(view_->verticalScrollBar(), view_->height(), point, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -118,6 +118,10 @@ private slots:
|
||||
|
||||
void InputDoubleClicked(NodeInput* input, int element, int track);
|
||||
|
||||
void KeyframeViewDragged(int x, int y);
|
||||
|
||||
void CatchUpYScrollToPoint(int point);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ void KeyframeViewBase::mousePressEvent(QMouseEvent *event)
|
||||
if (item_under_cursor) {
|
||||
|
||||
dragging_ = true;
|
||||
drag_start_ = event->pos();
|
||||
drag_start_ = mapToScene(event->pos());
|
||||
|
||||
// Determine what type of item is under the cursor
|
||||
dragging_bezier_point_ = dynamic_cast<BezierControlPointItem*>(item_under_cursor);
|
||||
@@ -186,7 +186,7 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
if (dragging_) {
|
||||
// Calculate cursor difference and scale it
|
||||
QPointF mouse_diff_scaled = GetScaledCursorPos(event->pos() - drag_start_);
|
||||
QPointF mouse_diff_scaled = GetScaledCursorPos(mapToScene(event->pos()) - drag_start_);
|
||||
|
||||
if (event->modifiers() & Qt::ShiftModifier) {
|
||||
// If holding shift, only move one axis
|
||||
@@ -241,6 +241,8 @@ void KeyframeViewBase::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
QToolTip::hideText();
|
||||
QToolTip::showText(QCursor::pos(), tip);
|
||||
|
||||
emit Dragged(qRound(initial_drag_item_->x()), qRound(initial_drag_item_->y()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,7 +258,7 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event)
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
|
||||
if (dragging_) {
|
||||
QPointF mouse_diff_scaled = GetScaledCursorPos(event->pos() - drag_start_);
|
||||
QPointF mouse_diff_scaled = GetScaledCursorPos(mapToScene(event->pos()) - drag_start_);
|
||||
|
||||
if (event->modifiers() & Qt::ShiftModifier) {
|
||||
// If holding shift, only move one axis
|
||||
@@ -447,10 +449,10 @@ void KeyframeViewBase::ProcessBezierDrag(QPointF mouse_diff_scaled, bool include
|
||||
}
|
||||
}
|
||||
|
||||
QPointF KeyframeViewBase::GetScaledCursorPos(const QPoint &cursor_pos)
|
||||
QPointF KeyframeViewBase::GetScaledCursorPos(const QPointF &cursor_pos)
|
||||
{
|
||||
return QPointF(static_cast<double>(cursor_pos.x()) / GetScale(),
|
||||
static_cast<double>(cursor_pos.y()) / GetYScale());
|
||||
return QPointF(cursor_pos.x() / GetScale(),
|
||||
cursor_pos.y() / GetYScale());
|
||||
}
|
||||
|
||||
void KeyframeViewBase::ShowContextMenu()
|
||||
|
||||
@@ -48,6 +48,9 @@ public:
|
||||
|
||||
void DeselectAll();
|
||||
|
||||
signals:
|
||||
void Dragged(int current_x, int current_y);
|
||||
|
||||
public slots:
|
||||
void RemoveKeyframe(NodeKeyframe* key);
|
||||
|
||||
@@ -82,7 +85,7 @@ private:
|
||||
|
||||
void ProcessBezierDrag(QPointF mouse_diff_scaled, bool include_opposing, bool undoable);
|
||||
|
||||
QPointF GetScaledCursorPos(const QPoint& cursor_pos);
|
||||
QPointF GetScaledCursorPos(const QPointF &cursor_pos);
|
||||
|
||||
struct KeyframeItemAndTime {
|
||||
KeyframeViewItem* key;
|
||||
@@ -95,7 +98,7 @@ private:
|
||||
|
||||
Tool::Item active_tool_;
|
||||
|
||||
QPoint drag_start_;
|
||||
QPointF drag_start_;
|
||||
|
||||
BezierControlPointItem* dragging_bezier_point_;
|
||||
QPointF dragging_bezier_point_start_;
|
||||
|
||||
@@ -91,6 +91,7 @@ NodeParamView::NodeParamView(QWidget *parent) :
|
||||
connect(ruler(), &TimeRuler::TimeChanged, keyframe_view_, &KeyframeView::SetTime);
|
||||
connect(keyframe_view_, &KeyframeView::TimeChanged, ruler(), &TimeRuler::SetTime);
|
||||
connect(keyframe_view_, &KeyframeView::TimeChanged, this, &NodeParamView::SetTimestamp);
|
||||
connect(keyframe_view_, &KeyframeView::Dragged, this, &NodeParamView::KeyframeViewDragged);
|
||||
|
||||
// Connect keyframe view scaling to this
|
||||
connect(keyframe_view_, &KeyframeView::ScaleChanged, this, &NodeParamView::SetScale);
|
||||
@@ -388,4 +389,12 @@ void NodeParamView::FocusChanged(QWidget* old, QWidget* now)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamView::KeyframeViewDragged(int x, int y)
|
||||
{
|
||||
Q_UNUSED(y)
|
||||
|
||||
QMetaObject::invokeMethod(this, "CatchUpScrollToPoint", Qt::QueuedConnection,
|
||||
Q_ARG(int, x));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -140,6 +140,8 @@ private slots:
|
||||
|
||||
void FocusChanged(QWidget *old, QWidget *now);
|
||||
|
||||
void KeyframeViewDragged(int x, int y);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -183,12 +183,17 @@ void TimeBasedWidget::ScrollBarResizeMoved(int movement)
|
||||
|
||||
void TimeBasedWidget::PageScrollToPlayhead()
|
||||
{
|
||||
PageScrollInternal(true);
|
||||
PageScrollInternal(qRound(TimeToScene(GetTime())), true);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::CatchUpScrollToPlayhead()
|
||||
{
|
||||
PageScrollInternal(false);
|
||||
CatchUpScrollToPoint(qRound(TimeToScene(GetTime())));
|
||||
}
|
||||
|
||||
void TimeBasedWidget::CatchUpScrollToPoint(int point)
|
||||
{
|
||||
PageScrollInternal(point, false);
|
||||
}
|
||||
|
||||
TimeRuler *TimeBasedWidget::ruler() const
|
||||
@@ -481,31 +486,33 @@ void TimeBasedWidget::ResetPoint(Timeline::MovementMode m)
|
||||
Core::instance()->undo_stack()->push(new WorkareaSetRangeCommand(GetTimelinePointsProject(), points_, r));
|
||||
}
|
||||
|
||||
void TimeBasedWidget::PageScrollInternal(bool whole_page_scroll)
|
||||
void TimeBasedWidget::PageScrollInternal(QScrollBar *bar, int maximum, int screen_position, bool whole_page_scroll)
|
||||
{
|
||||
int playhead_pos = qRound(TimeToScene(GetTime()));
|
||||
|
||||
int viewport_width = ruler()->width();
|
||||
int viewport_padding = viewport_width / 16;
|
||||
int viewport_padding = maximum / 16;
|
||||
|
||||
if (whole_page_scroll) {
|
||||
if (playhead_pos < scrollbar()->value()) {
|
||||
if (screen_position < bar->value()) {
|
||||
// Anchor the playhead to the RIGHT of where we scroll to
|
||||
scrollbar()->setValue(playhead_pos - viewport_width + viewport_padding);
|
||||
} else if (playhead_pos > scrollbar()->value() + viewport_width) {
|
||||
bar->setValue(screen_position - maximum + viewport_padding);
|
||||
} else if (screen_position > bar->value() + maximum) {
|
||||
// Anchor the playhead to the LEFT of where we scroll to
|
||||
scrollbar()->setValue(playhead_pos - viewport_padding);
|
||||
bar->setValue(screen_position - viewport_padding);
|
||||
}
|
||||
} else {
|
||||
// Just jump in increments
|
||||
if (playhead_pos < scrollbar()->value() + viewport_padding) {
|
||||
scrollbar()->setValue(scrollbar()->value() - viewport_padding);
|
||||
} else if (playhead_pos > scrollbar()->value() + viewport_width - viewport_padding) {
|
||||
scrollbar()->setValue(scrollbar()->value() + viewport_padding);
|
||||
if (screen_position < bar->value() + viewport_padding) {
|
||||
bar->setValue(bar->value() - viewport_padding);
|
||||
} else if (screen_position > bar->value() + maximum - viewport_padding) {
|
||||
bar->setValue(bar->value() + viewport_padding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::PageScrollInternal(int screen_position, bool whole_page_scroll)
|
||||
{
|
||||
PageScrollInternal(scrollbar(), ruler()->width(), screen_position, whole_page_scroll);
|
||||
}
|
||||
|
||||
bool TimeBasedWidget::UserIsDraggingPlayhead() const
|
||||
{
|
||||
if (ruler_->IsDraggingPlayhead()) {
|
||||
|
||||
@@ -137,6 +137,8 @@ protected slots:
|
||||
*/
|
||||
void SetAutoSetTimebase(bool e);
|
||||
|
||||
static void PageScrollInternal(QScrollBar* bar, int maximum, int screen_position, bool whole_page_scroll);
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t&);
|
||||
|
||||
@@ -184,7 +186,7 @@ private:
|
||||
*/
|
||||
void ResetPoint(Timeline::MovementMode m);
|
||||
|
||||
void PageScrollInternal(bool whole_page_scroll);
|
||||
void PageScrollInternal(int screen_position, bool whole_page_scroll);
|
||||
|
||||
bool UserIsDraggingPlayhead() const;
|
||||
|
||||
@@ -231,6 +233,8 @@ private slots:
|
||||
|
||||
void CatchUpScrollToPlayhead();
|
||||
|
||||
void CatchUpScrollToPoint(int point);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -771,7 +771,11 @@ void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event)
|
||||
if (GetConnectedNode()) {
|
||||
if (active_tool_) {
|
||||
active_tool_->MouseMove(event);
|
||||
|
||||
UpdateViewports();
|
||||
|
||||
QMetaObject::invokeMethod(this, "CatchUpScrollToPoint", Qt::QueuedConnection,
|
||||
Q_ARG(int, qRound(event->GetSceneX())));
|
||||
} else {
|
||||
// Mouse is not down, attempt a hover event
|
||||
TimelineTool* hover_tool = GetActiveTool();
|
||||
|
||||
@@ -76,8 +76,6 @@ void TimelineView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
TimelineViewMouseEvent timeline_event = CreateMouseEvent(event);
|
||||
|
||||
|
||||
|
||||
if (HandMove(event) || PlayheadMove(event)) {
|
||||
// Let the parent handle this
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user