LayerView.qml 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. // Copyright (c) 2015 Ultimaker B.V.
  2. // Cura is released under the terms of the AGPLv3 or higher.
  3. import QtQuick 2.2
  4. import QtQuick.Controls 1.2
  5. import QtQuick.Layouts 1.1
  6. import QtQuick.Controls.Styles 1.1
  7. import UM 1.0 as UM
  8. import Cura 1.0 as Cura
  9. Item
  10. {
  11. id: base
  12. width: {
  13. if (UM.LayerView.compatibilityMode) {
  14. return UM.Theme.getSize("layerview_menu_size_compatibility").width;
  15. } else {
  16. return UM.Theme.getSize("layerview_menu_size").width;
  17. }
  18. }
  19. height: {
  20. if (UM.LayerView.compatibilityMode) {
  21. return UM.Theme.getSize("layerview_menu_size_compatibility").height;
  22. } else {
  23. return UM.Theme.getSize("layerview_menu_size").height + UM.LayerView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height)
  24. }
  25. }
  26. property var buttonTarget: {
  27. var force_binding = parent.y; // ensure this gets reevaluated when the panel moves
  28. return base.mapFromItem(parent.parent, parent.buttonTarget.x, parent.buttonTarget.y);
  29. }
  30. UM.PointingRectangle {
  31. id: layerViewMenu
  32. anchors.left: parent.left
  33. anchors.top: parent.top
  34. width: parent.width
  35. height: parent.height
  36. z: slider.z - 1
  37. color: UM.Theme.getColor("tool_panel_background")
  38. borderWidth: UM.Theme.getSize("default_lining").width
  39. borderColor: UM.Theme.getColor("lining")
  40. target: parent.buttonTarget
  41. arrowSize: UM.Theme.getSize("default_arrow").width
  42. ColumnLayout {
  43. id: view_settings
  44. property var extruder_opacities: UM.Preferences.getValue("layerview/extruder_opacities").split("|")
  45. property bool show_travel_moves: UM.Preferences.getValue("layerview/show_travel_moves")
  46. property bool show_helpers: UM.Preferences.getValue("layerview/show_helpers")
  47. property bool show_skin: UM.Preferences.getValue("layerview/show_skin")
  48. property bool show_infill: UM.Preferences.getValue("layerview/show_infill")
  49. // if we are in compatibility mode, we only show the "line type"
  50. property bool show_legend: UM.LayerView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type") == 1
  51. property bool only_show_top_layers: UM.Preferences.getValue("view/only_show_top_layers")
  52. property int top_layer_count: UM.Preferences.getValue("view/top_layer_count")
  53. anchors.top: parent.top
  54. anchors.topMargin: UM.Theme.getSize("default_margin").height
  55. anchors.left: parent.left
  56. anchors.leftMargin: UM.Theme.getSize("default_margin").width
  57. spacing: UM.Theme.getSize("layerview_row_spacing").height
  58. Label
  59. {
  60. id: layersLabel
  61. anchors.left: parent.left
  62. text: catalog.i18nc("@label","View Mode: Layers")
  63. font.bold: true
  64. color: UM.Theme.getColor("text")
  65. }
  66. Label
  67. {
  68. id: spaceLabel
  69. anchors.left: parent.left
  70. text: " "
  71. font.pointSize: 0.5
  72. }
  73. Label
  74. {
  75. id: layerViewTypesLabel
  76. anchors.left: parent.left
  77. text: catalog.i18nc("@label","Color scheme")
  78. visible: !UM.LayerView.compatibilityMode
  79. Layout.fillWidth: true
  80. color: UM.Theme.getColor("text")
  81. }
  82. ListModel // matches LayerView.py
  83. {
  84. id: layerViewTypes
  85. }
  86. Component.onCompleted:
  87. {
  88. layerViewTypes.append({
  89. text: catalog.i18nc("@label:listbox", "Material Color"),
  90. type_id: 0
  91. })
  92. layerViewTypes.append({
  93. text: catalog.i18nc("@label:listbox", "Line Type"),
  94. type_id: 1 // these ids match the switching in the shader
  95. })
  96. }
  97. ComboBox
  98. {
  99. id: layerTypeCombobox
  100. anchors.left: parent.left
  101. Layout.fillWidth: true
  102. Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
  103. model: layerViewTypes
  104. visible: !UM.LayerView.compatibilityMode
  105. style: UM.Theme.styles.combobox
  106. onActivated:
  107. {
  108. UM.Preferences.setValue("layerview/layer_view_type", index);
  109. }
  110. Component.onCompleted:
  111. {
  112. currentIndex = UM.LayerView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type");
  113. updateLegends(currentIndex);
  114. }
  115. function updateLegends(type_id)
  116. {
  117. // update visibility of legends
  118. view_settings.show_legend = UM.LayerView.compatibilityMode || (type_id == 1);
  119. }
  120. }
  121. Label
  122. {
  123. id: compatibilityModeLabel
  124. anchors.left: parent.left
  125. text: catalog.i18nc("@label","Compatibility Mode")
  126. color: UM.Theme.getColor("text")
  127. visible: UM.LayerView.compatibilityMode
  128. Layout.fillWidth: true
  129. Layout.preferredHeight: UM.Theme.getSize("layerview_row").height
  130. Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
  131. }
  132. Label
  133. {
  134. id: space2Label
  135. anchors.left: parent.left
  136. text: " "
  137. font.pointSize: 0.5
  138. }
  139. Connections {
  140. target: UM.Preferences
  141. onPreferenceChanged:
  142. {
  143. layerTypeCombobox.currentIndex = UM.LayerView.compatibilityMode ? 1 : UM.Preferences.getValue("layerview/layer_view_type");
  144. layerTypeCombobox.updateLegends(layerTypeCombobox.currentIndex);
  145. view_settings.extruder_opacities = UM.Preferences.getValue("layerview/extruder_opacities").split("|");
  146. view_settings.show_travel_moves = UM.Preferences.getValue("layerview/show_travel_moves");
  147. view_settings.show_helpers = UM.Preferences.getValue("layerview/show_helpers");
  148. view_settings.show_skin = UM.Preferences.getValue("layerview/show_skin");
  149. view_settings.show_infill = UM.Preferences.getValue("layerview/show_infill");
  150. view_settings.only_show_top_layers = UM.Preferences.getValue("view/only_show_top_layers");
  151. view_settings.top_layer_count = UM.Preferences.getValue("view/top_layer_count");
  152. }
  153. }
  154. Repeater {
  155. model: Cura.ExtrudersModel{}
  156. CheckBox {
  157. checked: view_settings.extruder_opacities[index] > 0.5 || view_settings.extruder_opacities[index] == undefined || view_settings.extruder_opacities[index] == ""
  158. onClicked: {
  159. view_settings.extruder_opacities[index] = checked ? 1.0 : 0.0
  160. UM.Preferences.setValue("layerview/extruder_opacities", view_settings.extruder_opacities.join("|"));
  161. }
  162. text: model.name
  163. visible: !UM.LayerView.compatibilityMode
  164. enabled: index + 1 <= 4
  165. Rectangle {
  166. anchors.verticalCenter: parent.verticalCenter
  167. anchors.right: parent.right
  168. width: UM.Theme.getSize("layerview_legend_size").width
  169. height: UM.Theme.getSize("layerview_legend_size").height
  170. color: model.color
  171. border.width: UM.Theme.getSize("default_lining").width
  172. border.color: UM.Theme.getColor("lining")
  173. visible: !view_settings.show_legend
  174. }
  175. Layout.fillWidth: true
  176. Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
  177. Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
  178. style: UM.Theme.styles.checkbox
  179. }
  180. }
  181. Repeater {
  182. model: ListModel {
  183. id: typesLegenModel
  184. Component.onCompleted:
  185. {
  186. typesLegenModel.append({
  187. label: catalog.i18nc("@label", "Show Travels"),
  188. initialValue: view_settings.show_travel_moves,
  189. preference: "layerview/show_travel_moves",
  190. colorId: "layerview_move_combing"
  191. });
  192. typesLegenModel.append({
  193. label: catalog.i18nc("@label", "Show Helpers"),
  194. initialValue: view_settings.show_helpers,
  195. preference: "layerview/show_helpers",
  196. colorId: "layerview_support"
  197. });
  198. typesLegenModel.append({
  199. label: catalog.i18nc("@label", "Show Shell"),
  200. initialValue: view_settings.show_skin,
  201. preference: "layerview/show_skin",
  202. colorId: "layerview_inset_0"
  203. });
  204. typesLegenModel.append({
  205. label: catalog.i18nc("@label", "Show Infill"),
  206. initialValue: view_settings.show_infill,
  207. preference: "layerview/show_infill",
  208. colorId: "layerview_infill"
  209. });
  210. }
  211. }
  212. CheckBox {
  213. checked: model.initialValue
  214. onClicked: {
  215. UM.Preferences.setValue(model.preference, checked);
  216. }
  217. text: label
  218. Rectangle {
  219. anchors.verticalCenter: parent.verticalCenter
  220. anchors.right: parent.right
  221. width: UM.Theme.getSize("layerview_legend_size").width
  222. height: UM.Theme.getSize("layerview_legend_size").height
  223. color: UM.Theme.getColor(model.colorId)
  224. border.width: UM.Theme.getSize("default_lining").width
  225. border.color: UM.Theme.getColor("lining")
  226. visible: view_settings.show_legend
  227. }
  228. Layout.fillWidth: true
  229. Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
  230. Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
  231. style: UM.Theme.styles.checkbox
  232. }
  233. }
  234. CheckBox {
  235. checked: view_settings.only_show_top_layers
  236. onClicked: {
  237. UM.Preferences.setValue("view/only_show_top_layers", checked ? 1.0 : 0.0);
  238. }
  239. text: catalog.i18nc("@label", "Only Show Top Layers")
  240. visible: UM.LayerView.compatibilityMode
  241. style: UM.Theme.styles.checkbox
  242. }
  243. CheckBox {
  244. checked: view_settings.top_layer_count == 5
  245. onClicked: {
  246. UM.Preferences.setValue("view/top_layer_count", checked ? 5 : 1);
  247. }
  248. text: catalog.i18nc("@label", "Show 5 Detailed Layers On Top")
  249. visible: UM.LayerView.compatibilityMode
  250. style: UM.Theme.styles.checkbox
  251. }
  252. Repeater {
  253. model: ListModel {
  254. id: typesLegenModelNoCheck
  255. Component.onCompleted:
  256. {
  257. typesLegenModelNoCheck.append({
  258. label: catalog.i18nc("@label", "Top / Bottom"),
  259. colorId: "layerview_skin",
  260. });
  261. typesLegenModelNoCheck.append({
  262. label: catalog.i18nc("@label", "Inner Wall"),
  263. colorId: "layerview_inset_x",
  264. });
  265. }
  266. }
  267. Label {
  268. text: label
  269. visible: view_settings.show_legend
  270. Rectangle {
  271. anchors.verticalCenter: parent.verticalCenter
  272. anchors.right: parent.right
  273. width: UM.Theme.getSize("layerview_legend_size").width
  274. height: UM.Theme.getSize("layerview_legend_size").height
  275. color: UM.Theme.getColor(model.colorId)
  276. border.width: UM.Theme.getSize("default_lining").width
  277. border.color: UM.Theme.getColor("lining")
  278. visible: view_settings.show_legend
  279. }
  280. Layout.fillWidth: true
  281. Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
  282. Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
  283. color: UM.Theme.getColor("text")
  284. }
  285. }
  286. }
  287. Item
  288. {
  289. id: slider
  290. width: handleSize
  291. height: parent.height - 2*UM.Theme.getSize("slider_layerview_margin").height
  292. anchors.top: parent.top
  293. anchors.topMargin: UM.Theme.getSize("slider_layerview_margin").height
  294. anchors.right: layerViewMenu.right
  295. anchors.rightMargin: UM.Theme.getSize("slider_layerview_margin").width
  296. property real handleSize: UM.Theme.getSize("slider_handle").width
  297. property real handleRadius: handleSize / 2
  298. property real minimumRangeHandleSize: UM.Theme.getSize("slider_handle").width / 2
  299. property real trackThickness: UM.Theme.getSize("slider_groove").width
  300. property real trackRadius: trackThickness / 2
  301. property real trackBorderWidth: UM.Theme.getSize("default_lining").width
  302. property color upperHandleColor: UM.Theme.getColor("slider_handle")
  303. property color lowerHandleColor: UM.Theme.getColor("slider_handle")
  304. property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill")
  305. property color trackColor: UM.Theme.getColor("slider_groove")
  306. property color trackBorderColor: UM.Theme.getColor("slider_groove_border")
  307. property real maximumValue: UM.LayerView.numLayers
  308. property real minimumValue: 0
  309. property real minimumRange: 0
  310. property bool roundValues: true
  311. property var activeHandle: upperHandle
  312. property bool layersVisible: UM.LayerView.layerActivity && CuraApplication.platformActivity ? true : false
  313. function getUpperValueFromHandle()
  314. {
  315. var result = upperHandle.y / (height - (2 * handleSize + minimumRangeHandleSize));
  316. result = maximumValue + result * (minimumValue - (maximumValue - minimumRange));
  317. result = roundValues ? Math.round(result) | 0 : result;
  318. return result;
  319. }
  320. function getLowerValueFromHandle()
  321. {
  322. var result = (lowerHandle.y - (handleSize + minimumRangeHandleSize)) / (height - (2 * handleSize + minimumRangeHandleSize));
  323. result = maximumValue - minimumRange + result * (minimumValue - (maximumValue - minimumRange));
  324. result = roundValues ? Math.round(result) : result;
  325. return result;
  326. }
  327. function setUpperValue(value)
  328. {
  329. var value = (value - maximumValue) / (minimumValue - maximumValue);
  330. var new_upper_y = Math.round(value * (height - (2 * handleSize + minimumRangeHandleSize)));
  331. if(new_upper_y != upperHandle.y)
  332. {
  333. upperHandle.y = new_upper_y;
  334. }
  335. rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height);
  336. }
  337. function setLowerValue(value)
  338. {
  339. var value = (value - maximumValue) / (minimumValue - maximumValue);
  340. var new_lower_y = Math.round((handleSize + minimumRangeHandleSize) + value * (height - (2 * handleSize + minimumRangeHandleSize)));
  341. if(new_lower_y != lowerHandle.y)
  342. {
  343. lowerHandle.y = new_lower_y;
  344. }
  345. rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height);
  346. }
  347. Connections
  348. {
  349. target: UM.LayerView
  350. onMinimumLayerChanged: slider.setLowerValue(UM.LayerView.minimumLayer)
  351. onCurrentLayerChanged: slider.setUpperValue(UM.LayerView.currentLayer)
  352. }
  353. Rectangle {
  354. width: parent.trackThickness
  355. height: parent.height - parent.handleSize
  356. radius: parent.trackRadius
  357. anchors.centerIn: parent
  358. color: parent.trackColor
  359. border.width: parent.trackBorderWidth;
  360. border.color: parent.trackBorderColor;
  361. }
  362. Item {
  363. id: rangeHandle
  364. y: upperHandle.y + upperHandle.height
  365. width: parent.handleSize
  366. height: parent.minimumRangeHandleSize
  367. anchors.horizontalCenter: parent.horizontalCenter
  368. visible: slider.layersVisible
  369. property real value: UM.LayerView.currentLayer
  370. function setValue(value)
  371. {
  372. var range = upperHandle.value - lowerHandle.value;
  373. value = Math.min(value, slider.maximumValue);
  374. value = Math.max(value, slider.minimumValue + range);
  375. UM.LayerView.setCurrentLayer(value);
  376. UM.LayerView.setMinimumLayer(value - range);
  377. }
  378. Rectangle {
  379. anchors.centerIn: parent
  380. width: parent.parent.trackThickness - 2 * parent.parent.trackBorderWidth
  381. height: parent.height + parent.parent.handleSize
  382. color: parent.parent.rangeHandleColor
  383. }
  384. MouseArea {
  385. anchors.fill: parent
  386. drag.target: parent
  387. drag.axis: Drag.YAxis
  388. drag.minimumY: upperHandle.height
  389. drag.maximumY: parent.parent.height - (parent.height + lowerHandle.height)
  390. onPressed: parent.parent.activeHandle = rangeHandle
  391. onPositionChanged:
  392. {
  393. upperHandle.y = parent.y - upperHandle.height
  394. lowerHandle.y = parent.y + parent.height
  395. var upper_value = slider.getUpperValueFromHandle();
  396. var lower_value = upper_value - (upperHandle.value - lowerHandle.value);
  397. UM.LayerView.setCurrentLayer(upper_value);
  398. UM.LayerView.setMinimumLayer(lower_value);
  399. }
  400. }
  401. }
  402. Rectangle {
  403. id: upperHandle
  404. y: parent.height - (parent.minimumRangeHandleSize + 2 * parent.handleSize)
  405. width: parent.handleSize
  406. height: parent.handleSize
  407. anchors.horizontalCenter: parent.horizontalCenter
  408. radius: parent.handleRadius
  409. color: parent.upperHandleColor
  410. visible: slider.layersVisible
  411. property real value: UM.LayerView.currentLayer
  412. function setValue(value)
  413. {
  414. UM.LayerView.setCurrentLayer(value);
  415. }
  416. MouseArea {
  417. anchors.fill: parent
  418. drag.target: parent
  419. drag.axis: Drag.YAxis
  420. drag.minimumY: 0
  421. drag.maximumY: parent.parent.height - (2 * parent.parent.handleSize + parent.parent.minimumRangeHandleSize)
  422. onPressed: parent.parent.activeHandle = upperHandle
  423. onPositionChanged:
  424. {
  425. if(lowerHandle.y - (upperHandle.y + upperHandle.height) < parent.parent.minimumRangeHandleSize)
  426. {
  427. lowerHandle.y = upperHandle.y + upperHandle.height + parent.parent.minimumRangeHandleSize;
  428. }
  429. rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height);
  430. UM.LayerView.setCurrentLayer(slider.getUpperValueFromHandle());
  431. }
  432. }
  433. }
  434. Rectangle {
  435. id: lowerHandle
  436. y: parent.height - parent.handleSize
  437. width: parent.handleSize
  438. height: parent.handleSize
  439. anchors.horizontalCenter: parent.horizontalCenter
  440. radius: parent.handleRadius
  441. color: parent.lowerHandleColor
  442. visible: slider.layersVisible
  443. property real value: UM.LayerView.minimumLayer
  444. function setValue(value)
  445. {
  446. UM.LayerView.setMinimumLayer(value);
  447. }
  448. MouseArea {
  449. anchors.fill: parent
  450. drag.target: parent
  451. drag.axis: Drag.YAxis
  452. drag.minimumY: upperHandle.height + parent.parent.minimumRangeHandleSize
  453. drag.maximumY: parent.parent.height - parent.height
  454. onPressed: parent.parent.activeHandle = lowerHandle
  455. onPositionChanged:
  456. {
  457. if(lowerHandle.y - (upperHandle.y + upperHandle.height) < parent.parent.minimumRangeHandleSize)
  458. {
  459. upperHandle.y = lowerHandle.y - (upperHandle.height + parent.parent.minimumRangeHandleSize);
  460. }
  461. rangeHandle.height = lowerHandle.y - (upperHandle.y + upperHandle.height)
  462. UM.LayerView.setMinimumLayer(slider.getLowerValueFromHandle());
  463. }
  464. }
  465. }
  466. UM.PointingRectangle
  467. {
  468. x: parent.width + UM.Theme.getSize("slider_layerview_background").width / 2;
  469. y: Math.floor(slider.activeHandle.y + slider.activeHandle.height / 2 - height / 2);
  470. target: Qt.point(0, slider.activeHandle.y + slider.activeHandle.height / 2)
  471. arrowSize: UM.Theme.getSize("default_arrow").width
  472. height: UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height
  473. width: valueLabel.width + UM.Theme.getSize("default_margin").width
  474. Behavior on height { NumberAnimation { duration: 50; } }
  475. color: UM.Theme.getColor("tool_panel_background")
  476. borderColor: UM.Theme.getColor("lining")
  477. borderWidth: UM.Theme.getSize("default_lining").width
  478. visible: slider.layersVisible
  479. MouseArea //Catch all mouse events (so scene doesnt handle them)
  480. {
  481. anchors.fill: parent
  482. }
  483. TextField
  484. {
  485. id: valueLabel
  486. property string maxValue: slider.maximumValue + 1
  487. text: slider.activeHandle.value + 1
  488. horizontalAlignment: TextInput.AlignRight;
  489. onEditingFinished:
  490. {
  491. // Ensure that the cursor is at the first position. On some systems the text isn't fully visible
  492. // Seems to have to do something with different dpi densities that QML doesn't quite handle.
  493. // Another option would be to increase the size even further, but that gives pretty ugly results.
  494. cursorPosition = 0;
  495. if(valueLabel.text != '')
  496. {
  497. slider.activeHandle.setValue(valueLabel.text - 1);
  498. }
  499. }
  500. validator: IntValidator { bottom: 1; top: slider.maximumValue + 1; }
  501. anchors.left: parent.left;
  502. anchors.leftMargin: UM.Theme.getSize("default_margin").width / 2;
  503. anchors.verticalCenter: parent.verticalCenter;
  504. width: Math.max(UM.Theme.getSize("line").width * maxValue.length + 2, 20);
  505. style: TextFieldStyle
  506. {
  507. textColor: UM.Theme.getColor("setting_control_text");
  508. font: UM.Theme.getFont("default");
  509. background: Item { }
  510. }
  511. Keys.onUpPressed: slider.activeHandle.setValue(slider.activeHandle.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
  512. Keys.onDownPressed: slider.activeHandle.setValue(slider.activeHandle.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
  513. }
  514. BusyIndicator
  515. {
  516. id: busyIndicator;
  517. anchors.left: parent.right;
  518. anchors.leftMargin: UM.Theme.getSize("default_margin").width / 2;
  519. anchors.verticalCenter: parent.verticalCenter;
  520. width: UM.Theme.getSize("slider_handle").height;
  521. height: width;
  522. running: UM.LayerView.busy;
  523. visible: UM.LayerView.busy;
  524. }
  525. }
  526. }
  527. }
  528. }