[gegl-qt] Examples: Add example listing operations and their properties



commit 03a73d88a990c7986b7363cf8eeeda82dcd9722b
Author: Jon Nordby <jononor gmail com>
Date:   Wed Aug 3 00:23:02 2011 +0200

    Examples: Add example listing operations and their properties
    
    Not very good.
    - The operation list should allow one to select different operations interactively
    - There should be headers

 examples/examples.pro                      |    2 +-
 examples/python-random.py                  |    1 +
 examples/qml-operations/.gitignore         |    1 +
 examples/qml-operations/operation.cpp      |  210 ++++++++++++++++++++++++++++
 examples/qml-operations/operation.h        |   68 +++++++++
 examples/qml-operations/qml-operations.cpp |   56 ++++++++
 examples/qml-operations/qml-operations.pro |   11 ++
 examples/qml-operations/qml-operations.qml |   81 +++++++++++
 examples/qml-operations/qmloperations.qrc  |    5 +
 9 files changed, 434 insertions(+), 1 deletions(-)
---
diff --git a/examples/examples.pro b/examples/examples.pro
index 8900f84..3f8e47a 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -22,7 +22,7 @@ contains(HAVE_QT_QUICK1, yes) {
     SUBDIRS += \
         qml-basic \
         qml-paint \
-
+        qml-operations \
 }
 
 OTHER_FILES += \
