PerObjectSettingsPanel.qml 17 KB

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