SpinBox.qml 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. // This component extends the funtionality of QtControls 2.x Spinboxes to
  7. // - be able to contain fractional values
  8. // - hava a "prefix" and a "suffix". A validator is added that recognizes this pre-, suf-fix combo. When adding a custom
  9. // validator the pre-, suf-fix should be added (e.g. new RegExp("^" + prefix + \regex\ + suffix + "$")
  10. Item
  11. {
  12. id: base
  13. property string prefix: ""
  14. property string suffix: ""
  15. property int decimals: 0
  16. property real stepSize: 1
  17. property real value: 0
  18. property real from: 0
  19. property real to: 99
  20. property alias wrap: spinBox.wrap
  21. property bool editable: true
  22. property var validator: RegExpValidator
  23. {
  24. regExp: new RegExp("^" + prefix + "([0-9]+[.|,]?[0-9]*)?" + suffix + "$")
  25. }
  26. signal editingFinished()
  27. implicitWidth: spinBox.implicitWidth
  28. implicitHeight: spinBox.implicitHeight
  29. SpinBox
  30. {
  31. id: spinBox
  32. anchors.fill: base
  33. editable: base.editable
  34. topPadding: 0
  35. bottomPadding: 0
  36. padding: UM.Theme.getSize("spinbox").height / 4
  37. // The stepSize of the SpinBox is intentionally set to be always `1`
  38. // As SpinBoxes can only contain integer values the `base.stepSize` is concidered the precision/resolution
  39. // increasing the spinBox.value by one increases the actual/real value of the component by `base.stepSize`
  40. // as such spinBox.value * base.stepSizes produces the real value of the component
  41. stepSize: 1
  42. value: Math.floor(base.value / base.stepSize)
  43. from: Math.floor(base.from / base.stepSize)
  44. to: Math.floor(base.to / base.stepSize)
  45. valueFromText: function(text)
  46. {
  47. return parseFloat(text.substring(prefix.length, text.length - suffix.length).replace(",", ".")) / base.stepSize;
  48. }
  49. textFromValue: function(value)
  50. {
  51. return prefix + (value * base.stepSize).toFixed(decimals) + suffix;
  52. }
  53. validator: base.validator
  54. onValueModified:
  55. {
  56. base.value = value * base.stepSize;
  57. }
  58. background: Item
  59. {
  60. // Makes space between buttons and textfield transparent
  61. opacity: 0
  62. }
  63. //TextField should be swapped with UM.TextField when it is restyled
  64. contentItem: TextField
  65. {
  66. text: spinBox.textFromValue(spinBox.value, spinBox.locale)
  67. color: enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled")
  68. background: UM.UnderlineBackground {}
  69. selectByMouse: base.editable
  70. validator: base.validator
  71. onActiveFocusChanged:
  72. {
  73. if(!activeFocus)
  74. {
  75. base.editingFinished();
  76. }
  77. }
  78. }
  79. down.indicator: Rectangle
  80. {
  81. x: spinBox.mirrored ? parent.width - width : 0
  82. height: parent.height
  83. width: height
  84. UM.UnderlineBackground {
  85. color: spinBox.up.pressed ? spinBox.palette.mid : UM.Theme.getColor("detail_background")
  86. }
  87. // Minus icon
  88. Rectangle
  89. {
  90. x: (parent.width - width) / 2
  91. y: (parent.height - height) / 2
  92. width: parent.width / 4
  93. height: 2
  94. color: enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled")
  95. }
  96. }
  97. up.indicator: Rectangle
  98. {
  99. x: spinBox.mirrored ? 0 : parent.width - width
  100. height: parent.height
  101. width: height
  102. UM.UnderlineBackground {
  103. color: spinBox.up.pressed ? spinBox.palette.mid : UM.Theme.getColor("detail_background")
  104. }
  105. // Plus Icon
  106. Rectangle
  107. {
  108. x: (parent.width - width) / 2
  109. y: (parent.height - height) / 2
  110. width: parent.width / 3.5
  111. height: 2
  112. color: enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled")
  113. }
  114. Rectangle
  115. {
  116. x: (parent.width - width) / 2
  117. y: (parent.height - height) / 2
  118. width: 2
  119. height: parent.width / 3.5
  120. color: enabled ? UM.Theme.getColor("text") : UM.Theme.getColor("text_disabled")
  121. }
  122. }
  123. }
  124. }