PerObjectSettingsPanel.qml 17 KB

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