From 37f00b47a94e0b04c2e0d9657573801ba248d4ab Mon Sep 17 00:00:00 2001 From: Aleksei German Date: Tue, 24 Oct 2023 17:54:50 +0200 Subject: [PATCH] QmlDesigner: Support AnimatedSprite type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-11017 Change-Id: Icc7716a6b219e35a24b75633e7a67ad73240eee4 Reviewed-by: Qt CI Patch Build Bot Reviewed-by: Henning Gründl Reviewed-by: Thomas Hartmann --- .../QtQuick/AnimatedSpriteSpecifics.qml | 364 ++++++++++++++++++ .../propertyEditorQmlSources/quick.metainfo | 20 + .../images/animatedsprite-loading.png | Bin 0 -> 118 bytes .../qtquickplugin/qtquickplugin.qrc | 1 + .../qmldesigner/qtquickplugin/quick.metainfo | 20 + 5 files changed, 405 insertions(+) create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimatedSpriteSpecifics.qml create mode 100644 src/plugins/qmldesigner/qtquickplugin/images/animatedsprite-loading.png diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimatedSpriteSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimatedSpriteSpecifics.qml new file mode 100644 index 00000000000..1dbd0a343b7 --- /dev/null +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimatedSpriteSpecifics.qml @@ -0,0 +1,364 @@ +// Copyright (C) 2023 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 StudioControls as StudioControls +import StudioTheme as StudioTheme + +Column { + anchors.left: parent.left + anchors.right: parent.right + + Section { + caption: qsTr("Animated Sprite") + + anchors.left: parent.left + anchors.right: parent.right + + SectionLayout { + PropertyLabel { + text: qsTr("Source") + tooltip: qsTr("Adds an image from the local file system.") + } + + SecondColumnLayout { + UrlChooser { + backendValue: backendValues.source + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Frame size") + tooltip: qsTr("Sets the width and height of the frame.") + blockedByTemplate: !(backendValues.frameWidth.isAvailable || backendValues.frameHeight.isAvailable) + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameWidth + minimumValue: 0 + maximumValue: 8192 + decimals: 0 + enabled: backendValue.isAvailable + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The width of the animated sprite frame + text: qsTr("W", "width") + tooltip: qsTr("Width.") + enabled: backendValues.frameWidth.isAvailable + } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameHeight + minimumValue: 0 + maximumValue: 8192 + decimals: 0 + enabled: backendValue.isAvailable + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The height of the animated sprite frame + text: qsTr("H", "height") + tooltip: qsTr("Height.") + enabled: backendValues.frameHeight.isAvailable + } + /* + TODO QDS-4836 + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + LinkIndicator2D {} + */ + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Frame coordinates") + tooltip: qsTr("Sets the coordinates of the first frame of the animated sprite.") + blockedByTemplate: !(backendValues.frameX.isAvailable || backendValues.frameY.isAvailable) + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameX + minimumValue: 0 + maximumValue: 8192 + decimals: 0 + enabled: backendValue.isAvailable + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The width of the animated sprite frame + text: qsTr("X", "Frame X") + tooltip: qsTr("Frame X coordinate.") + enabled: backendValues.frameX.isAvailable + } + + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + SpinBox { + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameY + minimumValue: 0 + maximumValue: 8192 + decimals: 0 + enabled: backendValue.isAvailable + } + + Spacer { implicitWidth: StudioTheme.Values.controlLabelGap } + + ControlLabel { + //: The height of the animated sprite frame + text: qsTr("Y", "Frame Y") + tooltip: qsTr("Frame Y coordinate.") + enabled: backendValues.frameY.isAvailable + } + /* + TODO QDS-4836 + Spacer { implicitWidth: StudioTheme.Values.controlGap } + + LinkIndicator2D {} + */ + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Frame count") + tooltip: qsTr("Sets the number of frames in this animated sprite.") + blockedByTemplate: !backendValues.frameCount.isAvailable + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameCount + decimals: 0 + minimumValue: 0 + maximumValue: 10000 + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + //frame rate OR frame duration OR frame sync should be used + //frame rate has priority over frame duration + //frame sync has priority over rate and duration + PropertyLabel { + text: qsTr("Frame rate") + tooltip: qsTr("Sets the number of frames per second to show in the animation.") + blockedByTemplate: !backendValues.frameRate.isAvailable + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameRate + decimals: 2 + minimumValue: 0 + maximumValue: 1000 + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + //frame duration OR frame rate OR frame sync should be used + //frame rate has priority over frame duration + //frame sync has priority over rate and duration + PropertyLabel { + text: qsTr("Frame duration") + tooltip: qsTr("Sets the duration of each frame of the animation in milliseconds.") + blockedByTemplate: !backendValues.frameDuration.isAvailable + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameDuration + decimals: 0 + minimumValue: 0 + maximumValue: 100000 + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + //frame sync OR frame rate OR frame duration should be used + //frame rate has priority over frame duration + //frame sync has priority over rate and duration + PropertyLabel { + text: qsTr("Frame sync") + tooltip: qsTr("Sets frame advancements one frame each time a frame is rendered to the screen.") + blockedByTemplate: !backendValues.frameSync.isAvailable + } + + SecondColumnLayout { + CheckBox { + text: backendValues.frameSync.valueToString + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.frameSync + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Loops") + tooltip: qsTr("After playing the animation this many times, the animation will automatically stop.") + blockedByTemplate: !backendValues.loops.isAvailable + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.loops + decimals: 0 + minimumValue: 0 + maximumValue: 100000 + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Interpolate") + tooltip: qsTr("If true, interpolation will occur between sprite frames to make the animation appear smoother.") + blockedByTemplate: !backendValues.interpolate.isAvailable + } + + SecondColumnLayout { + CheckBox { + text: backendValues.interpolate.valueToString + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.interpolate + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Finish behavior") + tooltip: qsTr("Sets the behavior when the animation finishes on its own.") + blockedByTemplate: !backendValues.finishBehavior.isAvailable + } + + SecondColumnLayout { + ComboBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + width: implicitWidth + scope: "AnimatedSprite" + model: ["FinishAtInitialFrame", "FinishAtFinalFrame"] + backendValue: backendValues.finishBehavior + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Reverse") + tooltip: qsTr("If true, the animation will be played in reverse.") + blockedByTemplate: !backendValues.reverse.isAvailable + } + + SecondColumnLayout { + CheckBox { + text: backendValues.reverse.valueToString + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.reverse + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Running") + tooltip: qsTr("Whether the sprite is animating or not.") + blockedByTemplate: !backendValues.running.isAvailable + } + + SecondColumnLayout { + CheckBox { + text: backendValues.running.valueToString + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.running + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Paused") + tooltip: qsTr("When paused, the current frame can be advanced manually.") + blockedByTemplate: !backendValues.paused.isAvailable + } + + SecondColumnLayout { + CheckBox { + text: backendValues.paused.valueToString + implicitWidth: StudioTheme.Values.twoControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.paused + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + + PropertyLabel { + text: qsTr("Current frame") + tooltip: qsTr("When paused, the current frame can be advanced manually by setting this property.") + blockedByTemplate: !backendValues.currentFrame.isAvailable + } + + SecondColumnLayout { + SpinBox { + implicitWidth: StudioTheme.Values.singleControlColumnWidth + + StudioTheme.Values.actionIndicatorWidth + backendValue: backendValues.currentFrame + decimals: 0 + minimumValue: 0 + maximumValue: 100000 + enabled: backendValue.isAvailable + } + + ExpandingSpacer {} + } + } + } +} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/quick.metainfo b/share/qtcreator/qmldesigner/propertyEditorQmlSources/quick.metainfo index f1aeaa9ebbd..f390f72260d 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/quick.metainfo +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/quick.metainfo @@ -140,6 +140,26 @@ MetaInfo { } } + Type { + name: "QtQuick.AnimatedSprite" + icon: ":/qtquickplugin/images/animated-image-icon16.png" + + ItemLibraryEntry { + name: "Animated Sprite" + category: "a.Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/animated-image-icon.png" + version: "2.0" + + Property { name: "frameWidth"; type: "int"; value: 64; } + Property { name: "frameHeight"; type: "int"; value: 64; } + Property { name: "frameCount"; type: "int"; value: 4; } + Property { name: "frameDuration"; type: "int"; value: 500; } + Property { name: "source"; type: "QUrl"; value:"animatedsprite-loading.png"; } + ExtraFile { source: ":/qtquickplugin/images/animatedsprite-loading.png" } + toolTip: qsTr("Draws a sprite animation.") + } + } + Type { name: "QtQuick.BorderImage" icon: ":/qtquickplugin/images/border-image-icon16.png" diff --git a/src/plugins/qmldesigner/qtquickplugin/images/animatedsprite-loading.png b/src/plugins/qmldesigner/qtquickplugin/images/animatedsprite-loading.png new file mode 100644 index 0000000000000000000000000000000000000000..ff2bbbd140fc31c4de2eb530414d8153eb0715b4 GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0y~yU}RumU~ph$W?*1AKiT>(0|NtFfKP~P>46Xb|No!p z`u8#e1B14wi(`n#@#G)=3= literal 0 HcmV?d00001 diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc index 2e2dbf7819f..cb5346c0795 100644 --- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc +++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc @@ -122,5 +122,6 @@ images/drop-area-16px.png images/drop-area-24px.png images/drop-area-24px@2x.png + images/animatedsprite-loading.png diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index a25cdadf4ef..d3fdd6f55f0 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -156,6 +156,26 @@ MetaInfo { } } + Type { + name: "QtQuick.AnimatedSprite" + icon: ":/qtquickplugin/images/animated-image-icon16.png" + + ItemLibraryEntry { + name: "Animated Sprite" + category: "a.Qt Quick - Basic" + libraryIcon: ":/qtquickplugin/images/animated-image-icon.png" + version: "2.0" + + Property { name: "frameWidth"; type: "int"; value: 64; } + Property { name: "frameHeight"; type: "int"; value: 64; } + Property { name: "frameCount"; type: "int"; value: 4; } + Property { name: "frameDuration"; type: "int"; value: 500; } + Property { name: "source"; type: "QUrl"; value:"animatedsprite-loading.png"; } + ExtraFile { source: ":/qtquickplugin/images/animatedsprite-loading.png" } + toolTip: qsTr("Draws a sprite animation.") + } + } + Type { name: "QtQuick.BorderImage" icon: ":/qtquickplugin/images/border-image-icon16.png"