diff --git a/examples/python-random.py b/examples/python-random.py
new file mode 100644
index 0000000..18ff536
--- /dev/null
+++ b/examples/python-random.py
@@ -0,0 +1 @@
+#!/usr/bin/env python2
diff --git a/examples/qml-operations/.gitignore b/examples/qml-operations/.gitignore
new file mode 100644
index 0000000..7e5b0d0
--- /dev/null
+++ b/examples/qml-operations/.gitignore
@@ -0,0 +1 @@
+qml-operations
diff --git a/examples/qml-operations/operation.cpp b/examples/qml-operations/operation.cpp
new file mode 100644
index 0000000..7c67725
--- /dev/null
+++ b/examples/qml-operations/operation.cpp
@@ -0,0 +1,210 @@
+#include "operation.h"
+
+#include <gegl-qt.h>
+#include <gegl-0.1/gegl-plugin.h> // For GeglOperationClass
+
+enum ValueAttribute {
+    ValueMax,
+    ValueDefault,
+    ValueMin
+};
+
+QVariant
+getValueAttribute(ValueAttribute valueAttribute, GType valueType, GParamSpec *param_spec)
+{
+    QVariant minValue;
+    QVariant maxValue;
+    QVariant defaultValue;
+
+    if (g_type_is_a (valueType, G_TYPE_DOUBLE)) {
+        const gdouble def = G_PARAM_SPEC_DOUBLE (param_spec)->default_value;
+        const gdouble min = G_PARAM_SPEC_DOUBLE (param_spec)->minimum;
+        const gdouble max = G_PARAM_SPEC_DOUBLE (param_spec)->maximum;
+
+        defaultValue = QVariant::fromValue(def);
+        minValue = QVariant::fromValue(min);
+        maxValue = QVariant::fromValue(max);
+
+    } else if (g_type_is_a (valueType, G_TYPE_INT)) {
+        const gint def = G_PARAM_SPEC_INT (param_spec)->default_value;
+        const gint min = G_PARAM_SPEC_INT (param_spec)->minimum;
+        const gint max = G_PARAM_SPEC_INT (param_spec)->maximum;
+
+        defaultValue = QVariant::fromValue(def);
+        minValue = QVariant::fromValue(min);
+        maxValue = QVariant::fromValue(max);
+
+    } else if (g_type_is_a (valueType, G_TYPE_FLOAT)) {
+          const gfloat def = G_PARAM_SPEC_FLOAT (param_spec)->default_value;
+          const gfloat min = G_PARAM_SPEC_FLOAT (param_spec)->minimum;
+          const gfloat max = G_PARAM_SPEC_FLOAT (param_spec)->maximum;
+
+          defaultValue = QVariant::fromValue(def);
+          minValue = QVariant::fromValue(min);
+          maxValue = QVariant::fromValue(max);
+
+    } else if (g_type_is_a (valueType, G_TYPE_BOOLEAN)) {
+        const gboolean def = G_PARAM_SPEC_BOOLEAN (param_spec)->default_value;
+        defaultValue = QVariant::fromValue(def);
+
+    } else if (g_type_is_a (valueType, G_TYPE_STRING)) {
+        const gchar *string = G_PARAM_SPEC_STRING (param_spec)->default_value;
+        defaultValue = QVariant::fromValue(QString::fromUtf8(string));
+
+    } else {
+        // Unknown type
+    }
+
+    switch (valueAttribute) {
+    case ValueMax:
+        return maxValue;
+    case ValueMin:
+        return minValue;
+    case ValueDefault:
+    default:
+        return defaultValue;
+
+    }
+}
+
+QMap<QString,OperationProperty *>
+getPropertyMap(const QString &operationName)
+{
+    QMap<QString,OperationProperty *> propertyMap;
+
+    GParamSpec **properties;
+    guint prop_no;
+    guint n_properties;
+
+    properties = gegl_list_properties(operationName.toUtf8(), &n_properties);
+
+    for (prop_no = 0; prop_no < n_properties; prop_no++)
+    {
+        GParamSpec *param_spec = properties[prop_no];
+
+        QString name = QString::fromUtf8(g_param_spec_get_name(param_spec));
+        QString shortDescription = QString::fromUtf8(g_param_spec_get_blurb(param_spec));
+        GType valueType = G_PARAM_SPEC_VALUE_TYPE(param_spec);
+        QVariant minValue = getValueAttribute(ValueMin, valueType, param_spec);
+        QVariant maxValue = getValueAttribute(ValueMax, valueType, param_spec);
+        QVariant defaultValue = getValueAttribute(ValueDefault, valueType, param_spec);
+
+        OperationProperty *prop = new OperationProperty(name, shortDescription,
+                                                        defaultValue, minValue, maxValue);
+        propertyMap.insert(name, prop);
+    }
+    return propertyMap;
+}
+
+/* */
+QList<GeglOperationClass *> *
+getOperationsClasses(QList<GeglOperationClass *> *list, GType type)
+{
+    GeglOperationClass *klass;
+    GType *classes;
+    guint  no_children;
+    gint   no;
+
+    if (!type)
+      return list;
+
+    klass = GEGL_OPERATION_CLASS(g_type_class_ref(type));
+    if (klass->name != NULL)
+      list->append(klass);
+
+    classes = g_type_children(type, &no_children);
+
+    for (no=0; no < no_children; no++) {
+        list = getOperationsClasses(list, classes[no]);
+    }
+    if (classes) {
+        g_free(classes);
+    }
+    return list;
+}
+
+
+QMap<QString, Operation*> *
+getOperationMap() {
+    QMap<QString, Operation*> *operationMap = new QMap<QString, Operation*>();
+
+    QList<GeglOperationClass *> *operations = new QList<GeglOperationClass *>;
+    operations = getOperationsClasses(operations, GEGL_TYPE_OPERATION);
+
+    foreach (GeglOperationClass *op_class, *operations) {
+        QString name = QString::fromUtf8(op_class->name);
+        QStringList categories = QString::fromUtf8(op_class->categories).split(":");
+        QString description = QString::fromUtf8(op_class->description);
+
+        Operation *operation = new Operation(name, getPropertyMap(name));
+        operationMap->insert(name, operation);
+    }
+
+    return operationMap;
+}
+
+
+/* OperationProperty */
+OperationProperty::OperationProperty(QString name, QString description, QVariant defaultValue,
+                                     QVariant minValue, QVariant maxValue)
+    : QObject()
+    , mName(name)
+    , mShortDescription(description)
+    , mDefaultValue(defaultValue)
+    , mMinValue(minValue)
+    , mMaxValue(maxValue)
+{
+}
+
+QString OperationProperty::name()
+{
+    return mName;
+}
+
+QString OperationProperty::shortDescription()
+{
+    return mShortDescription;
+}
+
+QVariant OperationProperty::minValue()
+{
+    return mMinValue;
+}
+
+QVariant OperationProperty::maxValue()
+{
+    return mMaxValue;
+}
+
+QVariant OperationProperty::defaultValue()
+{
+    return mDefaultValue;
+}
+
+
+/* Operation */
+Operation::Operation(QString name, QMap<QString, OperationProperty *> properties)
+    : QObject()
+    , mName(name)
+    , mProperties(properties)
+{
+}
+
+QString Operation::name()
+{
+    return mName;
+}
+
+QObjectList Operation::properties()
+{
+    QObjectList list;
+
+    QStringList propertyNames = mProperties.keys();
+    qSort(propertyNames);
+
+    Q_FOREACH(const QString &propertyName, propertyNames) {
+        list.append(mProperties.value(propertyName));
+    }
+
+    return list;
+}
diff --git a/examples/qml-operations/operation.h b/examples/qml-operations/operation.h
new file mode 100644
index 0000000..77a8dce
--- /dev/null
+++ b/examples/qml-operations/operation.h
@@ -0,0 +1,68 @@
+#ifndef OPERATION_H
+#define OPERATION_H
+
+#include <QObject>
+
+#include <gegl-qt.h>
+
+/* OperationProperty:
+ *
+ * Essentially a value-type. Only a QObject in order to use properties,
+ * to be able to expose such objects to QML. */
+class OperationProperty : public QObject
+{
+    Q_OBJECT
+public:
+    explicit OperationProperty(QString name, QString description, QVariant defaultValue,
+                               QVariant minValue, QVariant maxValue);
+
+    QString name();
+    QString shortDescription();
+
+    QVariant minValue();
+    QVariant maxValue();
+    QVariant defaultValue();
+
+    Q_PROPERTY (QString name READ name CONSTANT)
+    Q_PROPERTY (QString shortDescription READ shortDescription CONSTANT)
+    Q_PROPERTY (QVariant defaultValue READ defaultValue CONSTANT)
+    Q_PROPERTY (QVariant minValue READ minValue CONSTANT)
+    Q_PROPERTY (QVariant maxValue READ minValue CONSTANT)
+
+private:
+    QString mName;
+    QString mShortDescription;
+    GType mValueType;
+    QVariant mDefaultValue;
+    QVariant mMinValue;
+    QVariant mMaxValue;
+};
+
+
+/* Operation:
+ *
+ * Essentially a value-type. Only a QObject in order to use properties,
+ * to be able to expose such objects to QML. */
+class Operation : public QObject
+{
+    Q_OBJECT
+public:
+    explicit Operation(QString name, QMap<QString, OperationProperty *> properties);
+
+    QString name();
+    QObjectList properties();
+
+    Q_PROPERTY (QString name READ name CONSTANT)
+    Q_PROPERTY (QObjectList properties READ properties CONSTANT)
+
+private:
+    QString mName;
+    GType mType;
+    QStringList mCategories;
+    QString mDescription;
+    QMap<QString, OperationProperty *> mProperties;
+};
+
+QMap<QString, Operation*> *getOperationMap();
+
+#endif // OPERATION_H
diff --git a/examples/qml-operations/qml-operations.cpp b/examples/qml-operations/qml-operations.cpp
new file mode 100644
index 0000000..d3c565e
--- /dev/null
+++ b/examples/qml-operations/qml-operations.cpp
@@ -0,0 +1,56 @@
+/* This file is part of GEGL-QT
+ *
+ * GEGL-QT is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL-QT is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL-QT; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2011 <jononor gmail com>
+ */
+
+#include <gegl-qt.h>
+
+#include <QtGui>
+#include <QtCore>
+#include <QtDeclarative>
+
+#include "operation.h"
+
+int main(int argc, char *argv[])
+{ 
+    QApplication a(argc, argv);
+    gegl_init(&argc, &argv);
+    Q_INIT_RESOURCE(qmloperations);
+
+    QMap<QString, Operation *> *operationMap = getOperationMap();
+    QStringList operations = operationMap->keys();
+    Operation *selectedOperation = operationMap->value("gegl:dropshadow");
+
+
+    QDeclarativeView view;
+
+    view.rootContext()->setContextProperty("availableOperations", QVariant::fromValue(operations));
+    view.rootContext()->setContextProperty("selectedOperation", selectedOperation);
+
+    view.setSource(QUrl("qrc:/qml-operations.qml"));
+    view.show();
+
+    int retCode = a.exec();
+
+    // FIXME: free props
+    gegl_exit();
+    return retCode;
+}
+
+
+
+
+
diff --git a/examples/qml-operations/qml-operations.pro b/examples/qml-operations/qml-operations.pro
new file mode 100644
index 0000000..a3f8cae
--- /dev/null
+++ b/examples/qml-operations/qml-operations.pro
@@ -0,0 +1,11 @@
+include(../../config.pri)
+include(../examples-common.pri)
+
+
+SOURCES += qml-operations.cpp \
+    operation.cpp
+RESOURCES += qmloperations.qrc
+OTHER_FILES += qml-operations.qml
+
+HEADERS += \
+    operation.h
diff --git a/examples/qml-operations/qml-operations.qml b/examples/qml-operations/qml-operations.qml
new file mode 100644
index 0000000..ba155a5
--- /dev/null
+++ b/examples/qml-operations/qml-operations.qml
@@ -0,0 +1,81 @@
+import QtQuick 1.0
+// import GeglQt 0.1
+
+Rectangle {
+    width: 500
+    height: 500
+    x: 0
+    y: 0
+
+
+    ListView {
+        anchors.left: parent.left
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+        width: parent.width/2
+
+        Component {
+            id: operationListDelegate
+
+            Rectangle {
+                height: 15
+
+                color: "black"
+
+                Text {
+                    text: modelData
+                }
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: {
+                            ListView.currentIndex = index
+                    }
+                }
+            }
+        }
+
+        id: operationsView
+        model: availableOperations
+        delegate: operationListDelegate
+
+        focus: true
+    }
+
+    Component {
+        id: propertyDelegate
+
+        Item {
+            height: 80
+
+            Column {
+                Text { text: modelData.name }
+                Text { text: modelData.shortDescription }
+                Text { text: modelData.defaultValue }
+                Text { text: modelData.minValue }
+                Text { text: modelData.maxValue }
+            }
+
+        }
+
+
+
+    }
+
+
+    ListView {
+        anchors.left: operationsView.right
+        anchors.right: parent.right
+        anchors.top: parent.top
+        anchors.bottom: parent.bottom
+
+        id: singleOperationView
+        model: selectedOperation.properties
+        delegate: propertyDelegate
+
+    }
+}
+
+
+
+
+
diff --git a/examples/qml-operations/qmloperations.qrc b/examples/qml-operations/qmloperations.qrc
new file mode 100644
index 0000000..bf31d20
--- /dev/null
+++ b/examples/qml-operations/qmloperations.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>qml-operations.qml</file>
+    </qresource>
+</RCC>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]