From 9dcfac3d44818d8492c6b7adb9e4a6981b77247c Mon Sep 17 00:00:00 2001
From: Don Gagne <don@thegagnes.com>
Date: Sat, 5 Mar 2016 17:39:24 -0800
Subject: [PATCH] Support increment meta data

---
 src/FactSystem/Fact.cc                         | 10 ++++++++++
 src/FactSystem/Fact.h                          |  6 ++++--
 src/FactSystem/FactMetaData.cc                 |  3 +++
 src/FactSystem/FactMetaData.h                  |  6 ++++++
 src/FirmwarePlugin/APM/APMParameterMetaData.cc | 11 +++++++++++
 src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc | 11 +++++++++++
 src/QmlControls/FactSliderPanel.qml            |  2 +-
 7 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/src/FactSystem/Fact.cc b/src/FactSystem/Fact.cc
index d3df47e..8e60775 100644
--- a/src/FactSystem/Fact.cc
+++ b/src/FactSystem/Fact.cc
@@ -552,3 +552,13 @@ QString Fact::enumOrValueString(void)
     }
     return QString();
 }
+
+double Fact::increment(void) const
+{
+    if (_metaData) {
+        return _metaData->increment();
+    } else {
+        qWarning() << "Meta data pointer missing";
+    }
+    return std::numeric_limits<double>::quiet_NaN();
+}
diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h
index 67e8a4a..60fae7d 100644
--- a/src/FactSystem/Fact.h
+++ b/src/FactSystem/Fact.h
@@ -74,6 +74,7 @@ public:
     Q_PROPERTY(bool         valueEqualsDefault      READ valueEqualsDefault                                 NOTIFY valueChanged)
     Q_PROPERTY(QString      valueString             READ cookedValueString                                  NOTIFY valueChanged)
     Q_PROPERTY(QString      enumOrValueString       READ enumOrValueString                                  NOTIFY valueChanged)
+    Q_PROPERTY(double       increment               READ increment                                          CONSTANT)
 
     /// Convert and validate value
     ///     @param convertOnly true: validate type conversion only, false: validate against meta data as well
@@ -87,8 +88,8 @@ public:
     QVariant        cookedDefaultValue      (void) const;
     bool            defaultValueAvailable   (void) const;
     QString         cookedDefaultValueString(void) const;
-    QStringList     bitmaskStrings             (void) const;
-    QVariantList    bitmaskValues              (void) const;
+    QStringList     bitmaskStrings          (void) const;
+    QVariantList    bitmaskValues           (void) const;
     int             enumIndex               (void);         // This is not const, since an unknown value can modify the enum lists
     QStringList     enumStrings             (void) const;
     QString         enumStringValue         (void);         // This is not const, since an unknown value can modify the enum lists
@@ -113,6 +114,7 @@ public:
     bool            valueEqualsDefault      (void) const;
     bool            rebootRequired          (void) const;
     QString         enumOrValueString       (void);         // This is not const, since an unknown value can modify the enum lists
+    double          increment               (void) const;
 
     void setRawValue        (const QVariant& value);
     void setCookedValue     (const QVariant& value);
diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc
index b1c3161..3510568 100644
--- a/src/FactSystem/FactMetaData.cc
+++ b/src/FactSystem/FactMetaData.cc
@@ -52,6 +52,7 @@ FactMetaData::FactMetaData(QObject* parent)
     , _rawTranslator(_defaultTranslator)
     , _cookedTranslator(_defaultTranslator)
     , _rebootRequired(false)
+    , _increment(std::numeric_limits<double>::quiet_NaN())
 {
 
 }
@@ -70,6 +71,7 @@ FactMetaData::FactMetaData(ValueType_t type, QObject* parent)
     , _rawTranslator(_defaultTranslator)
     , _cookedTranslator(_defaultTranslator)
     , _rebootRequired(false)
+    , _increment(std::numeric_limits<double>::quiet_NaN())
 {
 
 }
@@ -103,6 +105,7 @@ const FactMetaData& FactMetaData::operator=(const FactMetaData& other)
     _rawTranslator          = other._rawTranslator;
     _cookedTranslator       = other._cookedTranslator;
     _rebootRequired         = other._rebootRequired;
