From 518b282ee36de66be09bcabc95d0092c1ee3a2c4 Mon Sep 17 00:00:00 2001
From: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Date: Wed, 13 Feb 2013 17:02:34 +0100
Subject: [PATCH] Add support for SpinBox::prefix and fix size hint

This fixes QTBUG-1292 an QTBUG-1291

Change-Id: I3c0435d968717c23935e7671c055849547121279
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
---
 src/qtdesktop/SpinBox.qml                   | 118 +++++++++++++-------
 src/styles/Desktop/SpinBoxStyle.qml         |   8 +-
 tests/auto/qtdesktop/data/tst_spinbox.qml   |  35 ++++++
 tests/manual/controls/pages/SpinBoxPage.qml |   4 +-
 4 files changed, 117 insertions(+), 48 deletions(-)

diff --git a/src/qtdesktop/SpinBox.qml b/src/qtdesktop/SpinBox.qml
index e8adce999..63208e03f 100644
--- a/src/qtdesktop/SpinBox.qml
+++ b/src/qtdesktop/SpinBox.qml
@@ -123,6 +123,11 @@ FocusScope {
     */
     property alias font: input.font
 
+    /*! This property indicates if the Spinbox should get active
+      focus when pressed.
+      The default value is \c true
+    */
+    property bool activeFocusOnPress: true
 
     /*! \internal */
     property Component style: Qt.createComponent(Settings.THEME_PATH + "/SpinBoxStyle.qml", spinbox)
@@ -163,6 +168,26 @@ FocusScope {
     property alias __containsMouse: mouseArea.containsMouse
     /*! \internal */
     property alias __text: input.text
+    /*! \internal */
+    readonly property int __contentHeight: Math.max(input.implicitHeight, 20)
+    /*! \internal */
+    readonly property int __contentWidth: suffixItem.implicitWidth +
+                                   Math.max(maxSizeHint.implicitWidth,
+                                            minSizeHint.implicitWidth) +
+                                   prefixItem.implicitWidth
+    Text {
+        id: maxSizeHint
+        text: maximumValue.toFixed(decimals)
+        font: input.font
+        visible: false
+    }
+
+    Text {
+        id: minSizeHint
+        text: minimumValue.toFixed(decimals)
+        font: input.font
+        visible: false
+    }
 
     /*! \internal */
     onDecimalsChanged: input.setValue(value)
@@ -195,55 +220,66 @@ FocusScope {
         id: mouseArea
         anchors.fill: parent
         hoverEnabled: true
+        onPressed: if (activeFocusOnPress) input.forceActiveFocus()
     }
 
-    TextInput {
-        id: input
-
-        function setValue(v) {
-            var newval = parseFloat(v)
-
-            if (!isNaN(newval)) {
-                if (newval > maximumValue)
-                    newval = maximumValue
-                else if (v < minimumValue)
-                    newval = minimumValue
-                newval = newval.toFixed(decimals)
-                spinbox.value = parseFloat(newval)
-                input.text = newval
-            } else {
-                input.text = parseFloat(spinbox.value)
-            }
+    Row {
+        id: textLayout
+        anchors.fill: parent
+        spacing: 1
+        clip: true
+        anchors.leftMargin: loader.item ? loader.item.leftMargin : 0
+        anchors.topMargin: loader.item ? loader.item.topMargin : 0
+        anchors.rightMargin: loader.item ? loader.item.rightMargin: 0
+        anchors.bottomMargin: loader.item ? loader.item.bottomMargin: 0
+
+        Text {
+            id: prefixItem
+            text: prefix
+            color: loader.item ? loader.item.foregroundColor : "black"
+            anchors.verticalCenter: parent.verticalCenter
+            renderType: Text.NativeRendering
         }
 
-        property Item styleItem: loader.item
+        TextInput {
+            id: input
+            anchors.verticalCenter: parent.verticalCenter
+            activeFocusOnPress: spinbox.activeFocusOnPress
+            function setValue(v) {
+                var newval = parseFloat(v)
+
+                if (!isNaN(newval)) {
+                    if (newval > maximumValue)
+                        newval = maximumValue
+                    else if (v < minimumValue)
+                        newval = minimumValue
+                    newval = newval.toFixed(decimals)
+                    spinbox.value = parseFloat(newval)
+                    input.text = newval
+                } else {
+                    input.text = parseFloat(spinbox.value)
+                }
+            }
+
+            horizontalAlignment: loader.item ? loader.item.horizontalTextAlignment : Qt.AlignLeft
+            verticalAlignment: loader.item ? loader.item.verticalTextAlignment : Qt.AlignVCenter
+            selectByMouse: true
 
-        clip: true
+            validator: DoubleValidator { bottom: minimumValue; top: maximumValue; }
+            onAccepted: setValue(input.text)
+            color: loader.item ? loader.item.foregroundColor : "black"
+            selectionColor: loader.item ? loader.item.selectionColor : "black"
+            selectedTextColor: loader.item ? loader.item.selectedTextColor : "black"
 
-        horizontalAlignment: styleItem ? styleItem.horizontalTextAlignment : Qt.AlignLeft
-        verticalAlignment: styleItem ? styleItem.verticalTextAlignment : Qt.AlignVCenter
-        anchors.fill: parent
-        anchors.leftMargin: styleItem ? styleItem.leftMargin : 0
-        anchors.topMargin: styleItem ? styleItem.topMargin : 0
-        anchors.rightMargin: styleItem ? styleItem.rightMargin: 0
-        anchors.bottomMargin: styleItem ? styleItem.bottomMargin: 0
-        selectByMouse: true
-
-        validator: DoubleValidator { bottom: minimumValue; top: maximumValue; }
-        onAccepted: setValue(input.text)
-        onActiveFocusChanged: setValue(input.text)
-        color: loader.item ? loader.item.foregroundColor : "black"
-        selectionColor: loader.item ? loader.item.selectionColor : "black"
-        selectedTextColor: loader.item ? loader.item.selectedTextColor : "black"
-
-        opacity: parent.enabled ? 1 : 0.5
-        renderType: Text.NativeRendering
+            opacity: parent.enabled ? 1 : 0.5
+            renderType: Text.NativeRendering
+        }
         Text {
+            id: suffixItem
             text: suffix
             color: loader.item ? loader.item.foregroundColor : "black"
-            anchors.rightMargin: 4
-            anchors.right: parent.right
             anchors.verticalCenter: parent.verticalCenter
+            renderType: Text.NativeRendering
         }
     }
 
@@ -269,7 +305,7 @@ FocusScope {
         property bool autoincrement: false;
         onReleased: autoincrement = false
         Timer { running: mouseUp.pressed; interval: 350 ; onTriggered: mouseUp.autoincrement = true }
-        Timer { running: mouseUp.autoincrement; interval: 60 ; repeat: true ; onTriggered: increment() }
+        Timer { running: mouseUp.autoincrement; interval: 60 ; repeat: true ; onTriggered: __increment() }
     }
 
     // Spinbox decrement button
@@ -293,7 +329,7 @@ FocusScope {
         property bool autoincrement: false;
         onReleased: autoincrement = false
         Timer { running: mouseDown.pressed; interval: 350 ; onTriggered: mouseDown.autoincrement = true }
-        Timer { running: mouseDown.autoincrement; interval: 60 ; repeat: true ; onTriggered: decrement() }
+        Timer { running: mouseDown.autoincrement; interval: 60 ; repeat: true ; onTriggered: __decrement() }
     }
 
     Keys.onUpPressed: __increment()
diff --git a/src/styles/Desktop/SpinBoxStyle.qml b/src/styles/Desktop/SpinBoxStyle.qml
index dd372c855..a789438c5 100644
--- a/src/styles/Desktop/SpinBoxStyle.qml
+++ b/src/styles/Desktop/SpinBoxStyle.qml
@@ -117,10 +117,10 @@ Item {
         hasFocus: control.focus
         enabled: control.enabled
         value: (control.__upPressed ? 1 : 0)           |
-               (control.__downPressed == 1 ? 1<<1 : 0) |
+               (control.__downPressed ? 1<<1 : 0) |
                (control.__upEnabled ? (1<<2) : 0)      |
-               (control.__downEnabled == 1 ? (1<<3) : 0)
-        contentWidth: 200
-        contentHeight: 25
+               (control.__downEnabled ? (1<<3) : 0)
+        contentWidth: control.__contentWidth
+        contentHeight: control.__contentHeight
     }
 }
diff --git a/tests/auto/qtdesktop/data/tst_spinbox.qml b/tests/auto/qtdesktop/data/tst_spinbox.qml
index 4299b1b5b..5854f95fa 100644
--- a/tests/auto/qtdesktop/data/tst_spinbox.qml
+++ b/tests/auto/qtdesktop/data/tst_spinbox.qml
@@ -235,6 +235,41 @@ Item {
             compare(spinbox.value, spinbox.maximumValue)
         }
 
+        function test_ImplicitSize() // Verify if we correctly grow and shrink depending on contents
+        {
+            var spinbox = Qt.createQmlObject('import QtDesktop 1.0; SpinBox {}', container, '')
+            spinbox.forceActiveFocus()
+            spinbox.minimumValue = -50
+            spinbox.maximumValue = 50
+
+            var oldSize = spinbox.implicitWidth
+            spinbox.maximumValue = 5000
+            verify(oldSize < spinbox.implicitWidth)
+            oldSize = spinbox.implicitWidth
+            spinbox.maximumValue = 50
+            verify(oldSize > spinbox.implicitWidth)
+
+            oldSize = spinbox.implicitWidth
+            spinbox.minimumValue = -5000
+            verify(oldSize < spinbox.implicitWidth)
+
+            spinbox.minimumValue = -50
+            oldSize = spinbox.implicitWidth
+            spinbox.minimumValue = -5000
+            verify(oldSize < spinbox.implicitWidth)
+
+            spinbox.minimumValue = -50
+            oldSize = spinbox.implicitWidth
+            spinbox.minimumValue = -5000
+            verify(oldSize < spinbox.implicitWidth)
+
+            spinbox.minimumValue = -50
+            spinbox.decimals = 0
+            oldSize = spinbox.implicitWidth
+            spinbox.decimals = 4
+            verify(oldSize < spinbox.implicitWidth)
+        }
+
         function setCoordinates(item)
         {
             mainCoord.x = item.x + 1
diff --git a/tests/manual/controls/pages/SpinBoxPage.qml b/tests/manual/controls/pages/SpinBoxPage.qml
index 32b58c7d2..9dc4fb83e 100644
--- a/tests/manual/controls/pages/SpinBoxPage.qml
+++ b/tests/manual/controls/pages/SpinBoxPage.qml
@@ -99,10 +99,9 @@ Page {
 
                 SetupField {
                     id: prefix
-                    property variant defaultValue: "Not implemented"; //spinbox.prefix
+                    property variant defaultValue: spinbox.prefix
                     property string title: "Prefix"
                     property bool isText: true
-                    enabled: false // not yet implemented
                     onValidated: spinbox.prefix = validatedValue
                 }
 
@@ -219,7 +218,6 @@ Page {
         SpinBox {
             id: spinbox
 
-            width: parent.width
             decimals: decimalSpinBox.value
 
             onMaximumValueChanged: signalMaximumValueChangedCount.increment()
-- 
GitLab