From ddfacf6e290fe39dbdb55186ac76769014ce86cd Mon Sep 17 00:00:00 2001
From: Fadi SHEHADEH <fadi.shehadeh@savoirfairelinux.com>
Date: Thu, 1 Dec 2022 14:35:30 -0500
Subject: [PATCH] settingSpinBox: changed textfield to spinbox

- added spinbox item
- added customization

Gitlab: #472
Change-Id: I4a7415afbeeafda7651fa59e684daba8b500a8e7
---
 resources/icons/chevron_right_black_24dp.svg  |   1 +
 src/app/constant/JamiTheme.qml                |   4 +
 .../AdvancedConnectivitySettings.qml          |   5 -
 .../AdvancedPublicAddressSettings.qml         |   5 -
 .../components/AdvancedSDPSettings.qml        |  20 ----
 .../AdvancedSIPSecuritySettings.qml           |   5 -
 .../components/SettingSpinBox.qml             | 112 ++++++++++++++----
 .../components/SystemSettings.qml             |  18 ++-
 8 files changed, 100 insertions(+), 70 deletions(-)
 create mode 100644 resources/icons/chevron_right_black_24dp.svg

diff --git a/resources/icons/chevron_right_black_24dp.svg b/resources/icons/chevron_right_black_24dp.svg
new file mode 100644
index 000000000..c33dc8a37
--- /dev/null
+++ b/resources/icons/chevron_right_black_24dp.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>
\ No newline at end of file
diff --git a/src/app/constant/JamiTheme.qml b/src/app/constant/JamiTheme.qml
index 95c941797..d6dadc3c9 100644
--- a/src/app/constant/JamiTheme.qml
+++ b/src/app/constant/JamiTheme.qml
@@ -142,6 +142,10 @@ Item {
     property color comboboxBorderColor: darkTheme ? tintedBlue : Qt.rgba(0, 0.34, 0.6, 0.36)
     property color comboboxTextColorHovered: darkTheme ? "#03B9E9" : tintedBlue
 
+    //Spinbox
+    property color spinboxBackgroundColor: darkTheme ? editBackgroundColor : selectedColor
+    property color spinboxBorderColor: darkTheme ? tintedBlue : Qt.rgba(0, 0.34, 0.6, 0.36)
+
     // Call buttons
     property color acceptButtonGreen: "#4caf50"
     property color acceptButtonHoverGreen: "#5db761"
diff --git a/src/app/settingsview/components/AdvancedConnectivitySettings.qml b/src/app/settingsview/components/AdvancedConnectivitySettings.qml
index 69f516a2c..b51a9d7dc 100644
--- a/src/app/settingsview/components/AdvancedConnectivitySettings.qml
+++ b/src/app/settingsview/components/AdvancedConnectivitySettings.qml
@@ -85,11 +85,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.localPort
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.localPort })
-            }
-
             onNewValue: CurrentAccount.localPort = valueField
         }
 
diff --git a/src/app/settingsview/components/AdvancedPublicAddressSettings.qml b/src/app/settingsview/components/AdvancedPublicAddressSettings.qml
index 62769c429..fec002c50 100644
--- a/src/app/settingsview/components/AdvancedPublicAddressSettings.qml
+++ b/src/app/settingsview/components/AdvancedPublicAddressSettings.qml
@@ -101,11 +101,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.publishedPort
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.publishedPort })
-            }
-
             onNewValue: CurrentAccount.publishedPort = valueField
         }
     }
diff --git a/src/app/settingsview/components/AdvancedSDPSettings.qml b/src/app/settingsview/components/AdvancedSDPSettings.qml
index 916ec857b..c98dbca9a 100644
--- a/src/app/settingsview/components/AdvancedSDPSettings.qml
+++ b/src/app/settingsview/components/AdvancedSDPSettings.qml
@@ -62,11 +62,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.audioPortMin_Audio
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.audioPortMin_Audio })
-            }
-
             onNewValue: CurrentAccount.audioPortMin_Audio = valueField
         }
 
@@ -80,11 +75,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.audioPortMax_Audio
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.audioPortMax_Audio })
-            }
-
             onNewValue: CurrentAccount.audioPortMax_Audio = valueField
         }
 
@@ -98,11 +88,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.videoPortMin_Video
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.videoPortMin_Video })
-            }
-
             onNewValue: CurrentAccount.videoPortMin_Video = valueField
         }
 
@@ -116,11 +101,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.videoPortMax_Video
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.videoPortMax_Video })
-            }
-
             onNewValue: CurrentAccount.videoPortMax_Video = valueField
         }
     }
diff --git a/src/app/settingsview/components/AdvancedSIPSecuritySettings.qml b/src/app/settingsview/components/AdvancedSIPSecuritySettings.qml
index 33ae05697..61f501923 100644
--- a/src/app/settingsview/components/AdvancedSIPSecuritySettings.qml
+++ b/src/app/settingsview/components/AdvancedSIPSecuritySettings.qml
@@ -306,11 +306,6 @@ ColumnLayout {
 
             valueField: CurrentAccount.negotiationTimeoutSec_TLS
 
-            onInputAcceptableChanged: {
-                if (!inputAcceptable && valueField.length !== 0)
-                    valueField = Qt.binding(function() { return CurrentAccount.negotiationTimeoutSec_TLS })
-            }
-
             onNewValue: CurrentAccount.negotiationTimeoutSec_TLS = valueField
         }
     }
diff --git a/src/app/settingsview/components/SettingSpinBox.qml b/src/app/settingsview/components/SettingSpinBox.qml
index 0c4329853..7de1a8cea 100644
--- a/src/app/settingsview/components/SettingSpinBox.qml
+++ b/src/app/settingsview/components/SettingSpinBox.qml
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2020-2022 Savoir-faire Linux Inc.
  * Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
+ * Author: Fadi Shehadeh <fadi.shehadeh@savoirfairelinux.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,12 +31,12 @@ RowLayout {
     id: root
 
     property alias title: title.text
-    property alias enabled: textField.enabled
-    property alias bottomValue: textFieldValidator.bottom
-    property alias topValue: textFieldValidator.top
-    property alias valueField: textField.text
+    property alias enabled: spinbox.enabled
+    property alias bottomValue: spinbox.from
+    property alias topValue: spinbox.to
+    property alias valueField: spinbox.value
     property alias tooltipText: toolTip.text
-    property alias inputAcceptable: textField.acceptableInput
+    property alias step: spinbox.stepSize
 
     property string borderColor: JamiTheme.greyBorderColor
     property int itemWidth
@@ -56,8 +57,11 @@ RowLayout {
         verticalAlignment: Text.AlignVCenter
     }
 
-    TextField {
-        id: textField
+    SpinBox {
+        id: spinbox
+
+        wheelEnabled: true
+        hoverEnabled: true
 
         Layout.preferredWidth: root.itemWidth
         Layout.preferredHeight: JamiTheme.preferredFieldHeight
@@ -65,34 +69,94 @@ RowLayout {
         font.pointSize: JamiTheme.buttonFontSize
         font.kerning: true
 
-        validator: IntValidator {
-            id: textFieldValidator
+        onValueChanged: newValue()
+
+        Keys.onPressed: function (keyEvent) {
+
+            if (keyEvent.key === Qt.Key_Enter ||
+                    keyEvent.key === Qt.Key_Return) {
+                textInput.focus = false
+                spinbox.value = textInput.text
+                keyEvent.accepted = true
+            }
         }
 
-        color: JamiTheme.textColor
-        hoverEnabled: true
+        contentItem: TextInput {
+            id: textInput
+
+            text: spinbox.textFromValue(spinbox.value, spinbox.locale)
+            color : JamiTheme.textColor
+            horizontalAlignment: Qt.AlignHCenter
+            verticalAlignment: Qt.AlignVCenter
+            inputMethodHints : Qt.ImhDigitsOnly
+            validator: spinbox.validator
+        }
 
         background: Rectangle {
-            border.color: enabled ? root.borderColor : JamiTheme.transparentColor
-            color: JamiTheme.editBackgroundColor
+            border.color: JamiTheme.spinboxBorderColor
+            color: JamiTheme.transparentColor
             radius: JamiTheme.primaryRadius
         }
 
-        onEditingFinished: newValue()
+        MaterialToolTip {
+            id: toolTip
+            parent: spinbox
+            visible: spinbox.hovered && (root.tooltipText.length > 0)
+            delay: Qt.styleHints.mousePressAndHoldInterval
+        }
+
+        height: down.implicitIndicatorHeight
 
-        Keys.onPressed: {
-            if (event.key === Qt.Key_Enter ||
-                    event.key === Qt.Key_Return) {
-                textField.focus = false
-                event.accepted = true
+        up.indicator: Rectangle {
+
+            width: parent.width / 8
+            radius : 4
+            anchors {
+                top : parent.top
+                bottom : parent.bottom
+                right: parent.right
+                margins: 1
+            }
+
+            color: spinbox.up.pressed || spinbox.up.hovered ? JamiTheme.spinboxBorderColor : JamiTheme.transparentColor
+
+            ResponsiveImage {
+
+                containerHeight: 6
+                containerWidth: 10
+                width: 20
+                height: 20
+                color: JamiTheme.primaryForegroundColor
+                anchors.verticalCenter: parent.verticalCenter
+                anchors.horizontalCenter: parent.horizontalCenter
+                source: JamiResources.chevron_right_black_24dp_svg
             }
         }
 
-        MaterialToolTip {
-            id: toolTip
-            parent: textField
-            visible: textField.hovered && (root.tooltipText.length > 0)
-            delay: Qt.styleHints.mousePressAndHoldInterval
+        down.indicator: Rectangle {
+
+            width: parent.width / 8
+            radius : 4
+            anchors {
+                top : parent.top
+                bottom : parent.bottom
+                left: parent.left
+                margins: 1
+            }
+
+            color: spinbox.down.pressed || spinbox.down.hovered ? JamiTheme.spinboxBorderColor : JamiTheme.transparentColor
+
+            ResponsiveImage {
+
+                containerHeight: 6
+                containerWidth: 10
+                width: 20
+                height: 20
+                color: JamiTheme.primaryForegroundColor
+                anchors.verticalCenter: parent.verticalCenter
+                anchors.horizontalCenter: parent.horizontalCenter
+                source: JamiResources.chevron_left_black_24dp_svg
+            }
         }
     }
 }
diff --git a/src/app/settingsview/components/SystemSettings.qml b/src/app/settingsview/components/SystemSettings.qml
index a1d75222a..00dd39d0c 100644
--- a/src/app/settingsview/components/SystemSettings.qml
+++ b/src/app/settingsview/components/SystemSettings.qml
@@ -251,16 +251,12 @@ ColumnLayout {
         tooltipText: JamiStrings.changeTextSize
         itemWidth: root.itemWidth
 
-        valueField: Math.round(UtilsAdapter.getAppValue(Settings.BaseZoom) * 100.0)
-
-        onNewValue: {
-            // here, avoid validator cause it can be painful for the user to change
-            // values by modifying the whole field.
-            if (valueField < 10)
-                valueField = 10
-            else if (valueField > 200)
-                valueField = 200
-            UtilsAdapter.setAppValue(Settings.BaseZoom, Math.round(valueField / 100.0))
-        }
+        bottomValue: 50
+        topValue: 200
+        step: 10
+
+        valueField: UtilsAdapter.getAppValue(Settings.BaseZoom) * 100.0
+
+        onNewValue: UtilsAdapter.setAppValue(Settings.BaseZoom, valueField / 100.0)
     }
 }
-- 
GitLab