Initial commit
authorTobias Koenig <tobias.koenig@kdab.com>
Sat, 13 Oct 2012 17:41:11 +0000 (19:41 +0200)
committerTobias Koenig <tobias.koenig@kdab.com>
Sat, 13 Oct 2012 17:41:11 +0000 (19:41 +0200)
.gitignore [new file with mode: 0644]
declarativeobjects.cpp [new file with mode: 0644]
declarativeobjects_p.h [new file with mode: 0644]
declarativewidgetdocument.cpp [new file with mode: 0644]
declarativewidgetdocument.h [new file with mode: 0644]
main.cpp [new file with mode: 0644]
qmlwidgets.pro [new file with mode: 0644]
test.qml [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..9adc96a
--- /dev/null
@@ -0,0 +1,4 @@
+qmlwidgets
+Makefile
+moc_*
+*.o
diff --git a/declarativeobjects.cpp b/declarativeobjects.cpp
new file mode 100644 (file)
index 0000000..272e7a5
--- /dev/null
@@ -0,0 +1,232 @@
+#include "declarativeobjects_p.h"
+
+// DeclarativeObject
+DeclarativeObject::DeclarativeObject(QObject *parent)
+  : QObject(parent)
+{
+}
+
+DeclarativeObject::~DeclarativeObject()
+{
+}
+
+QDeclarativeListProperty<QObject> DeclarativeObject::data()
+{
+  return QDeclarativeListProperty<QObject>(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<QObject> *property, QObject *object)
+{
+  if (!object)
+    return;
+
+  DeclarativeObject *that = qobject_cast<DeclarativeObject*>(property->object);
+  that->dataAppend(object);
+}
+
+int DeclarativeObject::data_count(QDeclarativeListProperty<QObject> *property)
+{
+  DeclarativeObject *that = qobject_cast<DeclarativeObject*>(property->object);
+  return that->dataCount();
+}
+
+QObject* DeclarativeObject::data_at(QDeclarativeListProperty<QObject> *property, int index)
+{
+  DeclarativeObject *that = qobject_cast<DeclarativeObject*>(property->object);
+  return that->dataAt(index);
+}
+
+void DeclarativeObject::data_clear(QDeclarativeListProperty<QObject> *property)
+{
+  DeclarativeObject *that = qobject_cast<DeclarativeObject*>(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<DeclarativeWidget*>(object);
+  DeclarativeVBoxLayout *layout = qobject_cast<DeclarativeVBoxLayout*>(object);
+
+  if (widget) {
+    m_children.append(object);
+    qobject_cast<QVBoxLayout*>(this->object())->addWidget(qobject_cast<QWidget*>(widget->object()));
+  } else if (layout) {
+    m_children.append(object);
+    qobject_cast<QVBoxLayout*>(this->object())->addLayout(qobject_cast<QVBoxLayout*>(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<DeclarativeWidget*>(object);
+  DeclarativeVBoxLayout *layout = qobject_cast<DeclarativeVBoxLayout*>(object);
+
+  if (widget) {
+    // TODO: error when layout is set
+    m_children.append(object);
+    qobject_cast<QWidget*>(widget->object())->setParent(qobject_cast<QWidget*>(this->object()));
+  } else if (layout) {
+    // TODO: error when widget is set
+
+    m_children.append(layout);
+    qobject_cast<QWidget*>(this->object())->setLayout(qobject_cast<QVBoxLayout*>(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<DeclarativeWidget*>(object);
+
+  if (widget) {
+    // TODO: error when layout is set
+    m_children.append(object);
+    qobject_cast<QTabWidget*>(this->object())->addTab(qobject_cast<QWidget*>(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 (file)
index 0000000..b981ccd
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef DECLARATIVEOBJECTS_H
+#define DECLARATIVEOBJECTS_H
+
+#include <QtCore/QObject>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QTabWidget>
+#include <QtDeclarative/QDeclarativeListProperty>
+
+class DeclarativeObject : public QObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QDeclarativeListProperty<QObject> 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<QObject> data();
+
+    static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
+    static int data_count(QDeclarativeListProperty<QObject> *);
+    static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
+    static void data_clear(QDeclarativeListProperty<QObject> *);
+};
+
+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<QObject*> 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<QObject*> 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<QObject*> m_children;
+    QTabWidget* m_tabWidget;
+};
+
+#endif
diff --git a/declarativewidgetdocument.cpp b/declarativewidgetdocument.cpp
new file mode 100644 (file)
index 0000000..f2840f9
--- /dev/null
@@ -0,0 +1,64 @@
+#include "declarativewidgetdocument.h"
+
+#include "declarativeobjects_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtDeclarative/QDeclarativeComponent>
+#include <QtDeclarative/QDeclarativeEngine>
+
+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<DeclarativeWidget>("qtgui.widgets", 1, 0, "Widget");
+  qmlRegisterType<DeclarativeLabel>("qtgui.widgets", 1, 0, "Label");
+  qmlRegisterType<DeclarativeVBoxLayout>("qtgui.widgets", 1, 0, "VBoxLayout");
+  qmlRegisterType<DeclarativeTabWidget>("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<DeclarativeObject*>(object);
+  if (!declarativeObject) {
+    qWarning("Root element is no DeclarativeObject subclass");
+    return 0;
+  }
+
+  declarativeObject->setParent(this);
+
+  return qobject_cast<QWidget*>(declarativeObject->object());
+}
diff --git a/declarativewidgetdocument.h b/declarativewidgetdocument.h
new file mode 100644 (file)
index 0000000..bd38392
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef DECLARATIVEWIDGETDOCUMENT_H
+#define DECLARATIVEWIDGETDOCUMENT_H
+
+#include <QtCore/QObject>
+#include <QtCore/QUrl>
+
+class DeclarativeWidgetDocument : public QObject
+{
+  Q_OBJECT
+
+  public:
+    DeclarativeWidgetDocument(const QUrl &url, QObject *parent = 0);
+    ~DeclarativeWidgetDocument();
+
+    template <typename T>
+    T* create()
+    {
+      QWidget *widget = createWidget();
+      if (!widget)
+        return 0;
+
+      return qobject_cast<T*>(widget);
+    }
+
+  private:
+    QWidget* createWidget();
+
+    class Private;
+    Private* const d;
+};
+
+#endif
diff --git a/main.cpp b/main.cpp
new file mode 100644 (file)
index 0000000..3c5ea1a
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,17 @@
+#include "declarativewidgetdocument.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QLabel>
+
+int main(int argc, char **argv)
+{
+  QApplication app(argc, argv);
+
+  DeclarativeWidgetDocument document(QUrl("test.qml"));
+
+  QWidget *widget = document.create<QWidget>();
+  if (widget)
+    widget->show();
+
+  return app.exec();
+}
diff --git a/qmlwidgets.pro b/qmlwidgets.pro
new file mode 100644 (file)
index 0000000..55fc81d
--- /dev/null
@@ -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 (file)
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 {
+      }
+    }
+  }
+}