PerObjectSettingsPanel.qml 17 KB

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