+    _increment              = other._increment;
 
     return *this;
 }
diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h
index 9a3661f..62a624e 100644
--- a/src/FactSystem/FactMetaData.h
+++ b/src/FactSystem/FactMetaData.h
@@ -83,6 +83,10 @@ public:
     QString         cookedUnits             (void) const { return _cookedUnits; }
     bool            rebootRequired          (void) const { return _rebootRequired; }
 
+    /// Amount to increment value when used in controls such as spin button or slider with detents.
+    /// NaN for no increment available.
+    double          increment               (void) const { return _increment; }
+
     Translator      rawTranslator           (void) const { return _rawTranslator; }
     Translator      cookedTranslator        (void) const { return _cookedTranslator; }
 
@@ -104,6 +108,7 @@ public:
     void setShortDescription(const QString& shortDescription)   { _shortDescription = shortDescription; }
     void setRawUnits        (const QString& rawUnits);
     void setRebootRequired  (bool rebootRequired)               { _rebootRequired = rebootRequired; }
+    void setIncrement       (double increment)                  { _increment = increment; }
 
     void setTranslators(Translator rawTranslator, Translator cookedTranslator);
 
@@ -156,6 +161,7 @@ private:
     Translator      _rawTranslator;
     Translator      _cookedTranslator;
     bool            _rebootRequired;
+    double          _increment;
 
     struct BuiltInTranslation_s {
         const char* rawUnits;
diff --git a/src/FirmwarePlugin/APM/APMParameterMetaData.cc b/src/FirmwarePlugin/APM/APMParameterMetaData.cc
index ce391fb..a1b9209 100644
--- a/src/FirmwarePlugin/APM/APMParameterMetaData.cc
+++ b/src/FirmwarePlugin/APM/APMParameterMetaData.cc
@@ -580,6 +580,17 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
         }
     }
 
+    if (!rawMetaData->incrementSize.isEmpty()) {
+        double  increment;
+        bool    ok;
+        increment = rawMetaData->incrementSize.toDouble(&ok);
+        if (ok) {
+            metaData->setIncrement(increment);
+        } else {
+            qCDebug(APMParameterMetaDataLog) << "Invalid value for increment, name:" << metaData->name() << " increment:" << rawMetaData->incrementSize;
+        }
+    }
+
     // FixMe:: not handling increment size as their is no place for it in FactMetaData and no ui
     fact->setMetaData(metaData);
 }
diff --git a/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc b/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc
index 043eed2..9b31cac 100644
--- a/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc
+++ b/src/FirmwarePlugin/PX4/PX4ParameterMetaData.cc
@@ -306,6 +306,17 @@ void PX4ParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
                                                              << " type:" << metaData->type() << " value:" << enumValueStr
                                                              << " error:" << errorString;
                         }
+                    } else if (elementName == "increment") {
+                        Q_ASSERT(metaData);
+                        double  increment;
+                        bool    ok;
+                        QString text = xml.readElementText();
+                        increment = text.toDouble(&ok);
+                        if (ok) {
+                            metaData->setIncrement(increment);
+                        } else {
+                            qCWarning(PX4ParameterMetaDataLog) << "Invalid value for increment, name:" << metaData->name() << " increment:" << text;
+                        }
                     } else {
                         qDebug() << "Unknown element in XML: " << elementName;
                     }
diff --git a/src/QmlControls/FactSliderPanel.qml b/src/QmlControls/FactSliderPanel.qml
index 09b0892..b1d1321 100644
--- a/src/QmlControls/FactSliderPanel.qml
+++ b/src/QmlControls/FactSliderPanel.qml
@@ -122,7 +122,7 @@ QGCView {
                                 anchors.right:      parent.right
                                 minimumValue:       min
                                 maximumValue:       max
-                                stepSize:           step
+                                stepSize:           isNaN(fact.increment) ? step : fact.increment
                                 tickmarksEnabled:   true
 
                                 property Fact fact: controller.getParameterFact(-1, param)