PerObjectSettingsPanel.qml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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.ColorImage
  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.ColorImage
  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.ColorImage
  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.ColorImage
  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. forceHighlight: base.hovered
  131. model: ListModel
  132. {
  133. id: infillOnlyComboBoxModel
  134. Component.onCompleted: {
  135. append({ text: catalog.i18nc("@item:inlistbox", "Infill mesh only") })
  136. append({ text: catalog.i18nc("@item:inlistbox", "Cutting mesh") })
  137. }
  138. }
  139. visible: currentMeshType === infillMeshType || currentMeshType === cuttingMeshType
  140. onActivated:
  141. {
  142. setMeshType(index === 0 ? infillMeshType : cuttingMeshType);
  143. }
  144. Binding
  145. {
  146. target: infillOnlyComboBox
  147. property: "currentIndex"
  148. value: currentMeshType === infillMeshType ? 0 : 1
  149. }
  150. }
  151. Column // List of selected Settings to override for the selected object
  152. {
  153. // This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
  154. // It kinda looks ugly otherwise (big panel, no content on it)
  155. id: currentSettings
  156. property int maximumHeight: 200 * screenScaleFactor
  157. height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("narrow_margin").height + UM.Theme.getSize("default_lining").height), maximumHeight)
  158. visible: currentMeshType != "anti_overhang_mesh"
  159. ListView
  160. {
  161. id: contents
  162. height: parent.height
  163. width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width
  164. ScrollBar.vertical: UM.ScrollBar { id: scrollBar }
  165. clip: true
  166. spacing: UM.Theme.getSize("default_lining").height
  167. model: UM.SettingDefinitionsModel
  168. {
  169. id: addedSettingsModel
  170. containerId: Cura.MachineManager.activeMachine !== null ? Cura.MachineManager.activeMachine.definition.id: ""
  171. expanded: ["*"]
  172. filter:
  173. {
  174. if (printSequencePropertyProvider.properties.value === "one_at_a_time")
  175. {
  176. return { settable_per_meshgroup: true }
  177. }
  178. return { settable_per_meshgroup: true }
  179. }
  180. exclude:
  181. {
  182. const excluded_settings = ["support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh"]
  183. if (currentMeshType === "support_mesh")
  184. {
  185. excluded_settings = excluded_settings.concat(base.allCategoriesExceptSupport)
  186. }
  187. return excluded_settings
  188. }
  189. visibilityHandler: Cura.PerObjectSettingVisibilityHandler
  190. {
  191. id: visibility_handler
  192. selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
  193. }
  194. // For some reason the model object is updated after removing him from the memory and
  195. // it happens only on Windows. For this reason, set the destroyed value manually.
  196. Component.onDestruction:
  197. {
  198. setDestroyed(true)
  199. }
  200. }
  201. delegate: Row
  202. {
  203. spacing: UM.Theme.getSize("default_margin").width
  204. Loader
  205. {
  206. id: settingLoader
  207. width: UM.Theme.getSize("setting").width - removeButton.width - scrollBar.width
  208. enabled: provider.properties.enabled === "True"
  209. property var definition: model
  210. property var settingDefinitionsModel: addedSettingsModel
  211. property var propertyProvider: provider
  212. property var globalPropertyProvider: inheritStackProvider
  213. property var externalResetHandler: false
  214. //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
  215. //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
  216. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
  217. asynchronous: model.type !== "enum" && model.type !== "extruder"
  218. onLoaded:
  219. {
  220. settingLoader.item.showRevertButton = false
  221. settingLoader.item.showInheritButton = false
  222. settingLoader.item.showLinkedSettingIcon = false
  223. settingLoader.item.doDepthIndentation = false
  224. settingLoader.item.doQualityUserSettingEmphasis = false
  225. settingLoader.item.height = UM.Theme.getSize("setting").height + UM.Theme.getSize("narrow_margin").height
  226. }
  227. sourceComponent:
  228. {
  229. switch(model.type)
  230. {
  231. case "int":
  232. return settingTextField
  233. case "[int]":
  234. return settingTextField
  235. case "float":
  236. return settingTextField
  237. case "enum":
  238. return settingComboBox
  239. case "extruder":
  240. return settingExtruder
  241. case "optional_extruder":
  242. return settingOptionalExtruder
  243. case "bool":
  244. return settingCheckBox
  245. case "str":
  246. return settingTextField
  247. case "category":
  248. return settingCategory
  249. default:
  250. return settingUnknown
  251. }
  252. }
  253. }
  254. Button
  255. {
  256. id: removeButton
  257. width: UM.Theme.getSize("setting").height
  258. height: UM.Theme.getSize("setting").height + UM.Theme.getSize("narrow_margin").height
  259. onClicked: addedSettingsModel.setVisible(model.key, false)
  260. background: Item
  261. {
  262. UM.ColorImage
  263. {
  264. anchors.verticalCenter: parent.verticalCenter
  265. width: parent.width
  266. height: width
  267. color: parent.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
  268. source: UM.Theme.getIcon("Minus")
  269. }
  270. }
  271. }
  272. // Specialty provider that only watches global_inherits (we can't filter on what property changed we get events
  273. // so we bypass that to make a dedicated provider).
  274. UM.SettingPropertyProvider
  275. {
  276. id: provider
  277. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  278. key: model.key
  279. watchedProperties: [ "value", "enabled", "validationState" ]
  280. storeIndex: 0
  281. removeUnusedValue: false
  282. }
  283. UM.SettingPropertyProvider
  284. {
  285. id: inheritStackProvider
  286. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  287. key: model.key
  288. watchedProperties: [ "limit_to_extruder" ]
  289. }
  290. Connections
  291. {
  292. target: inheritStackProvider
  293. function onPropertiesChanged() { provider.forcePropertiesChanged() }
  294. }
  295. Connections
  296. {
  297. target: UM.ActiveTool
  298. function onPropertiesChanged()
  299. {
  300. // the values cannot be bound with UM.ActiveTool.properties.getValue() calls,
  301. // so here we connect to the signal and update the those values.
  302. if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
  303. {
  304. const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId")
  305. if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
  306. {
  307. addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId
  308. }
  309. }
  310. if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
  311. {
  312. const containerId = UM.ActiveTool.properties.getValue("ContainerID")
  313. if (provider.containerStackId !== containerId)
  314. {
  315. provider.containerStackId = containerId
  316. }
  317. if (inheritStackProvider.containerStackId !== containerId)
  318. {
  319. inheritStackProvider.containerStackId = containerId
  320. }
  321. }
  322. }
  323. }
  324. }
  325. }
  326. }
  327. Cura.SecondaryButton
  328. {
  329. id: customiseSettingsButton;
  330. height: UM.Theme.getSize("setting_control").height;
  331. visible: currentSettings.visible
  332. text: catalog.i18nc("@action:button", "Select settings");
  333. onClicked:
  334. {
  335. settingPickDialog.visible = true;
  336. if (currentMeshType === "support_mesh")
  337. {
  338. settingPickDialog.additional_excluded_settings = base.allCategoriesExceptSupport;
  339. }
  340. else
  341. {
  342. settingPickDialog.additional_excluded_settings = [];
  343. }
  344. }
  345. }
  346. }
  347. SettingPickDialog
  348. {
  349. id: settingPickDialog
  350. }
  351. UM.SettingPropertyProvider
  352. {
  353. id: machineExtruderCount
  354. containerStack: Cura.MachineManager.activeMachine
  355. key: "machine_extruder_count"
  356. watchedProperties: ["value"]
  357. storeIndex: 0
  358. }
  359. UM.SettingPropertyProvider
  360. {
  361. id: printSequencePropertyProvider
  362. containerStack: Cura.MachineManager.activeMachine
  363. key: "print_sequence"
  364. watchedProperties: ["value"]
  365. storeIndex: 0
  366. }
  367. Component { id: settingTextField; Cura.SettingTextField { } }
  368. Component { id: settingComboBox; Cura.SettingComboBox { } }
  369. Component { id: settingExtruder; Cura.SettingExtruder { } }
  370. Component { id: settingOptionalExtruder; Cura.SettingOptionalExtruder { } }
  371. Component { id: settingCheckBox; Cura.SettingCheckBox { } }
  372. Component { id: settingCategory; Cura.SettingCategory { } }
  373. Component { id: settingUnknown; Cura.SettingUnknown { } }
  374. }