forked from qt-creator/qt-creator
QmlDesigner: Fix shaking items when scrubbing the timeline
The reason for this is that when scrubbing the timeline, the bounding rectangle can change a lot (See bugreport). If this is the case the pixmap and the bounding rectangle get temporarily out of sync, which leads to the shaking. In this patch we add the bounding rectangle to the pixmap command. The bounding rectangle coming with the pixmap has higher precedence. This means if there is a pixmap, then the pixmap is always in sync with the pixmap. If there is no pixmap we use the "original" bounding rectangle. Task-number: QDS-7828 Change-Id: I40c0b7ed97863b9dca726547927ae1a37f9c415d Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
committed by
Tim Jenssen
parent
f6cfe31c7f
commit
2a44f8caaf
@@ -51,6 +51,11 @@ qint32 ImageContainer::keyNumber() const
|
|||||||
return m_keyNumber;
|
return m_keyNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRectF ImageContainer::rect() const
|
||||||
|
{
|
||||||
|
return m_rect;
|
||||||
|
}
|
||||||
|
|
||||||
void ImageContainer::setImage(const QImage &image)
|
void ImageContainer::setImage(const QImage &image)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_image.isNull(), /**/);
|
QTC_ASSERT(m_image.isNull(), /**/);
|
||||||
@@ -58,6 +63,11 @@ void ImageContainer::setImage(const QImage &image)
|
|||||||
m_image = image;
|
m_image = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageContainer::setRect(const QRectF &rectangle)
|
||||||
|
{
|
||||||
|
m_rect = rectangle;
|
||||||
|
}
|
||||||
|
|
||||||
void ImageContainer::removeSharedMemorys(const QVector<qint32> &keyNumberVector)
|
void ImageContainer::removeSharedMemorys(const QVector<qint32> &keyNumberVector)
|
||||||
{
|
{
|
||||||
for (qint32 keyNumber : keyNumberVector) {
|
for (qint32 keyNumber : keyNumberVector) {
|
||||||
@@ -140,6 +150,7 @@ QDataStream &operator<<(QDataStream &out, const ImageContainer &container)
|
|||||||
|
|
||||||
out << container.instanceId();
|
out << container.instanceId();
|
||||||
out << container.keyNumber();
|
out << container.keyNumber();
|
||||||
|
out << container.rect();
|
||||||
|
|
||||||
const QImage image = container.image();
|
const QImage image = container.image();
|
||||||
|
|
||||||
@@ -223,6 +234,7 @@ QDataStream &operator>>(QDataStream &in, ImageContainer &container)
|
|||||||
|
|
||||||
in >> container.m_instanceId;
|
in >> container.m_instanceId;
|
||||||
in >> container.m_keyNumber;
|
in >> container.m_keyNumber;
|
||||||
|
in >> container.m_rect;
|
||||||
in >> sharedMemoryIsUsed;
|
in >> sharedMemoryIsUsed;
|
||||||
|
|
||||||
if (sharedMemoryIsUsed) {
|
if (sharedMemoryIsUsed) {
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QMetaType>
|
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QRectF>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class ImageContainer
|
class ImageContainer
|
||||||
{
|
{
|
||||||
friend QDataStream &operator>>(QDataStream &in, ImageContainer &container);
|
friend QDataStream &operator>>(QDataStream &in, ImageContainer &container);
|
||||||
friend bool operator ==(const ImageContainer &first, const ImageContainer &second);
|
friend bool operator==(const ImageContainer &first, const ImageContainer &second);
|
||||||
friend bool operator <(const ImageContainer &first, const ImageContainer &second);
|
friend bool operator<(const ImageContainer &first, const ImageContainer &second);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ImageContainer();
|
ImageContainer();
|
||||||
@@ -21,8 +22,10 @@ public:
|
|||||||
qint32 instanceId() const;
|
qint32 instanceId() const;
|
||||||
QImage image() const;
|
QImage image() const;
|
||||||
qint32 keyNumber() const;
|
qint32 keyNumber() const;
|
||||||
|
QRectF rect() const;
|
||||||
|
|
||||||
void setImage(const QImage &image);
|
void setImage(const QImage &image);
|
||||||
|
void setRect(const QRectF &rectangle);
|
||||||
|
|
||||||
static void removeSharedMemorys(const QVector<qint32> &keyNumberVector);
|
static void removeSharedMemorys(const QVector<qint32> &keyNumberVector);
|
||||||
|
|
||||||
@@ -30,14 +33,15 @@ private:
|
|||||||
QImage m_image;
|
QImage m_image;
|
||||||
qint32 m_instanceId;
|
qint32 m_instanceId;
|
||||||
qint32 m_keyNumber;
|
qint32 m_keyNumber;
|
||||||
|
QRectF m_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &out, const ImageContainer &container);
|
QDataStream &operator<<(QDataStream &out, const ImageContainer &container);
|
||||||
QDataStream &operator>>(QDataStream &in, ImageContainer &container);
|
QDataStream &operator>>(QDataStream &in, ImageContainer &container);
|
||||||
|
|
||||||
bool operator ==(const ImageContainer &first, const ImageContainer &second);
|
bool operator==(const ImageContainer &first, const ImageContainer &second);
|
||||||
bool operator <(const ImageContainer &first, const ImageContainer &second);
|
bool operator<(const ImageContainer &first, const ImageContainer &second);
|
||||||
QDebug operator <<(QDebug debug, const ImageContainer &container);
|
QDebug operator<<(QDebug debug, const ImageContainer &container);
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
enum InformationName
|
enum InformationName {
|
||||||
{
|
|
||||||
NoName,
|
NoName,
|
||||||
NoInformationChange = NoName,
|
NoInformationChange = NoName,
|
||||||
AllStates,
|
AllStates,
|
||||||
Size,
|
Size,
|
||||||
BoundingRect,
|
BoundingRect,
|
||||||
|
BoundingRectPixmap,
|
||||||
Transform,
|
Transform,
|
||||||
HasAnchor,
|
HasAnchor,
|
||||||
Anchor,
|
Anchor,
|
||||||
@@ -37,5 +37,4 @@ enum InformationName
|
|||||||
ResizeView,
|
ResizeView,
|
||||||
HideView
|
HideView
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ protected:
|
|||||||
|
|
||||||
InformationName setInformationSize(const QSizeF &size);
|
InformationName setInformationSize(const QSizeF &size);
|
||||||
InformationName setInformationBoundingRect(const QRectF &rectangle);
|
InformationName setInformationBoundingRect(const QRectF &rectangle);
|
||||||
|
InformationName setInformationBoundingRectPixmap(const QRectF &rectangle);
|
||||||
InformationName setInformationContentItemBoundingRect(const QRectF &rectangle);
|
InformationName setInformationContentItemBoundingRect(const QRectF &rectangle);
|
||||||
InformationName setInformationTransform(const QTransform &transform);
|
InformationName setInformationTransform(const QTransform &transform);
|
||||||
InformationName setInformationContentTransform(const QTransform &contentTransform);
|
InformationName setInformationContentTransform(const QTransform &contentTransform);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
qint32 parentInstanceId{-1};
|
qint32 parentInstanceId{-1};
|
||||||
ModelNode modelNode;
|
ModelNode modelNode;
|
||||||
QRectF boundingRect;
|
QRectF boundingRect;
|
||||||
|
QRectF boundingRectPixmap;
|
||||||
QRectF contentItemBoundingRect;
|
QRectF contentItemBoundingRect;
|
||||||
QPointF position;
|
QPointF position;
|
||||||
QSizeF size;
|
QSizeF size;
|
||||||
@@ -166,9 +167,11 @@ void NodeInstance::makeInvalid()
|
|||||||
|
|
||||||
QRectF NodeInstance::boundingRect() const
|
QRectF NodeInstance::boundingRect() const
|
||||||
{
|
{
|
||||||
if (isValid())
|
if (isValid()) {
|
||||||
|
if (d->boundingRectPixmap.isValid())
|
||||||
|
return d->boundingRectPixmap;
|
||||||
return d->boundingRect;
|
return d->boundingRect;
|
||||||
else
|
} else
|
||||||
return QRectF();
|
return QRectF();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +530,16 @@ InformationName NodeInstance::setInformationBoundingRect(const QRectF &rectangle
|
|||||||
return NoInformationChange;
|
return NoInformationChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InformationName NodeInstance::setInformationBoundingRectPixmap(const QRectF &rectangle)
|
||||||
|
{
|
||||||
|
if (d->boundingRectPixmap != rectangle) {
|
||||||
|
d->boundingRectPixmap = rectangle;
|
||||||
|
return BoundingRectPixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NoInformationChange;
|
||||||
|
}
|
||||||
|
|
||||||
InformationName NodeInstance::setInformationContentItemBoundingRect(const QRectF &rectangle)
|
InformationName NodeInstance::setInformationContentItemBoundingRect(const QRectF &rectangle)
|
||||||
{
|
{
|
||||||
if (d->contentItemBoundingRect != rectangle) {
|
if (d->contentItemBoundingRect != rectangle) {
|
||||||
@@ -713,7 +726,10 @@ InformationName NodeInstance::setInformation(InformationName name, const QVarian
|
|||||||
{
|
{
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case Size: return setInformationSize(information.toSizeF());
|
case Size: return setInformationSize(information.toSizeF());
|
||||||
case BoundingRect: return setInformationBoundingRect(information.toRectF());
|
case BoundingRect:
|
||||||
|
return setInformationBoundingRect(information.toRectF());
|
||||||
|
case BoundingRectPixmap:
|
||||||
|
return setInformationBoundingRectPixmap(information.toRectF());
|
||||||
case ContentItemBoundingRect: return setInformationContentItemBoundingRect(information.toRectF());
|
case ContentItemBoundingRect: return setInformationContentItemBoundingRect(information.toRectF());
|
||||||
case Transform: return setInformationTransform(information.value<QTransform>());
|
case Transform: return setInformationTransform(information.value<QTransform>());
|
||||||
case ContentTransform: return setInformationContentTransform(information.value<QTransform>());
|
case ContentTransform: return setInformationContentTransform(information.value<QTransform>());
|
||||||
|
|||||||
@@ -1480,11 +1480,21 @@ void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
|
|||||||
|
|
||||||
QSet<ModelNode> renderImageChangeSet;
|
QSet<ModelNode> renderImageChangeSet;
|
||||||
|
|
||||||
|
QVector<InformationContainer> containerVector;
|
||||||
|
|
||||||
const QVector<ImageContainer> containers = command.images();
|
const QVector<ImageContainer> containers = command.images();
|
||||||
for (const ImageContainer &container : containers) {
|
for (const ImageContainer &container : containers) {
|
||||||
if (hasInstanceForId(container.instanceId())) {
|
if (hasInstanceForId(container.instanceId())) {
|
||||||
NodeInstance instance = instanceForId(container.instanceId());
|
NodeInstance instance = instanceForId(container.instanceId());
|
||||||
if (instance.isValid()) {
|
if (instance.isValid()) {
|
||||||
|
if (container.rect().isValid()) {
|
||||||
|
InformationContainer rectContainer = InformationContainer(container.instanceId(),
|
||||||
|
BoundingRectPixmap,
|
||||||
|
container.rect(),
|
||||||
|
{},
|
||||||
|
{});
|
||||||
|
containerVector.append(rectContainer);
|
||||||
|
}
|
||||||
instance.setRenderPixmap(container.image());
|
instance.setRenderPixmap(container.image());
|
||||||
renderImageChangeSet.insert(instance.modelNode());
|
renderImageChangeSet.insert(instance.modelNode());
|
||||||
}
|
}
|
||||||
@@ -1495,6 +1505,14 @@ void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
|
|||||||
|
|
||||||
if (!renderImageChangeSet.isEmpty())
|
if (!renderImageChangeSet.isEmpty())
|
||||||
emitInstancesRenderImageChanged(Utils::toList(renderImageChangeSet).toVector());
|
emitInstancesRenderImageChanged(Utils::toList(renderImageChangeSet).toVector());
|
||||||
|
|
||||||
|
if (!containerVector.isEmpty()) {
|
||||||
|
QMultiHash<ModelNode, InformationName> informationChangeHash = informationChanged(
|
||||||
|
containerVector);
|
||||||
|
|
||||||
|
if (!informationChangeHash.isEmpty())
|
||||||
|
emitInstanceInformationsChange(informationChangeHash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMultiHash<ModelNode, InformationName> NodeInstanceView::informationChanged(const QVector<InformationContainer> &containerVector)
|
QMultiHash<ModelNode, InformationName> NodeInstanceView::informationChanged(const QVector<InformationContainer> &containerVector)
|
||||||
|
|||||||
@@ -1316,7 +1316,9 @@ PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList<
|
|||||||
// item image in case the instance changed from having content to not having content.
|
// item image in case the instance changed from having content to not having content.
|
||||||
if (instance.hasContent())
|
if (instance.hasContent())
|
||||||
renderImage = instance.renderImage();
|
renderImage = instance.renderImage();
|
||||||
imageVector.append(ImageContainer(instance.instanceId(), renderImage, instance.instanceId()));
|
auto container = ImageContainer(instance.instanceId(), renderImage, instance.instanceId());
|
||||||
|
container.setRect(instance.boundingRect());
|
||||||
|
imageVector.append(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PixmapChangedCommand(imageVector);
|
return PixmapChangedCommand(imageVector);
|
||||||
|
|||||||
Reference in New Issue
Block a user