PerObjectSettingsPanel.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // Copyright (c) 2017 Ultimaker B.V.
  2. // Uranium is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 1.2
  5. import QtQuick.Controls.Styles 1.2
  6. import QtQuick.Window 2.2
  7. import UM 1.2 as UM
  8. import Cura 1.0 as Cura
  9. import ".."
  10. Item {
  11. id: base;
  12. UM.I18nCatalog { id: catalog; name: "cura"; }
  13. width: childrenRect.width;
  14. height: childrenRect.height;
  15. Column
  16. {
  17. id: items
  18. anchors.top: parent.top;
  19. anchors.left: parent.left;
  20. spacing: UM.Theme.getSize("default_margin").height
  21. Column
  22. {
  23. // This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
  24. // It kinda looks ugly otherwise (big panel, no content on it)
  25. property int maximumHeight: 200 * Screen.devicePixelRatio
  26. height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight)
  27. ScrollView
  28. {
  29. height: parent.height
  30. width: UM.Theme.getSize("setting").width + UM.Theme.getSize("setting").height
  31. style: UM.Theme.styles.scrollview
  32. ListView
  33. {
  34. id: contents
  35. spacing: UM.Theme.getSize("default_lining").height
  36. model: UM.SettingDefinitionsModel
  37. {
  38. id: addedSettingsModel;
  39. containerId: Cura.MachineManager.activeDefinitionId
  40. expanded: [ "*" ]
  41. visibilityHandler: Cura.PerObjectSettingVisibilityHandler
  42. {
  43. selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
  44. }
  45. }
  46. delegate: Row
  47. {
  48. Loader
  49. {
  50. id: settingLoader
  51. width: UM.Theme.getSize("setting").width
  52. height: UM.Theme.getSize("section").height
  53. property var definition: model
  54. property var settingDefinitionsModel: addedSettingsModel
  55. property var propertyProvider: provider
  56. property var globalPropertyProvider: inheritStackProvider
  57. //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
  58. //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
  59. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
  60. asynchronous: model.type != "enum" && model.type != "extruder"
  61. onLoaded: {
  62. settingLoader.item.showRevertButton = false
  63. settingLoader.item.showInheritButton = false
  64. settingLoader.item.showLinkedSettingIcon = false
  65. settingLoader.item.doDepthIndentation = false
  66. settingLoader.item.doQualityUserSettingEmphasis = false
  67. }
  68. sourceComponent:
  69. {
  70. switch(model.type)
  71. {
  72. case "int":
  73. return settingTextField
  74. case "[int]":
  75. return settingTextField
  76. case "float":
  77. return settingTextField
  78. case "enum":
  79. return settingComboBox
  80. case "extruder":
  81. return settingExtruder
  82. case "optional_extruder":
  83. return settingOptionalExtruder
  84. case "bool":
  85. return settingCheckBox
  86. case "str":
  87. return settingTextField
  88. case "category":
  89. return settingCategory
  90. default:
  91. return settingUnknown
  92. }
  93. }
  94. }
  95. Button
  96. {
  97. width: (UM.Theme.getSize("setting").height / 2) | 0
  98. height: UM.Theme.getSize("setting").height
  99. onClicked: addedSettingsModel.setVisible(model.key, false)
  100. style: ButtonStyle
  101. {
  102. background: Item
  103. {
  104. UM.RecolorImage
  105. {
  106. anchors.verticalCenter: parent.verticalCenter
  107. width: parent.width
  108. height: parent.height / 2
  109. sourceSize.width: width
  110. sourceSize.height: width
  111. color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
  112. source: UM.Theme.getIcon("minus")
  113. }
  114. }
  115. }
  116. }
  117. UM.SettingPropertyProvider
  118. {
  119. id: provider
  120. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  121. key: model.key
  122. watchedProperties: [ "value", "enabled", "validationState" ]
  123. storeIndex: 0
  124. removeUnusedValue: false
  125. }
  126. // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
  127. // so we bypass that to make a dedicated provider).
  128. UM.SettingPropertyProvider
  129. {
  130. id: inheritStackProvider
  131. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  132. key: model.key
  133. watchedProperties: [ "limit_to_extruder" ]
  134. }
  135. Binding
  136. {
  137. target: provider
  138. property: "containerStackId"
  139. when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0);
  140. value:
  141. {
  142. // associate this binding with Cura.MachineManager.activeMachineId in the beginning so this
  143. // binding will be triggered when activeMachineId is changed too.
  144. // Otherwise, if this value only depends on the extruderIds, it won't get updated when the
  145. // machine gets changed.
  146. var activeMachineId = Cura.MachineManager.activeMachineId;
  147. if(!model.settable_per_extruder || machineExtruderCount.properties.value == 1)
  148. {
  149. //Not settable per extruder or there only is global, so we must pick global.
  150. return activeMachineId;
  151. }
  152. if(inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0)
  153. {
  154. //We have limit_to_extruder, so pick that stack.
  155. return ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
  156. }
  157. if(ExtruderManager.activeExtruderStackId)
  158. {
  159. //We're on an extruder tab. Pick the current extruder.
  160. return ExtruderManager.activeExtruderStackId;
  161. }
  162. //No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
  163. return activeMachineId;
  164. }
  165. }
  166. }
  167. }
  168. }
  169. }
  170. Button
  171. {
  172. id: customise_settings_button;
  173. height: UM.Theme.getSize("setting").height;
  174. visible: parseInt(UM.Preferences.getValue("cura/active_mode")) == 1
  175. text: catalog.i18nc("@action:button", "Select settings");
  176. style: ButtonStyle
  177. {
  178. background: Rectangle
  179. {
  180. width: control.width;
  181. height: control.height;
  182. border.width: UM.Theme.getSize("default_lining").width;
  183. border.color: control.pressed ? UM.Theme.getColor("action_button_active_border") :
  184. control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border")
  185. color: control.pressed ? UM.Theme.getColor("action_button_active") :
  186. control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
  187. }
  188. label: Label
  189. {
  190. text: control.text;
  191. color: UM.Theme.getColor("setting_control_text");
  192. anchors.centerIn: parent
  193. }
  194. }
  195. onClicked: settingPickDialog.visible = true;
  196. Connections
  197. {
  198. target: UM.Preferences;
  199. onPreferenceChanged:
  200. {
  201. customise_settings_button.visible = parseInt(UM.Preferences.getValue("cura/active_mode"))
  202. }
  203. }
  204. }
  205. }
  206. UM.Dialog {
  207. id: settingPickDialog
  208. title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
  209. width: Screen.devicePixelRatio * 360;
  210. property string labelFilter: ""
  211. onVisibilityChanged:
  212. {
  213. // force updating the model to sync it with addedSettingsModel
  214. if(visible)
  215. {
  216. listview.model.forceUpdate()
  217. }
  218. }
  219. TextField {
  220. id: filter
  221. anchors {
  222. top: parent.top
  223. left: parent.left
  224. right: toggleShowAll.left
  225. rightMargin: UM.Theme.getSize("default_margin").width
  226. }
  227. placeholderText: catalog.i18nc("@label:textbox", "Filter...");
  228. onTextChanged:
  229. {
  230. if(text != "")
  231. {
  232. listview.model.filter = {"settable_per_mesh": true, "i18n_label": "*" + text}
  233. }
  234. else
  235. {
  236. listview.model.filter = {"settable_per_mesh": true}
  237. }
  238. }
  239. }
  240. CheckBox
  241. {
  242. id: toggleShowAll
  243. anchors {
  244. top: parent.top
  245. right: parent.right
  246. }
  247. text: catalog.i18nc("@label:checkbox", "Show all")
  248. checked: listview.model.showAll
  249. onClicked:
  250. {
  251. listview.model.showAll = checked;
  252. }
  253. }
  254. ScrollView
  255. {
  256. id: scrollView
  257. anchors
  258. {
  259. top: filter.bottom;
  260. left: parent.left;
  261. right: parent.right;
  262. bottom: parent.bottom;
  263. }
  264. ListView
  265. {
  266. id:listview
  267. model: UM.SettingDefinitionsModel
  268. {
  269. id: definitionsModel;
  270. containerId: Cura.MachineManager.activeDefinitionId
  271. filter:
  272. {
  273. "settable_per_mesh": true
  274. }
  275. visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
  276. expanded: [ "*" ]
  277. exclude: [ "machine_settings", "command_line_settings" ]
  278. }
  279. delegate:Loader
  280. {
  281. id: loader
  282. width: parent.width
  283. height: model.type != undefined ? UM.Theme.getSize("section").height : 0;
  284. property var definition: model
  285. property var settingDefinitionsModel: definitionsModel
  286. asynchronous: true
  287. source:
  288. {
  289. switch(model.type)
  290. {
  291. case "category":
  292. return "PerObjectCategory.qml"
  293. default:
  294. return "PerObjectItem.qml"
  295. }
  296. }
  297. }
  298. }
  299. }
  300. rightButtons: [
  301. Button {
  302. text: catalog.i18nc("@action:button", "Close");
  303. onClicked: {
  304. settingPickDialog.visible = false;
  305. }
  306. }
  307. ]
  308. }
  309. UM.SettingPropertyProvider
  310. {
  311. id: machineExtruderCount
  312. containerStackId: Cura.MachineManager.activeMachineId
  313. key: "machine_extruder_count"
  314. watchedProperties: [ "value" ]
  315. storeIndex: 0
  316. }
  317. SystemPalette { id: palette; }
  318. Component
  319. {
  320. id: settingTextField;
  321. Cura.SettingTextField { }
  322. }
  323. Component
  324. {
  325. id: settingComboBox;
  326. Cura.SettingComboBox { }
  327. }
  328. Component
  329. {
  330. id: settingExtruder;
  331. Cura.SettingExtruder { }
  332. }
  333. Component
  334. {
  335. id: settingOptionalExtruder
  336. Cura.SettingOptionalExtruder { }
  337. }
  338. Component
  339. {
  340. id: settingCheckBox;
  341. Cura.SettingCheckBox { }
  342. }
  343. Component
  344. {
  345. id: settingCategory;
  346. Cura.SettingCategory { }
  347. }
  348. Component
  349. {
  350. id: settingUnknown;
  351. Cura.SettingUnknown { }
  352. }
  353. }