Commit 2228fb14 authored by Marco Bubke's avatar Marco Bubke
Browse files

QmlDesigner: States preview are functional again

But still slow.
parent 8bf142fb
......@@ -32,6 +32,7 @@
**************************************************************************/
#include "stateseditorimageprovider.h"
#include "stateseditorview.h"
#include "nodeinstanceview.h"
#include <QtDebug>
......@@ -39,34 +40,45 @@ namespace QmlDesigner {
namespace Internal {
StatesEditorImageProvider::StatesEditorImageProvider() :
QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
StatesEditorImageProvider::StatesEditorImageProvider()
: QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
{
}
QImage StatesEditorImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
if (m_nodeInstanceView.isNull())
return QImage();
QSize newSize = requestedSize;
if (newSize.isEmpty())
newSize = QSize (100, 100);
QImage image = m_imageHash.value(id, QImage(newSize, QImage::Format_ARGB32));
image.fill(0xFFFFFFFF);
QString imageId = id.split("-").first();
QImage image;
if (imageId == "baseState") {
image = m_nodeInstanceView->statePreviewImage(m_nodeInstanceView->rootModelNode());
} else {
bool canBeConverted;
int instanceId = imageId.toInt(&canBeConverted);
if (canBeConverted && m_nodeInstanceView->hasModelNodeForInternalId(instanceId)) {
image = m_nodeInstanceView->statePreviewImage(m_nodeInstanceView->modelNodeForInternalId(instanceId));
} else {
image = QImage(newSize, QImage::Format_ARGB32);
image.fill(0xFFFFFFFF);
}
}
*size = image.size();
return image;
}
void StatesEditorImageProvider::setImage(const QString &id, const QImage &image)
{
m_imageHash.insert(id, image);
}
void StatesEditorImageProvider::removeImage(const QString &id)
void StatesEditorImageProvider::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
{
m_imageHash.remove(id);
m_nodeInstanceView = nodeInstanceView;
}
}
......
......@@ -35,7 +35,8 @@
#define STATESEDITORIMAGEPROVIDER_H
#include <QDeclarativeImageProvider>
#include <QHash>
#include <QWeakPointer>
#include"abstractview.h"
namespace QmlDesigner {
......@@ -50,11 +51,10 @@ public:
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
void setImage(const QString &id, const QImage &image);
void removeImage(const QString &id);
void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
private:
QHash<QString, QImage> m_imageHash;
QWeakPointer<NodeInstanceView> m_nodeInstanceView;
};
}
......
......@@ -118,7 +118,15 @@ QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
}
}
case StateImageSourceRole: return QString("image://qmldesigner_stateseditor/%1").arg(index.internalId());
case StateImageSourceRole: {
static int randomNumber = 0;
randomNumber++;
if (index.row() == 0) {
return QString("image://qmldesigner_stateseditor/baseState-%1").arg(randomNumber);
} else {
return QString("image://qmldesigner_stateseditor/%1-%2").arg(index.internalId()).arg(randomNumber);
}
}
case NodeId : return index.internalId();
}
......@@ -130,35 +138,34 @@ void StatesEditorModel::insertState(int stateIndex)
{
if (stateIndex >= 0) {
const int index = stateIndex + 1;
beginInsertRows(QModelIndex(), index, index);
const int updateIndex = stateIndex + 1;
beginInsertRows(QModelIndex(), updateIndex, updateIndex);
endInsertRows();
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
emit dataChanged(index(updateIndex, 0), index(updateIndex, 0));
emit countChanged();
}
}
void StatesEditorModel::updateState(int stateIndex)
void StatesEditorModel::updateState(int updateIndex)
{
if (stateIndex >= 0) {
const int index = stateIndex + 1;
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
if (updateIndex >= 0) {
QModelIndex modelIndex = index(updateIndex, 0);
emit dataChanged(modelIndex, modelIndex);
}
}
void StatesEditorModel::removeState(int stateIndex)
{
if (stateIndex >= 0) {
const int index = stateIndex + 1;
beginRemoveRows(QModelIndex(), index, index);
const int updateIndex = stateIndex + 1;
beginRemoveRows(QModelIndex(), updateIndex, updateIndex);
endRemoveRows();
emit dataChanged(createIndex(index, 0), createIndex(index, 0));
emit dataChanged(index(updateIndex, 0), index(updateIndex, 0));
emit countChanged();
}
}
......
......@@ -48,10 +48,6 @@
#include <variantproperty.h>
#include <nodelistproperty.h>
enum {
debug = false
};
namespace QmlDesigner {
/**
......@@ -228,6 +224,9 @@ void StatesEditorView::modelAttached(Model *model)
Q_ASSERT(model);
QmlModelView::modelAttached(model);
if (m_statesEditorWidget)
m_statesEditorWidget->setNodeInstanceView(nodeInstanceView());
resetModel();
}
......@@ -252,7 +251,7 @@ void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &pr
if (property.name() == "name" && property.parentModelNode().hasParentProperty()) {
NodeAbstractProperty parentProperty = property.parentModelNode().parentProperty();
if (parentProperty.name() == "states" && parentProperty.parentModelNode().isRootNode()) {
m_statesEditorModel->updateState(parentProperty.indexOf(property.parentModelNode()));
m_statesEditorModel->updateState(parentProperty.indexOf(property.parentModelNode()) + 1);
}
}
}
......@@ -337,22 +336,17 @@ void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode,
void StatesEditorView::customNotification(const AbstractView * view, const QString & identifier, const QList<ModelNode> & nodeList, const QList<QVariant> &imageList)
{
if (debug)
qDebug() << __FUNCTION__;
if (identifier == "__state preview updated__") {
if (nodeList.size() != imageList.size())
return;
// if (++m_updateCounter == INT_MAX)
// m_updateCounter = 0;
for (int i = 0; i < nodeList.size(); i++) {
QmlModelState modelState(nodeList.at(i));
if (identifier == "__instance preview image changed__") {
foreach(const ModelNode &node, nodeList) {
if (node.isRootNode()) {
m_statesEditorModel->updateState(0);
} else {
int index = rootStateGroup().allStates().indexOf(QmlModelState(node)) + 1;
if (index > 0)
m_statesEditorModel->updateState(index);
}
}
// emit dataChanged(createIndex(i, 0), createIndex(i, 0));
} else {
QmlModelView::customNotification(view, identifier, nodeList, imageList);
}
......@@ -360,8 +354,6 @@ void StatesEditorView::customNotification(const AbstractView * view, const QStri
void StatesEditorView::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList)
{
if (debug)
qDebug() << __FUNCTION__;
QmlModelView::scriptFunctionsChanged(node, scriptFunctionList);
}
......
......@@ -72,14 +72,21 @@ void StatesEditorWidget::setCurrentStateInternalId(int internalId)
m_declarativeView->rootObject()->setProperty("currentStateInternalId", internalId);
}
StatesEditorWidget::StatesEditorWidget(StatesEditorView *statesEditorView, StatesEditorModel *statesEditorModel):
QWidget()
void StatesEditorWidget::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
{
m_declarativeView = new QDeclarativeView(this);
m_imageProvider->setNodeInstanceView(nodeInstanceView);
}
StatesEditorWidget::StatesEditorWidget(StatesEditorView *statesEditorView, StatesEditorModel *statesEditorModel):
QWidget(),
m_declarativeView(new QDeclarativeView(this)),
m_statesEditorView(statesEditorView),
m_imageProvider(0)
{
m_imageProvider = new Internal::StatesEditorImageProvider;
m_imageProvider->setNodeInstanceView(statesEditorView->nodeInstanceView());
m_declarativeView->engine()->addImageProvider(
QLatin1String("qmldesigner_stateseditor"), new Internal::StatesEditorImageProvider);
QLatin1String("qmldesigner_stateseditor"), m_imageProvider);
m_declarativeView->setAcceptDrops(false);
......
......@@ -47,7 +47,11 @@ class Model;
class ModelState;
class StatesEditorModel;
class StatesEditorView;
class NodeInstanceView;
namespace Internal {
class StatesEditorImageProvider;
}
class StatesEditorWidget : public QWidget
{
......@@ -61,10 +65,12 @@ public:
int currentStateInternalId() const;
void setCurrentStateInternalId(int internalId);
void setNodeInstanceView(NodeInstanceView *nodeInstanceView);
private:
QWeakPointer<QDeclarativeView> m_declarativeView;
QWeakPointer<StatesEditorView> m_statesEditorView;
Internal::StatesEditorImageProvider *m_imageProvider;
};
}
......
......@@ -43,6 +43,7 @@
#include <QHash>
#include <QSet>
#include <QImage>
#include <QWeakPointer>
#include <QRectF>
......@@ -124,6 +125,8 @@ public:
void statePreviewImagesChanged(const StatePreviewImageChangedCommand &command);
void componentCompleted(const ComponentCompletedCommand &command);
QImage statePreviewImage(const ModelNode &stateNode) const;
private: // functions
NodeInstance rootNodeInstance() const;
......@@ -170,9 +173,11 @@ private: //variables
NodeInstance m_activeStateInstance;
QHash<ModelNode, NodeInstance> m_nodeInstanceHash;
QHash<ModelNode, QImage> m_statePreviewImage;
uint m_blockUpdates;
QWeakPointer<NodeInstanceServerInterface> m_nodeInstanceServer;
QImage m_baseStatePreviewImage;
};
} // namespace ProxyNodeInstanceView
......
......@@ -39,7 +39,7 @@ namespace QmlDesigner {
NodeInstanceClientProxy::NodeInstanceClientProxy(QObject *parent)
: QObject(parent),
m_nodeInstanceServer(new NodeInstanceServer(this)),
m_baseStateNodeInstancePreview(new PreviewNodeInstanceServer(this)),
m_stateNodeInstancePreview(new PreviewNodeInstanceServer(this)),
m_blockSize(0)
{
m_socket = new QLocalSocket(this);
......@@ -132,6 +132,11 @@ void NodeInstanceClientProxy::readDataStream()
}
}
NodeInstanceServerInterface *NodeInstanceClientProxy::stateNodeInstancePreview() const
{
return m_stateNodeInstancePreview;
}
NodeInstanceServerInterface *NodeInstanceClientProxy::nodeInstanceServer() const
{
return m_nodeInstanceServer;
......@@ -140,51 +145,61 @@ NodeInstanceServerInterface *NodeInstanceClientProxy::nodeInstanceServer() const
void NodeInstanceClientProxy::createInstances(const CreateInstancesCommand &command)
{
nodeInstanceServer()->createInstances(command);
stateNodeInstancePreview()->createInstances(command);
}
void NodeInstanceClientProxy::changeFileUrl(const ChangeFileUrlCommand &command)
{
nodeInstanceServer()->changeFileUrl(command);
stateNodeInstancePreview()->changeFileUrl(command);
}
void NodeInstanceClientProxy::createScene(const CreateSceneCommand &command)
{
nodeInstanceServer()->createScene(command);
stateNodeInstancePreview()->createScene(command);
}
void NodeInstanceClientProxy::clearScene(const ClearSceneCommand &command)
{
nodeInstanceServer()->clearScene(command);
stateNodeInstancePreview()->clearScene(command);
}
void NodeInstanceClientProxy::removeInstances(const RemoveInstancesCommand &command)
{
nodeInstanceServer()->removeInstances(command);
stateNodeInstancePreview()->removeInstances(command);
}
void NodeInstanceClientProxy::removeProperties(const RemovePropertiesCommand &command)
{
nodeInstanceServer()->removeProperties(command);
stateNodeInstancePreview()->removeProperties(command);
}
void NodeInstanceClientProxy::changePropertyBindings(const ChangeBindingsCommand &command)
{
nodeInstanceServer()->changePropertyBindings(command);
stateNodeInstancePreview()->changePropertyBindings(command);
}
void NodeInstanceClientProxy::changePropertyValues(const ChangeValuesCommand &command)
{
nodeInstanceServer()->changePropertyValues(command);
stateNodeInstancePreview()->changePropertyValues(command);
}
void NodeInstanceClientProxy::reparentInstances(const ReparentInstancesCommand &command)
{
nodeInstanceServer()->reparentInstances(command);
stateNodeInstancePreview()->reparentInstances(command);
}
void NodeInstanceClientProxy::changeIds(const ChangeIdsCommand &command)
{
nodeInstanceServer()->changeIds(command);
stateNodeInstancePreview()->changeIds(command);
}
void NodeInstanceClientProxy::changeState(const ChangeStateCommand &command)
......@@ -195,11 +210,13 @@ void NodeInstanceClientProxy::changeState(const ChangeStateCommand &command)
void NodeInstanceClientProxy::addImport(const AddImportCommand &command)
{
nodeInstanceServer()->addImport(command);
stateNodeInstancePreview()->addImport(command);
}
void NodeInstanceClientProxy::completeComponent(const CompleteComponentCommand &command)
{
nodeInstanceServer()->completeComponent(command);
stateNodeInstancePreview()->completeComponent(command);
}
void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
......
......@@ -49,7 +49,7 @@ protected:
void writeCommand(const QVariant &command);
void dispatchCommand(const QVariant &command);
NodeInstanceServerInterface *nodeInstanceServer() const;
NodeInstanceServerInterface *baseStateNodeInstancePreview() const;
NodeInstanceServerInterface *stateNodeInstancePreview() const;
void createInstances(const CreateInstancesCommand &command);
void changeFileUrl(const ChangeFileUrlCommand &command);
......@@ -71,8 +71,7 @@ private slots:
private:
QLocalSocket *m_socket;
NodeInstanceServerInterface *m_nodeInstanceServer;
NodeInstanceServerInterface *m_baseStateNodeInstancePreview;
QHash<qint32, QWeakPointer<NodeInstanceServerInterface> > m_nodeInstancePreviewVector;
NodeInstanceServerInterface *m_stateNodeInstancePreview;
quint32 m_blockSize;
};
......
......@@ -51,7 +51,9 @@ NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstance
m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)),
m_nodeInstanceClient(nodeInstanceClient),
m_timer(0),
m_slowRenderTimer(false)
m_renderTimerInterval(16),
m_slowRenderTimer(false),
m_slowRenderTimerInterval(1000)
{
m_importList.append("import Qt 4.7");
connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*)));
......@@ -123,13 +125,23 @@ bool NodeInstanceServer::hasInstanceForObject(QObject *object) const
return m_objectInstanceHash.contains(object);
}
void NodeInstanceServer::setRenderTimerInterval(int timerInterval)
{
m_renderTimerInterval = timerInterval;
}
void NodeInstanceServer::setSlowRenderTimerInterval(int timerInterval)
{
m_slowRenderTimerInterval = timerInterval;
}
void NodeInstanceServer::startRenderTimer()
{
if (m_slowRenderTimer)
stopRenderTimer();
if (m_timer == 0)
m_timer = startTimer(16);
m_timer = startTimer(m_renderTimerInterval);
m_slowRenderTimer = false;
}
......@@ -140,7 +152,7 @@ void NodeInstanceServer::slowDownRenderTimer()
stopRenderTimer();
if (m_timer == 0)
m_timer = startTimer(1000);
m_timer = startTimer(m_slowRenderTimerInterval);
m_slowRenderTimer = true;
}
......@@ -789,6 +801,28 @@ void NodeInstanceServer::initializeDeclarativeView()
#endif
}
QImage NodeInstanceServer::renderPreviewImage()
{
QSize size = rootNodeInstance().boundingRect().size().toSize();
size.scale(100, 100, Qt::KeepAspectRatio);
QImage image(size, QImage::Format_ARGB32);
image.fill(0xFFFFFFFF);
if (m_declarativeView) {
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::TextAntialiasing, true);
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
painter.setRenderHint(QPainter::NonCosmeticDefaultPen, true);
m_declarativeView->scene()->render(&painter, image.rect(), rootNodeInstance().boundingRect().toRect(), Qt::IgnoreAspectRatio);
}
return image;
}
QList<ServerNodeInstance> NodeInstanceServer::setupScene(const CreateSceneCommand &command)
{
if (!command.fileUrl().isEmpty())
......
......@@ -105,7 +105,7 @@ protected:
void timerEvent(QTimerEvent *);
bool nonInstanceChildIsDirty(QGraphicsObject *graphicsObject) const;
void findItemChangesAndSendChangeCommands();
virtual void findItemChangesAndSendChangeCommands();
void resetAllItems();
ValuesChangedCommand createValuesChangedCommand(const QList<ServerNodeInstance> &instanceList) const;
......@@ -121,9 +121,14 @@ protected:
void startRenderTimer();
void slowDownRenderTimer();
void stopRenderTimer();
void setRenderTimerInterval(int timerInterval);
void setSlowRenderTimerInterval(int timerInterval);
void initializeDeclarativeView();
QList<ServerNodeInstance> setupScene(const CreateSceneCommand &command);
QImage renderPreviewImage();
private:
ServerNodeInstance m_rootNodeInstance;
ServerNodeInstance m_activeStateInstance;
......@@ -136,7 +141,9 @@ private:
QUrl m_fileUrl;
NodeInstanceClientInterface *m_nodeInstanceClient;
int m_timer;
int m_renderTimerInterval;
bool m_slowRenderTimer;
int m_slowRenderTimerInterval;
QVector<InstancePropertyPair> m_changedPropertyList;
QStringList m_importList;
QSet<ServerNodeInstance> m_dirtyInstanceSet;
......
......@@ -113,8 +113,10 @@ d too.
\see ~NodeInstanceView setRenderOffScreen
*/
NodeInstanceView::NodeInstanceView(QObject *parent)
: AbstractView(parent)
: AbstractView(parent),
m_baseStatePreviewImage(QSize(100, 100), QImage::Format_ARGB32)
{
m_baseStatePreviewImage.fill(0xFFFFFF);
}
......@@ -891,7 +893,7 @@ void NodeInstanceView::valuesChanged(const ValuesChangedCommand &command)
void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
{
if (!model())
if (!model())
return;
QSet<ModelNode> renderImageChangeSet;
......@@ -907,7 +909,7 @@ void NodeInstanceView::pixmapChanged(const PixmapChangedCommand &command)
}
if (!renderImageChangeSet.isEmpty())
emitCustomNotification("__instance render pixmap changed__", renderImageChangeSet.toList());
emitCustomNotification("__instance render pixmap changed__", renderImageChangeSet.toList());
}
void NodeInstanceView::informationChanged(const InformationChangedCommand &command)
......@@ -931,9 +933,34 @@ void NodeInstanceView::informationChanged(const InformationChangedCommand &comma
emitCustomNotification("__instance information changed__", informationChangedList);
}
void NodeInstanceView::statePreviewImagesChanged(const StatePreviewImageChangedCommand &/*command*/)
QImage NodeInstanceView::statePreviewImage(const ModelNode &stateNode) const
{
if (stateNode == rootModelNode())
return m_baseStatePreviewImage;
return m_statePreviewImage.value(stateNode);
}
void NodeInstanceView::statePreviewImagesChanged(const StatePreviewImageChangedCommand &command)
{
if (!model())
return;
QList<ModelNode> previewImageChangeList;
foreach (const ImageContainer &container, command.previews()) {
if (container.instanceId() == 0) {
m_baseStatePreviewImage = container.image();
previewImageChangeList.append(rootModelNode());
} else if (hasInstanceForId(container.instanceId())) {
ModelNode node = modelNodeForInternalId(container.instanceId());
m_statePreviewImage.insert(node, container.image());