Commit 13b28288 authored by Marco Bubke's avatar Marco Bubke
Browse files

Add dynamic properties to the node instances

parent 1105e4d2
......@@ -91,7 +91,8 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/model/qmltextgenerator.cpp \
$$PWD/model/modelmerger.cpp \
$$PWD/instances/qmltransitionnodeinstance.cpp \
$$PWD/exceptions/rewritingexception.cpp
$$PWD/exceptions/rewritingexception.cpp \
$$PWD/instances/nodeinstancemetaobject.cpp
HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/abstractview.h \
$$PWD/include/nodeinstanceview.h \
......@@ -179,7 +180,8 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/mathutils.h \
$$PWD/instances/qmltransitionnodeinstance.h \
$$PWD/include/customnotifications.h \
$$PWD/include/rewritingexception.h
$$PWD/include/rewritingexception.h \
$$PWD/instances/nodeinstancemetaobject.h
DISTFILES += $$PWD/metafile/widget.metafile
RESOURCES += $$PWD/core.qrc
OTHER_FILES += $$PWD/metainfo/gui.metainfo
......@@ -366,10 +366,10 @@ void NodeInstance::setPropertyVariant(const QString &name, const QVariant &value
m_nodeInstance->setPropertyVariant(name, value);
}
void NodeInstance::setPropertyDynamicVariant(const QString &/*name*/, const QString &/*typeName*/, const QVariant &/*value*/)
void NodeInstance::setPropertyDynamicVariant(const QString &name, const QString &typeName, const QVariant &value)
{
// m_nodeInstance->createDynamicProperty(name, typeName);
// m_nodeInstance->setPropertyVariant(name, value);
m_nodeInstance->createDynamicProperty(name, typeName);
m_nodeInstance->setPropertyVariant(name, value);
}
void NodeInstance::setPropertyBinding(const QString &name, const QString &expression)
......@@ -377,10 +377,10 @@ void NodeInstance::setPropertyBinding(const QString &name, const QString &expres
m_nodeInstance->setPropertyBinding(name, expression);
}
void NodeInstance::setPropertyDynamicBinding(const QString &/*name*/, const QString &/*typeName*/, const QString &/*expression*/)
void NodeInstance::setPropertyDynamicBinding(const QString &name, const QString &typeName, const QString &expression)
{
// m_nodeInstance->createDynamicProperty(name, typeName);
// m_nodeInstance->setPropertyBinding(name, value);
m_nodeInstance->createDynamicProperty(name, typeName);
m_nodeInstance->setPropertyBinding(name, expression);
}
void NodeInstance::resetProperty(const QString &name)
......
#include "nodeinstancemetaobject.h"
namespace QmlDesigner {
namespace Internal {
NodeInstanceMetaObject::NodeInstanceMetaObject(QObject *object, QmlContext *context)
: QmlOpenMetaObject(object),
m_context(context)
{
}
void NodeInstanceMetaObject::createNewProperty(const QString &name)
{
createProperty(name.toLatin1(), 0);
}
int NodeInstanceMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
{
if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
&& id >= type()->propertyOffset()) {
int propId = id - type()->propertyOffset();
if (c == QMetaObject::ReadProperty) {
propertyRead(propId);
*reinterpret_cast<QVariant *>(a[0]) = value(propId);
} else if (c == QMetaObject::WriteProperty) {
if (value(propId) != *reinterpret_cast<QVariant *>(a[0])) {
propertyWrite(propId);
setValue(propId, *reinterpret_cast<QVariant *>(a[0]));
propertyWritten(propId);
activate(object(), type()->signalOffset() + propId, 0);
}
}
return -1;
} else {
if (parent())
return parent()->metaCall(c, id, a);
else
return object()->qt_metacall(c, id, a);
}
}
void NodeInstanceMetaObject::propertyWritten(int propertyId)
{
if (m_context)
m_context->setContextProperty(name(propertyId), value(propertyId));
}
} // namespace Internal
} // namespace QmlDesigner
#ifndef NODEINSTANCEMETAOBJECT_H
#define NODEINSTANCEMETAOBJECT_H
#include <private/qmlopenmetaobject_p.h>
#include <private/qmlcontext_p.h>
namespace QmlDesigner {
namespace Internal {
class NodeInstanceMetaObject : public QmlOpenMetaObject
{
public:
NodeInstanceMetaObject(QObject *object, QmlContext *context);
void createNewProperty(const QString &name);
protected:
int metaCall(QMetaObject::Call _c, int _id, void **_a);
void propertyWritten(int);
private:
QWeakPointer<QmlContext> m_context;
};
} // namespace Internal
} // namespace QmlDesigner
#endif // NODEINSTANCEMETAOBJECT_H
......@@ -63,6 +63,8 @@
#include <private/qmlvaluetype_p.h>
#include <private/qmlgraphicsanchors_p.h>
#include <private/qmlgraphicsrectangle_p.h> // to get QmlGraphicsPen
#include <private/qmetaobjectbuilder_p.h>
#include <private/qmlvmemetaobject_p.h>
......@@ -88,7 +90,8 @@ bool ChildrenChangeEventFilter::eventFilter(QObject *object, QEvent *event)
ObjectNodeInstance::ObjectNodeInstance(QObject *object)
: m_deleteHeldInstance(true),
m_object(object)
m_object(object),
m_metaObject(0)
{
}
......@@ -374,20 +377,10 @@ void ObjectNodeInstance::reparent(const NodeInstance &oldParentInstance, const Q
refreshBindings(context()->engine()->rootContext());
}
void ObjectNodeInstance::setPropertyVariant(const QString &name, const QVariant &valueArg)
void ObjectNodeInstance::setPropertyVariant(const QString &name, const QVariant &value)
{
QVariant value = valueArg;
QmlMetaProperty qmlMetaProperty = QmlMetaProperty::createProperty(object(), name, context());
// if (qmlMetaProperty.propertyType() == QVariant::Url) {
// QUrl url = value.toUrl();
// if (url.isRelative()) {
// QUrl baseUrl(nodeInstanceView()->model()->fileUrl());
// value.setValue(baseUrl.resolved(url));
// }
// }
qmlMetaProperty.write(value);
}
......@@ -592,7 +585,7 @@ QmlContext *ObjectNodeInstance::context() const
QmlContext *context = QmlEngine::contextForObject(object());
if (context)
return context;
else if (nodeInstanceView())
else if (nodeInstanceView())
return nodeInstanceView()->engine()->rootContext();
return 0;
......@@ -687,10 +680,27 @@ void ObjectNodeInstance::setVisible(bool /*isVisible*/)
{
}
void ObjectNodeInstance::createDynamicProperty(const QString &/*name*/, const QString &/*typeName*/)
static bool metaObjectHasNotPropertyName(NodeInstanceMetaObject *metaObject, const QString &propertyName)
{
//todo not implemented at all
for (int i = 0; i < metaObject->count(); i++) {
if (metaObject->name(i) == propertyName)
return false;
}
return true;
}
void ObjectNodeInstance::createDynamicProperty(const QString &name, const QString &/*typeName*/)
{
if (m_metaObject == 0) {
if (modelNode().isRootNode())
m_metaObject = new NodeInstanceMetaObject(object(), context());
else
m_metaObject = new NodeInstanceMetaObject(object(), 0);
}
if (metaObjectHasNotPropertyName(m_metaObject, name))
m_metaObject->createNewProperty(name);
}
/**
......
......@@ -34,9 +34,11 @@
#include <QStyleOptionGraphicsItem>
#include "modelnode.h"
#include <QSharedPointer>
#include <QScopedPointer>
#include <QWeakPointer>
#include <propertymetainfo.h>
#include <nodeinstanceview.h>
#include "nodeinstancemetaobject.h"
class QGraphicsItem;
class QmlContext;
......@@ -179,6 +181,7 @@ private:
QWeakPointer<NodeInstanceView> m_nodeInstanceView;
bool m_deleteHeldInstance;
QWeakPointer<QObject> m_object;
NodeInstanceMetaObject *m_metaObject;
};
......
......@@ -159,9 +159,9 @@ MetaInfo NodeMetaInfo::metaInfo() const
\throws InvalidArgumentException when the context argument is a null pointer
\throws InvalidMetaInfoException if the object is not valid
*/
QObject *NodeMetaInfo::createInstance(QmlContext *parentContext) const
QObject *NodeMetaInfo::createInstance(QmlContext *context) const
{
if (!parentContext) {
if (!context) {
Q_ASSERT_X(0, Q_FUNC_INFO, "Context cannot be null");
throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, "context");
}
......@@ -175,13 +175,13 @@ QObject *NodeMetaInfo::createInstance(QmlContext *parentContext) const
if (isComponent()) {
// qml component
// TODO: This is maybe expensive ...
QmlComponent component(parentContext->engine(), QUrl::fromLocalFile(m_data->qmlFile));
object = component.create(parentContext);
QmlComponent component(context->engine(), QUrl::fromLocalFile(m_data->qmlFile));
object = component.create(context);
} else {
// primitive
object = QmlMetaType::qmlType(typeName().toAscii(), 4, 6)->create();
if (object && parentContext)
QmlEngine::setContextForObject(object, new QmlContext(parentContext, object));
if (object && context)
QmlEngine::setContextForObject(object, context);
}
return object;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment