SpinBox.qml 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 2.15
  5. import UM 1.5 as UM
  6. import Cura 1.5 as Cura
  7. // This component extends the funtionality of QtControls 2.x Spinboxes to
  8. // - be able to contain fractional values
  9. // - hava a "prefix" and a "suffix". A validator is added that recognizes this pre-, suf-fix combo. When adding a custom
  10. // validator the pre-, suf-fix should be added (e.g. new RegExp("^" + prefix + \regex\ + suffix + "$")
  11. Item
  12. {
  13. id: base
  14. property string prefix: ""
  15. property string suffix: ""
  16. property int decimals: 0
  17. property real stepSize: 1
  18. property real value: 0
  19. property real from: 0
  20. property real to: 99
  21. property alias wrap: spinBox.wrap
  22. property bool editable: true
  23. property var validator: RegExpValidator
  24. {
  25. regExp: new RegExp("^" + prefix + "([0-9]+[.|,]?[0-9]*)?" + suffix + "$")
  26. }
  27. signal editingFinished()
  28. implicitWidth: spinBox.implicitWidth
  29. implicitHeight: spinBox.implicitHeight
  30. SpinBox
  31. {
  32. id: spinBox
  33. anchors.fill: base
  34. editable: base.editable
  35. topPadding: 0
  36. bottomPadding: 0
  37. padding: UM.Theme.getSize("narrow_margin").width
  38. // The stepSize of the SpinBox is intentionally set to be always `1`
  39. // As SpinBoxes can only contain integer values the `base.stepSize` is concidered the precision/resolution
  40. // increasing the spinBox.value by one increases the actual/real value of the component by `base.stepSize`
  41. // as such spinBox.value * base.stepSizes produces the real value of the component
  42. stepSize: 1
  43. value: Math.floor(base.value / base.stepSize)
  44. from: Math.floor(base.from / base.stepSize)
  45. to: Math.floor(base.to / base.stepSize)
  46. valueFromText: function(text)
  47. {
  48. return parseFloat(text.substring(prefix.length, text.length - suffix.length).replace(",", ".")) / base.stepSize;
  49. }
  50. textFromValue: function(value)
  51. {
  52. return prefix + (value * base.stepSize).toFixed(decimals) + suffix;
  53. }
  54. validator: base.validator
  55. onValueModified:
  56. {
  57. base.value = value * base.stepSize;
  58. }
  59. // This forces TextField to commit typed values before incrementing with buttons.
  60. // This fixes the typed value not being incremented when the textField has active focus.
  61. up.onPressedChanged:
  62. {
  63. base.forceActiveFocus()
  64. }
  65. down.onPressedChanged:
  66. {
  67. base.forceActiveFocus()
  68. }
  69. background: Item {}
  70. contentItem: Cura.TextField
  71. {
  72. text: spinBox.textFromValue(spinBox.value, spinBox.locale)
  73. validator: base.validator
  74. onActiveFocusChanged:
  75. {
  76. if (!activeFocus)
  77. {
  78. base.editingFinished();
  79. }
  80. }
  81. }
  82. down.indicator: Rectangle
  83. {
  84. x: spinBox.mirrored ? parent.width - width : 0
  85. height: parent.height
  86. width: height
  87. UM.UnderlineBackground {
  88. color: spinBox.down.pressed ? spinBox.palette.mid : UM.Theme.getColor("detail_background")
  89. }
  90. UM.RecolorImage
  91. {
  92. anchors.centerIn: parent
  93. height: parent.height / 2.5
  94. width: height
  95. color: enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled")
  96. source: UM.Theme.getIcon("Minus")
  97. }
  98. }
  99. up.indicator: Rectangle
  100. {
  101. x: spinBox.mirrored ? 0 : parent.width - width
  102. height: parent.height
  103. width: height
  104. UM.UnderlineBackground {
  105. color: spinBox.up.pressed ? spinBox.palette.mid : UM.Theme.getColor("detail_background")
  106. }
  107. UM.RecolorImage
  108. {
  109. anchors.centerIn: parent
  110. height: parent.height / 2.5
  111. width: height
  112. color: enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled")
  113. source: UM.Theme.getIcon("Plus")
  114. }
  115. }
  116. }
  117. }