Add attached properties to box layouts
authorKevin Krammer <kevin.krammer@kdab.com>
Wed, 17 Oct 2012 17:26:03 +0000 (19:26 +0200)
committerKevin Krammer <kevin.krammer@kdab.com>
Wed, 17 Oct 2012 17:26:33 +0000 (19:26 +0200)
declarativeobjects.cpp
declarativeobjects_p.h
declarativewidgetdocument.cpp
declarativewidgets.pro
layouts.qml [new file with mode: 0644]

index e25b3da..a25513d 100644 (file)
@@ -160,6 +160,52 @@ DeclarativeSeparator::DeclarativeSeparator(QObject *parent) : DeclarativeObjectP
 CUSTOM_METAOBJECT(DeclarativeSeparator, QAction)
 
 //// Layouts ////
+class DeclarativeBoxLayoutAttached::Private
+{
+  public:
+    Private() : stretch(0), alignment(0) {}
+
+    int stretch;
+    Qt::Alignment alignment;
+};
+
+DeclarativeBoxLayoutAttached::DeclarativeBoxLayoutAttached(QObject *parent)
+  : QObject(parent), d(new Private)
+{
+}
+
+DeclarativeBoxLayoutAttached::~DeclarativeBoxLayoutAttached()
+{
+  delete d;
+}
+
+void DeclarativeBoxLayoutAttached::setStretch(int stretch)
+{
+  if (stretch == d->stretch)
+    return;
+
+  d->stretch = stretch;
+  emit stretchChanged(stretch);
+}
+
+int DeclarativeBoxLayoutAttached::stretch() const
+{
+  return d->stretch;
+}
+
+void DeclarativeBoxLayoutAttached::setAlignment(Qt::Alignment alignment)
+{
+  if (alignment == d->alignment)
+    return;
+
+  d->alignment = alignment;
+  emit alignmentChanged(alignment);
+}
+
+Qt::Alignment DeclarativeBoxLayoutAttached::alignment() const
+{
+  return d->alignment;
+}
 
 // DeclarativeHBoxLayout
 DeclarativeHBoxLayout::DeclarativeHBoxLayout(QObject *parent) : DeclarativeBoxLayout<QHBoxLayout>(parent)
@@ -167,6 +213,27 @@ DeclarativeHBoxLayout::DeclarativeHBoxLayout(QObject *parent) : DeclarativeBoxLa
   connectAllSignals(m_proxiedObject, this);
 }
 
+DeclarativeBoxLayoutAttached *DeclarativeHBoxLayout::qmlAttachedProperties(QObject *parent)
+{
+  return new DeclarativeBoxLayoutAttached(parent);
+}
+
+void DeclarativeHBoxLayout::addWidget(QWidget *widget, AbstractDeclarativeObject *declarativeObject)
+{
+  int stretch = 0;
+  Qt::Alignment alignment = 0;
+
+  QObject *attachedProperties = qmlAttachedPropertiesObject<DeclarativeHBoxLayout>(declarativeObject, false);
+  DeclarativeBoxLayoutAttached *properties = qobject_cast<DeclarativeBoxLayoutAttached*>(attachedProperties);
+  if (properties) {
+    stretch = properties->stretch();
+    alignment = properties->alignment();
+  }
+
+  m_proxiedObject->addWidget(widget, stretch, alignment);
+  m_children.append(declarativeObject);
+}
+
 CUSTOM_METAOBJECT(DeclarativeHBoxLayout, QHBoxLayout)
 
 // DeclarativeVBoxLayout
@@ -175,6 +242,27 @@ DeclarativeVBoxLayout::DeclarativeVBoxLayout(QObject *parent) : DeclarativeBoxLa
   connectAllSignals(m_proxiedObject, this);
 }
 
+DeclarativeBoxLayoutAttached *DeclarativeVBoxLayout::qmlAttachedProperties(QObject *parent)
+{
+  return new DeclarativeBoxLayoutAttached(parent);
+}
+
+void DeclarativeVBoxLayout::addWidget(QWidget *widget, AbstractDeclarativeObject *declarativeObject)
+{
+  int stretch = 0;
+  Qt::Alignment alignment = 0;
+
+  QObject *attachedProperties = qmlAttachedPropertiesObject<DeclarativeVBoxLayout>(declarativeObject, false);
+  DeclarativeBoxLayoutAttached *properties = qobject_cast<DeclarativeBoxLayoutAttached*>(attachedProperties);
+  if (properties) {
+    stretch = properties->stretch();
+    alignment = properties->alignment();
+  }
+
+  m_proxiedObject->addWidget(widget, stretch, alignment);
+  m_children.append(declarativeObject);
+}
+
 CUSTOM_METAOBJECT(DeclarativeVBoxLayout, QVBoxLayout)
 
 //// Widgets ////
index 183536a..596ad0d 100644 (file)
@@ -179,6 +179,32 @@ class DeclarativeSeparator : public DeclarativeObjectProxy<QAction>
 };
 
 //// Layouts ////
