PerObjectSettingsPanel.qml 17 KB

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