From 476ea1404b0c8075c61a0335a7471ad0bb835a7b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 4 Apr 2024 17:22:51 +0200 Subject: QmlDesigner: Add Design Effects UI * Add EffectsSection * Make HelperWidgtes.Section able to have custom content * Cleanup on IconButton and Section Change-Id: I9aff4838ed9f2df9155161f36506f1514245ce6b Reviewed-by: Thomas Hartmann --- .../QtQuick/EffectsSection.qml | 475 +++++++++++++++++++++ .../propertyEditorQmlSources/QtQuick/ItemPane.qml | 4 + .../imports/HelperWidgets/IconButton.qml | 34 +- .../imports/HelperWidgets/Section.qml | 199 +++++---- 4 files changed, 613 insertions(+), 99 deletions(-) create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml (limited to 'share/qtcreator') diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml new file mode 100644 index 00000000000..37fca814423 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml @@ -0,0 +1,475 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Layouts +import HelperWidgets +import StudioTheme as StudioTheme +import StudioControls as StudioControls + +Section { + id: root + + property bool hasDesignerEffect: false + property var model + property var effectNode + property var effectNodeWrapper + + // Draggging + property Item draggedSec: null + property var secsY: [] + property int moveFromIdx: 0 + property int moveToIdx: 0 + + function invalidate() { + root.effectNode = null + root.model = null + + var effect = modelNodeBackend.allChildrenOfType("DesignEffect") + root.effectNode = effect + root.effectNodeWrapper = modelNodeBackend.registerSubSelectionWrapper(effect) + root.hasDesignerEffect = effect.length === 1 + + if (!root.hasDesignerEffect) + return + + root.model = modelNodeBackend.allChildren(effect[0]) //ids for all effects + } + + leftPadding: 0 + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr('Effects [beta]').arg(StudioTheme.Values.themeInteraction) + visible: backendValues.layer_effect.isAvailable + + property Connections connection: Connections { + target: modelNodeBackend + + function onSelectionChanged() { root.invalidate() } + function onSelectionToBeChanged() { root.model = [] } + } + + SectionLayout { + PropertyLabel {} + + SecondColumnLayout { + Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth } + + AbstractButton { + id: effectButton + implicitWidth: StudioTheme.Values.singleControlColumnWidth + width: StudioTheme.Values.singleControlColumnWidth + buttonIcon: root.hasDesignerEffect ? qsTr("Remove Effects") : qsTr("Add Effects") + iconFont: StudioTheme.Constants.font + tooltip: qsTr("Adds a note with a title to explain the component.") + onClicked: { + if (root.hasDesignerEffect) { + root.effectNodeWrapper.deleteModelNode() + } else { + modelNodeBackend.createModelNode(-1, "data", "DesignEffect") + var effectNode = modelNodeBackend.allChildrenOfType("DesignEffect") + modelNodeBackend.createModelNode(effectNode, "effects", "DesignDropShadow") + } + root.invalidate() + } + } + } + + PropertyLabel { text: qsTr("Visibility") } + + SecondColumnLayout { + CheckBox { + text: qsTr("Visible") + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: root.effectNodeWrapper.properties.visible + } + + ExpandingSpacer {} + } + } + + Item { + width: 1 + height: StudioTheme.Values.sectionHeadSpacerHeight + } + + function handleDragMove() { + root.dragTimer.stop() + if (root.secsY.length === 0) { + for (let i = 0; i < repeater.count; ++i) + root.secsY[i] = repeater.itemAt(i).y + } + + let scrollView = Controller.mainScrollView + + let oldContentY = scrollView.contentY + if (root.draggedSec.y < scrollView.dragScrollMargin + scrollView.contentY + && scrollView.contentY > 0) { + scrollView.contentY -= scrollView.dragScrollMargin / 2 + } else if (root.draggedSec.y > scrollView.contentY + scrollView.height - scrollView.dragScrollMargin + && scrollView.contentY < scrollView.contentHeight - scrollView.height) { + scrollView.contentY += scrollView.dragScrollMargin / 2 + if (scrollView.contentY > scrollView.contentHeight - scrollView.height) + scrollView.contentY = scrollView.contentHeight - scrollView.height + } + + if (scrollView.contentY < 0) + scrollView.contentY = 0 + + if (oldContentY !== scrollView.contentY) { + // Changing dragged section position in drag handler doesn't seem to stick + // when triggered by mouse move, so do it again async + root.dragTimer.targetY = root.draggedSec.y - oldContentY + scrollView.contentY + root.dragTimer.restart() + root.dragConnection.enabled = false + root.draggedSec.y = root.dragTimer.targetY + root.dragConnection.enabled = true + } + + root.moveToIdx = root.moveFromIdx + for (let i = 0; i < repeater.count; ++i) { + let currItem = repeater.itemAt(i) + if (i > root.moveFromIdx) { + if (root.draggedSec.y > currItem.y) { + currItem.y = root.secsY[i] - root.draggedSec.height - nodesCol.spacing + root.moveToIdx = i + } else { + currItem.y = root.secsY[i] + } + } else if (i < root.moveFromIdx) { + if (root.draggedSec.y < currItem.y) { + currItem.y = root.secsY[i] + root.draggedSec.height + nodesCol.spacing + root.moveToIdx = Math.min(root.moveToIdx, i) + } else { + currItem.y = root.secsY[i] + } + } + } + } + + property Connections dragConnection: Connections { + target: root.draggedSec + + function onYChanged() { root.handleDragMove() } + } + + property Timer dragTimer: Timer { + running: false + interval: 16 + repeat: false + + property real targetY: -1 + + onTriggered: { + // Ensure we get position change triggers even if user holds mouse still to + // make scrolling smooth + root.draggedSec.y = targetY + root.handleDragMove() + } + } + + Column { + id: nodesCol + anchors.left: parent.left + anchors.right: parent.right + spacing: 1 + + Section { + sectionHeight: 37 + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Layer Blur") + labelCapitalization: Font.MixedCase + visible: root.hasDesignerEffect + category: "DesignEffects" + expanded: false + + SectionLayout { + + PropertyLabel { text: qsTr("Visibility") } + + SecondColumnLayout { + CheckBox { + text: qsTr("Visible") + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: root.effectNodeWrapper.properties.layerBlurVisible + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Blur") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: root.effectNodeWrapper.properties.layerBlurRadius + } + + ExpandingSpacer {} + } + } + } + + Section { + sectionHeight: 37 + anchors.left: parent.left + anchors.right: parent.right + caption: qsTr("Background Blur") + labelCapitalization: Font.MixedCase + visible: root.hasDesignerEffect + category: "DesignEffects" + expanded: false + + SectionLayout { + + PropertyLabel { text: qsTr("Visibility") } + + SecondColumnLayout { + CheckBox { + text: qsTr("Visible") + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: root.effectNodeWrapper.properties.backgroundBlurVisible + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Blur") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: root.effectNodeWrapper.properties.backgroundBlurRadius + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Background") } + + SecondColumnLayout { + ItemFilterComboBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + typeFilter: "QtQuick.Item" + backendValue: root.effectNodeWrapper.properties.background + } + + ExpandingSpacer {} + } + } + } + + Repeater { + id: repeater + model: root.model + + Section { + id: delegate + + property QtObject wrapper: modelNodeBackend.registerSubSelectionWrapper(modelData) + property bool wasExpanded: false + + Behavior on y { + id: dragAnimation + + PropertyAnimation { + duration: 300 + easing.type: Easing.InOutQuad + } + } + + onStartDrag: function(section) { + root.draggedSec = section + root.moveFromIdx = index + // We only need to animate non-dragged sections + dragAnimation.enabled = false + delegate.wasExpanded = delegate.expanded + delegate.expanded = false + delegate.highlightBorder = true + root.secsY = [] + } + + onStopDrag: { + if (root.secsY.length !== 0) { + if (root.moveFromIdx === root.moveToIdx) + root.draggedSec.y = root.secsY[root.moveFromIdx] + else + modelNodeBackend.moveNode(root.effectNode, "effects", root.moveFromIdx, root.moveToIdx) + } + + delegate.highlightBorder = false + root.draggedSec = null + delegate.expanded = delegate.wasExpanded + dragAnimation.enabled = true + + Qt.callLater(root.invalidate) + } + + sectionHeight: 37 + anchors.left: parent.left + anchors.right: parent.right + category: "DesignEffects" + fillBackground: true + expanded: false + + draggable: true + showCloseButton: true + + content: StudioControls.ComboBox { + id: shadowComboBox + actionIndicatorVisible: false + width: 200 + textRole: "text" + valueRole: "value" + model: [ + { value: "DesignDropShadow", text: qsTr("Drop Shadow") }, + { value: "DesignInnerShadow", text: qsTr("Inner Shadow") } + ] + anchors.verticalCenter: parent.verticalCenter + + // When an item is selected, update the backend. + onActivated: modelNodeBackend.changeType(modelData, shadowComboBox.currentValue) + // Set the initial currentIndex to the value stored in the backend. + Component.onCompleted: { + shadowComboBox.currentIndex = shadowComboBox.indexOfValue(modelNodeBackend.simplifiedTypeName(modelData)) + } + } + + onCloseButtonClicked: { + delegate.wrapper.deleteModelNode() + Qt.callLater(root.invalidate) + } + + SectionLayout { + + PropertyLabel { text: qsTr("Visibility") } + + SecondColumnLayout { + CheckBox { + text: qsTr("Visible") + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: delegate.wrapper.properties.visible + } + + ExpandingSpacer {} + } + + PropertyLabel { text: qsTr("Blur") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: delegate.wrapper.properties.blur + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Spread") + enabled: modelNodeBackend.isInstanceOf("Rectangle") + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: delegate.wrapper.properties.spread + enabled: modelNodeBackend.isInstanceOf("Rectangle") + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Color") + tooltip: qsTr("Sets the color.") + } + + ColorEditor { + backendValue: delegate.wrapper.properties.color + supportGradient: false + } + + PropertyLabel { text: qsTr("Offset") } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: delegate.wrapper.properties.offsetX + maximumValue: 0xffff + minimumValue: -0xffff + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "X" + tooltip: qsTr("X-coordinate") + } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: delegate.wrapper.properties.offsetY + maximumValue: 0xffff + minimumValue: -0xffff + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + text: "Y" + tooltip: qsTr("Y-coordinate") + } + + ExpandingSpacer {} + } + } + } + } + } + + Item { + width: 1 + height: StudioTheme.Values.sectionHeadSpacerHeight + } + + SectionLayout { + visible: root.hasDesignerEffect + + PropertyLabel {} + + SecondColumnLayout { + Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth } + + AbstractButton { + id: addShadowEffectButton + implicitWidth: StudioTheme.Values.singleControlColumnWidth + width: StudioTheme.Values.singleControlColumnWidth + buttonIcon: qsTr("Add Shadow Effect") + iconFont: StudioTheme.Constants.font + tooltip: qsTr("Adds a Design Drop Shadow.") + onClicked: { + modelNodeBackend.createModelNode(root.effectNode, + "effects", + "DesignDropShadow") + root.invalidate() + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index 60bd415a6af..aeef8a9598e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -133,6 +133,10 @@ PropertyEditorPane { visible: specificsOne.source.toString() !== "" } + EffectsSection { + expanded: false + } + AdvancedSection { expanded: false } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconButton.qml index 008320cb92a..4534d3fe7da 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/IconButton.qml @@ -8,9 +8,9 @@ import StudioTheme as StudioTheme Rectangle { id: root - signal clicked() - signal pressed() - signal released() + signal clicked(mouse: var) + signal pressed(mouse: var) + signal released(mouse: var) property alias icon: icon.text property alias tooltip: toolTip.text @@ -30,18 +30,17 @@ Rectangle { property color hoverColor: root.transparentBg ? "transparent" : StudioTheme.Values.themeControlBackgroundHover property color pressColor: root.transparentBg ? "transparent" : StudioTheme.Values.themeControlBackgroundInteraction - width: buttonSize - height: buttonSize + width: root.buttonSize + height: root.buttonSize - color: !enabled ? normalColor - : mouseArea.pressed ? pressColor - : mouseArea.containsMouse ? hoverColor - : normalColor + color: !root.enabled ? root.normalColor + : mouseArea.pressed ? root.pressColor + : mouseArea.containsMouse ? root.hoverColor + : root.normalColor Text { id: icon anchors.centerIn: root - color: root.enabled ? StudioTheme.Values.themeTextColor : StudioTheme.Values.themeTextColorDisabled font.family: StudioTheme.Constants.iconFont.family font.pixelSize: StudioTheme.Values.baseIconFontSize @@ -49,30 +48,29 @@ Rectangle { MouseArea { id: mouseArea - anchors.fill: parent hoverEnabled: root.visible - onClicked: { + onClicked: function(mouse) { // We need to keep mouse area enabled even when button is disabled to make tooltip work if (root.enabled) - root.clicked() + root.clicked(mouse) } - onPressed: { + onPressed: function(mouse) { if (root.enabled) - root.pressed() + root.pressed(mouse) } - onReleased: { + onReleased: function(mouse) { if (root.enabled) - root.released() + root.released(mouse) } } ToolTip { id: toolTip - visible: mouseArea.containsMouse && text !== "" + visible: mouseArea.containsMouse && toolTip.text !== "" delay: 1000 } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml index dbbb200f738..245b8506a28 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml @@ -9,11 +9,13 @@ import StudioTheme as StudioTheme Item { id: section - property alias caption: label.text - property alias labelColor: label.color + + property string caption: "Title" + property color labelColor: StudioTheme.Values.themeTextColor + property int labelCapitalization: Font.AllUppercase property alias sectionHeight: header.height property alias sectionBackgroundColor: header.color - property alias sectionFontSize: label.font.pixelSize + property int sectionFontSize: StudioTheme.Values.myFontSize property alias showTopSeparator: topSeparator.visible property alias showArrow: arrow.visible property alias showLeftBorder: leftBorder.visible @@ -26,6 +28,17 @@ Item { property alias fillBackground: sectionBackground.visible property alias highlightBorder: sectionBorder.visible + property Item content: Controls.Label { + id: label + text: section.caption + color: section.labelColor + elide: Text.ElideRight + font.pixelSize: section.sectionFontSize + font.capitalization: section.labelCapitalization + anchors.verticalCenter: parent?.verticalCenter + textFormat: Text.RichText + } + property int leftPadding: StudioTheme.Values.sectionLeftPadding property int rightPadding: 0 property int topPadding: StudioTheme.Values.sectionHeadSpacerHeight @@ -59,7 +72,7 @@ Item { Connections { target: Controller function onCollapseAll(cat) { - if (collapsible && cat === section.category) { + if (section.collapsible && cat === section.category) { if (section.expandOnClick) section.expanded = false else @@ -106,6 +119,22 @@ Item { onExited: section.dropExit() } + StudioControls.Menu { + id: contextMenu + + StudioControls.MenuItem { + text: qsTr("Expand All") + onTriggered: Controller.expandAll(section.category) + } + + StudioControls.MenuItem { + text: qsTr("Collapse All") + onTriggered: Controller.collapseAll(section.category) + } + + onOpenedChanged: Controller.contextMenuOpened = contextMenu.opened + } + Rectangle { id: header height: section.hideHeader ? 0 : StudioTheme.Values.sectionHeadHeight @@ -116,43 +145,6 @@ Item { : Qt.lighter(StudioTheme.Values.themeSectionHeadBackground, 1.0 + (0.2 * section.level)) - Item { - StudioControls.Menu { - id: contextMenu - - StudioControls.MenuItem { - text: qsTr("Expand All") - onTriggered: Controller.expandAll(section.category) - } - - StudioControls.MenuItem { - text: qsTr("Collapse All") - onTriggered: Controller.collapseAll(section.category) - } - - onOpenedChanged: Controller.contextMenuOpened = contextMenu.opened - } - } - - Image { - id: arrow - width: 8 - height: 4 - source: "image://icons/down-arrow" - anchors.left: parent.left - anchors.leftMargin: 4 + (section.level * section.levelShift) + (section.draggable ? 20 : 0) + (section.showEyeButton ? 25 : 0) - anchors.verticalCenter: parent.verticalCenter - } - - Controls.Label { - id: label - anchors.verticalCenter: parent.verticalCenter - color: StudioTheme.Values.themeTextColor - x: arrow.x + 18 - font.pixelSize: StudioTheme.Values.myFontSize - font.capitalization: Font.AllUppercase - } - MouseArea { id: mouseArea anchors.fill: parent @@ -173,58 +165,102 @@ Item { } } - IconButton { - id: closeButton + RowLayout { + spacing: 1 + anchors.fill: parent - icon: StudioTheme.Constants.closeCross - buttonSize: 22 - iconScale: containsMouse ? 1.2 : 1 - transparentBg: true - anchors.right: parent.right - anchors.rightMargin: 10 - visible: false + IconButton { + id: dragButton + visible: false + icon: StudioTheme.Constants.dragmarks + buttonSize: 21 + iconScale: dragButton.enabled && dragButton.containsMouse ? 1.2 : 1 + transparentBg: true - onClicked: root.closeButtonClicked() - } + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: dragButton.width + Layout.maximumWidth: dragButton.width + + drag.target: dragButton.enabled ? section : null + drag.axis: Drag.YAxis + + onPressed: { + section.startDrag(section) + section.z = ++section.parent.z // put the dragged section on top + } - IconButton { - id: dragButton + onReleased: { + section.stopDrag() + } + } - icon: StudioTheme.Constants.dragmarks - buttonSize: 22 - iconScale: dragButton.enabled && dragButton.containsMouse ? 1.2 : 1 - transparentBg: true + IconButton { + id: eyeButton - visible: false - drag.target: dragButton.enabled ? section : null - drag.axis: Drag.YAxis + visible: false + icon: section.eyeEnabled ? StudioTheme.Constants.visible_small + : StudioTheme.Constants.invisible_small + buttonSize: 21 + iconScale: eyeButton.containsMouse ? 1.2 : 1 + transparentBg: true - onPressed: { - section.startDrag(section) + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: eyeButton.width + Layout.maximumWidth: eyeButton.width - section.z = ++section.parent.z // put the dragged section on top + onClicked: { + section.eyeEnabled = !section.eyeEnabled + section.eyeButtonClicked() + } } - onReleased: { - section.stopDrag() + IconButton { + id: arrow + icon: StudioTheme.Constants.sectionToggle + transparentBg: true + + buttonSize: 21 + iconSize: StudioTheme.Values.smallIconFontSize + iconColor: StudioTheme.Values.themeTextColor + + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: arrow.width + Layout.maximumWidth: arrow.width + + onClicked: function(mouse) { + if (!section.collapsible && section.expanded) + return + + transition.enabled = true + if (section.expandOnClick) + section.expanded = !section.expanded + else + section.toggleExpand() + } } - } - IconButton { - id: eyeButton + Item { + id: headerContent + height: header.height + Layout.fillWidth: true + children: [ section.content ] + } - anchors.left: dragButton.right + IconButton { + id: closeButton - icon: section.eyeEnabled ? StudioTheme.Constants.visible_small : StudioTheme.Constants.invisible_small - buttonSize: 22 - iconScale: eyeButton.containsMouse ? 1.2 : 1 - transparentBg: true + visible: false + icon: StudioTheme.Constants.closeCross + buttonSize: 21 + iconScale: closeButton.containsMouse ? 1.2 : 1 + transparentBg: true - visible: false + Layout.alignment: Qt.AlignVCenter + Layout.preferredWidth: closeButton.width + Layout.maximumWidth: closeButton.width + Layout.rightMargin: 10 - onClicked: { - section.eyeEnabled = !section.eyeEnabled - root.eyeButtonClicked() + onClicked: section.closeButtonClicked() } } } @@ -266,6 +302,7 @@ Item { border.width: 1 visible: false } + Item { id: topSpacer height: section.addTopPadding && column.height > 0 ? section.topPadding : 0 @@ -285,7 +322,7 @@ Item { id: leftBorder visible: false width: 1 - height: parent.height - bottomPadding + height: parent.height - section.bottomPadding color: header.color } @@ -320,8 +357,8 @@ Item { } onRunningChanged: { - if (!running) - enabled = false + if (!transition.running) + transition.enabled = false } } } -- cgit v1.2.3