+class DeclarativeBoxLayoutAttached : public QObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(int stretch READ stretch WRITE setStretch NOTIFY stretchChanged)
+  Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
+
+  public:
+    DeclarativeBoxLayoutAttached(QObject *parent);
+    ~DeclarativeBoxLayoutAttached();
+
+    void setStretch(int stretch);
+    int stretch() const;
+
+    void setAlignment(Qt::Alignment alignment);
+    Qt::Alignment alignment() const;
+
+  Q_SIGNALS:
+    void stretchChanged(int stretch);
+    void alignmentChanged(Qt::Alignment alignment);
+
+  private:
+    class Private;
+    Private *const d;
+};
+
 template <class T>
 class DeclarativeBoxLayout : public DeclarativeObjectProxy<T>
 {
@@ -192,8 +218,7 @@ class DeclarativeBoxLayout : public DeclarativeObjectProxy<T>
       if (declarativeObject) {
         QWidget *widget = qobject_cast<QWidget*>(declarativeObject->object());
         if (widget) {
-          DeclarativeObjectProxy<T>::m_children.append(object);
-          DeclarativeObjectProxy<T>::m_proxiedObject->addWidget(widget);
+          addWidget(widget, declarativeObject);
           return;
         }
 
@@ -207,6 +232,8 @@ class DeclarativeBoxLayout : public DeclarativeObjectProxy<T>
 
       DeclarativeObjectProxy<T>::dataAppend(object);
     }
+
+    virtual void addWidget(QWidget *widget, AbstractDeclarativeObject *declarativeObject) = 0;
 };
 
 class DeclarativeHBoxLayout : public DeclarativeBoxLayout<QHBoxLayout>
@@ -215,16 +242,31 @@ class DeclarativeHBoxLayout : public DeclarativeBoxLayout<QHBoxLayout>
 
   public:
     DeclarativeHBoxLayout(QObject *parent = 0);
+
+    static DeclarativeBoxLayoutAttached *qmlAttachedProperties(QObject *parent);
+
+  protected:
+    void addWidget(QWidget *widget, AbstractDeclarativeObject *declarativeObject);
 };
 
+
+QML_DECLARE_TYPEINFO(DeclarativeHBoxLayout, QML_HAS_ATTACHED_PROPERTIES)
+
 class DeclarativeVBoxLayout : public DeclarativeBoxLayout<QVBoxLayout>
 {
   DECLARATIVE_OBJECT
 
   public:
     DeclarativeVBoxLayout(QObject *parent = 0);
+
+    static DeclarativeBoxLayoutAttached *qmlAttachedProperties(QObject *parent);
+
+  protected:
+    void addWidget(QWidget *widget, AbstractDeclarativeObject *declarativeObject);
 };
 
+QML_DECLARE_TYPEINFO(DeclarativeVBoxLayout, QML_HAS_ATTACHED_PROPERTIES)
+
 //// Widgets ////
 class DeclarativeCalendarWidget : public DeclarativeWidgetProxy<QCalendarWidget>
 {
index 28f5432..a1d7777 100644 (file)
@@ -35,6 +35,7 @@ DeclarativeWidgetDocument::DeclarativeWidgetDocument(const QUrl &url, QObject *p
   qmlRegisterType<DeclarativeSeparator>("QtGui", 1, 0, "Separator");
 
   // layouts
+  qmlRegisterType<DeclarativeBoxLayoutAttached>();
   qmlRegisterType<DeclarativeHBoxLayout>("QtGui", 1, 0, "HBoxLayout");
   qmlRegisterType<DeclarativeVBoxLayout>("QtGui", 1, 0, "VBoxLayout");
 
index 8851bb9..ecb92d3 100644 (file)
@@ -12,3 +12,6 @@ HEADERS += declarativeobjects_p.h declarativewidgetdocument.h qmetaobjectbuilder
 SOURCES += declarativeobjects.cpp declarativewidgetdocument.cpp main.cpp qmetaobjectbuilder.cpp
 
 QT += declarative
+
+OTHER_FILES += \
+    layouts.qml
diff --git a/layouts.qml b/layouts.qml
new file mode 100644 (file)
index 0000000..6fce9c9
--- /dev/null
@@ -0,0 +1,63 @@
+import QtGui 1.0
+
+Widget {
+  VBoxLayout {
+    Widget {
+      HBoxLayout {
+        PushButton {
+          HBoxLayout.stretch: 1
+          text: "1"
+        }
+        PushButton {
+          HBoxLayout.stretch: 1
+          text: "1"
+        }
+        PushButton {
+          HBoxLayout.stretch: 2
+          text: "2"
+        }
+      }
+    }
+    Widget {
+      HBoxLayout {
+        Label {
+          HBoxLayout.alignment: Qt.AlignRight
+          text: "Top"
+        }
+        Label {
+          HBoxLayout.alignment: Qt.AlignVCenter
+          text: "VCenter"
+        }
+        Label {
+          HBoxLayout.alignment: Qt.AlignBottom
+          text: "Bottom"
+        }
+      }
+    }
+
+    HBoxLayout {
+      VBoxLayout {
+        Label {
+          VBoxLayout.alignment: Qt.AlignLeft
+          text: "Left"
+        }
+        Label {
+          VBoxLayout.alignment: Qt.AlignHCenter
+          text: "HCenter"
+        }
+        Label {
+          VBoxLayout.alignment: Qt.AlignRight
+          text: "Right"
+        }
+      }
+      VBoxLayout {
+        TextEdit {
+          VBoxLayout.stretch: 1
+        }
+        TextEdit {
+          VBoxLayout.stretch: 2
+        }
+      }
+    }
+  }
+}