MaterialView.qml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // Copyright (c) 2016 Ultimaker B.V.
  2. // Uranium is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.1
  4. import QtQuick.Controls 1.3
  5. import QtQuick.Dialogs 1.2
  6. import UM 1.2 as UM
  7. import Cura 1.0 as Cura
  8. TabView
  9. {
  10. id: base
  11. property QtObject properties;
  12. property bool editingEnabled: false;
  13. property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
  14. property real firstColumnWidth: width * 0.45
  15. property real secondColumnWidth: width * 0.45
  16. property string containerId: ""
  17. property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
  18. property double spoolLength: calculateSpoolLength()
  19. property real costPerMeter: calculateCostPerMeter()
  20. Tab
  21. {
  22. title: catalog.i18nc("@title","Information")
  23. anchors
  24. {
  25. leftMargin: UM.Theme.getSize("default_margin").width
  26. topMargin: UM.Theme.getSize("default_margin").height
  27. bottomMargin: UM.Theme.getSize("default_margin").height
  28. rightMargin: 0
  29. }
  30. ScrollView
  31. {
  32. anchors.fill: parent
  33. horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
  34. flickableItem.flickableDirection: Flickable.VerticalFlick
  35. Flow
  36. {
  37. id: containerGrid
  38. width: base.width;
  39. property real rowHeight: textField.height;
  40. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
  41. ReadOnlyTextField
  42. {
  43. id: displayNameTextField;
  44. width: base.secondColumnWidth;
  45. text: properties.name;
  46. readOnly: !base.editingEnabled;
  47. onEditingFinished: base.setName(properties.name, text)
  48. }
  49. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
  50. ReadOnlyTextField
  51. {
  52. id: textField;
  53. width: base.secondColumnWidth;
  54. text: properties.supplier;
  55. readOnly: !base.editingEnabled;
  56. onEditingFinished: base.setMetaDataEntry("brand", properties.supplier, text)
  57. }
  58. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
  59. ReadOnlyTextField
  60. {
  61. width: base.secondColumnWidth;
  62. text: properties.material_type;
  63. readOnly: !base.editingEnabled;
  64. onEditingFinished: base.setMetaDataEntry("material", properties.material_type, text)
  65. }
  66. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
  67. Row
  68. {
  69. width: base.secondColumnWidth;
  70. height: parent.rowHeight;
  71. spacing: UM.Theme.getSize("default_margin").width/2
  72. Rectangle
  73. {
  74. id: colorSelector
  75. color: properties.color_code
  76. width: colorLabel.height * 0.75
  77. height: colorLabel.height * 0.75
  78. border.width: UM.Theme.getSize("default_lining").height
  79. anchors.verticalCenter: parent.verticalCenter
  80. MouseArea { anchors.fill: parent; onClicked: colorDialog.open(); enabled: base.editingEnabled }
  81. }
  82. ReadOnlyTextField
  83. {
  84. id: colorLabel;
  85. text: properties.color_name;
  86. readOnly: !base.editingEnabled
  87. onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
  88. }
  89. ColorDialog { id: colorDialog; color: properties.color_code; onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color) }
  90. }
  91. Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
  92. Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
  93. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
  94. ReadOnlySpinBox
  95. {
  96. id: densitySpinBox
  97. width: base.secondColumnWidth
  98. value: properties.density
  99. decimals: 2
  100. suffix: " g/cm³"
  101. stepSize: 0.01
  102. readOnly: !base.editingEnabled
  103. onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
  104. onValueChanged: updateCostPerMeter()
  105. }
  106. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
  107. ReadOnlySpinBox
  108. {
  109. id: diameterSpinBox
  110. width: base.secondColumnWidth
  111. value: properties.diameter
  112. decimals: 2
  113. suffix: " mm"
  114. stepSize: 0.01
  115. readOnly: !base.editingEnabled
  116. onEditingFinished: base.setMetaDataEntry("properties/diameter", properties.diameter, value)
  117. onValueChanged: updateCostPerMeter()
  118. }
  119. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
  120. SpinBox
  121. {
  122. id: spoolCostSpinBox
  123. width: base.secondColumnWidth
  124. value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
  125. prefix: base.currency + " "
  126. decimals: 2
  127. maximumValue: 100000000
  128. onValueChanged: {
  129. base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
  130. updateCostPerMeter()
  131. }
  132. }
  133. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
  134. SpinBox
  135. {
  136. id: spoolWeightSpinBox
  137. width: base.secondColumnWidth
  138. value: base.getMaterialPreferenceValue(properties.guid, "spool_weight")
  139. suffix: " g"
  140. stepSize: 100
  141. decimals: 0
  142. maximumValue: 10000
  143. onValueChanged: {
  144. base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
  145. updateCostPerMeter()
  146. }
  147. }
  148. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
  149. Label
  150. {
  151. width: base.secondColumnWidth
  152. text: "~ %1 m".arg(Math.round(base.spoolLength))
  153. verticalAlignment: Qt.AlignVCenter
  154. height: parent.rowHeight
  155. }
  156. Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
  157. Label
  158. {
  159. width: base.secondColumnWidth
  160. text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
  161. verticalAlignment: Qt.AlignVCenter
  162. height: parent.rowHeight
  163. }
  164. Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
  165. Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
  166. ReadOnlyTextArea
  167. {
  168. text: properties.description;
  169. width: base.firstColumnWidth + base.secondColumnWidth
  170. wrapMode: Text.WordWrap
  171. readOnly: !base.editingEnabled;
  172. onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
  173. }
  174. Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") }
  175. ReadOnlyTextArea
  176. {
  177. text: properties.adhesion_info;
  178. width: base.firstColumnWidth + base.secondColumnWidth
  179. wrapMode: Text.WordWrap
  180. readOnly: !base.editingEnabled;
  181. onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
  182. }
  183. }
  184. function updateCostPerMeter()
  185. {
  186. base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
  187. base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
  188. }
  189. }
  190. }
  191. Tab
  192. {
  193. title: catalog.i18nc("@label", "Print settings")
  194. anchors
  195. {
  196. leftMargin: UM.Theme.getSize("default_margin").width
  197. topMargin: UM.Theme.getSize("default_margin").height
  198. bottomMargin: UM.Theme.getSize("default_margin").height
  199. rightMargin: 0
  200. }
  201. ScrollView
  202. {
  203. anchors.fill: parent;
  204. ListView
  205. {
  206. model: UM.SettingDefinitionsModel
  207. {
  208. containerId: Cura.MachineManager.activeDefinitionId
  209. visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
  210. expanded: ["*"]
  211. }
  212. delegate: UM.TooltipArea
  213. {
  214. width: childrenRect.width
  215. height: childrenRect.height
  216. text: model.description
  217. Label
  218. {
  219. id: label
  220. width: base.firstColumnWidth;
  221. height: spinBox.height
  222. text: model.label
  223. }
  224. ReadOnlySpinBox
  225. {
  226. id: spinBox
  227. anchors.left: label.right
  228. value: parseFloat(provider.properties.value);
  229. width: base.secondColumnWidth;
  230. readOnly: !base.editingEnabled
  231. suffix: model.unit
  232. maximumValue: 99999
  233. decimals: model.unit == "mm" ? 2 : 0
  234. onEditingFinished: provider.setPropertyValue("value", value)
  235. }
  236. UM.ContainerPropertyProvider { id: provider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key }
  237. }
  238. }
  239. }
  240. }
  241. function calculateSpoolLength(diameter, density, spoolWeight)
  242. {
  243. if(!diameter)
  244. {
  245. diameter = properties.diameter;
  246. }
  247. if(!density)
  248. {
  249. density = properties.density;
  250. }
  251. if(!spoolWeight)
  252. {
  253. spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight");
  254. }
  255. if (diameter == 0 || density == 0 || spoolWeight == 0)
  256. {
  257. return 0;
  258. }
  259. var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2
  260. var volume = (spoolWeight / density); // in cm3
  261. return volume / area; // in m
  262. }
  263. function calculateCostPerMeter(spoolCost)
  264. {
  265. if(!spoolCost)
  266. {
  267. spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost");
  268. }
  269. if (spoolLength == 0)
  270. {
  271. return 0;
  272. }
  273. return spoolCost / spoolLength;
  274. }
  275. // Tiny convenience function to check if a value really changed before trying to set it.
  276. function setMetaDataEntry(entry_name, old_value, new_value)
  277. {
  278. if(old_value != new_value)
  279. {
  280. Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value);
  281. }
  282. }
  283. function setMaterialPreferenceValue(material_guid, entry_name, new_value)
  284. {
  285. if(!(material_guid in materialPreferenceValues))
  286. {
  287. materialPreferenceValues[material_guid] = {};
  288. }
  289. if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value)
  290. {
  291. // value has not changed
  292. return
  293. }
  294. materialPreferenceValues[material_guid][entry_name] = new_value;
  295. // store preference
  296. UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues));
  297. }
  298. function getMaterialPreferenceValue(material_guid, entry_name)
  299. {
  300. if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid])
  301. {
  302. return materialPreferenceValues[material_guid][entry_name];
  303. }
  304. return 0;
  305. }
  306. function setName(old_value, new_value)
  307. {
  308. if(old_value != new_value)
  309. {
  310. Cura.ContainerManager.setContainerName(base.containerId, new_value);
  311. // update material name label. not so pretty, but it works
  312. materialProperties.name = new_value;
  313. }
  314. }
  315. }