forked from qt-creator/qt-creator
Some timeline visual updates and corrections
- Selection rect selects keyframes based on center point rather than the whole keyframe. - Make playhead vertical line extend to the whole height of the timeline widget. - Prevent a jump when dragging a selection of keyframes. - Prevent dragging keyframes if the clicked keyframe is deselected (i.e. Ctrl+click a selected keyframe). - Correct timeline bounds checking while dragging multiple keyframes. Task-number: QDS-1073 Change-Id: Ibf118ecccfe86346f2d4e921c0958294a15c24f1 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -112,7 +112,7 @@ TimelineGraphicsScene::TimelineGraphicsScene(TimelineWidget *parent)
|
||||
if (auto *rview = rulerView())
|
||||
rview->setSceneRect(rect);
|
||||
|
||||
m_currentFrameIndicator->setHeight(m_layout->geometry().height());
|
||||
m_currentFrameIndicator->setHeight(9999); // big enough number (> timeline widget height)
|
||||
});
|
||||
|
||||
auto moveFrameIndicator = [this](const QPointF &pos) {
|
||||
|
||||
@@ -68,7 +68,12 @@ void TimelineMoveTool::mousePressEvent(TimelineMovableAbstractItem *item,
|
||||
QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(item)
|
||||
Q_UNUSED(event)
|
||||
|
||||
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
||||
const qreal sourceFrame = qRound(current->mapFromSceneToFrame(current->rect().center().x()));
|
||||
const qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
|
||||
m_pressKeyframeDelta = targetFrame - sourceFrame;
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
|
||||
@@ -80,34 +85,34 @@ void TimelineMoveTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
|
||||
return;
|
||||
|
||||
if (auto *current = currentItem()->asTimelineKeyframeItem()) {
|
||||
// prevent dragging if deselecting a keyframe (Ctrl+click and drag a selected keyframe)
|
||||
if (!current->highlighted())
|
||||
return;
|
||||
|
||||
const qreal sourceFrame = qRound(current->mapFromSceneToFrame(current->rect().center().x()));
|
||||
const qreal targetFrame = qRound(current->mapFromSceneToFrame(event->scenePos().x()));
|
||||
qreal deltaFrame = targetFrame - sourceFrame;
|
||||
qreal deltaFrame = targetFrame - sourceFrame - m_pressKeyframeDelta;
|
||||
|
||||
const qreal minFrame = scene()->startFrame();
|
||||
const qreal maxFrame = scene()->endFrame();
|
||||
|
||||
auto bbox = scene()->selectionBounds().united(current->rect());
|
||||
auto bbox = scene()->selectionBounds().adjusted(TimelineConstants::keyFrameSize / 2, 0,
|
||||
-TimelineConstants::keyFrameSize / 2, 0);
|
||||
double firstFrame = std::round(current->mapFromSceneToFrame(bbox.left()));
|
||||
double lastFrame = std::round(current->mapFromSceneToFrame(bbox.right()));
|
||||
|
||||
double firstFrame = std::round(current->mapFromSceneToFrame(bbox.center().x()));
|
||||
double lastFrame = std::round(current->mapFromSceneToFrame(bbox.center().x()));
|
||||
|
||||
if ((lastFrame + deltaFrame) > maxFrame)
|
||||
if (lastFrame + deltaFrame > maxFrame)
|
||||
deltaFrame = maxFrame - lastFrame;
|
||||
|
||||
if ((firstFrame + deltaFrame) <= minFrame)
|
||||
else if (firstFrame + deltaFrame < minFrame)
|
||||
deltaFrame = minFrame - firstFrame;
|
||||
|
||||
current->setPosition(sourceFrame + deltaFrame);
|
||||
|
||||
scene()->statusBarMessageChanged(tr(TimelineConstants::statusBarKeyframe)
|
||||
.arg(sourceFrame + deltaFrame));
|
||||
|
||||
for (auto *keyframe : scene()->selectedKeyframes()) {
|
||||
if (keyframe != current) {
|
||||
qreal pos = std::round(current->mapFromSceneToFrame(keyframe->rect().center().x()));
|
||||
keyframe->setPosition(pos + deltaFrame);
|
||||
}
|
||||
const QList<TimelineKeyframeItem *> selectedKeyframes = scene()->selectedKeyframes();
|
||||
for (auto *keyframe : selectedKeyframes) {
|
||||
qreal pos = std::round(keyframe->mapFromSceneToFrame(keyframe->rect().center().x()));
|
||||
keyframe->setPosition(pos + deltaFrame);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -52,6 +52,9 @@ public:
|
||||
|
||||
void keyPressEvent(QKeyEvent *keyEvent) override;
|
||||
void keyReleaseEvent(QKeyEvent *keyEvent) override;
|
||||
|
||||
private:
|
||||
qreal m_pressKeyframeDelta = 0.;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -517,10 +517,10 @@ void TimelineKeyframeItem::updateFrame()
|
||||
setPosition(m_frame.variantProperty("frame").value().toReal());
|
||||
}
|
||||
|
||||
void TimelineKeyframeItem::setPosition(qreal position)
|
||||
void TimelineKeyframeItem::setPosition(qreal frame)
|
||||
{
|
||||
int offset = (TimelineConstants::sectionHeight - TimelineConstants::keyFrameSize) / 2;
|
||||
const qreal scenePostion = mapFromFrameToScene(position);
|
||||
const qreal scenePostion = mapFromFrameToScene(frame);
|
||||
|
||||
setRect(scenePostion - TimelineConstants::keyFrameSize / 2,
|
||||
offset,
|
||||
@@ -622,6 +622,11 @@ void TimelineKeyframeItem::setHighlighted(bool b)
|
||||
update();
|
||||
}
|
||||
|
||||
bool TimelineKeyframeItem::highlighted() const
|
||||
{
|
||||
return m_highlight;
|
||||
}
|
||||
|
||||
TimelinePropertyItem *TimelineKeyframeItem::propertyItem() const
|
||||
{
|
||||
/* The parentItem is always a TimelinePropertyItem. See constructor */
|
||||
|
||||
@@ -58,8 +58,9 @@ public:
|
||||
void updateFrame();
|
||||
|
||||
void setHighlighted(bool b);
|
||||
bool highlighted() const;
|
||||
|
||||
void setPosition(qreal position);
|
||||
void setPosition(qreal frame);
|
||||
|
||||
void commitPosition(const QPointF &point) override;
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ void TimelineSelectionTool::mouseMoveEvent(TimelineMovableAbstractItem *item,
|
||||
m_selectionRect->show();
|
||||
|
||||
aboutToSelect(selectionMode(event),
|
||||
scene()->items(m_selectionRect->rect(), Qt::ContainsItemShape));
|
||||
scene()->items(m_selectionRect->rect(), Qt::IntersectsItemBoundingRect));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,6 +164,10 @@ void TimelineSelectionTool::aboutToSelect(SelectionMode mode, QList<QGraphicsIte
|
||||
|
||||
for (auto *item : items) {
|
||||
if (auto *keyframe = TimelineMovableAbstractItem::asTimelineKeyframeItem(item)) {
|
||||
// if keyframe's center isn't inside m_selectionRect, discard it
|
||||
if (!m_selectionRect->rect().contains(keyframe->rect().center() + item->scenePos()))
|
||||
continue;
|
||||
|
||||
if (mode == SelectionMode::Remove)
|
||||
keyframe->setHighlighted(false);
|
||||
else if (mode == SelectionMode::Toggle)
|
||||
|
||||
Reference in New Issue
Block a user