ComboBox.qml 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.10
  4. import QtQuick.Controls 2.3
  5. import UM 1.5 as UM
  6. import Cura 1.1 as Cura
  7. //
  8. // ComboBox with Cura styling.
  9. //
  10. ComboBox
  11. {
  12. id: control
  13. property var defaultTextOnEmptyModel: catalog.i18nc("@label", "No items to select from") // Text displayed in the combobox when the model is empty
  14. property var defaultTextOnEmptyIndex: "" // Text displayed in the combobox when the model has items but no item is selected
  15. property alias textFormat: contentLabel.textFormat
  16. property alias backgroundColor: background.color
  17. property bool forceHighlight: false
  18. enabled: delegateModel.count > 0
  19. onVisibleChanged: { popup.close() }
  20. states: [
  21. State
  22. {
  23. name: "disabled"
  24. when: !control.enabled
  25. PropertyChanges { target: background; color: UM.Theme.getColor("setting_control_disabled")}
  26. PropertyChanges { target: contentLabel; color: UM.Theme.getColor("setting_control_disabled_text")}
  27. },
  28. State
  29. {
  30. name: "active"
  31. when: control.activeFocus
  32. PropertyChanges
  33. {
  34. target: background
  35. borderColor: UM.Theme.getColor("text_field_border_active")
  36. liningColor: UM.Theme.getColor("text_field_border_active")
  37. }
  38. },
  39. State
  40. {
  41. name: "highlighted"
  42. when: (control.hovered && !control.activeFocus) || forceHighlight
  43. PropertyChanges
  44. {
  45. target: background
  46. liningColor: UM.Theme.getColor("text_field_border_hovered")
  47. }
  48. }
  49. ]
  50. background: UM.UnderlineBackground
  51. {
  52. id: background
  53. // Rectangle for highlighting when this combobox needs to pulse.
  54. Rectangle
  55. {
  56. anchors.fill: parent
  57. opacity: 0
  58. color: "transparent"
  59. border.color: UM.Theme.getColor("text_field_border_active")
  60. border.width: UM.Theme.getSize("default_lining").width
  61. SequentialAnimation on opacity
  62. {
  63. id: pulseAnimation
  64. running: false
  65. loops: 2
  66. PropertyAnimation
  67. {
  68. to: 1
  69. duration: 150
  70. }
  71. PropertyAnimation
  72. {
  73. to: 0
  74. duration : 150
  75. }
  76. }
  77. }
  78. }
  79. indicator: UM.ColorImage
  80. {
  81. id: downArrow
  82. x: control.width - width - control.rightPadding
  83. y: control.topPadding + Math.round((control.availableHeight - height) / 2)
  84. source: UM.Theme.getIcon("ChevronSingleDown")
  85. width: UM.Theme.getSize("standard_arrow").width
  86. height: UM.Theme.getSize("standard_arrow").height
  87. color: UM.Theme.getColor("setting_control_button")
  88. }
  89. contentItem: UM.Label
  90. {
  91. id: contentLabel
  92. leftPadding: UM.Theme.getSize("setting_unit_margin").width + UM.Theme.getSize("default_margin").width
  93. anchors.right: downArrow.left
  94. wrapMode: Text.NoWrap
  95. text:
  96. {
  97. if (control.delegateModel.count == 0)
  98. {
  99. return control.defaultTextOnEmptyModel != "" ? control.defaultTextOnEmptyModel : control.defaultTextOnEmptyIndex
  100. }
  101. else
  102. {
  103. return control.currentIndex == -1 ? control.defaultTextOnEmptyIndex : control.currentText
  104. }
  105. }
  106. textFormat: Text.PlainText
  107. color: control.currentIndex == -1 ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
  108. elide: Text.ElideRight
  109. }
  110. popup: Popup
  111. {
  112. y: control.height - UM.Theme.getSize("default_lining").height
  113. width: control.width
  114. implicitHeight: contentItem.implicitHeight + 2 * UM.Theme.getSize("default_lining").width
  115. bottomMargin: UM.Theme.getSize("default_margin").height
  116. padding: UM.Theme.getSize("default_lining").width
  117. contentItem: ListView
  118. {
  119. implicitHeight: contentHeight
  120. ScrollBar.vertical: UM.ScrollBar {}
  121. clip: true
  122. model: control.popup.visible ? control.delegateModel : null
  123. currentIndex: control.highlightedIndex
  124. }
  125. background: Rectangle
  126. {
  127. color: UM.Theme.getColor("setting_control")
  128. border.color: UM.Theme.getColor("setting_control_border")
  129. }
  130. }
  131. delegate: ItemDelegate
  132. {
  133. id: delegateItem
  134. width: control.width - 2 * UM.Theme.getSize("default_lining").width
  135. height: control.height
  136. highlighted: control.highlightedIndex == index
  137. text:
  138. // FIXME: Maybe there is a better way to do this. Check model and modelData doc page:
  139. // https://doc.qt.io/qt-5/qtquick-modelviewsdata-modelview.html
  140. {
  141. var _val = undefined
  142. if (typeof _val === 'undefined') // try to get textRole from "model".
  143. {
  144. _val = model[textRole]
  145. }
  146. if (typeof _val === 'undefined') // try to get textRole from "modelData" if it's still undefined.
  147. {
  148. _val = modelData[textRole]
  149. }
  150. return (typeof _val !== 'undefined') ? _val : ""
  151. }
  152. contentItem: UM.Label
  153. {
  154. id: delegateLabel
  155. // FIXME: Somehow the top/bottom anchoring is not correct on Linux and it results in invisible texts.
  156. anchors.fill: parent
  157. anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
  158. anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
  159. text: delegateItem.text
  160. textFormat: control.textFormat
  161. color: UM.Theme.getColor("setting_control_text")
  162. elide: Text.ElideRight
  163. wrapMode: Text.NoWrap
  164. }
  165. background: UM.TooltipArea
  166. {
  167. Rectangle
  168. {
  169. color: delegateItem.highlighted ? UM.Theme.getColor("setting_control_highlight") : "transparent"
  170. anchors.fill: parent
  171. }
  172. text: delegateLabel.truncated ? delegateItem.text : ""
  173. }
  174. }
  175. function pulse()
  176. {
  177. pulseAnimation.restart();
  178. }
  179. }