[gegl-qt] Widgets: Implement some AutoCenter/AutoScale options.



commit 808cf526c6b50587fd5d7df81741246ef7adc1f9
Author: Jon Nordby <jononor gmail com>
Date:   Mon Aug 1 00:55:02 2011 +0200

    Widgets: Implement some AutoCenter/AutoScale options.
    
    GeglQtViewOptions::AutoScaleViewport is not supported yet.

 gegl-qt/geglqtviewimplementation.cpp |   56 ++++++++++++++++++++++++++++++++++
 gegl-qt/geglqtviewimplementation.h   |    1 +
 gegl-qt/geglqtviewoptions.cpp        |    5 +++
 gegl-qt/geglqtviewoptions.h          |   12 +++++++-
 4 files changed, 73 insertions(+), 1 deletions(-)
---
diff --git a/gegl-qt/geglqtviewimplementation.cpp b/gegl-qt/geglqtviewimplementation.cpp
index 5a83232..f6eda1e 100644
--- a/gegl-qt/geglqtviewimplementation.cpp
+++ b/gegl-qt/geglqtviewimplementation.cpp
@@ -19,6 +19,7 @@
 #include "geglqtviewimplementation.h"
 
 #include <QtCore>
+#include <QTransform>
 
 /* Utility functions */
 namespace {
@@ -87,6 +88,7 @@ GeglQtViewImplementation::GeglQtViewImplementation(QObject *parent)
     , processor(0)
     , timer(new QTimer())
     , mOptions(0)
+    , mViewportSize(-1.0, -1.0)
 {
     setOptions(0); // default
 
@@ -151,9 +153,60 @@ GeglQtViewImplementation::setOptions(GeglQtViewOptions *newOptions)
     connect(options(), SIGNAL(transformationChanged()),
             this, SLOT(transformationChanged()));
 
+    connect(options(), SIGNAL(autoCenterPolicyChanged()),
+            this, SLOT(updateAutoCenterScale()));
+    connect(options(), SIGNAL(autoScalePolicyChanged()),
+            this, SLOT(updateAutoCenterScale()));
+
     Q_EMIT viewAreaChanged(QRectF(0.0, 0.0, -1.0, -1.0)); // Redraws everything
 }
 
+/*
+ * Depends on three things
+ * - Model bounding box
+ * - Viewport bounding box
+ * - Autoscale and Autocenter options
+ */
+void
+GeglQtViewImplementation::updateAutoCenterScale()
+{
+    if (!mViewportSize.isValid() || !inputNode()) {
+        return;
+    }
+
+    if (options()->autoScalePolicy() == GeglQtViewOptions::AutoScaleToView) {
+        // Set scale such that the full model fits inside the viewport
+        GeglRectangle bbox = gegl_node_get_bounding_box(inputNode());
+        QRectF modelArea(bbox.x, bbox.y, bbox.width, bbox.height);
+
+        QSizeF view(options()->transformation().mapRect(modelArea).size());
+        QSizeF viewport(mViewportSize);
+
+        float widthRatio = view.width() / viewport.width();
+        float heightRatio = view.height() / viewport.height();
+        float maxRatio = widthRatio >= heightRatio ? widthRatio : heightRatio;
+
+        options()->setScale(options()->scale()*(1.0/maxRatio));
+
+    } else if (options()->autoScalePolicy() == GeglQtViewOptions::AutoScaleViewport) {
+        // TODO: emit a viewportChangeRequest(QSize) signal that widgets catch
+        // and then resize themselves after.
+        qDebug() << __PRETTY_FUNCTION__ << "GeglQtViewOptions::AutoScaleViewport is currently not supported.";
+    }
+
+    if (options()->autoCenterPolicy() == GeglQtViewOptions::AutoCenterEnabled) {
+        // Set translation such that the center of the model is center of the viewport
+        GeglRectangle bbox = gegl_node_get_bounding_box(inputNode());
+        QPointF modelCenter(bbox.width/2.0, bbox.height/2.0);
+
+        QPointF viewCenter(options()->transformation().map(modelCenter));
+        QPointF viewportCenter(mViewportSize.width()/2.0, mViewportSize.height()/2.0);
+
+        options()->setTranslationX(options()->translationX() + viewportCenter.x() - viewCenter.x());
+        options()->setTranslationY(options()->translationY() + viewportCenter.y() - viewCenter.y());
+    }
+}
+
 /* The model->view transformation changed
  * we must recalculate the viewport */
 void
@@ -172,6 +225,7 @@ void
 GeglQtViewImplementation::viewportSizeChanged(QSizeF newSize)
 {
     mViewportSize = newSize;
+    updateAutoCenterScale();
 }
 
 /* An area in the GeglNode has been invalidated,
@@ -211,6 +265,8 @@ GeglQtViewImplementation::processNode()
 void
 GeglQtViewImplementation::nodeComputed(GeglRectangle *rect)
 {
+    updateAutoCenterScale(); // Notify of potential changes in the GeglNode bounding box
+
     QRect modelRect;
     qrect_set_from_gegl_rectangle(modelRect, rect);
     QRectF viewArea = viewAreaFromModelArea(QRectF(modelRect), options());
diff --git a/gegl-qt/geglqtviewimplementation.h b/gegl-qt/geglqtviewimplementation.h
index e458f02..9efbdd8 100644
--- a/gegl-qt/geglqtviewimplementation.h
+++ b/gegl-qt/geglqtviewimplementation.h
@@ -53,6 +53,7 @@ Q_SIGNALS:
 private Q_SLOTS:
     void processNode();
     void transformationChanged();
+    void updateAutoCenterScale();
 
 private:
     void modelAreaChanged();
diff --git a/gegl-qt/geglqtviewoptions.cpp b/gegl-qt/geglqtviewoptions.cpp
index 7aad52d..99b454b 100644
--- a/gegl-qt/geglqtviewoptions.cpp
+++ b/gegl-qt/geglqtviewoptions.cpp
@@ -60,9 +60,12 @@ GeglQtViewOptions::GeglQtViewOptions(QObject *parent)
     : QObject(parent)
     , priv(new GeglQtViewOptionsPrivate())
 {
+    // Defaults
     setScale(1.0);
     setTranslationX(0.0);
     setTranslationY(0.0);
+    setAutoCenterPolicy(AutoCenterDisabled);
+    setAutoScalePolicy(AutoScaleDisabled);
 }
 
 void
@@ -133,6 +136,7 @@ GeglQtViewOptions::setAutoCenterPolicy(AutoCenter newAutoCenter)
         return;
     }
     priv->autoCenter = newAutoCenter;
+    Q_EMIT autoCenterPolicyChanged();
 }
 
 void
@@ -142,6 +146,7 @@ GeglQtViewOptions::setAutoScalePolicy(AutoScale newAutoScale)
         return;
     }
     priv->autoScale = newAutoScale;
+    Q_EMIT autoScalePolicyChanged();
 }
 
 GeglQtViewOptions::AutoCenter
diff --git a/gegl-qt/geglqtviewoptions.h b/gegl-qt/geglqtviewoptions.h
index bb27bce..465c4aa 100644
--- a/gegl-qt/geglqtviewoptions.h
+++ b/gegl-qt/geglqtviewoptions.h
@@ -39,7 +39,6 @@ public:
     enum AutoScale {
       AutoScaleDisabled,
       AutoScaleToView,
-      AutoScaleToViewIgnoreAspectRatio,
       AutoScaleViewport
     };
 
@@ -68,14 +67,25 @@ public:
     Q_PROPERTY(double translationY
                READ translationY WRITE setTranslationY NOTIFY translationChanged)
 
+    Q_PROPERTY(GeglQtViewOptions::AutoCenter autoCenterPolicy
+               READ autoCenterPolicy WRITE setAutoCenterPolicy NOTIFY autoCenterPolicyChanged)
+    Q_PROPERTY(GeglQtViewOptions::AutoScale autoScalePolicy
+               READ autoScalePolicy WRITE setAutoScalePolicy NOTIFY autoScalePolicyChanged)
+
 Q_SIGNALS:
     void translationChanged();
     void scaleChanged();
     void transformationChanged();
 
+    void autoCenterPolicyChanged();
+    void autoScalePolicyChanged();
+
 private:
     Q_DISABLE_COPY(GeglQtViewOptions)
     GeglQtViewOptionsPrivate *priv;
 };
 
+Q_DECLARE_METATYPE(GeglQtViewOptions::AutoCenter)
+Q_DECLARE_METATYPE(GeglQtViewOptions::AutoScale)
+
 #endif // GEGLVIEWOPTIONS_H



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