PerObjectSettingsPanel.qml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. import Cura 1.0 as Cura
  7. import ".."
  8. Item
  9. {
  10. id: base
  11. width: childrenRect.width
  12. height: childrenRect.height
  13. property var allCategoriesExceptSupport: [ "machine_settings", "resolution", "shell", "infill", "material", "speed",
  14. "travel", "cooling", "platform_adhesion", "dual", "meshfix", "blackmagic", "experimental"]
  15. readonly property string normalMeshType: ""
  16. readonly property string supportMeshType: "support_mesh"
  17. readonly property string cuttingMeshType: "cutting_mesh"
  18. readonly property string infillMeshType: "infill_mesh"
  19. readonly property string antiOverhangMeshType: "anti_overhang_mesh"
  20. property var currentMeshType: UM.ActiveTool.properties.getValue("MeshType")
  21. // Update the view every time the currentMeshType changes
  22. onCurrentMeshTypeChanged:
  23. {
  24. var type = currentMeshType
  25. // set checked state of mesh type buttons
  26. updateMeshTypeCheckedState(type)
  27. // update active type label
  28. for (var button in meshTypeButtons.children)
  29. {
  30. if (meshTypeButtons.children[button].checked)
  31. {
  32. meshTypeLabel.text = catalog.i18nc("@label", "Mesh Type") + ": " + meshTypeButtons.children[button].text
  33. break
  34. }
  35. }
  36. visibility_handler.addSkipResetSetting(currentMeshType)
  37. }
  38. function updateMeshTypeCheckedState(type)
  39. {
  40. // set checked state of mesh type buttons
  41. normalButton.checked = type === normalMeshType
  42. supportMeshButton.checked = type === supportMeshType
  43. overlapMeshButton.checked = type === infillMeshType || type === cuttingMeshType
  44. antiOverhangMeshButton.checked = type === antiOverhangMeshType
  45. }
  46. function setMeshType(type)
  47. {
  48. UM.ActiveTool.setProperty("MeshType", type)
  49. updateMeshTypeCheckedState(type)
  50. }
  51. UM.I18nCatalog { id: catalog; name: "cura"}
  52. Column
  53. {
  54. id: items
  55. anchors.top: parent.top;
  56. anchors.left: parent.left;
  57. spacing: UM.Theme.getSize("default_margin").height
  58. Row // Mesh type buttons
  59. {
  60. id: meshTypeButtons
  61. spacing: UM.Theme.getSize("default_margin").width
  62. UM.ToolbarButton
  63. {
  64. id: normalButton
  65. text: catalog.i18nc("@label", "Normal model")
  66. toolItem: UM.RecolorImage
  67. {
  68. source: UM.Theme.getIcon("Infill0")
  69. color: UM.Theme.getColor("icon")
  70. }
  71. property bool needBorder: true
  72. checkable: true
  73. onClicked: setMeshType(normalMeshType);
  74. z: 4
  75. }
  76. UM.ToolbarButton
  77. {
  78. id: supportMeshButton
  79. text: catalog.i18nc("@label", "Print as support")
  80. toolItem: UM.RecolorImage
  81. {
  82. source: UM.Theme.getIcon("MeshTypeSupport")
  83. color: UM.Theme.getColor("icon")
  84. }
  85. property bool needBorder: true
  86. checkable:true
  87. onClicked: setMeshType(supportMeshType)
  88. z: 3
  89. }
  90. UM.ToolbarButton
  91. {
  92. id: overlapMeshButton
  93. text: catalog.i18nc("@label", "Modify settings for overlaps")
  94. toolItem: UM.RecolorImage
  95. {
  96. source: UM.Theme.getIcon("MeshTypeIntersect")
  97. color: UM.Theme.getColor("icon")
  98. }
  99. property bool needBorder: true
  100. checkable:true
  101. onClicked: setMeshType(infillMeshType)
  102. z: 2
  103. }
  104. UM.ToolbarButton
  105. {
  106. id: antiOverhangMeshButton
  107. text: catalog.i18nc("@label", "Don't support overlaps")
  108. toolItem: UM.RecolorImage
  109. {
  110. source: UM.Theme.getIcon("BlockSupportOverlaps")
  111. color: UM.Theme.getColor("icon")
  112. }
  113. property bool needBorder: true
  114. checkable: true
  115. onClicked: setMeshType(antiOverhangMeshType)
  116. z: 1
  117. }
  118. }
  119. UM.Label
  120. {
  121. id: meshTypeLabel
  122. height: UM.Theme.getSize("setting").height
  123. }
  124. Cura.ComboBox
  125. {
  126. id: infillOnlyComboBox
  127. width: parent.width / 2 - UM.Theme.getSize("default_margin").width
  128. height: UM.Theme.getSize("setting_control").height
  129. textRole: "text"
  130. model: ListModel
  131. {
  132. id: infillOnlyComboBoxModel
  133. Component.onCompleted: {
  134. append({ text: catalog.i18nc("@item:inlistbox", "Infill mesh only") })
  135. append({ text: catalog.i18nc("@item:inlistbox", "Cutting mesh") })
  136. }
  137. }
  138. visible: currentMeshType === infillMeshType || currentMeshType === cuttingMeshType
  139. onActivated:
  140. {
  141. if (index == 0){
  142. setMeshType(infillMeshType)
  143. } else {
  144. setMeshType(cuttingMeshType)
  145. }
  146. }
  147. Binding
  148. {
  149. target: infillOnlyComboBox
  150. property: "currentIndex"
  151. value: currentMeshType === infillMeshType ? 0 : 1
  152. }
  153. }
  154. Column // List of selected Settings to override for the selected object
  155. {
  156. // This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
  157. // It kinda looks ugly otherwise (big panel, no content on it)
  158. id: currentSettings
  159. property int maximumHeight: 200 * screenScaleFactor
  160. height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("narrow_margin").height + UM.Theme.getSize("default_lining").height), maximumHeight)
  161. visible: currentMeshType != "anti_overhang_mesh"
  162. ListView
  163. {
  164. id: contents
  165. height: parent.height
  166. width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width
  167. ScrollBar.vertical: UM.ScrollBar {}
  168. clip: true
  169. spacing: UM.Theme.getSize("default_lining").height
  170. model: UM.SettingDefinitionsModel
  171. {
  172. id: addedSettingsModel
  173. containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: ""
  174. expanded: [ "*" ]
  175. filter:
  176. {
  177. if (printSequencePropertyProvider.properties.value == "one_at_a_time")
  178. {
  179. return {"settable_per_meshgroup": true}
  180. }
  181. return {"settable_per_mesh": true}
  182. }
  183. exclude:
  184. {
  185. var excluded_settings = [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
  186. if (currentMeshType == "support_mesh")
  187. {
  188. excluded_settings = excluded_settings.concat(base.allCategoriesExceptSupport)
  189. }
  190. return excluded_settings
  191. }
  192. visibilityHandler: Cura.PerObjectSettingVisibilityHandler
  193. {
  194. id: visibility_handler
  195. selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
  196. }
  197. // For some reason the model object is updated after removing him from the memory and
  198. // it happens only on Windows. For this reason, set the destroyed value manually.
  199. Component.onDestruction:
  200. {
  201. setDestroyed(true)
  202. }
  203. }
  204. delegate: Row
  205. {
  206. spacing: - UM.Theme.getSize("default_margin").width
  207. Loader
  208. {
  209. id: settingLoader
  210. width: UM.Theme.getSize("setting").width
  211. height: UM.Theme.getSize("section").height + UM.Theme.getSize("narrow_margin").height
  212. enabled: provider.properties.enabled === "True"
  213. property var definition: model
  214. property var settingDefinitionsModel: addedSettingsModel
  215. property var propertyProvider: provider
  216. property var globalPropertyProvider: inheritStackProvider
  217. property var externalResetHandler: false
  218. //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
  219. //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
  220. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
  221. asynchronous: model.type != "enum" && model.type != "extruder"
  222. onLoaded:
  223. {
  224. settingLoader.item.showRevertButton = false
  225. settingLoader.item.showInheritButton = false
  226. settingLoader.item.showLinkedSettingIcon = false
  227. settingLoader.item.doDepthIndentation = false
  228. settingLoader.item.doQualityUserSettingEmphasis = false
  229. }
  230. sourceComponent:
  231. {
  232. switch(model.type)
  233. {
  234. case "int":
  235. return settingTextField
  236. case "[int]":
  237. return settingTextField
  238. case "float":
  239. return settingTextField
  240. case "enum":
  241. return settingComboBox
  242. case "extruder":
  243. return settingExtruder
  244. case "optional_extruder":
  245. return settingOptionalExtruder
  246. case "bool":
  247. return settingCheckBox
  248. case "str":
  249. return settingTextField
  250. case "category":
  251. return settingCategory
  252. default:
  253. return settingUnknown
  254. }
  255. }
  256. }
  257. Button
  258. {
  259. width: Math.round(UM.Theme.getSize("setting").height / 2)
  260. height: UM.Theme.getSize("setting").height
  261. onClicked: addedSettingsModel.setVisible(model.key, false)
  262. background: Item
  263. {
  264. UM.RecolorImage
  265. {
  266. anchors.verticalCenter: parent.verticalCenter
  267. width: parent.width
  268. height: width
  269. sourceSize.height: width
  270. color: parent.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
  271. source: UM.Theme.getIcon("Minus")
  272. }
  273. }
  274. }
  275. // Specialty provider that only watches global_inherits (we can't filter on what property changed we get events
  276. // so we bypass that to make a dedicated provider).
  277. UM.SettingPropertyProvider
  278. {
  279. id: provider
  280. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  281. key: model.key
  282. watchedProperties: [ "value", "enabled", "validationState" ]
  283. storeIndex: 0
  284. removeUnusedValue: false
  285. }
  286. UM.SettingPropertyProvider
  287. {
  288. id: inheritStackProvider
  289. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  290. key: model.key
  291. watchedProperties: [ "limit_to_extruder" ]
  292. }
  293. Connections
  294. {
  295. target: inheritStackProvider
  296. function onPropertiesChanged() { provider.forcePropertiesChanged() }
  297. }
  298. Connections
  299. {
  300. target: UM.ActiveTool
  301. function onPropertiesChanged()
  302. {
  303. // the values cannot be bound with UM.ActiveTool.properties.getValue() calls,
  304. // so here we connect to the signal and update the those values.
  305. if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
  306. {
  307. const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId")
  308. if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
  309. {
  310. addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId
  311. }
  312. }
  313. if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
  314. {
  315. const containerId = UM.ActiveTool.properties.getValue("ContainerID")
  316. if (provider.containerStackId != containerId)
  317. {
  318. provider.containerStackId = containerId
  319. }
  320. if (inheritStackProvider.containerStackId != containerId)
  321. {
  322. inheritStackProvider.containerStackId = containerId
  323. }
  324. }
  325. }
  326. }
  327. }
  328. }
  329. }
  330. Cura.SecondaryButton
  331. {
  332. id: customiseSettingsButton;
  333. height: UM.Theme.getSize("setting_control").height;
  334. visible: currentSettings.visible
  335. text: catalog.i18nc("@action:button", "Select settings");
  336. onClicked:
  337. {
  338. settingPickDialog.visible = true;
  339. if (currentMeshType == "support_mesh")
  340. {
  341. settingPickDialog.additional_excluded_settings = base.allCategoriesExceptSupport;
  342. }
  343. else
  344. {
  345. settingPickDialog.additional_excluded_settings = []
  346. }
  347. }
  348. }
  349. }
  350. SettingPickDialog
  351. {
  352. id: settingPickDialog
  353. }
  354. UM.SettingPropertyProvider
  355. {
  356. id: machineExtruderCount
  357. containerStack: Cura.MachineManager.activeMachine
  358. key: "machine_extruder_count"
  359. watchedProperties: [ "value" ]
  360. storeIndex: 0
  361. }
  362. UM.SettingPropertyProvider
  363. {
  364. id: printSequencePropertyProvider
  365. containerStack: Cura.MachineManager.activeMachine
  366. key: "print_sequence"
  367. watchedProperties: [ "value" ]
  368. storeIndex: 0
  369. }
  370. Component
  371. {
  372. id: settingTextField
  373. Cura.SettingTextField { }
  374. }
  375. Component
  376. {
  377. id: settingComboBox
  378. Cura.SettingComboBox { }
  379. }
  380. Component
  381. {
  382. id: settingExtruder
  383. Cura.SettingExtruder { }
  384. }
  385. Component
  386. {
  387. id: settingOptionalExtruder
  388. Cura.SettingOptionalExtruder { }
  389. }
  390. Component
  391. {
  392. id: settingCheckBox
  393. Cura.SettingCheckBox { }
  394. }
  395. Component
  396. {
  397. id: settingCategory
  398. Cura.SettingCategory { }
  399. }
  400. Component
  401. {
  402. id: settingUnknown
  403. Cura.SettingUnknown { }
  404. }
  405. }