PerObjectSettingsPanel.qml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  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 QtQuick.Window 2.2
  7. import UM 1.2 as UM
  8. import Cura 1.0 as Cura
  9. import ".."
  10. Item {
  11. id: base;
  12. UM.I18nCatalog { id: catalog; name: "cura"; }
  13. width: childrenRect.width;
  14. height: childrenRect.height;
  15. Column
  16. {
  17. id: items
  18. anchors.top: parent.top;
  19. anchors.left: parent.left;
  20. spacing: UM.Theme.getSize("default_margin").height
  21. Row
  22. {
  23. spacing: UM.Theme.getSize("default_margin").width
  24. Label
  25. {
  26. text: catalog.i18nc("@label","Mesh Type")
  27. font: UM.Theme.getFont("default")
  28. color: UM.Theme.getColor("text")
  29. height: UM.Theme.getSize("setting").height
  30. verticalAlignment: Text.AlignVCenter
  31. }
  32. ComboBox
  33. {
  34. id: meshTypeSelection
  35. style: UM.Theme.styles.combobox
  36. onActivated: {
  37. UM.ActiveTool.setProperty("MeshType", model.get(index).type)
  38. }
  39. model: ListModel
  40. {
  41. id: meshTypeModel
  42. Component.onCompleted:
  43. {
  44. meshTypeModel.append({
  45. type: "",
  46. text: catalog.i18nc("@label", "Normal model")
  47. });
  48. meshTypeModel.append({
  49. type: "support_mesh",
  50. text: catalog.i18nc("@label", "Print as support")
  51. });
  52. meshTypeModel.append({
  53. type: "anti_overhang_mesh",
  54. text: catalog.i18nc("@label", "Don't support overlap with other models")
  55. });
  56. meshTypeModel.append({
  57. type: "cutting_mesh",
  58. text: catalog.i18nc("@label", "Modify settings for overlap with other models")
  59. });
  60. meshTypeModel.append({
  61. type: "infill_mesh",
  62. text: catalog.i18nc("@label", "Modify settings for infill of other models")
  63. });
  64. meshTypeSelection.updateCurrentIndex();
  65. }
  66. }
  67. function updateCurrentIndex()
  68. {
  69. var mesh_type = UM.ActiveTool.properties.getValue("MeshType");
  70. for(var index=0; index < meshTypeSelection.model.count; index++)
  71. {
  72. if(meshTypeSelection.model.get(index).type == mesh_type)
  73. {
  74. meshTypeSelection.currentIndex = index;
  75. return;
  76. }
  77. }
  78. meshTypeSelection.currentIndex = 0;
  79. }
  80. }
  81. Connections
  82. {
  83. target: UM.Selection
  84. onSelectionChanged: meshTypeSelection.updateCurrentIndex()
  85. }
  86. }
  87. Column
  88. {
  89. // This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
  90. // It kinda looks ugly otherwise (big panel, no content on it)
  91. id: currentSettings
  92. property int maximumHeight: 200 * screenScaleFactor
  93. height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight)
  94. visible: ["support_mesh", "anti_overhang_mesh"].indexOf(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type) == -1
  95. ScrollView
  96. {
  97. height: parent.height
  98. width: UM.Theme.getSize("setting").width + UM.Theme.getSize("default_margin").width
  99. style: UM.Theme.styles.scrollview
  100. ListView
  101. {
  102. id: contents
  103. spacing: UM.Theme.getSize("default_lining").height
  104. model: UM.SettingDefinitionsModel
  105. {
  106. id: addedSettingsModel;
  107. containerId: Cura.MachineManager.activeDefinitionId
  108. expanded: [ "*" ]
  109. exclude: [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
  110. visibilityHandler: Cura.PerObjectSettingVisibilityHandler
  111. {
  112. selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId")
  113. }
  114. }
  115. delegate: Row
  116. {
  117. spacing: - UM.Theme.getSize("default_margin").width
  118. Loader
  119. {
  120. id: settingLoader
  121. width: UM.Theme.getSize("setting").width
  122. height: UM.Theme.getSize("section").height
  123. property var definition: model
  124. property var settingDefinitionsModel: addedSettingsModel
  125. property var propertyProvider: provider
  126. property var globalPropertyProvider: inheritStackProvider
  127. property var externalResetHandler: false
  128. //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
  129. //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
  130. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
  131. asynchronous: model.type != "enum" && model.type != "extruder"
  132. onLoaded: {
  133. settingLoader.item.showRevertButton = false
  134. settingLoader.item.showInheritButton = false
  135. settingLoader.item.showLinkedSettingIcon = false
  136. settingLoader.item.doDepthIndentation = false
  137. settingLoader.item.doQualityUserSettingEmphasis = false
  138. }
  139. sourceComponent:
  140. {
  141. switch(model.type)
  142. {
  143. case "int":
  144. return settingTextField
  145. case "[int]":
  146. return settingTextField
  147. case "float":
  148. return settingTextField
  149. case "enum":
  150. return settingComboBox
  151. case "extruder":
  152. return settingExtruder
  153. case "optional_extruder":
  154. return settingOptionalExtruder
  155. case "bool":
  156. return settingCheckBox
  157. case "str":
  158. return settingTextField
  159. case "category":
  160. return settingCategory
  161. default:
  162. return settingUnknown
  163. }
  164. }
  165. }
  166. Button
  167. {
  168. width: Math.floor(UM.Theme.getSize("setting").height / 2)
  169. height: UM.Theme.getSize("setting").height
  170. onClicked: addedSettingsModel.setVisible(model.key, false)
  171. style: ButtonStyle
  172. {
  173. background: Item
  174. {
  175. UM.RecolorImage
  176. {
  177. anchors.verticalCenter: parent.verticalCenter
  178. width: parent.width
  179. height: width
  180. sourceSize.width: width
  181. sourceSize.height: width
  182. color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
  183. source: UM.Theme.getIcon("minus")
  184. }
  185. }
  186. }
  187. }
  188. // Specialty provider that only watches global_inherits (we cant filter on what property changed we get events
  189. // so we bypass that to make a dedicated provider).
  190. UM.SettingPropertyProvider
  191. {
  192. id: provider
  193. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  194. key: model.key
  195. watchedProperties: [ "value", "enabled", "validationState" ]
  196. storeIndex: 0
  197. removeUnusedValue: false
  198. }
  199. UM.SettingPropertyProvider
  200. {
  201. id: inheritStackProvider
  202. containerStackId: UM.ActiveTool.properties.getValue("ContainerID")
  203. key: model.key
  204. watchedProperties: [ "limit_to_extruder" ]
  205. }
  206. Connections
  207. {
  208. target: inheritStackProvider
  209. onPropertiesChanged:
  210. {
  211. provider.forcePropertiesChanged();
  212. }
  213. }
  214. Connections
  215. {
  216. target: UM.ActiveTool
  217. onPropertiesChanged:
  218. {
  219. // the values cannot be bound with UM.ActiveTool.properties.getValue() calls,
  220. // so here we connect to the signal and update the those values.
  221. if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined")
  222. {
  223. const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId");
  224. if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
  225. {
  226. addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId;
  227. }
  228. }
  229. if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined")
  230. {
  231. const containerId = UM.ActiveTool.properties.getValue("ContainerID");
  232. if (provider.containerStackId != containerId)
  233. {
  234. provider.containerStackId = containerId;
  235. }
  236. if (inheritStackProvider.containerStackId != containerId)
  237. {
  238. inheritStackProvider.containerStackId = containerId;
  239. }
  240. }
  241. }
  242. }
  243. }
  244. }
  245. }
  246. }
  247. Button
  248. {
  249. id: customiseSettingsButton;
  250. height: UM.Theme.getSize("setting_control").height;
  251. visible: currentSettings.visible
  252. text: catalog.i18nc("@action:button", "Select settings");
  253. style: ButtonStyle
  254. {
  255. background: Rectangle
  256. {
  257. width: control.width;
  258. height: control.height;
  259. border.width: UM.Theme.getSize("default_lining").width;
  260. border.color: control.pressed ? UM.Theme.getColor("action_button_active_border") :
  261. control.hovered ? UM.Theme.getColor("action_button_hovered_border") : UM.Theme.getColor("action_button_border")
  262. color: control.pressed ? UM.Theme.getColor("action_button_active") :
  263. control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
  264. }
  265. label: Label
  266. {
  267. text: control.text;
  268. color: UM.Theme.getColor("setting_control_text");
  269. font: UM.Theme.getFont("default")
  270. anchors.centerIn: parent
  271. }
  272. }
  273. onClicked: settingPickDialog.visible = true;
  274. }
  275. }
  276. UM.Dialog {
  277. id: settingPickDialog
  278. title: catalog.i18nc("@title:window", "Select Settings to Customize for this model")
  279. width: screenScaleFactor * 360;
  280. property string labelFilter: ""
  281. onVisibilityChanged:
  282. {
  283. // force updating the model to sync it with addedSettingsModel
  284. if(visible)
  285. {
  286. // Set skip setting, it will prevent from resetting selected mesh_type
  287. contents.model.visibilityHandler.addSkipResetSetting(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type)
  288. listview.model.forceUpdate()
  289. }
  290. }
  291. TextField {
  292. id: filter
  293. anchors {
  294. top: parent.top
  295. left: parent.left
  296. right: toggleShowAll.left
  297. rightMargin: UM.Theme.getSize("default_margin").width
  298. }
  299. placeholderText: catalog.i18nc("@label:textbox", "Filter...");
  300. onTextChanged:
  301. {
  302. if(text != "")
  303. {
  304. listview.model.filter = {"settable_per_mesh": true, "i18n_label": "*" + text}
  305. }
  306. else
  307. {
  308. listview.model.filter = {"settable_per_mesh": true}
  309. }
  310. }
  311. }
  312. CheckBox
  313. {
  314. id: toggleShowAll
  315. anchors {
  316. top: parent.top
  317. right: parent.right
  318. }
  319. text: catalog.i18nc("@label:checkbox", "Show all")
  320. checked: listview.model.showAll
  321. onClicked:
  322. {
  323. listview.model.showAll = checked;
  324. }
  325. }
  326. ScrollView
  327. {
  328. id: scrollView
  329. anchors
  330. {
  331. top: filter.bottom;
  332. left: parent.left;
  333. right: parent.right;
  334. bottom: parent.bottom;
  335. }
  336. ListView
  337. {
  338. id:listview
  339. model: UM.SettingDefinitionsModel
  340. {
  341. id: definitionsModel;
  342. containerId: Cura.MachineManager.activeDefinitionId
  343. filter:
  344. {
  345. "settable_per_mesh": true
  346. }
  347. visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
  348. expanded: [ "*" ]
  349. exclude: [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
  350. }
  351. delegate:Loader
  352. {
  353. id: loader
  354. width: parent.width
  355. height: model.type != undefined ? UM.Theme.getSize("section").height : 0;
  356. property var definition: model
  357. property var settingDefinitionsModel: definitionsModel
  358. asynchronous: true
  359. source:
  360. {
  361. switch(model.type)
  362. {
  363. case "category":
  364. return "PerObjectCategory.qml"
  365. default:
  366. return "PerObjectItem.qml"
  367. }
  368. }
  369. }
  370. }
  371. }
  372. rightButtons: [
  373. Button {
  374. text: catalog.i18nc("@action:button", "Close");
  375. onClicked: {
  376. settingPickDialog.visible = false;
  377. }
  378. }
  379. ]
  380. }
  381. UM.SettingPropertyProvider
  382. {
  383. id: machineExtruderCount
  384. containerStackId: Cura.MachineManager.activeMachineId
  385. key: "machine_extruder_count"
  386. watchedProperties: [ "value" ]
  387. storeIndex: 0
  388. }
  389. SystemPalette { id: palette; }
  390. Component
  391. {
  392. id: settingTextField;
  393. Cura.SettingTextField { }
  394. }
  395. Component
  396. {
  397. id: settingComboBox;
  398. Cura.SettingComboBox { }
  399. }
  400. Component
  401. {
  402. id: settingExtruder;
  403. Cura.SettingExtruder { }
  404. }
  405. Component
  406. {
  407. id: settingOptionalExtruder
  408. Cura.SettingOptionalExtruder { }
  409. }
  410. Component
  411. {
  412. id: settingCheckBox;
  413. Cura.SettingCheckBox { }
  414. }
  415. Component
  416. {
  417. id: settingCategory;
  418. Cura.SettingCategory { }
  419. }
  420. Component
  421. {
  422. id: settingUnknown;
  423. Cura.SettingUnknown { }
  424. }
  425. }