summaryrefslogtreecommitdiffstats
path: root/src/Authoring
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2018-06-25 14:58:39 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2018-06-26 08:14:10 +0000
commit7045f185a1efae8dee4fcb425a0b2d92d21303ff (patch)
treeb2e5927947d737287c3e94c7d4aafd14e2ebb534 /src/Authoring
parent1bde524d4583d2f3d5cae76e0836904b4228a22b (diff)
Add autoscroll on edges for keyframe selection rectangle
Now timeline autoscrolls when dragging keyframe selection box is dragged beyond timeline edges. Also added limiter to autoscroll speed per frame and a distance divisor, which allows more precise scrolling. Task-number: QT3DS-717 Change-Id: I29b992ba80fadf60bfec421cbd7e401e36b01ae1 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Jere Tuliniemi <jere.tuliniemi@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Authoring')
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.cpp17
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.h7
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h3
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp109
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h5
-rw-r--r--src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h1
6 files changed, 100 insertions, 42 deletions
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.cpp
index 39c1bc99..f04165e8 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.cpp
@@ -32,7 +32,7 @@
#include <QtGui/qpainter.h>
-SelectionRect::SelectionRect(Ruler *ruler) : m_ruler(ruler)
+SelectionRect::SelectionRect()
{
setZValue(100);
setActive(false);
@@ -55,14 +55,17 @@ void SelectionRect::start(const QPointF &origin)
m_active = true;
}
-void SelectionRect::updateSize(const QPointF &pos)
+void SelectionRect::updateSize(const QPointF &pos, const QRectF &visibleScene)
{
QPointF newPos = pos;
- if (newPos.x() < m_ruler->x())
- newPos.setX(m_ruler->x());
-
- if (newPos.y() < TimelineConstants::ROW_H)
- newPos.setY(TimelineConstants::ROW_H);
+ if (newPos.x() < visibleScene.left())
+ newPos.setX(visibleScene.left());
+ else if (newPos.x() > visibleScene.right())
+ newPos.setX(visibleScene.right());
+ if (newPos.y() < visibleScene.top())
+ newPos.setY(visibleScene.top());
+ else if (newPos.y() > visibleScene.bottom())
+ newPos.setY(visibleScene.bottom());
m_rect.setBottomRight(newPos);
setRect(m_rect.normalized());
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.h
index 36ea3fb7..cad62662 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/SelectionRect.h
@@ -29,17 +29,15 @@
#ifndef SELECTIONRECT_H
#define SELECTIONRECT_H
-class Ruler;
-
#include <QtWidgets/qgraphicsitem.h>
class SelectionRect : public QGraphicsRectItem
{
public:
- explicit SelectionRect(Ruler *ruler);
+ explicit SelectionRect();
void start(const QPointF &origin);
- void updateSize(const QPointF &pos);
+ void updateSize(const QPointF &pos, const QRectF &visibleScene);
void end();
bool isActive();
@@ -47,7 +45,6 @@ public:
QWidget *widget = nullptr) override;
private:
- Ruler *m_ruler = nullptr;
bool m_active = false;
QRectF m_rect;
};
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h
index c5233ca2..9c3ab457 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineConstants.h
@@ -92,6 +92,9 @@ namespace TimelineConstants
const int AUTO_EXPAND_TIME = 500; // auto expand a hovered row (while DnD-ing)
const double MAX_SLIDE_TIME = 3599.0; // seconds
+ const int TIMELINE_SCROLL_MAX_DELTA = 25; // Maximum amount of pixels to scroll per frame
+ const int TIMELINE_SCROLL_DIVISOR = 6; // Divisor for timeline autoscroll distance
+
// TODO: move the colors and dimensions to StudioPreferences.
}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
index 0efaefdf..65aa65cc 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.cpp
@@ -77,7 +77,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget)
, m_layoutTimeline(new QGraphicsLinearLayout(Qt::Vertical))
, m_ruler(new Ruler)
, m_playHead(new PlayHead(m_ruler))
- , m_selectionRect(new SelectionRect(m_ruler))
+ , m_selectionRect(new SelectionRect())
, m_rowMover(new RowMover(this))
, m_widgetTimeline(timelineWidget)
, m_widgetRoot(new QGraphicsWidget)
@@ -138,26 +138,68 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget)
connect(&m_autoScrollTimelineTimer, &QTimer::timeout, [this]() {
if (!qApp->focusWindow() && !g_StudioApp.isOnProgress()) {
- m_autoScrollTimelineTimer.stop();
resetMousePressParams();
return;
}
+ QGraphicsView *timelineContent = m_widgetTimeline->viewTimelineContent();
+ QPoint scrollBarOffsets(timelineContent->verticalScrollBar()->isVisible()
+ ? timelineContent->verticalScrollBar()->width() : 0,
+ timelineContent->horizontalScrollBar()->isVisible()
+ ? timelineContent->horizontalScrollBar()->height() : 0);
+ const QRect contentRect = timelineContent->contentsRect();
+ const double right = timelineContent->width() - scrollBarOffsets.x();
+ QPoint p = m_widgetTimeline->mapFromGlobal(QCursor::pos())
+ - QPoint(m_widgetTimeline->viewTreeContent()->width()
+ + TimelineConstants::SPLITTER_W, 0);
+
+ // Limit the maximum scroll speed
+ if (p.x() < 0) {
+ p.setX(qMax(-TimelineConstants::TIMELINE_SCROLL_MAX_DELTA,
+ p.x() / TimelineConstants::TIMELINE_SCROLL_DIVISOR));
+ } else if (p.x() > right) {
+ p.setX(qMin(right + TimelineConstants::TIMELINE_SCROLL_MAX_DELTA,
+ right + 1 + ((p.x() - right)
+ / TimelineConstants::TIMELINE_SCROLL_DIVISOR)));
+ }
+
+ if (m_selectionRect->isActive()) {
+ p -= QPoint(0, m_widgetTimeline->navigationBar()->height()
+ + TimelineConstants::ROW_H);
+ const double bottom = timelineContent->contentsRect().height() - scrollBarOffsets.y();
+ if (m_lastAutoScrollX != p.x() || p.x() <= 0 || p.x() >= right
+ || m_lastAutoScrollY != p.y() || p.y() <= 0 || p.y() >= bottom) {
+ m_lastAutoScrollX = p.x();
+ m_lastAutoScrollY = p.y();
+
+ if (p.y() < 0) {
+ p.setY(qMax(-TimelineConstants::TIMELINE_SCROLL_MAX_DELTA,
+ p.y() / TimelineConstants::TIMELINE_SCROLL_DIVISOR));
+ } else if (p.y() > bottom) {
+ p.setY(qMin(bottom + TimelineConstants::TIMELINE_SCROLL_MAX_DELTA,
+ bottom + 1 + ((p.y() - bottom)
+ / TimelineConstants::TIMELINE_SCROLL_DIVISOR)));
+ }
- QPoint p = m_widgetTimeline->mapFromGlobal(QCursor::pos());
- double left = m_widgetTimeline->viewTreeContent()->width()
- + TimelineConstants::SPLITTER_W;
- double right = left + m_widgetTimeline->viewTimelineContent()->width()
- - TimelineConstants::RULER_EDGE_OFFSET;
- if (m_lastPlayHeadX != p.x() || p.x() < left || p.x() > right) {
- m_lastPlayHeadX = p.x();
+ // Resize keyframe selection rect
+ const QPointF scenePoint = timelineContent->mapToScene(p);
+ timelineContent->ensureVisible(scenePoint.x(), scenePoint.y(),
+ 0, 0, 0, 0);
+ QRectF visibleScene(
+ timelineContent->mapToScene(contentRect.topLeft()),
+ timelineContent->mapToScene(contentRect.bottomRight()
+ - scrollBarOffsets));
+ m_selectionRect->updateSize(scenePoint, visibleScene);
+ m_keyframeManager->selectKeyframesInRect(m_selectionRect->rect());
+ }
+ } else if (m_lastAutoScrollX != p.x() || p.x() <= 0 || p.x() >= right) {
+ m_lastAutoScrollX = p.x();
bool shift = QGuiApplication::queryKeyboardModifiers() & Qt::ShiftModifier;
- double scroll = m_widgetTimeline->viewTimelineContent()
- ->horizontalScrollBar()->value();
+ double scroll = timelineContent->horizontalScrollBar()->value();
if (scroll != 0)
scroll -= TimelineConstants::TREE_BOUND_W;
- double distance = p.x() - left + scroll;
+ double distance = p.x() + scroll;
if (m_clickedTimelineControlType == TimelineControlType::Duration)
distance -= m_editedTimelineRow->getDurationMoveOffsetX();
@@ -178,9 +220,8 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget)
m_editedTimelineRow->setStartX(distance);
m_editedTimelineRow->showToolTip(QCursor::pos());
- m_widgetTimeline->viewTimelineContent()->ensureVisible(
- TimelineConstants::TREE_BOUND_W + visiblePtX,
- m_editedTimelineRow->y(), 0, 0, 0, 0);
+ timelineContent->ensureVisible(TimelineConstants::TREE_BOUND_W + visiblePtX,
+ m_editedTimelineRow->y(), 0, 0, 0, 0);
} else if (m_clickedTimelineControlType == TimelineControlType::EndHandle) {
double time = m_ruler->distanceToTime(distance
- TimelineConstants::RULER_EDGE_OFFSET);
@@ -195,10 +236,9 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget)
m_editedTimelineRow->setEndX(distance);
m_editedTimelineRow->showToolTip(QCursor::pos());
rowManager()->updateRulerDuration(p.x() > right);
- m_widgetTimeline->viewTimelineContent()->ensureVisible(
- TimelineConstants::TREE_BOUND_W
- + m_editedTimelineRow->getEndX() + edgeMargin,
- m_editedTimelineRow->y(), 0, 0, 0, 0);
+ timelineContent->ensureVisible(TimelineConstants::TREE_BOUND_W
+ + m_editedTimelineRow->getEndX() + edgeMargin,
+ m_editedTimelineRow->y(), 0, 0, 0, 0);
} else if (m_clickedTimelineControlType == TimelineControlType::Duration) {
double time = m_ruler->distanceToTime(
distance - TimelineConstants::RULER_EDGE_OFFSET)
@@ -215,7 +255,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *timelineWidget)
m_editedTimelineRow->moveDurationTo(distance);
m_editedTimelineRow->showToolTip(QCursor::pos());
rowManager()->updateRulerDuration(p.x() > right);
- m_widgetTimeline->viewTimelineContent()->ensureVisible(
+ timelineContent->ensureVisible(
TimelineConstants::TREE_BOUND_W + visiblePtX, m_editedTimelineRow->y(),
0, 0, 0, 0);
}
@@ -458,18 +498,19 @@ void TimelineGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
m_rowManager->selectRow(m_editedTimelineRow->rowTree(), ctrlKeyDown);
// click position in ruler space
m_editedTimelineRow->startDurationMove(m_pressPos.x() - m_ruler->x());
- m_autoScrollTimelineTimer.start();
} else if (m_clickedTimelineControlType == TimelineControlType::StartHandle
|| m_clickedTimelineControlType == TimelineControlType::EndHandle) {
- m_autoScrollTimelineTimer.start();
}
+ m_autoScrollTimelineTimer.start();
}
}
} else {
m_keyframeManager->deselectAllKeyframes();
- if (m_pressPos.x() > m_ruler->x() && m_pressPos.y() > TimelineConstants::ROW_H)
+ if (m_pressPos.x() > m_ruler->x() && m_pressPos.y() > TimelineConstants::ROW_H) {
m_selectionRect->start(m_pressPos);
+ m_autoScrollTimelineTimer.start();
+ }
}
}
@@ -488,11 +529,7 @@ void TimelineGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
bool shift = event->modifiers() & Qt::ShiftModifier;
if (m_dragging) {
- if (m_selectionRect->isActive()) {
- // resizing keyframe selection rect
- m_selectionRect->updateSize(event->scenePos());
- m_keyframeManager->selectKeyframesInRect(m_selectionRect->rect());
- } else if (m_startRowMoverOnNextDrag || m_rowMover->isActive()) {
+ if (m_startRowMoverOnNextDrag || m_rowMover->isActive()) {
// moving rows vertically (reorder/reparent)
if (m_startRowMoverOnNextDrag) {
m_startRowMoverOnNextDrag = false;
@@ -600,6 +637,8 @@ void TimelineGraphicsScene::resetMousePressParams()
m_autoScrollTriggerTimer.stop();
m_timebarToolTip->hide();
m_pressPos = invalidPoint;
+ m_lastAutoScrollX = -1.0;
+ m_lastAutoScrollY = -1.0;
}
QLabel *TimelineGraphicsScene::timebarTooltip()
@@ -733,6 +772,14 @@ void TimelineGraphicsScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *even
QGraphicsScene::mouseDoubleClickEvent(event);
}
+void TimelineGraphicsScene::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
+{
+ // Make sure drag states update on wheel scrolls done during drag
+ m_lastAutoScrollX = -1.0;
+ m_lastAutoScrollY = -1.0;
+ QGraphicsScene::wheelEvent(wheelEvent);
+}
+
void TimelineGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
{
// Eat left/right arrow keys on tree side unless some item (e.g. label) has focus
@@ -745,6 +792,12 @@ void TimelineGraphicsScene::keyPressEvent(QKeyEvent *keyEvent)
} else if (keyEvent->key() == Qt::Key_Delete && !m_rowMover->isActive()) {
g_StudioApp.DeleteSelectedObject(); // Despite the name, this deletes objects and keyframes
}
+ // Make sure drag states update on keyboard scrolls done during drag
+ if (keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right
+ || keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) {
+ m_lastAutoScrollX = -1.0;
+ m_lastAutoScrollY = -1.0;
+ }
QGraphicsScene::keyPressEvent(keyEvent);
}
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
index b8ef2174..ec878bf0 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineGraphicsScene.h
@@ -93,7 +93,7 @@ protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
-
+ void wheelEvent(QGraphicsSceneWheelEvent *wheelEvent);
void keyPressEvent(QKeyEvent *keyEvent) override;
void keyReleaseEvent(QKeyEvent *keyEvent) override;
@@ -143,7 +143,8 @@ private:
TreeControlType m_clickedTreeControlType = TreeControlType::None;
double m_pressPosInKeyframe;
double m_treeWidth = TimelineConstants::TREE_DEFAULT_W;
- double m_lastPlayHeadX = 0;
+ double m_lastAutoScrollX = -1.0;
+ double m_lastAutoScrollY = -1.0;
TExpandMap m_expandMap;
RowTree *m_releaseSelectRow = nullptr;
bool m_autoScrollDownOn = false;
diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h
index 6ca6c734..cfeed854 100644
--- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h
+++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/TimelineWidget.h
@@ -99,6 +99,7 @@ public:
CPt GetPreferredSize() override;
void SetSize(long inX, long inY) override;
bool isFullReconstructPending() const { return m_fullReconstruct; }
+ NavigationBar *navigationBar() const { return m_navigationBar; }
protected:
// DataModel callbacks