PerObjectSettingsPanel.qml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. // Copyright (c) 2017 Ultimaker B.V.
  2. // Uranium is released under the terms of the LGPLv3 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 * screenScaleFactor
  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. // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
  118. // so we bypass that to make a dedicated provider).
  119. UM.SettingPropertyProvider
  120. {
  121. id: provider
  122. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  123. key: model.key
  124. watchedProperties: [ "value", "enabled", "validationState" ]
  125. storeIndex: 0
  126. removeUnusedValue: false
  127. }
  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. Connections
  136. {
  137. target: inheritStackProvider
  138. onPropertiesChanged:
  139. {
  140. provider.forcePropertiesChanged();
  141. }
  142. }
  143. Connections
  144. {
  145. target: UM.ActiveTool
  146. onPropertiesChanged:
  147. {
  148. // the values cannot be bound with UM.ActiveTool.properties.getValue() calls,
  149. // so here we connect to the signal and update the those values.
  150. if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
  151. {
  152. const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId");
  153. if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
  154. {
  155. addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId;
  156. }
  157. }
  158. if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
  159. {
  160. const containerId = UM.ActiveTool.properties.getValue("ContainerID");
  161. if (provider.containerStackId != containerId)
  162. {
  163. provider.containerStackId = containerId;
  164. }
  165. if (inheritStackProvider.containerStackId != containerId)
  166. {
  167. inheritStackProvider.containerStackId = containerId;
  168. }
  169. }
  170. }
  171. }
  172. }
  173. }
  174. }
  175. }
  176. Button
  177. {
  178. id: customise_settings_button;
  179. height: UM.Theme.getSize("setting").height;
  180. visible: parseInt(UM.Preferences.getValue("cura/active_mode")) == 1
  181. text: catalog.i18nc("@action:button", "Select settings");
  182. style: ButtonStyle
  183. {
  184. background: Rectangle
  185. {
  186. width: control.width;
  187. height: control.height;
  188. border.width: UM.Theme.getSize("default_lining").width;
  189. border.color: control.pressed ? UM.Theme.getColor("action_button_active_border") :
  190. control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border")
  191. color: control.pressed ? UM.Theme.getColor("action_button_active") :
  192. control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
  193. }
  194. label: Label
  195. {
  196. text: control.text;
  197. color: UM.Theme.getColor("setting_control_text");
  198. anchors.centerIn: parent
  199. }
  200. }
  201. onClicked: settingPickDialog.visible = true;
  202. Connections
  203. {
  204. target: UM.Preferences;
  205. onPreferenceChanged:
  206. {
  207. customise_settings_button.visible = parseInt(UM.Preferences.getValue("cura/active_mode"))
  208. }
  209. }
  210. }
  211. }
  212. UM.Dialog {
  213. id: settingPickDialog
  214. title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
  215. width: screenScaleFactor * 360;
  216. property string labelFilter: ""
  217. onVisibilityChanged:
  218. {
  219. // force updating the model to sync it with addedSettingsModel
  220. if(visible)
  221. {
  222. listview.model.forceUpdate()
  223. }
  224. }
  225. TextField {
  226. id: filter
  227. anchors {
  228. top: parent.top
  229. left: parent.left
  230. right: toggleShowAll.left
  231. rightMargin: UM.Theme.getSize("default_margin").width
  232. }
  233. placeholderText: catalog.i18nc("@label:textbox", "Filter...");
  234. onTextChanged:
  235. {
  236. if(text != "")
  237. {
  238. listview.model.filter = {"settable_per_mesh": true, "i18n_label": "*" + text}
  239. }
  240. else
  241. {
  242. listview.model.filter = {"settable_per_mesh": true}
  243. }
  244. }
  245. }
  246. CheckBox
  247. {
  248. id: toggleShowAll
  249. anchors {
  250. top: parent.top
  251. right: parent.right
  252. }
  253. text: catalog.i18nc("@label:checkbox", "Show all")
  254. checked: listview.model.showAll
  255. onClicked:
  256. {
  257. listview.model.showAll = checked;
  258. }
  259. }
  260. ScrollView
  261. {
  262. id: scrollView
  263. anchors
  264. {
  265. top: filter.bottom;
  266. left: parent.left;
  267. right: parent.right;
  268. bottom: parent.bottom;
  269. }
  270. ListView
  271. {
  272. id:listview
  273. model: UM.SettingDefinitionsModel
  274. {
  275. id: definitionsModel;
  276. containerId: Cura.MachineManager.activeDefinitionId
  277. filter:
  278. {
  279. "settable_per_mesh": true
  280. }
  281. visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
  282. expanded: [ "*" ]
  283. exclude: [ "machine_settings", "command_line_settings" ]
  284. }
  285. delegate:Loader
  286. {
  287. id: loader
  288. width: parent.width
  289. height: model.type != undefined ? UM.Theme.getSize("section").height : 0;
  290. property var definition: model
  291. property var settingDefinitionsModel: definitionsModel
  292. asynchronous: true
  293. source:
  294. {
  295. switch(model.type)
  296. {
  297. case "category":
  298. return "PerObjectCategory.qml"
  299. default:
  300. return "PerObjectItem.qml"
  301. }
  302. }
  303. }
  304. }
  305. }
  306. rightButtons: [
  307. Button {
  308. text: catalog.i18nc("@action:button", "Close");
  309. onClicked: {
  310. settingPickDialog.visible = false;
  311. }
  312. }
  313. ]
  314. }
  315. UM.SettingPropertyProvider
  316. {
  317. id: machineExtruderCount
  318. containerStackId: Cura.MachineManager.activeMachineId
  319. key: "machine_extruder_count"
  320. watchedProperties: [ "value" ]
  321. storeIndex: 0
  322. }
  323. SystemPalette { id: palette; }
  324. Component
  325. {
  326. id: settingTextField;
  327. Cura.SettingTextField { }
  328. }
  329. Component
  330. {
  331. id: settingComboBox;
  332. Cura.SettingComboBox { }
  333. }
  334. Component
  335. {
  336. id: settingExtruder;
  337. Cura.SettingExtruder { }
  338. }
  339. Component
  340. {
  341. id: settingOptionalExtruder
  342. Cura.SettingOptionalExtruder { }
  343. }
  344. Component
  345. {
  346. id: settingCheckBox;
  347. Cura.SettingCheckBox { }
  348. }
  349. Component
  350. {
  351. id: settingCategory;
  352. Cura.SettingCategory { }
  353. }
  354. Component
  355. {
  356. id: settingUnknown;
  357. Cura.SettingUnknown { }
  358. }
  359. }