[gegl-qt] Examples: Add QML paint example



commit 0ce933b5d234dc382e3d93bd94535eded6f55a7b
Author: Jon Nordby <jononor gmail com>
Date:   Tue Jul 26 21:02:18 2011 +0200

    Examples: Add QML paint example

 examples/examples.pro                   |    2 +-
 examples/qml-paint/.gitignore           |    1 +
 examples/qml-paint/qml-paint-engine.cpp |   87 +++++++++++++++++++++++++++++++
 examples/qml-paint/qml-paint-engine.h   |   25 +++++++++
 examples/qml-paint/qml-paint.cpp        |   58 ++++++++++++++++++++
 examples/qml-paint/qml-paint.pro        |    6 ++
 examples/qml-paint/qml-paint.qml        |   23 ++++++++
 examples/qml-paint/qmlpaint.qrc         |    5 ++
 8 files changed, 206 insertions(+), 1 deletions(-)
---
diff --git a/examples/examples.pro b/examples/examples.pro
index 6615697..ae0315e 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -2,5 +2,5 @@
 # TODO: install examples
 
 TEMPLATE = subdirs
-SUBDIRS = qwidget-basic qgv-basic qml-basic
+SUBDIRS = qwidget-basic qgv-basic qml-basic qml-paint
 
diff --git a/examples/qml-paint/.gitignore b/examples/qml-paint/.gitignore
new file mode 100644
index 0000000..e0a2bfe
--- /dev/null
+++ b/examples/qml-paint/.gitignore
@@ -0,0 +1 @@
+qml-paint
diff --git a/examples/qml-paint/qml-paint-engine.cpp b/examples/qml-paint/qml-paint-engine.cpp
new file mode 100644
index 0000000..1a8d09c
--- /dev/null
+++ b/examples/qml-paint/qml-paint-engine.cpp
@@ -0,0 +1,87 @@
+#include "qml-paint-engine.h"
+
+#include <gegl.h>
+
+/* Just holds the state used by PaintEngine. */
+struct PaintEnginePrivate
+{
+    GeglNode *graph;
+    GeglNode *outputNode;
+    GeglNode *strokeNode;
+    GeglPath *strokePath;
+    bool inStroke;
+};
+
+namespace {
+    const gchar * const DefaultColor = "black";
+    float DefaultHardness = 0.3;
+    float DefaultLineWidth = 20.0;
+}
+
+/* PaintEngine
+ * Trivial painting engine implemented using Gegl.
+ * Is not tied to QML, could be used in any toolkit. */
+PaintEngine::PaintEngine(QObject *parent)
+    : QObject(parent)
+    , priv(new PaintEnginePrivate())
+{
+    priv->graph = gegl_node_new();
+    priv->outputNode = gegl_node_new_child(priv->graph,
+                                           "operation", "gegl:nop", NULL);
+    priv->inStroke = false;
+
+}
+
+PaintEngine::~PaintEngine()
+{
+    g_object_unref(priv->strokePath);
+    g_object_unref(priv->graph);
+    // Nodes are owned by the graph
+    delete priv;
+}
+
+QVariant
+PaintEngine::outputNode()
+{
+    return qVariantFromValue(static_cast<void*>(priv->outputNode));
+}
+
+void
+PaintEngine::positionChanged(double x, double y, bool buttonPressed)
+{
+    if (buttonPressed && !priv->inStroke) {
+        // Start new stroke
+        GeglNode *oldStrokeNode = priv->strokeNode;
+        priv->inStroke = true;
+
+        priv->strokePath = gegl_path_new();
+        gegl_path_append (priv->strokePath, 'M', x, y);
+
+        priv->strokeNode = gegl_node_new_child(priv->graph,
+                                               "operation", "gegl:path",
+                                               "d", priv->strokePath,
+                                               "fill-opacity", 0.0,
+                                               "stroke", gegl_color_new (DefaultColor),
+                                               "stroke-width", DefaultLineWidth,
+                                               "stroke-hardness", DefaultHardness,
+                                               NULL);
+        if (oldStrokeNode) {
+            gegl_node_link_many(oldStrokeNode, priv->strokeNode, NULL);
+        }
+        gegl_node_link_many(priv->strokeNode, priv->outputNode, NULL);
+
+    } else if (buttonPressed && priv->inStroke) {
+        // Add a new point to the stroke
+        gegl_path_append(priv->strokePath, 'L', x, y, NULL);
+
+    } else if (!buttonPressed && priv->inStroke) {
+        // End stroke
+        priv->inStroke = false;
+        gegl_path_append (priv->strokePath, 'M', x, y);
+        g_object_unref (priv->strokePath);
+
+    } else if (!buttonPressed && !priv->inStroke) {
+        // Do nothing
+    }
+
+}
diff --git a/examples/qml-paint/qml-paint-engine.h b/examples/qml-paint/qml-paint-engine.h
new file mode 100644
index 0000000..ac8751b
--- /dev/null
+++ b/examples/qml-paint/qml-paint-engine.h
@@ -0,0 +1,25 @@
+#ifndef QMLPAINTENGINE_H
+#define QMLPAINTENGINE_H
+
+#include <QtCore>
+
+class PaintEnginePrivate;
+
+class PaintEngine : public QObject
+{
+    Q_OBJECT
+public:
+    explicit PaintEngine(QObject *parent = 0);
+    ~PaintEngine();
+
+    Q_INVOKABLE QVariant outputNode();
+    Q_INVOKABLE void positionChanged(double x, double y, bool buttonPressed);
+
+private:
+    void clear();
+
+private:
+    PaintEnginePrivate* priv;
+};
+
+#endif // QMLPAINTENGINE_H
diff --git a/examples/qml-paint/qml-paint.cpp b/examples/qml-paint/qml-paint.cpp
new file mode 100644
index 0000000..283f056
--- /dev/null
+++ b/examples/qml-paint/qml-paint.cpp
@@ -0,0 +1,58 @@
+/* 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 "qml-paint-engine.h"
+
+#include <gegl-qt.h>
+
+#include <QtGui>
+#include <QtCore>
+#include <QtDeclarative>
+
+int main(int argc, char *argv[])
+{
+    GeglNode *graph, *node;
+
+    QApplication a(argc, argv);
+    gegl_init(&argc, &argv);
+    Q_INIT_RESOURCE(qmlpaint);
+
+    // Does all the GEGL graph stuff
+    PaintEngine paintEngine;
+
+    qDebug() << "PaintEngine created";
+    // TODO: Create an QDeclarativeExtensionPlugin which does this?
+    qmlRegisterType<GeglQtDeclarativeView>("GeglQt", 0, 1, "GeglQtView");
+
+    QDeclarativeView view;
+    // Expose the paint engine to QML, so it can be used there
+    view.rootContext()->setContextProperty("paintEngine", &paintEngine);
+    view.setSource(QUrl("qrc:/qml-paint.qml"));
+    view.show();
+
+    qDebug() << "Executing application";
+    int retCode = a.exec();
+
+    g_object_unref(graph);
+    gegl_exit();
+    return retCode;
+}
+
+
+
+
diff --git a/examples/qml-paint/qml-paint.pro b/examples/qml-paint/qml-paint.pro
new file mode 100644
index 0000000..2b4ace3
--- /dev/null
+++ b/examples/qml-paint/qml-paint.pro
@@ -0,0 +1,6 @@
+include(../examples-common.pri)
+
+SOURCES += qml-paint.cpp qml-paint-engine.cpp
+HEADERS += qml-paint-engine.h
+RESOURCES += qmlpaint.qrc
+OTHER_FILES += qml-paint.qml
diff --git a/examples/qml-paint/qml-paint.qml b/examples/qml-paint/qml-paint.qml
new file mode 100644
index 0000000..945e7e6
--- /dev/null
+++ b/examples/qml-paint/qml-paint.qml
@@ -0,0 +1,23 @@
+import QtQuick 1.0
+import GeglQt 0.1
+
+Rectangle {
+    width: 512
+    height: 512
+
+    GeglQtView {
+        id: view
+        anchors.fill: parent
+        inputNode: paintEngine.outputNode()
+        x: 0
+        y: 0
+    }
+
+    MouseArea {
+        anchors.fill: view
+        hoverEnabled: true
+        onPositionChanged: {
+            paintEngine.positionChanged(mouse.x, mouse.y, (mouse.buttons & Qt.LeftButton))
+        }
+    }
+}
diff --git a/examples/qml-paint/qmlpaint.qrc b/examples/qml-paint/qmlpaint.qrc
new file mode 100644
index 0000000..b410a34
--- /dev/null
+++ b/examples/qml-paint/qmlpaint.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>qml-paint.qml</file>
+    </qresource>
+</RCC>



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