From 96048a7dbb5ee615e6dd24b0371bd26641af1612 Mon Sep 17 00:00:00 2001 From: Tobias Koenig Date: Sat, 13 Oct 2012 19:41:11 +0200 Subject: [PATCH 1/1] Initial commit --- .gitignore | 4 + declarativeobjects.cpp | 232 +++++++++++++++++++++++++++++++++++++++++ declarativeobjects_p.h | 112 ++++++++++++++++++++ declarativewidgetdocument.cpp | 64 +++++++++++ declarativewidgetdocument.h | 32 ++++++ main.cpp | 17 +++ qmlwidgets.pro | 14 +++ test.qml | 27 +++++ 8 files changed, 502 insertions(+), 0 deletions(-) create mode 100644 .gitignore create mode 100644 declarativeobjects.cpp create mode 100644 declarativeobjects_p.h create mode 100644 declarativewidgetdocument.cpp create mode 100644 declarativewidgetdocument.h create mode 100644 main.cpp create mode 100644 qmlwidgets.pro create mode 100644 test.qml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9adc96a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +qmlwidgets +Makefile +moc_* +*.o diff --git a/declarativeobjects.cpp b/declarativeobjects.cpp new file mode 100644 index 0000000..272e7a5 --- /dev/null +++ b/declarativeobjects.cpp @@ -0,0 +1,232 @@ +#include "declarativeobjects_p.h" + +// DeclarativeObject +DeclarativeObject::DeclarativeObject(QObject *parent) + : QObject(parent) +{ +} + +DeclarativeObject::~DeclarativeObject() +{ +} + +QDeclarativeListProperty DeclarativeObject::data() +{ + return QDeclarativeListProperty(this, 0, DeclarativeObject::data_append, + DeclarativeObject::data_count, + DeclarativeObject::data_at, + DeclarativeObject::data_clear); +} + +void DeclarativeObject::dataAppend(QObject *) +{ +} + +int DeclarativeObject::dataCount() +{ + return 0; +} + +QObject* DeclarativeObject::dataAt(int) +{ + return 0; +} + +void DeclarativeObject::dataClear() +{ +} + +void DeclarativeObject::data_append(QDeclarativeListProperty *property, QObject *object) +{ + if (!object) + return; + + DeclarativeObject *that = qobject_cast(property->object); + that->dataAppend(object); +} + +int DeclarativeObject::data_count(QDeclarativeListProperty *property) +{ + DeclarativeObject *that = qobject_cast(property->object); + return that->dataCount(); +} + +QObject* DeclarativeObject::data_at(QDeclarativeListProperty *property, int index) +{ + DeclarativeObject *that = qobject_cast(property->object); + return that->dataAt(index); +} + +void DeclarativeObject::data_clear(QDeclarativeListProperty *property) +{ + DeclarativeObject *that = qobject_cast(property->object); + that->dataClear(); +} + +// DeclarativeVBoxLayout +DeclarativeVBoxLayout::DeclarativeVBoxLayout(QObject *parent) + : DeclarativeObject(parent) + , m_layout(0) +{ +} + +DeclarativeVBoxLayout::~DeclarativeVBoxLayout() +{ +} + +QObject* DeclarativeVBoxLayout::object() +{ + if (!m_layout) + m_layout = new QVBoxLayout; + + return m_layout; +} + +void DeclarativeVBoxLayout::dataAppend(QObject *object) +{ + DeclarativeWidget *widget = qobject_cast(object); + DeclarativeVBoxLayout *layout = qobject_cast(object); + + if (widget) { + m_children.append(object); + qobject_cast(this->object())->addWidget(qobject_cast(widget->object())); + } else if (layout) { + m_children.append(object); + qobject_cast(this->object())->addLayout(qobject_cast(layout->object())); + } else { + // TODO: error unknown type + } +} + +int DeclarativeVBoxLayout::dataCount() +{ + return m_children.count(); +} + +QObject* DeclarativeVBoxLayout::dataAt(int index) +{ + return m_children.at(index); +} + +void DeclarativeVBoxLayout::dataClear() +{ + qDeleteAll(m_children); + m_children.clear(); +} + +// DeclarativeWidget +DeclarativeWidget::DeclarativeWidget(QObject *parent) + : DeclarativeObject(parent) + , m_widget(0) +{ +} + +DeclarativeWidget::~DeclarativeWidget() +{ +} + +QObject* DeclarativeWidget::object() +{ + if (!m_widget) + m_widget = new QWidget(); + + return m_widget; +} + +void DeclarativeWidget::dataAppend(QObject *object) +{ + DeclarativeWidget *widget = qobject_cast(object); + DeclarativeVBoxLayout *layout = qobject_cast(object); + + if (widget) { + // TODO: error when layout is set + m_children.append(object); + qobject_cast(widget->object())->setParent(qobject_cast(this->object())); + } else if (layout) { + // TODO: error when widget is set + + m_children.append(layout); + qobject_cast(this->object())->setLayout(qobject_cast(layout->object())); + } else { + // TODO: error unknown type + } +} + +int DeclarativeWidget::dataCount() +{ + return m_children.count(); +} + +QObject *DeclarativeWidget::dataAt(int index) +{ + return m_children.at(index); +} + +void DeclarativeWidget::dataClear() +{ + qDeleteAll(m_children); + m_children.clear(); +} + +// DeclarativeLabel +DeclarativeLabel::DeclarativeLabel(QObject *parent) + : DeclarativeWidget(parent) + , m_label(0) +{ +} + +DeclarativeLabel::~DeclarativeLabel() +{ +} + +QObject* DeclarativeLabel::object() +{ + if (!m_label) + m_label = new QLabel("Hello QML Widgets"); + + return m_label; +} + +// DeclarativeTabWidget +DeclarativeTabWidget::DeclarativeTabWidget(QObject *parent) + : DeclarativeWidget(parent) + , m_tabWidget(0) +{ +} + +QObject* DeclarativeTabWidget::object() +{ + if (!m_tabWidget) + m_tabWidget = new QTabWidget(); + + return m_tabWidget; +} + +void DeclarativeTabWidget::dataAppend(QObject *object) +{ + DeclarativeWidget *widget = qobject_cast(object); + + if (widget) { + // TODO: error when layout is set + m_children.append(object); + qobject_cast(this->object())->addTab(qobject_cast(widget->object()), "MyTab"); + } else { + // TODO: error unknown type + } +} + +int DeclarativeTabWidget::dataCount() +{ + return m_children.count(); +} + +QObject *DeclarativeTabWidget::dataAt(int index) +{ + return m_children.at(index); +} + +void DeclarativeTabWidget::dataClear() +{ + qDeleteAll(m_children); + m_children.clear(); +} diff --git a/declarativeobjects_p.h b/declarativeobjects_p.h new file mode 100644 index 0000000..b981ccd --- /dev/null +++ b/declarativeobjects_p.h @@ -0,0 +1,112 @@ +#ifndef DECLARATIVEOBJECTS_H +#define DECLARATIVEOBJECTS_H + +#include +#include +#include +#include +#include + +class DeclarativeObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QDeclarativeListProperty data READ data DESIGNABLE false) + + Q_CLASSINFO("DefaultProperty", "data") + + public: + DeclarativeObject(QObject *parent = 0); + virtual ~DeclarativeObject(); + + virtual QObject* object() = 0; + + protected: + virtual void dataAppend(QObject *); + virtual int dataCount(); + virtual QObject *dataAt(int); + virtual void dataClear(); + + private: + QDeclarativeListProperty data(); + + static void data_append(QDeclarativeListProperty *, QObject *); + static int data_count(QDeclarativeListProperty *); + static QObject *data_at(QDeclarativeListProperty *, int); + static void data_clear(QDeclarativeListProperty *); +}; + +class DeclarativeVBoxLayout : public DeclarativeObject +{ + Q_OBJECT + + public: + DeclarativeVBoxLayout(QObject *parent = 0); + ~DeclarativeVBoxLayout(); + + virtual QObject* object(); + + virtual void dataAppend(QObject *); + virtual int dataCount(); + virtual QObject *dataAt(int); + virtual void dataClear(); + + private: + QVBoxLayout* m_layout; + QVector m_children; +}; + +class DeclarativeWidget : public DeclarativeObject +{ + Q_OBJECT + + public: + DeclarativeWidget(QObject *parent = 0); + ~DeclarativeWidget(); + + virtual QObject* object(); + + private: + virtual void dataAppend(QObject *); + virtual int dataCount(); + virtual QObject *dataAt(int); + virtual void dataClear(); + + QWidget* m_widget; + QVector m_children; +}; + +class DeclarativeLabel : public DeclarativeWidget +{ + Q_OBJECT + + public: + DeclarativeLabel(QObject *parent = 0); + ~DeclarativeLabel(); + + virtual QObject* object(); + + private: + QLabel* m_label; +}; + +class DeclarativeTabWidget : public DeclarativeWidget +{ + Q_OBJECT + + public: + DeclarativeTabWidget(QObject *parent = 0); + + virtual QObject* object(); + + private: + virtual void dataAppend(QObject *); + virtual int dataCount(); + virtual QObject *dataAt(int); + virtual void dataClear(); + + QVector m_children; + QTabWidget* m_tabWidget; +}; + +#endif diff --git a/declarativewidgetdocument.cpp b/declarativewidgetdocument.cpp new file mode 100644 index 0000000..f2840f9 --- /dev/null +++ b/declarativewidgetdocument.cpp @@ -0,0 +1,64 @@ +#include "declarativewidgetdocument.h" + +#include "declarativeobjects_p.h" + +#include +#include +#include +#include + +class DeclarativeWidgetDocument::Private +{ + public: + Private(DeclarativeWidgetDocument *qq, const QUrl &url) + : q(qq) + , m_url(url) + , m_engine(new QDeclarativeEngine(q)) + , m_component(new QDeclarativeComponent(m_engine, q)) + { + } + + DeclarativeWidgetDocument* q; + QUrl m_url; + QDeclarativeEngine* m_engine; + QDeclarativeComponent* m_component; +}; + +DeclarativeWidgetDocument::DeclarativeWidgetDocument(const QUrl &url, QObject *parent) + : QObject(parent) + , d(new Private(this, url)) +{ + qmlRegisterType("qtgui.widgets", 1, 0, "Widget"); + qmlRegisterType("qtgui.widgets", 1, 0, "Label"); + qmlRegisterType("qtgui.widgets", 1, 0, "VBoxLayout"); + qmlRegisterType("qtgui.widgets", 1, 0, "TabWidget"); + d->m_component->loadUrl(d->m_url); + if (d->m_component->isError()) { + foreach (const QDeclarativeError &error, d->m_component->errors()) + qDebug() << error.toString(); + } +} + +DeclarativeWidgetDocument::~DeclarativeWidgetDocument() +{ + delete d; +} + +QWidget* DeclarativeWidgetDocument::createWidget() +{ + QObject *object = d->m_component->create(); + if (!object) { + qWarning("Unable to create component"); + return 0; + } + + DeclarativeObject *declarativeObject = qobject_cast(object); + if (!declarativeObject) { + qWarning("Root element is no DeclarativeObject subclass"); + return 0; + } + + declarativeObject->setParent(this); + + return qobject_cast(declarativeObject->object()); +} diff --git a/declarativewidgetdocument.h b/declarativewidgetdocument.h new file mode 100644 index 0000000..bd38392 --- /dev/null +++ b/declarativewidgetdocument.h @@ -0,0 +1,32 @@ +#ifndef DECLARATIVEWIDGETDOCUMENT_H +#define DECLARATIVEWIDGETDOCUMENT_H + +#include +#include + +class DeclarativeWidgetDocument : public QObject +{ + Q_OBJECT + + public: + DeclarativeWidgetDocument(const QUrl &url, QObject *parent = 0); + ~DeclarativeWidgetDocument(); + + template + T* create() + { + QWidget *widget = createWidget(); + if (!widget) + return 0; + + return qobject_cast(widget); + } + + private: + QWidget* createWidget(); + + class Private; + Private* const d; +}; + +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..3c5ea1a --- /dev/null +++ b/main.cpp @@ -0,0 +1,17 @@ +#include "declarativewidgetdocument.h" + +#include +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + DeclarativeWidgetDocument document(QUrl("test.qml")); + + QWidget *widget = document.create(); + if (widget) + widget->show(); + + return app.exec(); +} diff --git a/qmlwidgets.pro b/qmlwidgets.pro new file mode 100644 index 0000000..55fc81d --- /dev/null +++ b/qmlwidgets.pro @@ -0,0 +1,14 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Sat Oct 13 15:43:11 2012 +###################################################################### + +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +HEADERS += declarativeobjects_p.h declarativewidgetdocument.h +SOURCES += declarativeobjects.cpp declarativewidgetdocument.cpp main.cpp + +QT += declarative diff --git a/test.qml b/test.qml new file mode 100644 index 0000000..b851bd0 --- /dev/null +++ b/test.qml @@ -0,0 +1,27 @@ +import qtgui.widgets 1.0 + +Widget { + VBoxLayout { + Label { + } + Label { + } + Label { + } + + TabWidget { + Widget { + VBoxLayout { + Label { + } + Label { + } + } + } + Label { + } + Label { + } + } + } +} -- 1.7.2.5