SettingOptionalExtruder.qml 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright (c) 2022 Ultimaker B.V.
  2. // Cura is released under the terms of the LGPLv3 or higher.
  3. import QtQuick 2.7
  4. import QtQuick.Controls 2.0
  5. import UM 1.5 as UM
  6. import Cura 1.5 as Cura
  7. SettingItem
  8. {
  9. id: base
  10. property var focusItem: control
  11. // Somehow if we directory set control.model to CuraApplication.getExtrudersModelWithOptional()
  12. // and in the Connections.onModelChanged use control.model as a reference, it will complain about
  13. // non-existing properties such as "onModelChanged" and "getItem". I guess if we access the model
  14. // via "control.model", it gives back a generic/abstract model instance. To avoid this, we add
  15. // this extra property to keep the ExtrudersModel and use this in the rest of the code.
  16. property var extrudersWithOptionalModel: CuraApplication.getExtrudersModelWithOptional()
  17. contents: Cura.ComboBox
  18. {
  19. id: control
  20. anchors.fill: parent
  21. model: base.extrudersWithOptionalModel
  22. Connections
  23. {
  24. target: base.extrudersWithOptionalModel
  25. function onModelChanged() { control.color = base.extrudersWithOptionalModel.getItem(control.currentIndex).color }
  26. }
  27. textRole: "name"
  28. onActivated:
  29. {
  30. if (model.getItem(index).enabled)
  31. {
  32. forceActiveFocus();
  33. propertyProvider.setPropertyValue("value", model.getItem(index).index);
  34. }
  35. else
  36. {
  37. if (propertyProvider.properties.value == -1)
  38. {
  39. control.currentIndex = model.count - 1; // we know the last item is "Not overridden"
  40. }
  41. else
  42. {
  43. control.currentIndex = propertyProvider.properties.value; // revert to the old value
  44. }
  45. }
  46. }
  47. onActiveFocusChanged:
  48. {
  49. if(activeFocus)
  50. {
  51. base.focusReceived();
  52. }
  53. }
  54. Keys.onTabPressed:
  55. {
  56. base.setActiveFocusToNextSetting(true)
  57. }
  58. Keys.onBacktabPressed:
  59. {
  60. base.setActiveFocusToNextSetting(false)
  61. }
  62. Binding
  63. {
  64. target: control
  65. property: "currentIndex"
  66. value:
  67. {
  68. if(propertyProvider.properties.value == -1)
  69. {
  70. return control.model.items.length - 1
  71. }
  72. return propertyProvider.properties.value
  73. }
  74. // Sometimes when the value is already changed, the model is still being built.
  75. // The when clause ensures that the current index is not updated when this happens.
  76. when: control.model.items.length > 0
  77. }
  78. property string color: "transparent"
  79. Binding
  80. {
  81. // We override the color property's value when the ExtruderModel changes. So we need to use an
  82. // explicit binding here otherwise we do not handle value changes after the model changes.
  83. target: control
  84. property: "color"
  85. value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : "transparent"
  86. }
  87. indicator: UM.RecolorImage
  88. {
  89. id: downArrow
  90. x: control.width - width - control.rightPadding
  91. y: control.topPadding + Math.round((control.availableHeight - height) / 2)
  92. source: UM.Theme.getIcon("ChevronSingleDown")
  93. width: UM.Theme.getSize("standard_arrow").width
  94. height: UM.Theme.getSize("standard_arrow").height
  95. sourceSize.width: width + 5 * screenScaleFactor
  96. sourceSize.height: width + 5 * screenScaleFactor
  97. color: UM.Theme.getColor("setting_control_button")
  98. }
  99. background: UM.UnderlineBackground
  100. {
  101. color:
  102. {
  103. if (!enabled)
  104. {
  105. return UM.Theme.getColor("setting_control_disabled")
  106. }
  107. if (control.hovered || base.activeFocus)
  108. {
  109. return UM.Theme.getColor("setting_control_highlight")
  110. }
  111. return UM.Theme.getColor("setting_control")
  112. }
  113. liningColor:
  114. {
  115. if (!enabled)
  116. {
  117. return UM.Theme.getColor("setting_control_disabled_border")
  118. }
  119. if (control.hovered || control.activeFocus)
  120. {
  121. return UM.Theme.getColor("border_main")
  122. }
  123. return UM.Theme.getColor("border_field_light")
  124. }
  125. }
  126. contentItem: UM.Label
  127. {
  128. anchors.verticalCenter: parent.verticalCenter
  129. anchors.left: parent.left
  130. anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
  131. anchors.right: downArrow.left
  132. rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
  133. text: control.currentText
  134. textFormat: Text.PlainText
  135. color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
  136. elide: Text.ElideRight
  137. background: Rectangle
  138. {
  139. id: swatch
  140. height: Math.round(parent.height / 2)
  141. width: height
  142. radius: Math.round(width / 2)
  143. anchors.right: parent.right
  144. anchors.verticalCenter: parent.verticalCenter
  145. anchors.rightMargin: UM.Theme.getSize("thin_margin").width
  146. color: control.color
  147. }
  148. }
  149. popup: Popup
  150. {
  151. y: control.height - UM.Theme.getSize("default_lining").height
  152. width: control.width
  153. implicitHeight: contentItem.implicitHeight + 2 * UM.Theme.getSize("default_lining").width
  154. padding: UM.Theme.getSize("default_lining").width
  155. contentItem: ListView
  156. {
  157. implicitHeight: contentHeight
  158. ScrollBar.vertical: UM.ScrollBar {}
  159. clip: true
  160. model: control.popup.visible ? control.delegateModel : null
  161. currentIndex: control.highlightedIndex
  162. }
  163. background: Rectangle {
  164. color: UM.Theme.getColor("setting_control")
  165. border.color: UM.Theme.getColor("setting_control_border")
  166. }
  167. }
  168. delegate: ItemDelegate
  169. {
  170. width: control.width - 2 * UM.Theme.getSize("default_lining").width
  171. height: control.height
  172. highlighted: control.highlightedIndex == index
  173. contentItem: UM.Label
  174. {
  175. anchors.fill: parent
  176. anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
  177. anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
  178. text: model.name
  179. textFormat: Text.PlainText
  180. color:
  181. {
  182. if (model.enabled) {
  183. UM.Theme.getColor("setting_control_text")
  184. } else {
  185. UM.Theme.getColor("action_button_disabled_text")
  186. }
  187. }
  188. elide: Text.ElideRight
  189. rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
  190. background: Rectangle
  191. {
  192. id: swatch
  193. height: Math.round(parent.height / 2)
  194. width: height
  195. radius: Math.round(width / 2)
  196. anchors.right: parent.right
  197. anchors.verticalCenter: parent.verticalCenter
  198. anchors.rightMargin: UM.Theme.getSize("thin_margin").width
  199. color: control.model.getItem(index).color
  200. }
  201. }
  202. background: Rectangle
  203. {
  204. color: parent.highlighted ? UM.Theme.getColor("setting_control_highlight") : "transparent"
  205. }
  206. }
  207. }
  208. }