diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc index 01706aa950e..4e4e609d94c 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc @@ -17,33 +17,35 @@ To preview the currently active QML file on the desktop: \list - \li Select \uicontrol Build > \uicontrol {QML Preview}. - \li Select the \inlineimage icons/live_preview.png - (\uicontrol {Show Live Preview}) button. + \li Select the \uicontrol {Live Preview} button on the top toolbar. \li Press \key {Alt+P}. \endlist - \image studio-live-preview.png + \image studio-live-preview.webp \endif - To preview any QML file that belongs to the project, right-click the + To preview any QML file that belongs to the project, + \list + \li Select the \uicontrol {Live Preview} button on the top toolbar. + \li Right-click the filename in the \l Projects view, and select \uicontrol {Preview File}. + \endlist \if defined(qtdesignstudio) - To preview the whole UI, select \uicontrol {Show Live Preview} + To preview the whole UI, select \uicontrol {Live Preview} when viewing the main QML file of the project. To view the UI in different sizes, select the zooming level on the toolbar. - The frames-per-second (FPS) refresh rate of animations is displayed in the - \uicontrol FPS field. - \section1 Selecting the Preview Tool By default, the QML runtime is used for previewing. To use some other tool, specify it in the \uicontrol {QML viewer} field in the run settings of the project in the Projects mode. + \note Click \inlineimage icons/settings.png + to access the setting options. + \image studio-run-settings.png "Run settings" \endif */ diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc index 4eddcf25456..b292540c3f2 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc @@ -32,7 +32,7 @@ \if defined(qtcreator) \image qtcreator-live-preview.png \else - \image studio-live-preview.png + \image studio-live-preview.webp \endif \list diff --git a/doc/qtdesignstudio/images/studio-design-mode.webp b/doc/qtdesignstudio/images/studio-design-mode.webp index c739d88f995..5c49b60391f 100644 Binary files a/doc/qtdesignstudio/images/studio-design-mode.webp and b/doc/qtdesignstudio/images/studio-design-mode.webp differ diff --git a/doc/qtdesignstudio/images/studio-imported-assets.png b/doc/qtdesignstudio/images/studio-imported-assets.png deleted file mode 100644 index 92042383078..00000000000 Binary files a/doc/qtdesignstudio/images/studio-imported-assets.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-imported-assets.webp b/doc/qtdesignstudio/images/studio-imported-assets.webp new file mode 100644 index 00000000000..32c5b091183 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-imported-assets.webp differ diff --git a/doc/qtdesignstudio/images/studio-live-preview.png b/doc/qtdesignstudio/images/studio-live-preview.png deleted file mode 100644 index 30d5c822d00..00000000000 Binary files a/doc/qtdesignstudio/images/studio-live-preview.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-live-preview.webp b/doc/qtdesignstudio/images/studio-live-preview.webp new file mode 100644 index 00000000000..0dff1a411b8 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-live-preview.webp differ diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-material-texture.png b/doc/qtdesignstudio/images/studio-qtquick-3d-material-texture.png deleted file mode 100644 index 32008885cea..00000000000 Binary files a/doc/qtdesignstudio/images/studio-qtquick-3d-material-texture.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-material-texture.webp b/doc/qtdesignstudio/images/studio-qtquick-3d-material-texture.webp new file mode 100644 index 00000000000..0ae680f31b6 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-qtquick-3d-material-texture.webp differ diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-texture-properties.png b/doc/qtdesignstudio/images/studio-qtquick-3d-texture-properties.png deleted file mode 100644 index 3f0225dff4e..00000000000 Binary files a/doc/qtdesignstudio/images/studio-qtquick-3d-texture-properties.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-texture-properties.webp b/doc/qtdesignstudio/images/studio-qtquick-3d-texture-properties.webp new file mode 100644 index 00000000000..87e60ee256a Binary files /dev/null and b/doc/qtdesignstudio/images/studio-qtquick-3d-texture-properties.webp differ diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-texture.png b/doc/qtdesignstudio/images/studio-qtquick-3d-texture.png deleted file mode 100644 index 6165d74b1c3..00000000000 Binary files a/doc/qtdesignstudio/images/studio-qtquick-3d-texture.png and /dev/null differ diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-texture.webp b/doc/qtdesignstudio/images/studio-qtquick-3d-texture.webp new file mode 100644 index 00000000000..ba754535ae2 Binary files /dev/null and b/doc/qtdesignstudio/images/studio-qtquick-3d-texture.webp differ diff --git a/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc b/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc index 196edd941bc..b4864debbf8 100644 --- a/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc +++ b/doc/qtdesignstudio/src/mcus/qtdesignstudio-features-on-mcu-projects.qdoc @@ -82,9 +82,9 @@ \li \b X \li \b - \li \b - - \li The feature is fully supported as such, but there are some - limitations such as StateGroup and the ones listed in - \l {\QMCU Known Issues or Limitations}. + \li The feature is fully supported, but there are some limitations listed + in \l {\QMCU Known Issues or Limitations}. + In addition, StateGroup is disabled. \row \li \l {Transitions} \li \b X @@ -98,7 +98,6 @@ \li \b - \li The \uicontrol Translations view previews with regular Qt Quick instead of \QUL, and it can be inaccurate in calculating the text overflow in some translations. - Also, the developer needs to configure the \QUL project to use \QDS translations (.ts) files. \row \li \l {Timeline} \li \b X diff --git a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc index e77015c8335..3ce7c52cde2 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc @@ -30,7 +30,7 @@ \section1 Importing Designs From Other Design Tools - \image studio-imported-assets.png "UI imported into Qt Design Studio" + \image studio-imported-assets.webp "UI imported into Qt Design Studio" \QB enables you to export assets and then import them to a \QDS project as images and QML files for editing in the \l {2D} view. If you make changes diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-texture.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-texture.qdoc index f720544ddeb..c00d0f354f3 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-texture.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-texture.qdoc @@ -12,7 +12,7 @@ You specify an image to use as the source file for the \uicontrol Texture, and also define how it is mapped to meshes in a 3D scene. - \image studio-qtquick-3d-texture.png "Texture attached to a material in Design mode" + \image studio-qtquick-3d-texture.webp {Texture attached to a material in Design mode} \section1 Selecting the Mapping Method @@ -53,7 +53,7 @@ \section1 UV Scaling - The \uicontrol {U scale} and \uicontrol {V scale} properties define how + The \uicontrol {U} and \uicontrol {V} scale properties define how to scale the U and V texture coordinates when mapping to a mesh's UV coordinates. @@ -77,8 +77,8 @@ the component in the \uicontrol {U position} field. To offset the mapping from bottom to top, set it in the \uicontrol {V position} field. - Specify the U and V pivot point in the \uicontrol {U pivot} and - \uicontrol {V pivot} fields. + Specify the U and V pivot points in the \uicontrol {U} and + \uicontrol {V} pivot fields. To rotate the texture around the pivot point, specify rotation as degrees in the \uicontrol {UV rotation} field. A positive value indicates clockwise @@ -89,28 +89,31 @@ \section1 Applying Textures to Materials - Drag-and-drop an image from \l Assets on a material to - create a texture component. Dragging an image to a default or principled - material opens a \uicontrol {Select Texture Property} dialog. You can select - the property to attach the texture to in the \uicontrol {Set texture to property} - field. For a custom material, you must assign the texture to a map. If the - \uicontrol Texture component is not displayed in \uicontrol {Components}, - you should add the \uicontrol {Qt Quick 3D} module to your project, as - described in \l {Adding and Removing Modules}. + To create and apply a texture on the material from an image: + \list 1 + \li Drag an image from \l Assets to a material + in \uicontrol {Material Browser}. + \li Select a property from the list of properties. + \li Select \uicontrol Apply. + \endlist - To use Texture components to apply textures to materials, drag-and-drop a - Texture component from \uicontrol Components > - \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D} to a material component - in \l Navigator. The new texture should now be visible in the \l {2D} - and \l {3D} views. \note If the colors in your texture are not visualized - correctly, you should check the color in the \uicontrol Diffuse property of - the material and try changing it to white (#ffffff). + Alternatively, you can add textures to materials as instructed + in \l {Working with Textures}. - \image studio-qtquick-3d-material-texture.png "Material properties" + \note If the colors in your texture are not visualized + correctly, try setting the \uicontrol {Base Color} + in \uicontrol {Material Editor} to \e {white (#ffffff)}. - To change the source file for the texture, select the \uicontrol Texture - component in \uicontrol Navigator, go to the \l Properties view, and specify - a new image to use in the \uicontrol Source field. + \image studio-qtquick-3d-material-texture.webp {Material Editor} - \image studio-qtquick-3d-texture-properties.png "Texture properties" + To change the source file for the texture: + \list 1 + \li Double-click the texture in \uicontrol {Material Browser}. + \li In \uicontrol {Texture Editor}, select \inlineimage icons/add-file-16px.png + next to \uicontrol {Source}. + \li Select the new texture. + \li Select \uicontrol Open. + \endlist + + \image studio-qtquick-3d-texture-properties.webp {Texture Editor} */ diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml index 96690fd9690..26a1f6acd99 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml @@ -201,7 +201,7 @@ TreeViewDelegate { mouseArea.allowTooltip = false AssetsLibraryBackend.tooltipBackend.hideTooltip() if (mouse.button === Qt.LeftButton && root.isEffect) - AssetsLibraryBackend.rootView.openEffectMaker(filePath) + AssetsLibraryBackend.rootView.openEffectComposer(filePath) } ToolTip { diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsEditDelegate.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsEditDelegate.qml index e368bb09331..d3285462609 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsEditDelegate.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsEditDelegate.qml @@ -74,16 +74,16 @@ Item { } Component { - id: numberEditor + id: realEditor EditorPopup { - editor: numberField + editor: realField StudioControls.RealSpinBox { - id: numberField + id: realField - property alias editValue: numberField.realValue + property alias editValue: realField.realValue actionIndicator.visible: false realFrom: -9e9 @@ -95,6 +95,27 @@ Item { } } + Component { + id: integerEditor + + EditorPopup { + + editor: integerField + + StudioControls.SpinBox { + id: integerField + + property alias editValue: integerField.value + + actionIndicatorVisible: false + spinBoxIndicatorVisible: true + from: -2147483647 + to: 2147483647 + decimals: 0 + } + } + } + Component { id: boolEditor @@ -150,7 +171,8 @@ Item { name: "default" when: columnType !== CollectionDetails.DataType.Boolean && columnType !== CollectionDetails.DataType.Color - && columnType !== CollectionDetails.DataType.Number + && columnType !== CollectionDetails.DataType.Integer + && columnType !== CollectionDetails.DataType.Real PropertyChanges { target: editorLoader @@ -158,12 +180,21 @@ Item { } }, State { - name: "number" - when: columnType === CollectionDetails.DataType.Number + name: "integer" + when: columnType === CollectionDetails.DataType.Integer PropertyChanges { target: editorLoader - sourceComponent: numberEditor + sourceComponent: integerEditor + } + }, + State { + name: "real" + when: columnType === CollectionDetails.DataType.Real + + PropertyChanges { + target: editorLoader + sourceComponent: realEditor } }, State { diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsToolbar.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsToolbar.qml index da13f62db0b..0c8fcd5b989 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsToolbar.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsToolbar.qml @@ -10,15 +10,15 @@ import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme import CollectionEditorBackend -Item { +Rectangle { id: root - property real iconHeight: 2 * StudioTheme.Values.bigFont required property var model required property var backend property int selectedRow: -1 - implicitHeight: container.height + implicitHeight: StudioTheme.Values.toolbarHeight + color: StudioTheme.Values.themeToolbarBackground function addNewColumn() { addColumnDialog.popUp(root.model.columnCount()) @@ -30,32 +30,36 @@ Item { RowLayout { id: container - width: parent.width + + anchors.fill: parent + anchors.topMargin: StudioTheme.Values.toolbarVerticalMargin + anchors.bottomMargin: StudioTheme.Values.toolbarVerticalMargin spacing: StudioTheme.Values.sectionRowSpacing RowLayout { id: leftSideToolbar - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + Layout.leftMargin: StudioTheme.Values.toolbarHorizontalMargin spacing: StudioTheme.Values.sectionRowSpacing IconButton { - icon: StudioTheme.Constants.addcolumnleft_medium - tooltip: qsTr("Add property left %1").arg(leftSideToolbar.topPadding) + buttonIcon: StudioTheme.Constants.addcolumnleft_medium + tooltip: qsTr("Add property left") enabled: root.model.selectedColumn > -1 - onClicked: addColumnDialog.popUp(root.model.selectedColumn - 1) + onClicked: addColumnDialog.popUp(root.model.selectedColumn) } IconButton { - icon: StudioTheme.Constants.addcolumnright_medium + buttonIcon: StudioTheme.Constants.addcolumnright_medium tooltip: qsTr("Add property right") enabled: root.model.selectedColumn > -1 onClicked: addColumnDialog.popUp(root.model.selectedColumn + 1) } IconButton { - icon: StudioTheme.Constants.deletecolumn_medium + buttonIcon: StudioTheme.Constants.deletecolumn_medium tooltip: qsTr("Delete selected property") enabled: root.model.selectedColumn > -1 onClicked: root.model.removeColumn(root.model.selectedColumn) @@ -67,46 +71,43 @@ Item { } IconButton { - icon: StudioTheme.Constants.addrowbelow_medium + buttonIcon: StudioTheme.Constants.addrowbelow_medium tooltip: qsTr("Insert row below") enabled: root.model.selectedRow > -1 onClicked: root.model.insertRow(root.model.selectedRow + 1) } IconButton { - icon: StudioTheme.Constants.addrowabove_medium + buttonIcon: StudioTheme.Constants.addrowabove_medium tooltip: qsTr("Insert row above") enabled: root.model.selectedRow > -1 onClicked: root.model.insertRow(root.model.selectedRow) } IconButton { - icon: StudioTheme.Constants.deleterow_medium + buttonIcon: StudioTheme.Constants.deleterow_medium tooltip: qsTr("Delete selected row") enabled: root.model.selectedRow > -1 onClicked: root.model.removeRow(root.model.selectedRow) } } - Item { // spacer - Layout.minimumHeight: 1 - Layout.fillWidth: true - } - RowLayout { id: rightSideToolbar + spacing: StudioTheme.Values.sectionRowSpacing - Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + Layout.rightMargin: StudioTheme.Values.toolbarHorizontalMargin IconButton { - icon: StudioTheme.Constants.save_medium + buttonIcon: StudioTheme.Constants.save_medium tooltip: qsTr("Save changes") enabled: root.model.collectionName !== "" onClicked: root.model.saveDataStoreCollections() } IconButton { - icon: StudioTheme.Constants.export_medium + buttonIcon: StudioTheme.Constants.export_medium tooltip: qsTr("Export model") enabled: root.model.collectionName !== "" onClicked: fileDialog.open() @@ -131,11 +132,8 @@ Item { } } - component IconButton: HelperWidgets.IconButton { - Layout.preferredHeight: root.iconHeight - Layout.preferredWidth: root.iconHeight - radius: StudioTheme.Values.smallRadius - iconSize: StudioTheme.Values.bigFont + component IconButton: HelperWidgets.AbstractButton { + style: StudioTheme.Values.viewBarButtonStyle } component Spacer: Item { @@ -160,6 +158,7 @@ Item { { addColumnDialog.clickedIndex = index columnName.text = "" + columnName.forceActiveFocus() addedPropertyType.currentIndex = addedPropertyType.find("String") addColumnDialog.open() diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsView.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsView.qml index 598ed562295..037f42fe638 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsView.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionDetailsView.qml @@ -20,62 +20,34 @@ Rectangle { implicitHeight: 400 color: StudioTheme.Values.themeControlBackground - ColumnLayout { + Column { id: topRow - visible: collectionNameText.text !== "" - - spacing: 0 - anchors { - fill: parent - topMargin: 10 - leftMargin: 15 - rightMargin: 15 - bottomMargin: 10 - } - - Text { - id: collectionNameText - - leftPadding: 8 - rightPadding: 8 - topPadding: 3 - bottomPadding: 3 - - color: StudioTheme.Values.themeTextColor - text: root.model.collectionName - font.pixelSize: StudioTheme.Values.baseFontSize - elide: Text.ElideRight - } - - Item { // spacer - implicitWidth: 1 - implicitHeight: 10 - } + visible: root.model.collectionName !== "" + width: parent.width + spacing: 10 CollectionDetailsToolbar { id: toolbar model: root.model backend: root.backend - Layout.fillWidth: true - Layout.minimumWidth: implicitWidth - } - - Item { // spacer - implicitWidth: 1 - implicitHeight: 5 + width: parent.width } GridLayout { columns: 3 rowSpacing: 1 columnSpacing: 1 + width: parent.width - Layout.fillWidth: true - Layout.fillHeight: true - Layout.maximumWidth: parent.width + anchors { + left: parent.left + leftMargin: StudioTheme.Values.collectionTableHorizontalMargin + } Rectangle { + id: tableTopLeftCorner + clip: true visible: !tableView.model.isEmpty color: StudioTheme.Values.themeControlBackgroundInteraction @@ -128,6 +100,8 @@ Rectangle { headerMenu.clickedHeaderIndex = index headerMenu.dialogPos = parent.mapToGlobal(posX, parent.height) headerMenu.popup() + } else { + headerMenu.close() } } } @@ -188,6 +162,7 @@ Rectangle { Layout.preferredHeight: tableView.height Layout.rowSpan: 2 Layout.alignment: Qt.AlignTop + Qt.AlignLeft + width: implicitWidth // suppresses GridLayout warnings when resizing delegate: HeaderDelegate { selectedItem: tableView.model.selectedRow @@ -208,11 +183,33 @@ Rectangle { model: root.sortedModel clip: true + property point tableStart: tableTopLeftCorner.mapToItem(root, Qt.point(x, y)); + + Layout.alignment: Qt.AlignTop + Qt.AlignLeft Layout.preferredWidth: tableView.contentWidth Layout.preferredHeight: tableView.contentHeight Layout.minimumWidth: 100 Layout.minimumHeight: 20 - Layout.maximumWidth: root.width + Layout.maximumWidth: root.width - (tableStart.x + addColumnContainer.width) + Layout.maximumHeight: root.height - (tableStart.y + addRowContainer.height) + + columnWidthProvider: function(column) { + if (!isColumnLoaded(column)) + return -1 + let w = explicitColumnWidth(column) + if (w < 0) + w = implicitColumnWidth(column) + return Math.max(w, StudioTheme.Values.collectionCellMinimumWidth) + } + + rowHeightProvider: function(row) { + if (!isRowLoaded(row)) + return -1 + let h = explicitRowHeight(row) + if (h < 0) + h = implicitRowHeight(row) + return Math.max(h, StudioTheme.Values.collectionCellMinimumHeight) + } delegate: Rectangle { id: itemCell @@ -261,7 +258,7 @@ Rectangle { id: cellText Text { - text: display + text: display ?? "" color: itemSelected ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themePlaceholderTextColorInteraction leftPadding: 5 @@ -361,6 +358,26 @@ Rectangle { } } } + + HoverHandler { id: hoverHandler } + + ScrollBar.horizontal: StudioControls.TransientScrollBar { + id: horizontalScrollBar + style: StudioTheme.Values.viewStyle + orientation: Qt.Horizontal + + show: (hoverHandler.hovered || tableView.focus || horizontalScrollBar.inUse) + && horizontalScrollBar.isNeeded + } + + ScrollBar.vertical: StudioControls.TransientScrollBar { + id: verticalScrollBar + style: StudioTheme.Values.viewStyle + orientation: Qt.Vertical + + show: (hoverHandler.hovered || tableView.focus || verticalScrollBar.inUse) + && verticalScrollBar.isNeeded + } } HelperWidgets.IconButton { @@ -439,7 +456,6 @@ Rectangle { color: StudioTheme.Values.themeTextColor horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - anchors.fill: parent elide: Text.ElideRight } @@ -481,7 +497,7 @@ Rectangle { Connections { target: root.parent - onIsHorizontalChanged: editPropertyDialog.close() + function onIsHorizontalChanged() { editPropertyDialog.close() } } StudioControls.Dialog { diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml index a53453ac499..6b808d1ab26 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml @@ -49,6 +49,9 @@ Item { id: grid readonly property bool isHorizontal: width >= 500 + columnSpacing: 0 + rowSpacing: 0 + anchors.fill: parent columns: isHorizontal ? 3 : 1 @@ -62,6 +65,7 @@ Item { Rectangle { color: StudioTheme.Values.themeToolbarBackground + Layout.preferredHeight: StudioTheme.Values.toolbarHeight Layout.fillWidth: true diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/EditPropertyDialog.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/EditPropertyDialog.qml index 27e3527e017..814778f2b77 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/EditPropertyDialog.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/EditPropertyDialog.qml @@ -28,6 +28,7 @@ StudioControls.Dialog { nameTextField.forceActiveFocus() typeComboBox.initialType = root.model.propertyType(root.__propertyIndex) + typeComboBox.currentIndex = typeComboBox.find(typeComboBox.initialType) let newPoint = mapFromGlobal(initialPosition.x, initialPosition.y) x = newPoint.x @@ -92,8 +93,6 @@ StudioControls.Dialog { model: root.model.typesList() actionIndicatorVisible: false - - onInitialTypeChanged: typeComboBox.currentIndex = typeComboBox.find(initialType) } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/BlurHelper.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml similarity index 100% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/BlurHelper.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/BlurHelper.qml diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml new file mode 100644 index 00000000000..95ab2c49bd4 --- /dev/null +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml @@ -0,0 +1,288 @@ +// 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.Controls +import QtQuick.Layouts +import QtQuick.Templates as T +import HelperWidgets as HelperWidgets +import StudioControls as StudioControls +import StudioTheme as StudioTheme +import EffectComposerBackend + +ColumnLayout { + id: root + + spacing: 1 + + readonly property var backendModel: EffectComposerBackend.effectComposerModel + + property var draggedSec: null + property var secsY: [] + property int moveFromIdx: 0 + property int moveToIdx: 0 + property bool previewAnimationRunning: false + + // Invoked after save changes is done + property var onSaveChangesCallback: () => {} + + // Invoked from C++ side when open composition is requested and there are unsaved changes + function promptToSaveBeforeOpen() { + root.onSaveChangesCallback = () => { EffectComposerBackend.rootView.doOpenComposition() } + + saveChangesDialog.open() + } + + Connections { + target: root.backendModel + function onIsEmptyChanged() { + if (root.backendModel.isEmpty) + saveAsDialog.close() + } + } + + SaveAsDialog { + id: saveAsDialog + anchors.centerIn: parent + } + + SaveChangesDialog { + id: saveChangesDialog + anchors.centerIn: parent + + onSave: { + if (root.backendModel.currentComposition === "") { + // if current composition is unsaved, show save as dialog and clear afterwards + saveAsDialog.clearOnClose = true + saveAsDialog.open() + } else { + root.onSaveChangesCallback() + } + } + + onDiscard: { + root.onSaveChangesCallback() + } + } + + EffectComposerTopBar { + Layout.fillWidth: true + + onAddClicked: { + root.onSaveChangesCallback = () => { root.backendModel.clear(true) } + + if (root.backendModel.hasUnsavedChanges) + saveChangesDialog.open() + else + root.backendModel.clear(true) + } + + onSaveClicked: { + let name = root.backendModel.currentComposition + + if (name === "") + saveAsDialog.open() + else + root.backendModel.saveComposition(name) + } + + onSaveAsClicked: saveAsDialog.open() + + onAssignToSelectedClicked: { + root.backendModel.assignToSelected() + } + } + + SplitView { + id: splitView + + Layout.fillWidth: true + Layout.fillHeight: true + + orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical + + handle: Rectangle { + implicitWidth: splitView.orientation === Qt.Horizontal ? 6 : splitView.width + implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : 6 + color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction + : (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover + : "transparent") + } + + EffectComposerPreview { + mainRoot: root + + SplitView.minimumWidth: 250 + SplitView.minimumHeight: 200 + SplitView.preferredWidth: 300 + SplitView.preferredHeight: 300 + Layout.fillWidth: true + Layout.fillHeight: true + + FrameAnimation { + id: previewFrameTimer + running: true + paused: !previewAnimationRunning + } + } + + Column { + spacing: 1 + + SplitView.minimumWidth: 250 + SplitView.minimumHeight: 100 + + Component.onCompleted: HelperWidgets.Controller.mainScrollView = scrollView + + Rectangle { + width: parent.width + height: StudioTheme.Values.toolbarHeight + color: StudioTheme.Values.themeToolbarBackground + + EffectNodesComboBox { + mainRoot: root + + anchors.verticalCenter: parent.verticalCenter + x: 5 + width: parent.width - 50 + } + + HelperWidgets.AbstractButton { + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.clearList_medium + tooltip: qsTr("Remove all effect nodes.") + enabled: !root.backendModel.isEmpty + + onClicked: root.backendModel.clear() + } + + HelperWidgets.AbstractButton { + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.code + tooltip: qsTr("Open Shader in Code Editor.") + visible: false // TODO: to be implemented + + onClicked: {} // TODO + } + } + + Item { + width: parent.width + height: parent.height - y + + HelperWidgets.ScrollView { + id: scrollView + + anchors.fill: parent + clip: true + interactive: !HelperWidgets.Controller.contextMenuOpened + + onContentHeightChanged: { + if (scrollView.contentItem.height > scrollView.height) { + let lastItemH = repeater.itemAt(repeater.count - 1).height + scrollView.contentY = scrollView.contentItem.height - lastItemH + } + } + + Column { + id: nodesCol + width: scrollView.width + spacing: 1 + + Repeater { + id: repeater + + width: parent.width + model: root.backendModel + + onCountChanged: { + HelperWidgets.Controller.setCount("EffectComposer", repeater.count) + } + + delegate: EffectCompositionNode { + width: parent.width + modelIndex: index + + Behavior on y { + PropertyAnimation { + duration: 300 + easing.type: Easing.InOutQuad + } + } + + onStartDrag: (section) => { + root.draggedSec = section + root.moveFromIdx = index + + highlightBorder = true + + root.secsY = [] + for (let i = 0; i < repeater.count; ++i) + root.secsY[i] = repeater.itemAt(i).y + } + + onStopDrag: { + if (root.moveFromIdx === root.moveToIdx) + root.draggedSec.y = root.secsY[root.moveFromIdx] + else + root.backendModel.moveNode(root.moveFromIdx, root.moveToIdx) + + highlightBorder = false + root.draggedSec = null + } + } + } // Repeater + + Timer { + running: root.draggedSec + interval: 50 + repeat: true + + onTriggered: { + 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.height - root.draggedSec.height) * .5) { + 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 (!repeater.model.isDependencyNode(i) + && root.draggedSec.y < currItem.y + (currItem.height - root.draggedSec.height) * .5) { + currItem.y = root.secsY[i] + root.draggedSec.height + nodesCol.spacing + root.moveToIdx = Math.min(root.moveToIdx, i) + } else { + currItem.y = root.secsY[i] + } + } + } + } + } // Timer + } // Column + } // ScrollView + + Text { + text: root.backendModel.isEnabled ? qsTr("Add an effect node to start") + : qsTr("Effect Composer is disabled on MCU projects") + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.baseFontSize + + anchors.centerIn: parent + + visible: root.backendModel.isEmpty + } + } // Item + } // Column + } // SplitView +} diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMakerPreview.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml similarity index 94% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMakerPreview.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml index 16dc2bf3a1c..84c521aac97 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMakerPreview.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerPreview.qml @@ -5,7 +5,7 @@ import QtQuick import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Column { id: root @@ -14,10 +14,8 @@ Column { property int animatedFrame: previewFrameTimer.currentFrame property bool timeRunning: previewAnimationRunning - width: parent.width - required property Item mainRoot - property var effectMakerModel: EffectMakerBackend.effectMakerModel + property var effectComposerModel: EffectComposerBackend.effectComposerModel property alias source: source // The delay in ms to wait until updating the effect readonly property int updateDelay: 100 @@ -33,11 +31,11 @@ Column { oldComponent.destroy(); try { const newObject = Qt.createQmlObject( - effectMakerModel.qmlComponentString, + effectComposerModel.qmlComponentString, componentParent, "" ); - effectMakerModel.resetEffectError(0); + effectComposerModel.resetEffectError(0); } catch (error) { let errorString = "QML: ERROR: "; let errorLine = -1; @@ -47,7 +45,7 @@ Column { errorString += e.lineNumber + ": " + e.message; errorLine = e.lineNumber; } - effectMakerModel.setEffectError(errorString, 0, errorLine); + effectComposerModel.setEffectError(errorString, 0, errorLine); source.visible = true; } } @@ -166,7 +164,7 @@ Column { color: colorEditor.color width: parent.width - height: 200 + height: root.height - y clip: true Item { // Source item as a canvas (render target) for effect @@ -212,7 +210,7 @@ Column { } Connections { - target: effectMakerModel + target: effectComposerModel function onShadersBaked() { console.log("Shaders Baked!") updateTimer.restart() @@ -223,7 +221,7 @@ Column { id: updateTimer interval: updateDelay onTriggered: { - effectMakerModel.updateQmlComponent() + effectComposerModel.updateQmlComponent() createNewComponent() } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMakerTopBar.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerTopBar.qml similarity index 75% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMakerTopBar.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerTopBar.qml index 2dfa8562377..c01bc6dc992 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMakerTopBar.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposerTopBar.qml @@ -5,15 +5,16 @@ import QtQuick import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Rectangle { id: root - width: parent.width height: StudioTheme.Values.toolbarHeight color: StudioTheme.Values.themeToolbarBackground + readonly property var backendModel: EffectComposerBackend.effectComposerModel + signal addClicked signal saveClicked signal saveAsClicked @@ -27,7 +28,7 @@ Rectangle { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.add_medium tooltip: qsTr("Add new composition") - + enabled: root.backendModel.isEnabled onClicked: root.addClicked() } @@ -35,8 +36,8 @@ Rectangle { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.save_medium tooltip: qsTr("Save current composition") - enabled: EffectMakerBackend.effectMakerModel.hasUnsavedChanges - || EffectMakerBackend.effectMakerModel.currentComposition === "" + enabled: root.backendModel.isEnabled && (root.backendModel.hasUnsavedChanges + || root.backendModel.currentComposition === "") onClicked: root.saveClicked() } @@ -45,7 +46,7 @@ Rectangle { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.saveAs_medium tooltip: qsTr("Save current composition with a new name") - enabled: !EffectMakerBackend.effectMakerModel.isEmpty + enabled: root.backendModel.isEnabled && !root.backendModel.isEmpty onClicked: root.saveAsClicked() } @@ -54,7 +55,7 @@ Rectangle { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.assignTo_medium tooltip: qsTr("Assign current composition to selected item") - enabled: EffectMakerBackend.effectMakerModel.currentComposition !== "" + enabled: root.backendModel.isEnabled && root.backendModel.currentComposition !== "" onClicked: root.assignToSelectedClicked() } @@ -62,7 +63,7 @@ Rectangle { Text { - readonly property string compName: EffectMakerBackend.effectMakerModel.currentComposition + readonly property string compName: root.backendModel.currentComposition text: compName !== "" ? compName : qsTr("Untitled") anchors.centerIn: parent @@ -76,11 +77,13 @@ Rectangle { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.help - tooltip: qsTr("How to use Effect Maker: + tooltip: qsTr("How to use Effect Composer: 1. Click \"+ Add Effect\" to add effect node 2. Adjust the effect nodes properties 3. Change the order of the effects, if you like 4. See the preview 5. Save in the library, if you wish to reuse the effect later") // TODO: revise with doc engineer + + onClicked: Qt.openUrlExternally("https://doc.qt.io/qtdesignstudio/qt-using-effect-maker-effects.html") } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectCompositionNode.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml similarity index 87% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/EffectCompositionNode.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml index c1cd4632d24..6defa3b0922 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectCompositionNode.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNode.qml @@ -6,7 +6,7 @@ import QtQuick.Controls import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend HelperWidgets.Section { id: root @@ -14,7 +14,7 @@ HelperWidgets.Section { property int modelIndex: 0 caption: nodeName - category: "EffectMaker" + category: "EffectComposer" draggable: !isDependency fillBackground: true @@ -23,7 +23,7 @@ HelperWidgets.Section { visible: repeater.count > 0 || !isDependency onCloseButtonClicked: { - EffectMakerBackend.effectMakerModel.removeNode(root.modelIndex) + EffectComposerBackend.effectComposerModel.removeNode(root.modelIndex) } showEyeButton: !isDependency diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectCompositionNodeUniform.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml similarity index 98% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/EffectCompositionNodeUniform.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml index 9cd42633d4a..8dc3b75c9b5 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectCompositionNodeUniform.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectCompositionNodeUniform.qml @@ -7,7 +7,7 @@ import QtQuick.Layouts import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Item { id: root diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectNode.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectNode.qml similarity index 80% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/EffectNode.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/EffectNode.qml index 865b60cf824..dd361b08d73 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectNode.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectNode.qml @@ -6,7 +6,7 @@ import QtQuick.Controls import HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Rectangle { id: root @@ -25,7 +25,8 @@ Rectangle { anchors.fill: parent acceptedButtons: Qt.LeftButton - tooltip: modelData.canBeAdded ? "" : qsTr("Existing effect has conflicting properties, this effect cannot be added.") + tooltip: modelData.canBeAdded ? modelData.nodeDescription + : qsTr("Existing effect has conflicting properties, this effect cannot be added.") onClicked: { if (modelData.canBeAdded) @@ -35,6 +36,7 @@ Rectangle { Row { spacing: 5 + anchors.fill: parent IconImage { id: nodeIcon @@ -51,8 +53,11 @@ Rectangle { text: modelData.nodeName color: modelData.canBeAdded ? StudioTheme.Values.themeTextColor : StudioTheme.Values.themeTextColorDisabled + font.pointSize: StudioTheme.Values.smallFontSize anchors.verticalCenter: nodeIcon.verticalCenter + wrapMode: Text.WordWrap + width: parent.width - parent.spacing - nodeIcon.width } } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectNodesComboBox.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectNodesComboBox.qml similarity index 90% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/EffectNodesComboBox.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/EffectNodesComboBox.qml index dc6f54a5aa8..dbab36051d2 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectNodesComboBox.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectNodesComboBox.qml @@ -5,7 +5,7 @@ import QtQuick import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend StudioControls.ComboBox { id: root @@ -23,8 +23,8 @@ StudioControls.ComboBox { readonly property int popupHeight: Math.min(800, row.height + 2) function calculateWindowGeometry() { - var globalPos = EffectMakerBackend.rootView.globalPos(mainRoot.mapFromItem(root, 0, 0)) - var screenRect = EffectMakerBackend.rootView.screenRect(); + var globalPos = EffectComposerBackend.rootView.globalPos(mainRoot.mapFromItem(root, 0, 0)) + var screenRect = EffectComposerBackend.rootView.screenRect(); window.width = row.width + 2 // 2: scrollView left and right 1px margins @@ -97,7 +97,7 @@ StudioControls.ComboBox { spacing: 10 Repeater { - model: EffectMakerBackend.effectMakerNodesModel + model: EffectComposerBackend.effectComposerNodesModel Column { spacing: 10 @@ -115,7 +115,7 @@ StudioControls.ComboBox { EffectNode { onAddEffectNode: (nodeQenPath) => { - EffectMakerBackend.rootView.addEffectNode(modelData.nodeQenPath) + EffectComposerBackend.rootView.addEffectNode(modelData.nodeQenPath) root.popup.close() } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/PreviewImagesComboBox.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/PreviewImagesComboBox.qml similarity index 96% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/PreviewImagesComboBox.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/PreviewImagesComboBox.qml index 988b28a0729..2a35606a14a 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/PreviewImagesComboBox.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/PreviewImagesComboBox.qml @@ -5,7 +5,7 @@ import QtQuick import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend StudioControls.ComboBox { id: root @@ -32,8 +32,8 @@ StudioControls.ComboBox { readonly property int popupHeight: Math.min(800, col.height + 2) function calculateWindowGeometry() { - var globalPos = EffectMakerBackend.rootView.globalPos(mainRoot.mapFromItem(root, 0, 0)) - var screenRect = EffectMakerBackend.rootView.screenRect(); + var globalPos = EffectComposerBackend.rootView.globalPos(mainRoot.mapFromItem(root, 0, 0)) + var screenRect = EffectComposerBackend.rootView.screenRect(); window.width = col.width + 2 // 2: scrollView left and right 1px margins diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/SaveAsDialog.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/SaveAsDialog.qml similarity index 87% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/SaveAsDialog.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/SaveAsDialog.qml index eef24116697..d1bb00d9237 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/SaveAsDialog.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/SaveAsDialog.qml @@ -6,7 +6,7 @@ import QtQuick.Controls import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend StudioControls.Dialog { id: root @@ -18,10 +18,10 @@ StudioControls.Dialog { implicitWidth: 250 implicitHeight: 160 - property bool clearOnClose: false // clear the effect maker after saving + property bool clearOnClose: false // clear the effect composer after saving onOpened: { - nameText.text = EffectMakerBackend.effectMakerModel.getUniqueEffectName() + nameText.text = EffectComposerBackend.effectComposerModel.getUniqueEffectName() nameText.selectAll() nameText.forceActiveFocus() emptyText.text = "" @@ -87,10 +87,10 @@ StudioControls.Dialog { if (!enabled) // needed since this event handler can be triggered from keyboard events return - EffectMakerBackend.effectMakerModel.saveComposition(nameText.text) + EffectComposerBackend.effectComposerModel.saveComposition(nameText.text) if (root.clearOnClose) { - EffectMakerBackend.effectMakerModel.clear() + EffectComposerBackend.effectComposerModel.clear() root.clearOnClose = false } @@ -103,7 +103,7 @@ StudioControls.Dialog { onClicked: { if (root.clearOnClose) { - EffectMakerBackend.effectMakerModel.clear() + EffectComposerBackend.effectComposerModel.clear() root.clearOnClose = false } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/SaveChangesDialog.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/SaveChangesDialog.qml similarity index 87% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/SaveChangesDialog.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/SaveChangesDialog.qml index c048c645d84..1e466c1100f 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/SaveChangesDialog.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/SaveChangesDialog.qml @@ -6,7 +6,7 @@ import QtQuick.Controls import HelperWidgets as HelperWidgets import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend StudioControls.Dialog { id: root @@ -43,9 +43,9 @@ StudioControls.Dialog { width: 50 text: qsTr("Save") onClicked: { - let name = EffectMakerBackend.effectMakerModel.currentComposition + let name = EffectComposerBackend.effectComposerModel.currentComposition if (name !== "") - EffectMakerBackend.effectMakerModel.saveComposition(name) + EffectComposerBackend.effectComposerModel.saveComposition(name) root.save() root.accept() diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueBool.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueBool.qml new file mode 100644 index 00000000000..9d2a518dcf0 --- /dev/null +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueBool.qml @@ -0,0 +1,16 @@ +// 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 StudioControls as StudioControls +import StudioTheme as StudioTheme +import EffectComposerBackend + +Item { // The wrapper Item is used to limit hovering and clicking the CheckBox to its area + StudioControls.CheckBox { + actionIndicatorVisible: false + checked: uniformValue + onToggled: uniformValue = checked + anchors.verticalCenter: parent.verticalCenter + } +} diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueColor.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueColor.qml similarity index 94% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueColor.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueColor.qml index 5d86d3513f4..4b00bd76135 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueColor.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueColor.qml @@ -4,7 +4,7 @@ import QtQuick import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Row { id: itemPane diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueDefine.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueDefine.qml similarity index 94% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueDefine.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueDefine.qml index 7aa4a8a568c..b854cd890cb 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueDefine.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueDefine.qml @@ -4,7 +4,7 @@ import QtQuick import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Row { width: parent.width diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueFloat.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueFloat.qml similarity index 97% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueFloat.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueFloat.qml index ea557b18776..61c5dca825f 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueFloat.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueFloat.qml @@ -4,7 +4,7 @@ import QtQuick import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Row { width: parent.width diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueImage.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueImage.qml similarity index 74% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueImage.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueImage.qml index a4f3ccd5aee..b172eb302eb 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueImage.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueImage.qml @@ -4,18 +4,18 @@ import QtQuick import HelperWidgets as HelperWidgets import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Row { id: itemPane - width: parent.width spacing: 5 HelperWidgets.UrlChooser { backendValue: uniformBackendValue actionIndicatorVisible: false + comboBox.width: Math.min(parent.width - 70, 300) onAbsoluteFilePathChanged: uniformValue = absoluteFilePath @@ -30,7 +30,7 @@ Row { return urlStr } - defaultItems: [uniformDefaultValue.split('/').pop()] - defaultPaths: [defaultAsString(uniformDefaultValue)] + defaultItems: uniformDefaultValue ? [uniformDefaultValue.split('/').pop()] : undefined + defaultPaths: uniformDefaultValue ? [defaultAsString(uniformDefaultValue)] : undefined } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueInt.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueInt.qml similarity index 88% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueInt.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueInt.qml index 38a95f4970f..86ba9ba78d4 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueInt.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueInt.qml @@ -4,7 +4,7 @@ import QtQuick import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend Row { width: parent.width @@ -35,8 +35,8 @@ Row { to: uniformMaxValue value: uniformValue onMoved: { - uniformValue = value - spinBox.value = value + uniformValue = Math.round(value) + spinBox.value = Math.round(value) } } } diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec2.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec2.qml similarity index 98% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec2.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec2.qml index a5c0c9db74a..0685b5f41a2 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec2.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec2.qml @@ -5,7 +5,7 @@ import QtQuick import QtQuick.Layouts import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend RowLayout { width: parent.width diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec3.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec3.qml similarity index 99% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec3.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec3.qml index 5369795a680..bb33cb68e4f 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec3.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec3.qml @@ -5,7 +5,7 @@ import QtQuick import QtQuick.Layouts import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend RowLayout { width: parent.width diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec4.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec4.qml similarity index 99% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec4.qml rename to share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec4.qml index bb93cd00080..bcb35161466 100644 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueVec4.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/ValueVec4.qml @@ -5,7 +5,7 @@ import QtQuick import QtQuick.Layouts import StudioControls as StudioControls import StudioTheme as StudioTheme -import EffectMakerBackend +import EffectComposerBackend RowLayout { width: parent.width diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview0.png b/share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview0.png similarity index 100% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview0.png rename to share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview0.png diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview1.png b/share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview1.png similarity index 100% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview1.png rename to share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview1.png diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview2.png b/share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview2.png similarity index 100% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview2.png rename to share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview2.png diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview3.png b/share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview3.png similarity index 100% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview3.png rename to share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview3.png diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview4.png b/share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview4.png similarity index 100% rename from share/qtcreator/qmldesigner/effectMakerQmlSources/images/preview4.png rename to share/qtcreator/qmldesigner/effectComposerQmlSources/images/preview4.png diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMaker.qml b/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMaker.qml deleted file mode 100644 index d86aaad27d2..00000000000 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/EffectMaker.qml +++ /dev/null @@ -1,243 +0,0 @@ -// 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 HelperWidgets as HelperWidgets -import StudioControls as StudioControls -import StudioTheme as StudioTheme -import EffectMakerBackend - -Item { - id: root - - property var draggedSec: null - property var secsY: [] - property int moveFromIdx: 0 - property int moveToIdx: 0 - property bool previewAnimationRunning: false - - // Invoked after save changes is done - property var onSaveChangesCallback: () => {} - - // Invoked from C++ side when open composition is requested and there are unsaved changes - function promptToSaveBeforeOpen() { - root.onSaveChangesCallback = () => { EffectMakerBackend.rootView.doOpenComposition() } - - saveChangesDialog.open() - } - - Connections { - target: EffectMakerBackend.effectMakerModel - function onIsEmptyChanged() { - if (EffectMakerBackend.effectMakerModel.isEmpty) - saveAsDialog.close() - } - } - - SaveAsDialog { - id: saveAsDialog - anchors.centerIn: parent - } - - SaveChangesDialog { - id: saveChangesDialog - anchors.centerIn: parent - - onSave: { - if (EffectMakerBackend.effectMakerModel.currentComposition === "") { - // if current composition is unsaved, show save as dialog and clear afterwards - saveAsDialog.clearOnClose = true - saveAsDialog.open() - } else { - root.onSaveChangesCallback() - } - } - - onDiscard: { - root.onSaveChangesCallback() - } - } - - Column { - id: col - anchors.fill: parent - spacing: 1 - - EffectMakerTopBar { - onAddClicked: { - root.onSaveChangesCallback = () => { EffectMakerBackend.effectMakerModel.clear(true) } - - if (EffectMakerBackend.effectMakerModel.hasUnsavedChanges) - saveChangesDialog.open() - else - EffectMakerBackend.effectMakerModel.clear(true) - } - - onSaveClicked: { - let name = EffectMakerBackend.effectMakerModel.currentComposition - - if (name === "") - saveAsDialog.open() - else - EffectMakerBackend.effectMakerModel.saveComposition(name) - } - - onSaveAsClicked: saveAsDialog.open() - - onAssignToSelectedClicked: { - EffectMakerBackend.effectMakerModel.assignToSelected() - } - } - - EffectMakerPreview { - mainRoot: root - - FrameAnimation { - id: previewFrameTimer - running: true - paused: !previewAnimationRunning - } - } - - Rectangle { - width: parent.width - height: StudioTheme.Values.toolbarHeight - color: StudioTheme.Values.themeToolbarBackground - - EffectNodesComboBox { - mainRoot: root - - anchors.verticalCenter: parent.verticalCenter - x: 5 - width: parent.width - 50 - } - - HelperWidgets.AbstractButton { - anchors.right: parent.right - anchors.rightMargin: 5 - anchors.verticalCenter: parent.verticalCenter - - style: StudioTheme.Values.viewBarButtonStyle - buttonIcon: StudioTheme.Constants.clearList_medium - tooltip: qsTr("Remove all effect nodes.") - enabled: !EffectMakerBackend.effectMakerModel.isEmpty - - onClicked: EffectMakerBackend.effectMakerModel.clear() - } - - HelperWidgets.AbstractButton { - anchors.right: parent.right - anchors.rightMargin: 5 - anchors.verticalCenter: parent.verticalCenter - - style: StudioTheme.Values.viewBarButtonStyle - buttonIcon: StudioTheme.Constants.code - tooltip: qsTr("Open Shader in Code Editor.") - visible: false // TODO: to be implemented - - onClicked: {} // TODO - } - } - - Component.onCompleted: HelperWidgets.Controller.mainScrollView = scrollView - - HelperWidgets.ScrollView { - id: scrollView - - width: parent.width - height: parent.height - y - clip: true - - Column { - width: scrollView.width - spacing: 1 - - Repeater { - id: repeater - - width: root.width - model: EffectMakerBackend.effectMakerModel - - onCountChanged: { - HelperWidgets.Controller.setCount("EffectMaker", repeater.count) - } - - delegate: EffectCompositionNode { - width: root.width - modelIndex: index - - Behavior on y { - PropertyAnimation { - duration: 300 - easing.type: Easing.InOutQuad - } - } - - onStartDrag: (section) => { - root.draggedSec = section - root.moveFromIdx = index - - highlightBorder = true - - root.secsY = [] - for (let i = 0; i < repeater.count; ++i) - root.secsY[i] = repeater.itemAt(i).y - } - - onStopDrag: { - if (root.moveFromIdx === root.moveToIdx) - root.draggedSec.y = root.secsY[root.moveFromIdx] - else - EffectMakerBackend.effectMakerModel.moveNode(root.moveFromIdx, root.moveToIdx) - - highlightBorder = false - root.draggedSec = null - } - } - } // Repeater - - Timer { - running: root.draggedSec - interval: 50 - repeat: true - - onTriggered: { - 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.height - root.draggedSec.height) * .5) { - currItem.y = root.secsY[i] - root.draggedSec.height - root.moveToIdx = i - } else { - currItem.y = root.secsY[i] - } - } else if (i < root.moveFromIdx) { - if (!repeater.model.isDependencyNode(i) - && root.draggedSec.y < currItem.y + (currItem.height - root.draggedSec.height) * .5) { - currItem.y = root.secsY[i] + root.draggedSec.height - root.moveToIdx = Math.min(root.moveToIdx, i) - } else { - currItem.y = root.secsY[i] - } - } - } - } - } // Timer - } // Column - } // ScrollView - } - - Text { - id: emptyText - - text: qsTr("Add an effect node to start") - color: StudioTheme.Values.themeTextColor - font.pixelSize: StudioTheme.Values.baseFontSize - - x: scrollView.x + (scrollView.width - emptyText.width) * .5 - y: scrollView.y + scrollView.height * .5 - - visible: EffectMakerBackend.effectMakerModel.isEmpty - } -} diff --git a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueBool.qml b/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueBool.qml deleted file mode 100644 index f59a3a4408b..00000000000 --- a/share/qtcreator/qmldesigner/effectMakerQmlSources/ValueBool.qml +++ /dev/null @@ -1,13 +0,0 @@ -// 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 StudioControls as StudioControls -import StudioTheme as StudioTheme -import EffectMakerBackend - -StudioControls.CheckBox { - actionIndicatorVisible: false - checked: uniformValue - onToggled: uniformValue = checked -} diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index f9e72ad67da..4b4d2b8dc6a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -237,6 +237,7 @@ SecondColumnLayout { shapeGradients: colorEditor.shapeGradients supportGradient: colorEditor.supportGradient width: popupDialog.contentWidth + visible: popupDialog.visible } onLoaded: { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml index 0591d1cb5a2..22be367c378 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml @@ -827,7 +827,7 @@ Column { twoColumnWidth: root.twoColumnWidth fourColumnWidth: root.fourColumnWidth - enableSingletonConnection: root.opened + enableSingletonConnection: root.visible onSelectedColorChanged: { colorPicker.color = colorPalette.selectedColor colorEditor.color = colorPalette.selectedColor diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml index b3353f2fba2..39176ca82a9 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml @@ -516,6 +516,8 @@ Section { return aliasEditor if (propertyType == "variant") return readonlyEditor + if (propertyType == "var") + return readonlyEditor if (propertyType == "TextureInput") return textureInputEditor if (propertyType == "vector2d" || propertyType == "vector3d" || propertyType == "vector4d") diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml index 16d74c66f07..6c0e334dec6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/UrlChooser.qml @@ -32,6 +32,8 @@ Row { property alias spacer: spacer property alias actionIndicatorVisible: comboBox.actionIndicatorVisible + property bool hideDuplicates: true + FileResourcesModel { id: fileModel modelNodeBackendProperty: modelNodeBackend @@ -423,6 +425,8 @@ Row { // QtDS very slow. This will happen when selecting different items in the scene. comboBox.model = {} + let nameSet = new Set; + if (root.defaultItems !== undefined) { for (var i = 0; i < root.defaultItems.length; ++i) { comboBox.listModel.append({ @@ -433,6 +437,7 @@ Row { name: root.defaultItems[i], group: 0 }) + nameSet.add(root.defaultItems[i]) } } @@ -440,12 +445,15 @@ Row { for (var j = 0; j < myModel.length; ++j) { let item = myModel[j] - comboBox.listModel.append({ - absoluteFilePath: item.absoluteFilePath, - relativeFilePath: item.relativeFilePath, - name: item.fileName, - group: 1 - }) + if (!root.hideDuplicates || !nameSet.has(item.fileName)) { + comboBox.listModel.append({ + absoluteFilePath: item.absoluteFilePath, + relativeFilePath: item.relativeFilePath, + name: item.fileName, + group: 1 + }) + nameSet.add(item.fileName) + } } comboBox.model = Qt.binding(function() { return comboBox.listModel }) @@ -461,6 +469,7 @@ Row { onDefaultItemsChanged: root.createModel() onDefaultPathsChanged: root.createModel() + onHideDuplicatesChanged: root.createModel() Component.onCompleted: { root.createModel() diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml index 9069370e9c9..640f21de9e2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml @@ -90,6 +90,7 @@ Item { sourceComponent: ColorEditorPopup { id: popup width: popupDialog.contentWidth + visible: popupDialog.visible onActivateColor: function(color) { colorBackend.activateColor(color) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml index 6b2e6b75cbb..fadebdd720b 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml @@ -246,6 +246,10 @@ QtObject { property real collectionItemTextSideMargin: 10 property real collectionItemTextMargin: 5 property real collectionItemTextPadding: 5 + property real collectionTableHorizontalMargin: 10 + property real collectionTableVerticalMargin: 10 + property real collectionCellMinimumWidth: 60 + property real collectionCellMinimumHeight: 20 // NEW NEW NEW readonly property int flowMargin: 7 diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl index 1c57554f38b..8c72c47af2d 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl @@ -52,10 +52,10 @@ Rectangle { Item { id: __materialLibrary__ - DefaultMaterial { + PrincipledMaterial { id: defaultMaterial objectName: "Default Material" - diffuseColor: "#4aee45" + baseColor: "#4aee45" } } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index 2a2e1bd53d0..d5b1fef1e45 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -382,22 +382,6 @@ { "source": "../shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo" - }, - { - "source": "../shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml" - }, - { - "source": "../shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml" - }, - { - "source": "../shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json" - }, - { - "source": "../shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index 24434e00762..0708838a5ae 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -395,22 +395,6 @@ { "source": "../shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo" - }, - { - "source": "../shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml" - }, - { - "source": "../shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml" - }, - { - "source": "../shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json" - }, - { - "source": "../shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index 2f590855690..913eb0bf28b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -382,22 +382,6 @@ { "source": "../shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo" - }, - { - "source": "../shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml" - }, - { - "source": "../shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml" - }, - { - "source": "../shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json" - }, - { - "source": "../shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 008e3eb9952..944b6b6289c 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -341,22 +341,6 @@ { "source": "../shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo" - }, - { - "source": "../shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml" - }, - { - "source": "../shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml" - }, - { - "source": "../shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json" - }, - { - "source": "../shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index e385b58ff8f..c8733770e07 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -343,22 +343,6 @@ { "source": "../shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo" - }, - { - "source": "../shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml" - }, - { - "source": "../shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml" - }, - { - "source": "../shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json" - }, - { - "source": "../shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index 47fe3bd4e3d..295c85aa63a 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -343,22 +343,6 @@ { "source": "../shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo" - }, - { - "source": "../shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml" - }, - { - "source": "../shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml" - }, - { - "source": "../shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json" - }, - { - "source": "../shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl index 3b74123f7b0..e3cc78f3421 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl @@ -13,12 +13,7 @@ qt6_add_qml_module(%{ImportModuleName} RESOURCE_PREFIX "/qt/qml" QML_FILES Constants.qml - DataStore.qml DirectoryFontLoader.qml EventListModel.qml EventListSimulator.qml - JsonData.qml - RESOURCES - data.json - models.json ) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl index a0ec2f17cfc..c0050290386 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl @@ -1,5 +1,4 @@ Module %{ImportModuleName} -singleton DataStore 1.0 DataStore.qml singleton Constants 1.0 Constants.qml EventListSimulator 1.0 EventListSimulator.qml EventListModel 1.0 EventListModel.qml diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir index b5924a433cc..3ba5adcc643 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir @@ -1,5 +1,4 @@ singleton Constants 1.0 Constants.qml -singleton DataStore 1.0 DataStore.qml EventListModel 1.0 EventListModel.qml EventListSimulator 1.0 EventListSimulator.qml DirectoryFontLoader 1.0 DirectoryFontLoader.qml diff --git a/share/qtcreator/qmldesigner/welcomepage/TwitterButton.qml b/share/qtcreator/qmldesigner/welcomepage/FigmaButton.qml similarity index 75% rename from share/qtcreator/qmldesigner/welcomepage/TwitterButton.qml rename to share/qtcreator/qmldesigner/welcomepage/FigmaButton.qml index 9349fcd32c3..6fa8d3f92fc 100644 --- a/share/qtcreator/qmldesigner/welcomepage/TwitterButton.qml +++ b/share/qtcreator/qmldesigner/welcomepage/FigmaButton.qml @@ -6,29 +6,29 @@ import WelcomeScreen 1.0 import StudioTheme 1.0 as StudioTheme Item { - id: twitterButton + id: figmaButton state: "darkNormal" property bool isHovered: mouseArea.containsMouse Image { - id: twitterDarkNormal + id: figmaDarkNormal anchors.fill: parent - source: "images/twitterDarkNormal.png" + source: "images/figmaDarkNormal.png" fillMode: Image.PreserveAspectFit } Image { - id: twitterLightNormal + id: figmaLightNormal anchors.fill: parent - source: "images/twitterLightNormal.png" + source: "images/figmaLightNormal.png" fillMode: Image.PreserveAspectFit } Image { - id: twitterHover + id: figmaHover anchors.fill: parent - source: "images/twitterHover.png" + source: "images/figmaHover.png" fillMode: Image.PreserveAspectFit } @@ -39,7 +39,7 @@ Item { Connections { target: mouseArea - function onClicked(mouse) { Qt.openUrlExternally("https://twitter.com/qtproject/") } + function onClicked(mouse) { Qt.openUrlExternally("https://www.figma.com/@qtdesignstudio/") } } } @@ -49,17 +49,17 @@ Item { when: !StudioTheme.Values.isLightTheme && !mouseArea.containsMouse && !mouseArea.pressed PropertyChanges { - target: twitterDarkNormal + target: figmaDarkNormal visible: true } PropertyChanges { - target: twitterLightNormal + target: figmaLightNormal visible: false } PropertyChanges { - target: twitterHover + target: figmaHover visible: false } }, @@ -68,17 +68,17 @@ Item { when: StudioTheme.Values.isLightTheme && !mouseArea.containsMouse && !mouseArea.pressed PropertyChanges { - target: twitterHover + target: figmaHover visible: false } PropertyChanges { - target: twitterLightNormal + target: figmaLightNormal visible: true } PropertyChanges { - target: twitterDarkNormal + target: figmaDarkNormal visible: false } }, @@ -87,17 +87,17 @@ Item { when: mouseArea.containsMouse && !mouseArea.pressed PropertyChanges { - target: twitterHover + target: figmaHover visible: true } PropertyChanges { - target: twitterLightNormal + target: figmaLightNormal visible: false } PropertyChanges { - target: twitterDarkNormal + target: figmaDarkNormal visible: false } }, @@ -106,18 +106,18 @@ Item { when: (mouseArea.containsMouse || !mouseArea.containsMouse) && mouseArea.pressed PropertyChanges { - target: twitterHover + target: figmaHover visible: true scale: 1.1 } PropertyChanges { - target: twitterLightNormal + target: figmaLightNormal visible: false } PropertyChanges { - target: twitterDarkNormal + target: figmaDarkNormal visible: false } } diff --git a/share/qtcreator/qmldesigner/welcomepage/SocialButton.qml b/share/qtcreator/qmldesigner/welcomepage/SocialButton.qml index 864486966d3..1da340845d2 100644 --- a/share/qtcreator/qmldesigner/welcomepage/SocialButton.qml +++ b/share/qtcreator/qmldesigner/welcomepage/SocialButton.qml @@ -80,8 +80,8 @@ Button { Layout.fillWidth: true } - TwitterButton { - id: twitterButton + FigmaButton { + id: figmaButton Layout.maximumHeight: 15 Layout.minimumHeight: 15 Layout.preferredHeight: 15 @@ -100,7 +100,7 @@ Button { states: [ State { name: "normal" - when: !youtubeButton.isHovered && !twitterButton.isHovered && !control.hovered + when: !youtubeButton.isHovered && !figmaButton.isHovered && !control.hovered PropertyChanges { target: buttonBackground @@ -110,7 +110,7 @@ Button { }, State { name: "hover" - when: control.hovered || youtubeButton.isHovered || twitterButton.isHovered + when: control.hovered || youtubeButton.isHovered || figmaButton.isHovered PropertyChanges { target: buttonBackground diff --git a/share/qtcreator/qmldesigner/welcomepage/images/figmaDarkNormal.png b/share/qtcreator/qmldesigner/welcomepage/images/figmaDarkNormal.png new file mode 100644 index 00000000000..0e55d19e9ad Binary files /dev/null and b/share/qtcreator/qmldesigner/welcomepage/images/figmaDarkNormal.png differ diff --git a/share/qtcreator/qmldesigner/welcomepage/images/figmaHover.png b/share/qtcreator/qmldesigner/welcomepage/images/figmaHover.png new file mode 100644 index 00000000000..2436cbf27cd Binary files /dev/null and b/share/qtcreator/qmldesigner/welcomepage/images/figmaHover.png differ diff --git a/share/qtcreator/qmldesigner/welcomepage/images/figmaLightNormal.png b/share/qtcreator/qmldesigner/welcomepage/images/figmaLightNormal.png new file mode 100644 index 00000000000..3281ce31753 Binary files /dev/null and b/share/qtcreator/qmldesigner/welcomepage/images/figmaLightNormal.png differ diff --git a/share/qtcreator/qmldesigner/welcomepage/images/twitterDarkNormal.png b/share/qtcreator/qmldesigner/welcomepage/images/twitterDarkNormal.png deleted file mode 100644 index bd2349329c3..00000000000 Binary files a/share/qtcreator/qmldesigner/welcomepage/images/twitterDarkNormal.png and /dev/null differ diff --git a/share/qtcreator/qmldesigner/welcomepage/images/twitterHover.png b/share/qtcreator/qmldesigner/welcomepage/images/twitterHover.png deleted file mode 100644 index a10316113d0..00000000000 Binary files a/share/qtcreator/qmldesigner/welcomepage/images/twitterHover.png and /dev/null differ diff --git a/share/qtcreator/qmldesigner/welcomepage/images/twitterLightNormal.png b/share/qtcreator/qmldesigner/welcomepage/images/twitterLightNormal.png deleted file mode 100644 index b6ad88c5b62..00000000000 Binary files a/share/qtcreator/qmldesigner/welcomepage/images/twitterLightNormal.png and /dev/null differ diff --git a/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk b/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk index 011ead83a65..f072a348f3c 100644 --- a/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk +++ b/share/qtcreator/qmldesigner/workspacePresets/Views-All.wrk @@ -74,8 +74,8 @@ AdnQywADAAAAAAQuAAAB5gAABdEAAAOcAAAELgAAAfkAAAXRAAADnAAAAAAAAAAACgAAAAQuAAAB+QAABdEAAAOc - - + + 420 diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json index ddc90597ded..2e885c2bb63 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json @@ -261,26 +261,6 @@ "source": "%{QdsWizardPath}/shared-plugin/name/designer/plugin.metainfo", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/designer/plugin.metainfo", "condition": "%{QdsProjectStyle}" - }, - { - "source": "%{QdsWizardPath}/shared-plugin/name/JsonData.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/JsonData.qml", - "condition": "%{QdsProjectStyle}" - }, - { - "source": "%{QdsWizardPath}/shared-plugin/name/DataStore.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DataStore.qml", - "condition": "%{QdsProjectStyle}" - }, - { - "source": "%{QdsWizardPath}/shared-plugin/name/models.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/models.json", - "condition": "%{QdsProjectStyle}" - }, - { - "source": "%{QdsWizardPath}/shared-plugin/name/data.json.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/data.json", - "condition": "%{QdsProjectStyle}" } ] } diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 34671d290fc..85de56b4285 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -109,7 +109,7 @@ if (WITH_QMLDESIGNER) set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr) endif() add_subdirectory(qmldesigner ${qmldesigner_builddir}) - add_subdirectory(effectmakernew) + add_subdirectory(effectcomposer) add_subdirectory(studiowelcome) add_subdirectory(insight) endif() diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp index aafa1741526..4b75c15a7e0 100644 --- a/src/plugins/coreplugin/generalsettings.cpp +++ b/src/plugins/coreplugin/generalsettings.cpp @@ -110,6 +110,10 @@ GeneralSettingsWidget::GeneralSettingsWidget() m_languageBox->setObjectName("languageBox"); m_languageBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); m_languageBox->setMinimumContentsLength(20); + if (Core::ICore::isQtDesignStudio()) { + m_languageBox->setDisabled(true); + m_languageBox->setToolTip("Qt Design Studio is currently available in English only."); + } m_codecBox->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); m_codecBox->setMinimumContentsLength(20); @@ -211,7 +215,7 @@ void GeneralSettingsWidget::fillLanguageBox() const m_languageBox->addItem(Tr::tr(""), QString()); // need to add this explicitly, since there is no qm file for English m_languageBox->addItem(QLatin1String("English"), QLatin1String("C")); - if (currentLocale == QLatin1String("C")) + if (currentLocale == QLatin1String("C") || Core::ICore::isQtDesignStudio()) m_languageBox->setCurrentIndex(m_languageBox->count() - 1); const FilePath creatorTrPath = ICore::resourcePath("translations"); diff --git a/src/plugins/effectmakernew/CMakeLists.txt b/src/plugins/effectcomposer/CMakeLists.txt similarity index 59% rename from src/plugins/effectmakernew/CMakeLists.txt rename to src/plugins/effectcomposer/CMakeLists.txt index bd7b0f723f4..71805ea1be2 100644 --- a/src/plugins/effectmakernew/CMakeLists.txt +++ b/src/plugins/effectcomposer/CMakeLists.txt @@ -1,4 +1,4 @@ -add_qtc_plugin(EffectMakerNew +add_qtc_plugin(EffectComposer CONDITION TARGET Qt::Quick AND TARGET QtCreator::QmlDesigner PLUGIN_DEPENDS QtCreator::QmlDesigner QtCreator::ProjectExplorer QtCreator::QmlProjectManager @@ -6,18 +6,18 @@ add_qtc_plugin(EffectMakerNew Qt::Core Qt::CorePrivate Qt::Widgets Qt::Qml Qt::QmlPrivate Qt::Quick QtCreator::Utils SOURCES - effectmakerplugin.cpp - effectmakerwidget.cpp effectmakerwidget.h - effectmakerview.cpp effectmakerview.h - effectmakermodel.cpp effectmakermodel.h - effectmakernodesmodel.cpp effectmakernodesmodel.h - effectmakeruniformsmodel.cpp effectmakeruniformsmodel.h + effectcomposerplugin.cpp + effectcomposerwidget.cpp effectcomposerwidget.h + effectcomposerview.cpp effectcomposerview.h + effectcomposermodel.cpp effectcomposermodel.h + effectcomposernodesmodel.cpp effectcomposernodesmodel.h + effectcomposeruniformsmodel.cpp effectcomposeruniformsmodel.h effectnode.cpp effectnode.h effectnodescategory.cpp effectnodescategory.h compositionnode.cpp compositionnode.h uniform.cpp uniform.h effectutils.cpp effectutils.h - effectmakercontextobject.cpp effectmakercontextobject.h + effectcomposercontextobject.cpp effectcomposercontextobject.h shaderfeatures.cpp shaderfeatures.h syntaxhighlighterdata.cpp syntaxhighlighterdata.h propertyhandler.cpp propertyhandler.h diff --git a/src/plugins/effectmakernew/EffectMakerNew.json.in b/src/plugins/effectcomposer/EffectComposer.json.in similarity index 88% rename from src/plugins/effectmakernew/EffectMakerNew.json.in rename to src/plugins/effectcomposer/EffectComposer.json.in index c48476418b5..48c6955796f 100644 --- a/src/plugins/effectmakernew/EffectMakerNew.json.in +++ b/src/plugins/effectcomposer/EffectComposer.json.in @@ -1,5 +1,5 @@ { - "Name" : "EffectMakerNew", + "Name" : "EffectComposer", "Version" : "${IDE_VERSION}", "CompatVersion" : "${IDE_VERSION_COMPAT}", "Vendor" : "The Qt Company Ltd", @@ -8,7 +8,7 @@ "", "Licensees holding valid Qt Enterprise licenses may use this plugin in accordance with the Qt Enterprise License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company." ], - "Description" : "Plugin for Effect Maker.", + "Description" : "Plugin for Effect Composer.", "Url" : "http://www.qt.io", "DisabledByDefault" : true, ${IDE_PLUGIN_DEPENDENCIES} diff --git a/src/plugins/effectmakernew/compositionnode.cpp b/src/plugins/effectcomposer/compositionnode.cpp similarity index 97% rename from src/plugins/effectmakernew/compositionnode.cpp rename to src/plugins/effectcomposer/compositionnode.cpp index 811cdbcb8f9..b63258e0af3 100644 --- a/src/plugins/effectmakernew/compositionnode.cpp +++ b/src/plugins/effectcomposer/compositionnode.cpp @@ -4,7 +4,7 @@ #include "compositionnode.h" #include "effectutils.h" -#include "effectmakeruniformsmodel.h" +#include "effectcomposeruniformsmodel.h" #include "propertyhandler.h" #include "uniform.h" @@ -12,7 +12,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { CompositionNode::CompositionNode(const QString &effectName, const QString &qenPath, const QJsonObject &jsonObject) @@ -187,5 +187,5 @@ QString CompositionNode::name() const return m_name; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/compositionnode.h b/src/plugins/effectcomposer/compositionnode.h similarity index 90% rename from src/plugins/effectmakernew/compositionnode.h rename to src/plugins/effectcomposer/compositionnode.h index 04f5dd5c02b..589954ec871 100644 --- a/src/plugins/effectmakernew/compositionnode.h +++ b/src/plugins/effectcomposer/compositionnode.h @@ -3,12 +3,12 @@ #pragma once -#include "effectmakeruniformsmodel.h" +#include "effectcomposeruniformsmodel.h" #include #include -namespace EffectMaker { +namespace EffectComposer { class CompositionNode : public QObject { @@ -70,10 +70,9 @@ private: bool m_isEnabled = true; int m_refCount = 0; - QList m_uniforms; + QList m_uniforms; - EffectMakerUniformsModel m_unifomrsModel; + EffectComposerUniformsModel m_unifomrsModel; }; -} // namespace EffectMaker - +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakercontextobject.cpp b/src/plugins/effectcomposer/effectcomposercontextobject.cpp similarity index 70% rename from src/plugins/effectmakernew/effectmakercontextobject.cpp rename to src/plugins/effectcomposer/effectcomposercontextobject.cpp index 6a37765d5c2..dd42092e72e 100644 --- a/src/plugins/effectmakernew/effectmakercontextobject.cpp +++ b/src/plugins/effectcomposer/effectcomposercontextobject.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "effectmakercontextobject.h" +#include "effectcomposercontextobject.h" #include #include @@ -27,15 +27,15 @@ #include -namespace EffectMaker { +namespace EffectComposer { -EffectMakerContextObject::EffectMakerContextObject(QQmlContext *context, QObject *parent) +EffectComposerContextObject::EffectComposerContextObject(QQmlContext *context, QObject *parent) : QObject(parent) , m_qmlContext(context) { } -QString EffectMakerContextObject::convertColorToString(const QVariant &color) +QString EffectComposerContextObject::convertColorToString(const QVariant &color) { QString colorString; QColor theColor; @@ -52,17 +52,17 @@ QString EffectMakerContextObject::convertColorToString(const QVariant &color) } // TODO: this method is used by the ColorEditor helper widget, check if at all needed? -QColor EffectMakerContextObject::colorFromString(const QString &colorString) +QColor EffectComposerContextObject::colorFromString(const QString &colorString) { return colorString; } -int EffectMakerContextObject::majorVersion() const +int EffectComposerContextObject::majorVersion() const { return m_majorVersion; } -void EffectMakerContextObject::setMajorVersion(int majorVersion) +void EffectComposerContextObject::setMajorVersion(int majorVersion) { if (m_majorVersion == majorVersion) return; @@ -72,7 +72,7 @@ void EffectMakerContextObject::setMajorVersion(int majorVersion) emit majorVersionChanged(); } -void EffectMakerContextObject::setStateName(const QString &newStateName) +void EffectComposerContextObject::setStateName(const QString &newStateName) { if (newStateName == m_stateName) return; @@ -81,7 +81,7 @@ void EffectMakerContextObject::setStateName(const QString &newStateName) emit stateNameChanged(); } -void EffectMakerContextObject::setAllStateNames(const QStringList &allStates) +void EffectComposerContextObject::setAllStateNames(const QStringList &allStates) { if (allStates == m_allStateNames) return; @@ -90,7 +90,7 @@ void EffectMakerContextObject::setAllStateNames(const QStringList &allStates) emit allStateNamesChanged(); } -void EffectMakerContextObject::setIsBaseState(bool newIsBaseState) +void EffectComposerContextObject::setIsBaseState(bool newIsBaseState) { if (newIsBaseState == m_isBaseState) return; @@ -99,7 +99,7 @@ void EffectMakerContextObject::setIsBaseState(bool newIsBaseState) emit isBaseStateChanged(); } -void EffectMakerContextObject::setSelectionChanged(bool newSelectionChanged) +void EffectComposerContextObject::setSelectionChanged(bool newSelectionChanged) { if (newSelectionChanged == m_selectionChanged) return; @@ -108,7 +108,7 @@ void EffectMakerContextObject::setSelectionChanged(bool newSelectionChanged) emit selectionChangedChanged(); } -void EffectMakerContextObject::setBackendValues(QQmlPropertyMap *newBackendValues) +void EffectComposerContextObject::setBackendValues(QQmlPropertyMap *newBackendValues) { if (newBackendValues == m_backendValues) return; @@ -117,17 +117,17 @@ void EffectMakerContextObject::setBackendValues(QQmlPropertyMap *newBackendValue emit backendValuesChanged(); } -void EffectMakerContextObject::setModel(QmlDesigner::Model *model) +void EffectComposerContextObject::setModel(QmlDesigner::Model *model) { m_model = model; } -void EffectMakerContextObject::triggerSelectionChanged() +void EffectComposerContextObject::triggerSelectionChanged() { setSelectionChanged(!m_selectionChanged); } -void EffectMakerContextObject::hideCursor() +void EffectComposerContextObject::hideCursor() { if (QApplication::overrideCursor()) return; @@ -138,7 +138,7 @@ void EffectMakerContextObject::hideCursor() m_lastPos = QCursor::pos(w->screen()); } -void EffectMakerContextObject::restoreCursor() +void EffectComposerContextObject::restoreCursor() { if (!QApplication::overrideCursor()) return; @@ -149,7 +149,7 @@ void EffectMakerContextObject::restoreCursor() QCursor::setPos(w->screen(), m_lastPos); } -void EffectMakerContextObject::holdCursorInPlace() +void EffectComposerContextObject::holdCursorInPlace() { if (!QApplication::overrideCursor()) return; @@ -158,7 +158,7 @@ void EffectMakerContextObject::holdCursorInPlace() QCursor::setPos(w->screen(), m_lastPos); } -int EffectMakerContextObject::devicePixelRatio() +int EffectComposerContextObject::devicePixelRatio() { if (QWidget *w = QApplication::activeWindow()) return w->devicePixelRatio(); @@ -166,7 +166,7 @@ int EffectMakerContextObject::devicePixelRatio() return 1; } -QStringList EffectMakerContextObject::allStatesForId(const QString &id) +QStringList EffectComposerContextObject::allStatesForId(const QString &id) { if (m_model && m_model->rewriterView()) { const QmlDesigner::QmlObjectNode node = m_model->rewriterView()->modelNodeForId(id); @@ -177,10 +177,10 @@ QStringList EffectMakerContextObject::allStatesForId(const QString &id) return {}; } -bool EffectMakerContextObject::isBlocked(const QString &) const +bool EffectComposerContextObject::isBlocked(const QString &) const { return false; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakercontextobject.h b/src/plugins/effectcomposer/effectcomposercontextobject.h similarity index 94% rename from src/plugins/effectmakernew/effectmakercontextobject.h rename to src/plugins/effectcomposer/effectcomposercontextobject.h index 9b76dc36d8f..5a5a5131653 100644 --- a/src/plugins/effectmakernew/effectmakercontextobject.h +++ b/src/plugins/effectcomposer/effectcomposercontextobject.h @@ -14,9 +14,9 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { -class EffectMakerContextObject : public QObject +class EffectComposerContextObject : public QObject { Q_OBJECT @@ -32,7 +32,7 @@ class EffectMakerContextObject : public QObject Q_PROPERTY(QQmlPropertyMap *backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged) public: - EffectMakerContextObject(QQmlContext *context, QObject *parent = nullptr); + EffectComposerContextObject(QQmlContext *context, QObject *parent = nullptr); QString stateName() const { return m_stateName; } QStringList allStateNames() const { return m_allStateNames; } @@ -98,5 +98,5 @@ private: bool m_selectionChanged = false; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp similarity index 89% rename from src/plugins/effectmakernew/effectmakermodel.cpp rename to src/plugins/effectcomposer/effectcomposermodel.cpp index dc71418f1d0..1edc70c75b4 100644 --- a/src/plugins/effectmakernew/effectmakermodel.cpp +++ b/src/plugins/effectcomposer/effectcomposermodel.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "effectmakermodel.h" +#include "effectcomposermodel.h" #include "compositionnode.h" #include "effectutils.h" @@ -26,7 +26,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { enum class FileType { @@ -49,12 +49,12 @@ static bool writeToFile(const QByteArray &buf, const QString &filename, FileType return true; } -EffectMakerModel::EffectMakerModel(QObject *parent) +EffectComposerModel::EffectComposerModel(QObject *parent) : QAbstractListModel{parent} { } -QHash EffectMakerModel::roleNames() const +QHash EffectComposerModel::roleNames() const { QHash roles; roles[NameRole] = "nodeName"; @@ -64,14 +64,14 @@ QHash EffectMakerModel::roleNames() const return roles; } -int EffectMakerModel::rowCount(const QModelIndex &parent) const +int EffectComposerModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) return m_nodes.count(); } -QVariant EffectMakerModel::data(const QModelIndex &index, int role) const +QVariant EffectComposerModel::data(const QModelIndex &index, int role) const { QTC_ASSERT(index.isValid() && index.row() < m_nodes.size(), return {}); QTC_ASSERT(roleNames().contains(role), return {}); @@ -79,7 +79,7 @@ QVariant EffectMakerModel::data(const QModelIndex &index, int role) const return m_nodes.at(index.row())->property(roleNames().value(role)); } -bool EffectMakerModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool EffectComposerModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid() || !roleNames().contains(role)) return false; @@ -95,7 +95,7 @@ bool EffectMakerModel::setData(const QModelIndex &index, const QVariant &value, return true; } -void EffectMakerModel::setIsEmpty(bool val) +void EffectComposerModel::setIsEmpty(bool val) { if (m_isEmpty != val) { m_isEmpty = val; @@ -106,12 +106,12 @@ void EffectMakerModel::setIsEmpty(bool val) } } -void EffectMakerModel::addNode(const QString &nodeQenPath) +void EffectComposerModel::addNode(const QString &nodeQenPath) { beginResetModel(); auto *node = new CompositionNode({}, nodeQenPath); - connect(qobject_cast(node->uniformsModel()), - &EffectMakerUniformsModel::dataChanged, this, [this] { + connect(qobject_cast(node->uniformsModel()), + &EffectComposerUniformsModel::dataChanged, this, [this] { setHasUnsavedChanges(true); }); @@ -125,8 +125,8 @@ void EffectMakerModel::addNode(const QString &nodeQenPath) const QString path = EffectUtils::nodesSourcesPath() + "/common/" + requiredId + ".qen"; auto requiredNode = new CompositionNode({}, path); - connect(qobject_cast(requiredNode->uniformsModel()), - &EffectMakerUniformsModel::dataChanged, this, [this] { + connect(qobject_cast(requiredNode->uniformsModel()), + &EffectComposerUniformsModel::dataChanged, this, [this] { setHasUnsavedChanges(true); }); requiredNode->setRefCount(1); @@ -144,7 +144,7 @@ void EffectMakerModel::addNode(const QString &nodeQenPath) emit nodesChanged(); } -CompositionNode *EffectMakerModel::findNodeById(const QString &id) const +CompositionNode *EffectComposerModel::findNodeById(const QString &id) const { for (CompositionNode *node : std::as_const(m_nodes)) { if (node->id() == id) @@ -153,7 +153,7 @@ CompositionNode *EffectMakerModel::findNodeById(const QString &id) const return {}; } -void EffectMakerModel::moveNode(int fromIdx, int toIdx) +void EffectComposerModel::moveNode(int fromIdx, int toIdx) { if (fromIdx == toIdx) return; @@ -167,7 +167,7 @@ void EffectMakerModel::moveNode(int fromIdx, int toIdx) bakeShaders(); } -void EffectMakerModel::removeNode(int idx) +void EffectComposerModel::removeNode(int idx) { beginResetModel(); CompositionNode *node = m_nodes.takeAt(idx); @@ -193,7 +193,7 @@ void EffectMakerModel::removeNode(int idx) emit nodesChanged(); } -void EffectMakerModel::clear(bool clearName) +void EffectComposerModel::clear(bool clearName) { beginResetModel(); qDeleteAll(m_nodes); @@ -209,14 +209,14 @@ void EffectMakerModel::clear(bool clearName) emit nodesChanged(); } -void EffectMakerModel::assignToSelected() +void EffectComposerModel::assignToSelected() { const QString effectsAssetsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory(); const QString path = effectsAssetsDir + QDir::separator() + m_currentComposition + ".qep"; emit assignToSelectedTriggered(path); } -QString EffectMakerModel::getUniqueEffectName() const +QString EffectComposerModel::getUniqueEffectName() const { const QString effectsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory(); const QString path = effectsDir + QDir::separator() + "Effect%1.qep"; @@ -229,12 +229,12 @@ QString EffectMakerModel::getUniqueEffectName() const return QString("Effect%1").arg(num, 2, 10, QChar('0')); } -QString EffectMakerModel::fragmentShader() const +QString EffectComposerModel::fragmentShader() const { return m_fragmentShader; } -void EffectMakerModel::setFragmentShader(const QString &newFragmentShader) +void EffectComposerModel::setFragmentShader(const QString &newFragmentShader) { if (m_fragmentShader == newFragmentShader) return; @@ -242,12 +242,12 @@ void EffectMakerModel::setFragmentShader(const QString &newFragmentShader) m_fragmentShader = newFragmentShader; } -QString EffectMakerModel::vertexShader() const +QString EffectComposerModel::vertexShader() const { return m_vertexShader; } -void EffectMakerModel::setVertexShader(const QString &newVertexShader) +void EffectComposerModel::setVertexShader(const QString &newVertexShader) { if (m_vertexShader == newVertexShader) return; @@ -255,20 +255,20 @@ void EffectMakerModel::setVertexShader(const QString &newVertexShader) m_vertexShader = newVertexShader; } -const QString &EffectMakerModel::qmlComponentString() const +const QString &EffectComposerModel::qmlComponentString() const { return m_qmlComponentString; } -const QList EffectMakerModel::allUniforms() const +const QList EffectComposerModel::allUniforms() const { QList uniforms = {}; for (const auto &node : std::as_const(m_nodes)) - uniforms.append(static_cast(node->uniformsModel())->uniforms()); + uniforms.append(static_cast(node->uniformsModel())->uniforms()); return uniforms; } -const QString EffectMakerModel::getBufUniform() +const QString EffectComposerModel::getBufUniform() { QList uniforms = allUniforms(); QString s; @@ -295,7 +295,7 @@ const QString EffectMakerModel::getBufUniform() return s; } -const QString EffectMakerModel::getVSUniforms() +const QString EffectComposerModel::getVSUniforms() { QString s; s += "#version 440\n"; @@ -313,7 +313,7 @@ const QString EffectMakerModel::getVSUniforms() return s; } -const QString EffectMakerModel::getFSUniforms() +const QString EffectComposerModel::getFSUniforms() { const QList uniforms = allUniforms(); QString s; @@ -359,7 +359,7 @@ const QString EffectMakerModel::getFSUniforms() // Detects common GLSL error messages and returns potential // additional error information related to them. -QString EffectMakerModel::detectErrorMessage(const QString &errorMessage) +QString EffectComposerModel::detectErrorMessage(const QString &errorMessage) { static QHash nodeErrors { { "'BLUR_HELPER_MAX_LEVEL' : undeclared identifier", "BlurHelper"}, @@ -380,7 +380,7 @@ QString EffectMakerModel::detectErrorMessage(const QString &errorMessage) } // Return first error message (if any) -EffectError EffectMakerModel::effectError() const +EffectError EffectComposerModel::effectError() const { for (const EffectError &e : std::as_const(m_effectErrors)) { if (!e.m_message.isEmpty()) @@ -392,7 +392,7 @@ EffectError EffectMakerModel::effectError() const // Set the effect error message with optional type and lineNumber. // Type comes from ErrorTypes, defaulting to common errors (-1). // Note that type must match with UI editor tab index. -void EffectMakerModel::setEffectError(const QString &errorMessage, int type, int lineNumber) +void EffectComposerModel::setEffectError(const QString &errorMessage, int type, int lineNumber) { EffectError error; error.m_type = type; @@ -557,7 +557,7 @@ QJsonObject nodeToJson(const CompositionNode &node) return nodeObject; } -QString EffectMakerModel::getQmlEffectString() +QString EffectComposerModel::getQmlEffectString() { QString s; @@ -571,7 +571,9 @@ import QtQuick Item { id: rootItem + // This is an internal property used by tooling to identify effect items property var _isEffectItem + property Item _oldParent: null )" }; @@ -616,6 +618,20 @@ R"( )" }; + if (m_shaderFeatures.enabled(ShaderFeatures::Mipmap)) { + QString mipmap1{ + R"(parent.layer.smooth = true + parent.layer.mipmap = true + %1)" + }; + QString mipmap2{ + R"(_oldParent.layer.smooth = false + _oldParent.layer.mipmap = false + %2)" + }; + parentChanged = parentChanged.arg(mipmap1, mipmap2); + } + parentChanged = parentChanged.arg(m_shaderFeatures.enabled(ShaderFeatures::Source) ? QString("source = parent") : QString(), m_shaderFeatures.enabled(ShaderFeatures::Source) @@ -648,7 +664,7 @@ R"( return s; } -void EffectMakerModel::saveComposition(const QString &name) +void EffectComposerModel::saveComposition(const QString &name) { const QString effectsAssetsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory(); const QString path = effectsAssetsDir + QDir::separator() + name + ".qep"; @@ -685,7 +701,7 @@ void EffectMakerModel::saveComposition(const QString &name) saveResources(name); } -void EffectMakerModel::openComposition(const QString &path) +void EffectComposerModel::openComposition(const QString &path) { clear(true); @@ -741,8 +757,8 @@ void EffectMakerModel::openComposition(const QString &path) for (const auto &nodeElement : nodesArray) { auto *node = new CompositionNode(effectName, {}, nodeElement.toObject()); - connect(qobject_cast(node->uniformsModel()), - &EffectMakerUniformsModel::dataChanged, this, [this] { + connect(qobject_cast(node->uniformsModel()), + &EffectComposerUniformsModel::dataChanged, this, [this] { setHasUnsavedChanges(true); }); m_nodes.append(node); @@ -767,7 +783,7 @@ void EffectMakerModel::openComposition(const QString &path) emit nodesChanged(); } -void EffectMakerModel::saveResources(const QString &name) +void EffectComposerModel::saveResources(const QString &name) { // Make sure that uniforms are up-to-date updateCustomUniforms(); @@ -878,7 +894,7 @@ void EffectMakerModel::saveResources(const QString &name) emit resourcesSaved(QString("Effects.%1.%1").arg(name).toUtf8(), effectPath); } -void EffectMakerModel::resetEffectError(int type) +void EffectComposerModel::resetEffectError(int type) { if (m_effectErrors.contains(type)) { m_effectErrors.remove(type); @@ -887,7 +903,7 @@ void EffectMakerModel::resetEffectError(int type) } // Get value in QML format that used for exports -QString EffectMakerModel::valueAsString(const Uniform &uniform) +QString EffectComposerModel::valueAsString(const Uniform &uniform) { if (uniform.type() == Uniform::Type::Bool) { return uniform.value().toBool() ? QString("true") : QString("false"); @@ -905,7 +921,7 @@ QString EffectMakerModel::valueAsString(const Uniform &uniform) QVector4D v4 = uniform.value().value(); return QString("Qt.vector4d(%1, %2, %3, %4)").arg(v4.x()).arg(v4.y()).arg(v4.z()).arg(v4.w()); } else if (uniform.type() == Uniform::Type::Sampler) { - return getImageElementName(uniform); + return getImageElementName(uniform, true); } else if (uniform.type() == Uniform::Type::Color) { return QString("\"%1\"").arg(uniform.value().toString()); } else if (uniform.type() == Uniform::Type::Define) { @@ -917,7 +933,7 @@ QString EffectMakerModel::valueAsString(const Uniform &uniform) } // Get value in QML binding that used for previews -QString EffectMakerModel::valueAsBinding(const Uniform &uniform) +QString EffectComposerModel::valueAsBinding(const Uniform &uniform) { if (uniform.type() == Uniform::Type::Bool || uniform.type() == Uniform::Type::Int @@ -941,7 +957,7 @@ QString EffectMakerModel::valueAsBinding(const Uniform &uniform) QString sw = QString("g_propertyData.%1.w").arg(uniform.name()); return QString("Qt.vector4d(%1, %2, %3, %4)").arg(sx, sy, sz, sw); } else if (uniform.type() == Uniform::Type::Sampler) { - return getImageElementName(uniform); + return getImageElementName(uniform, false); } else { qWarning() << QString("Unhandled const variable type: %1").arg(int(uniform.type())).toLatin1(); return QString(); @@ -949,7 +965,7 @@ QString EffectMakerModel::valueAsBinding(const Uniform &uniform) } // Get value in GLSL format that is used for non-exported const properties -QString EffectMakerModel::valueAsVariable(const Uniform &uniform) +QString EffectComposerModel::valueAsVariable(const Uniform &uniform) { if (uniform.type() == Uniform::Type::Bool) { return uniform.value().toBool() ? QString("true") : QString("false"); @@ -976,16 +992,16 @@ QString EffectMakerModel::valueAsVariable(const Uniform &uniform) } // Return name for the image property Image element -QString EffectMakerModel::getImageElementName(const Uniform &uniform) +QString EffectComposerModel::getImageElementName(const Uniform &uniform, bool localFiles) { - if (uniform.value().toString().isEmpty()) + if (localFiles && uniform.value().toString().isEmpty()) return QStringLiteral("null"); QString simplifiedName = uniform.name().simplified(); simplifiedName = simplifiedName.remove(' '); return QStringLiteral("imageItem") + simplifiedName; } -const QString EffectMakerModel::getConstVariables() +const QString EffectComposerModel::getConstVariables() { const QList uniforms = allUniforms(); QString s; @@ -1001,7 +1017,7 @@ const QString EffectMakerModel::getConstVariables() return s; } -const QString EffectMakerModel::getDefineProperties() +const QString EffectComposerModel::getDefineProperties() { const QList uniforms = allUniforms(); QString s; @@ -1018,7 +1034,7 @@ const QString EffectMakerModel::getDefineProperties() return s; } -int EffectMakerModel::getTagIndex(const QStringList &code, const QString &tag) +int EffectComposerModel::getTagIndex(const QStringList &code, const QString &tag) { int index = -1; int line = 0; @@ -1040,7 +1056,7 @@ int EffectMakerModel::getTagIndex(const QStringList &code, const QString &tag) return index; } -QString EffectMakerModel::processVertexRootLine(const QString &line) +QString EffectComposerModel::processVertexRootLine(const QString &line) { QString output; QStringList lineList = line.split(m_spaceReg, Qt::SkipEmptyParts); @@ -1054,7 +1070,7 @@ QString EffectMakerModel::processVertexRootLine(const QString &line) return output; } -QString EffectMakerModel::processFragmentRootLine(const QString &line) +QString EffectComposerModel::processFragmentRootLine(const QString &line) { QString output; QStringList lineList = line.split(m_spaceReg, Qt::SkipEmptyParts); @@ -1065,7 +1081,7 @@ QString EffectMakerModel::processFragmentRootLine(const QString &line) return output; } -QStringList EffectMakerModel::getDefaultRootVertexShader() +QStringList EffectComposerModel::getDefaultRootVertexShader() { if (m_defaultRootVertexShader.isEmpty()) { m_defaultRootVertexShader << "void main() {"; @@ -1079,7 +1095,7 @@ QStringList EffectMakerModel::getDefaultRootVertexShader() return m_defaultRootVertexShader; } -QStringList EffectMakerModel::getDefaultRootFragmentShader() +QStringList EffectComposerModel::getDefaultRootFragmentShader() { if (m_defaultRootFragmentShader.isEmpty()) { m_defaultRootFragmentShader << "void main() {"; @@ -1093,7 +1109,7 @@ QStringList EffectMakerModel::getDefaultRootFragmentShader() // Remove all post-processing tags ("@tag") from the code. // Except "@nodes" tag as that is handled later. -QStringList EffectMakerModel::removeTagsFromCode(const QStringList &codeLines) +QStringList EffectComposerModel::removeTagsFromCode(const QStringList &codeLines) { QStringList s; for (const QString &line : codeLines) { @@ -1118,13 +1134,13 @@ QStringList EffectMakerModel::removeTagsFromCode(const QStringList &codeLines) return s; } -QString EffectMakerModel::removeTagsFromCode(const QString &code) +QString EffectComposerModel::removeTagsFromCode(const QString &code) { QStringList codeLines = removeTagsFromCode(code.split('\n')); return codeLines.join('\n'); } -QString EffectMakerModel::getCustomShaderVaryings(bool outState) +QString EffectComposerModel::getCustomShaderVaryings(bool outState) { QString output; QString direction = outState ? QStringLiteral("out") : QStringLiteral("in"); @@ -1136,7 +1152,7 @@ QString EffectMakerModel::getCustomShaderVaryings(bool outState) return output; } -QString EffectMakerModel::generateVertexShader(bool includeUniforms) +QString EffectComposerModel::generateVertexShader(bool includeUniforms) { QString s; @@ -1192,7 +1208,7 @@ QString EffectMakerModel::generateVertexShader(bool includeUniforms) return s; } -QString EffectMakerModel::generateFragmentShader(bool includeUniforms) +QString EffectComposerModel::generateFragmentShader(bool includeUniforms) { QString s; @@ -1247,7 +1263,7 @@ QString EffectMakerModel::generateFragmentShader(bool includeUniforms) return s; } -void EffectMakerModel::handleQsbProcessExit(Utils::Process *qsbProcess, const QString &shader, bool preview) +void EffectComposerModel::handleQsbProcessExit(Utils::Process *qsbProcess, const QString &shader, bool preview) { --m_remainingQsbTargets; @@ -1279,7 +1295,7 @@ void EffectMakerModel::handleQsbProcessExit(Utils::Process *qsbProcess, const QS // Generates string of the custom properties (uniforms) into ShaderEffect component // Also generates QML images elements for samplers. -void EffectMakerModel::updateCustomUniforms() +void EffectComposerModel::updateCustomUniforms() { QString exportedRootPropertiesString; QString previewEffectPropertiesString; @@ -1345,7 +1361,7 @@ void EffectMakerModel::updateCustomUniforms() m_exportedEffectPropertiesString = exportedEffectPropertiesString; } -void EffectMakerModel::createFiles() +void EffectComposerModel::createFiles() { if (QFileInfo(m_vertexShaderFilename).exists()) QFile(m_vertexShaderFilename).remove(); @@ -1378,7 +1394,7 @@ void EffectMakerModel::createFiles() } } -void EffectMakerModel::bakeShaders() +void EffectComposerModel::bakeShaders() { const QString failMessage = "Shader baking failed: "; @@ -1460,12 +1476,12 @@ void EffectMakerModel::bakeShaders() } -bool EffectMakerModel::shadersUpToDate() const +bool EffectComposerModel::shadersUpToDate() const { return m_shadersUpToDate; } -void EffectMakerModel::setShadersUpToDate(bool UpToDate) +void EffectComposerModel::setShadersUpToDate(bool UpToDate) { if (m_shadersUpToDate == UpToDate) return; @@ -1473,9 +1489,22 @@ void EffectMakerModel::setShadersUpToDate(bool UpToDate) emit shadersUpToDateChanged(); } +bool EffectComposerModel::isEnabled() const +{ + return m_isEnabled; +} + +void EffectComposerModel::setIsEnabled(bool enabled) +{ + if (m_isEnabled == enabled) + return; + m_isEnabled = enabled; + emit isEnabledChanged(); +} + // Returns name for image mipmap property. // e.g. "myImage" -> "myImageMipmap". -QString EffectMakerModel::mipmapPropertyName(const QString &name) const +QString EffectComposerModel::mipmapPropertyName(const QString &name) const { QString simplifiedName = name.simplified(); simplifiedName = simplifiedName.remove(' '); @@ -1483,41 +1512,43 @@ QString EffectMakerModel::mipmapPropertyName(const QString &name) const return simplifiedName; } -QString EffectMakerModel::getQmlImagesString(bool localFiles) +QString EffectComposerModel::getQmlImagesString(bool localFiles) { QString imagesString; const QList uniforms = allUniforms(); for (Uniform *uniform : uniforms) { if (uniform->type() == Uniform::Type::Sampler) { QString imagePath = uniform->value().toString(); - if (imagePath.isEmpty()) + // For preview, generate image element even if path is empty, as changing uniform values + // will not trigger qml code regeneration + if (localFiles && imagePath.isEmpty()) continue; - imagesString += " Image {\n"; - QString simplifiedName = getImageElementName(*uniform); - imagesString += QString(" id: %1\n").arg(simplifiedName); - imagesString += " anchors.fill: parent\n"; + imagesString += " Image {\n"; + QString simplifiedName = getImageElementName(*uniform, localFiles); + imagesString += QString(" id: %1\n").arg(simplifiedName); + imagesString += " anchors.fill: parent\n"; // File paths are absolute, return as local when requested if (localFiles) { QFileInfo fi(imagePath); imagePath = fi.fileName(); - imagesString += QString(" source: \"%1\"\n").arg(imagePath); + imagesString += QString(" source: \"%1\"\n").arg(imagePath); } else { - imagesString += QString(" source: g_propertyData.%1\n").arg(uniform->name()); + imagesString += QString(" source: g_propertyData.%1\n").arg(uniform->name()); if (uniform->enableMipmap()) - imagesString += " mipmap: true\n"; + imagesString += " mipmap: true\n"; else QString mipmapProperty = mipmapPropertyName(uniform->name()); } - imagesString += " visible: false\n"; - imagesString += " }\n"; + imagesString += " visible: false\n"; + imagesString += " }\n"; } } return imagesString; } -QString EffectMakerModel::getQmlComponentString(bool localFiles) +QString EffectComposerModel::getQmlComponentString(bool localFiles) { auto addProperty = [localFiles](const QString &name, const QString &var, const QString &type, bool blurHelper = false) @@ -1604,12 +1635,12 @@ QString EffectMakerModel::getQmlComponentString(bool localFiles) return s; } -QString EffectMakerModel::currentComposition() const +QString EffectComposerModel::currentComposition() const { return m_currentComposition; } -void EffectMakerModel::setCurrentComposition(const QString &newCurrentComposition) +void EffectComposerModel::setCurrentComposition(const QString &newCurrentComposition) { if (m_currentComposition == newCurrentComposition) return; @@ -1618,12 +1649,12 @@ void EffectMakerModel::setCurrentComposition(const QString &newCurrentCompositio emit currentCompositionChanged(); } -bool EffectMakerModel::hasUnsavedChanges() const +bool EffectComposerModel::hasUnsavedChanges() const { return m_hasUnsavedChanges; } -void EffectMakerModel::setHasUnsavedChanges(bool val) +void EffectComposerModel::setHasUnsavedChanges(bool val) { if (m_hasUnsavedChanges == val) return; @@ -1632,7 +1663,7 @@ void EffectMakerModel::setHasUnsavedChanges(bool val) emit hasUnsavedChangesChanged(); } -QStringList EffectMakerModel::uniformNames() const +QStringList EffectComposerModel::uniformNames() const { QStringList usedList; const QList uniforms = allUniforms(); @@ -1641,14 +1672,14 @@ QStringList EffectMakerModel::uniformNames() const return usedList; } -bool EffectMakerModel::isDependencyNode(int index) const +bool EffectComposerModel::isDependencyNode(int index) const { if (m_nodes.size() > index) return m_nodes[index]->isDependency(); return false; } -void EffectMakerModel::updateQmlComponent() +void EffectComposerModel::updateQmlComponent() { // Clear possible QML runtime errors resetEffectError(ErrorQMLRuntime); @@ -1657,11 +1688,11 @@ void EffectMakerModel::updateQmlComponent() // Removes "file:" from the URL path. // So e.g. "file:///C:/myimages/steel1.jpg" -> "C:/myimages/steel1.jpg" -QString EffectMakerModel::stripFileFromURL(const QString &urlString) const +QString EffectComposerModel::stripFileFromURL(const QString &urlString) const { QUrl url(urlString); QString filePath = (url.scheme() == QStringLiteral("file")) ? url.toLocalFile() : url.toString(); return filePath; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakermodel.h b/src/plugins/effectcomposer/effectcomposermodel.h similarity index 93% rename from src/plugins/effectmakernew/effectmakermodel.h rename to src/plugins/effectcomposer/effectcomposermodel.h index 1bbac9cd55b..69afc503ea4 100644 --- a/src/plugins/effectmakernew/effectmakermodel.h +++ b/src/plugins/effectcomposer/effectcomposermodel.h @@ -21,7 +21,7 @@ namespace Utils { class Process; } -namespace EffectMaker { +namespace EffectComposer { class CompositionNode; class Uniform; @@ -38,7 +38,7 @@ public: int m_type = -1; }; -class EffectMakerModel : public QAbstractListModel +class EffectComposerModel : public QAbstractListModel { Q_OBJECT @@ -46,11 +46,12 @@ class EffectMakerModel : public QAbstractListModel Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged) Q_PROPERTY(bool hasUnsavedChanges MEMBER m_hasUnsavedChanges WRITE setHasUnsavedChanges NOTIFY hasUnsavedChangesChanged) Q_PROPERTY(bool shadersUpToDate READ shadersUpToDate WRITE setShadersUpToDate NOTIFY shadersUpToDateChanged) + Q_PROPERTY(bool isEnabled READ isEnabled WRITE setIsEnabled NOTIFY isEnabledChanged) Q_PROPERTY(QString qmlComponentString READ qmlComponentString) Q_PROPERTY(QString currentComposition READ currentComposition WRITE setCurrentComposition NOTIFY currentCompositionChanged) public: - EffectMakerModel(QObject *parent = nullptr); + EffectComposerModel(QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex & parent = QModelIndex()) const override; @@ -73,6 +74,9 @@ public: bool shadersUpToDate() const; void setShadersUpToDate(bool newShadersUpToDate); + bool isEnabled() const; + void setIsEnabled(bool enabled); + QString fragmentShader() const; void setFragmentShader(const QString &newFragmentShader); @@ -105,6 +109,7 @@ signals: void selectedIndexChanged(int idx); void effectErrorChanged(); void shadersUpToDateChanged(); + void isEnabledChanged(); void shadersBaked(); void currentCompositionChanged(); void nodesChanged(); @@ -143,7 +148,7 @@ private: QString valueAsString(const Uniform &uniform); QString valueAsBinding(const Uniform &uniform); QString valueAsVariable(const Uniform &uniform); - QString getImageElementName(const Uniform &uniform); + QString getImageElementName(const Uniform &uniform, bool localFiles); const QString getConstVariables(); const QString getDefineProperties(); int getTagIndex(const QStringList &code, const QString &tag); @@ -201,10 +206,11 @@ private: QString m_previewEffectPropertiesString; QString m_qmlComponentString; bool m_loadComponentImages = true; + bool m_isEnabled = true; QString m_currentComposition; const QRegularExpression m_spaceReg = QRegularExpression("\\s+"); }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakernodesmodel.cpp b/src/plugins/effectcomposer/effectcomposernodesmodel.cpp similarity index 82% rename from src/plugins/effectmakernew/effectmakernodesmodel.cpp rename to src/plugins/effectcomposer/effectcomposernodesmodel.cpp index 7f35e935ba9..28fc9434463 100644 --- a/src/plugins/effectmakernew/effectmakernodesmodel.cpp +++ b/src/plugins/effectcomposer/effectcomposernodesmodel.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "effectmakernodesmodel.h" +#include "effectcomposernodesmodel.h" #include "effectutils.h" #include @@ -9,14 +9,14 @@ #include -namespace EffectMaker { +namespace EffectComposer { -EffectMakerNodesModel::EffectMakerNodesModel(QObject *parent) +EffectComposerNodesModel::EffectComposerNodesModel(QObject *parent) : QAbstractListModel{parent} { } -QHash EffectMakerNodesModel::roleNames() const +QHash EffectComposerNodesModel::roleNames() const { QHash roles; roles[CategoryNameRole] = "categoryName"; @@ -25,14 +25,14 @@ QHash EffectMakerNodesModel::roleNames() const return roles; } -int EffectMakerNodesModel::rowCount(const QModelIndex &parent) const +int EffectComposerNodesModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) return m_categories.count(); } -QVariant EffectMakerNodesModel::data(const QModelIndex &index, int role) const +QVariant EffectComposerNodesModel::data(const QModelIndex &index, int role) const { QTC_ASSERT(index.isValid() && index.row() < m_categories.size(), return {}); QTC_ASSERT(roleNames().contains(role), return {}); @@ -40,7 +40,7 @@ QVariant EffectMakerNodesModel::data(const QModelIndex &index, int role) const return m_categories.at(index.row())->property(roleNames().value(role)); } -void EffectMakerNodesModel::loadModel() +void EffectComposerNodesModel::loadModel() { if (m_modelLoaded) return; @@ -86,13 +86,13 @@ void EffectMakerNodesModel::loadModel() resetModel(); } -void EffectMakerNodesModel::resetModel() +void EffectComposerNodesModel::resetModel() { beginResetModel(); endResetModel(); } -void EffectMakerNodesModel::updateCanBeAdded(const QStringList &uniforms) +void EffectComposerNodesModel::updateCanBeAdded(const QStringList &uniforms) { for (const EffectNodesCategory *cat : std::as_const(m_categories)) { const QList nodes = cat->nodes(); @@ -108,4 +108,4 @@ void EffectMakerNodesModel::updateCanBeAdded(const QStringList &uniforms) } } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakernodesmodel.h b/src/plugins/effectcomposer/effectcomposernodesmodel.h similarity index 83% rename from src/plugins/effectmakernew/effectmakernodesmodel.h rename to src/plugins/effectcomposer/effectcomposernodesmodel.h index 7320ca729fc..7edabcd9f9f 100644 --- a/src/plugins/effectmakernew/effectmakernodesmodel.h +++ b/src/plugins/effectcomposer/effectcomposernodesmodel.h @@ -7,9 +7,9 @@ #include -namespace EffectMaker { +namespace EffectComposer { -class EffectMakerNodesModel : public QAbstractListModel +class EffectComposerNodesModel : public QAbstractListModel { Q_OBJECT @@ -19,7 +19,7 @@ class EffectMakerNodesModel : public QAbstractListModel }; public: - EffectMakerNodesModel(QObject *parent = nullptr); + EffectComposerNodesModel(QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex & parent = QModelIndex()) const override; @@ -40,5 +40,5 @@ private: bool m_modelLoaded = false; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectcomposer/effectcomposerplugin.cpp b/src/plugins/effectcomposer/effectcomposerplugin.cpp new file mode 100644 index 00000000000..be37b1c6c42 --- /dev/null +++ b/src/plugins/effectcomposer/effectcomposerplugin.cpp @@ -0,0 +1,51 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include + +#include + + +namespace EffectComposer { + +static bool enableEffectComposer() +{ + return true; +} + +class EffectComposerPlugin : public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "EffectComposer.json") + +public: + EffectComposerPlugin() {} + ~EffectComposerPlugin() override {} + + bool delayedInitialize() override + { + if (m_delayedInitialized) + return true; + + if (enableEffectComposer()) { + auto *designerPlugin = QmlDesigner::QmlDesignerPlugin::instance(); + auto &viewManager = designerPlugin->viewManager(); + + viewManager.registerView(std::make_unique( + QmlDesigner::QmlDesignerPlugin::externalDependenciesForPluginInitializationOnly())); + } + + m_delayedInitialized = true; + + return true; + } + +private: + bool m_delayedInitialized = false; +}; + +} // namespace EffectComposer + +#include "effectcomposerplugin.moc" diff --git a/src/plugins/effectmakernew/effectmakeruniformsmodel.cpp b/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp similarity index 74% rename from src/plugins/effectmakernew/effectmakeruniformsmodel.cpp rename to src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp index c4f9796f835..e547883b9dd 100644 --- a/src/plugins/effectmakernew/effectmakeruniformsmodel.cpp +++ b/src/plugins/effectcomposer/effectcomposeruniformsmodel.cpp @@ -1,21 +1,21 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "effectmakeruniformsmodel.h" +#include "effectcomposeruniformsmodel.h" #include "propertyhandler.h" #include "uniform.h" #include -namespace EffectMaker { +namespace EffectComposer { -EffectMakerUniformsModel::EffectMakerUniformsModel(QObject *parent) +EffectComposerUniformsModel::EffectComposerUniformsModel(QObject *parent) : QAbstractListModel{parent} { } -QHash EffectMakerUniformsModel::roleNames() const +QHash EffectComposerUniformsModel::roleNames() const { QHash roles; roles[NameRole] = "uniformName"; @@ -30,14 +30,14 @@ QHash EffectMakerUniformsModel::roleNames() const return roles; } -int EffectMakerUniformsModel::rowCount(const QModelIndex &parent) const +int EffectComposerUniformsModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent) return m_uniforms.size(); } -QVariant EffectMakerUniformsModel::data(const QModelIndex &index, int role) const +QVariant EffectComposerUniformsModel::data(const QModelIndex &index, int role) const { QTC_ASSERT(index.isValid() && index.row() < m_uniforms.size(), return {}); QTC_ASSERT(roleNames().contains(role), return {}); @@ -45,7 +45,7 @@ QVariant EffectMakerUniformsModel::data(const QModelIndex &index, int role) cons return m_uniforms.at(index.row())->property(roleNames().value(role)); } -bool EffectMakerUniformsModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool EffectComposerUniformsModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid() || !roleNames().contains(role)) return false; @@ -71,23 +71,23 @@ bool EffectMakerUniformsModel::setData(const QModelIndex &index, const QVariant return true; } -void EffectMakerUniformsModel::resetModel() +void EffectComposerUniformsModel::resetModel() { beginResetModel(); endResetModel(); } -void EffectMakerUniformsModel::addUniform(Uniform *uniform) +void EffectComposerUniformsModel::addUniform(Uniform *uniform) { beginInsertRows({}, m_uniforms.size(), m_uniforms.size()); m_uniforms.append(uniform); endInsertRows(); } -QList EffectMakerUniformsModel::uniforms() const +QList EffectComposerUniformsModel::uniforms() const { return m_uniforms; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakeruniformsmodel.h b/src/plugins/effectcomposer/effectcomposeruniformsmodel.h similarity index 83% rename from src/plugins/effectmakernew/effectmakeruniformsmodel.h rename to src/plugins/effectcomposer/effectcomposeruniformsmodel.h index 8b83a63dfe3..3e2d44c6260 100644 --- a/src/plugins/effectmakernew/effectmakeruniformsmodel.h +++ b/src/plugins/effectcomposer/effectcomposeruniformsmodel.h @@ -5,16 +5,16 @@ #include -namespace EffectMaker { +namespace EffectComposer { class Uniform; -class EffectMakerUniformsModel : public QAbstractListModel +class EffectComposerUniformsModel : public QAbstractListModel { Q_OBJECT public: - EffectMakerUniformsModel(QObject *parent = nullptr); + EffectComposerUniformsModel(QObject *parent = nullptr); QHash roleNames() const override; int rowCount(const QModelIndex & parent = QModelIndex()) const override; @@ -43,5 +43,5 @@ private: QList m_uniforms; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectcomposer/effectcomposerview.cpp b/src/plugins/effectcomposer/effectcomposerview.cpp new file mode 100644 index 00000000000..3c1901a3d4c --- /dev/null +++ b/src/plugins/effectcomposer/effectcomposerview.cpp @@ -0,0 +1,102 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "effectcomposerview.h" + +#include "effectcomposermodel.h" +#include "effectcomposernodesmodel.h" +#include "effectcomposerwidget.h" + +#include +#include +#include +#include + +#include + +namespace EffectComposer { + +EffectComposerContext::EffectComposerContext(QWidget *widget) + : IContext(widget) +{ + setWidget(widget); + setContext(Core::Context(QmlDesigner::Constants::C_QMLEFFECTCOMPOSER, + QmlDesigner::Constants::C_QT_QUICK_TOOLS_MENU)); +} + +void EffectComposerContext::contextHelp(const HelpCallback &callback) const +{ + qobject_cast(m_widget)->contextHelp(callback); +} + +EffectComposerView::EffectComposerView(QmlDesigner::ExternalDependenciesInterface &externalDependencies) + : AbstractView{externalDependencies} +{ +} + +EffectComposerView::~EffectComposerView() +{} + +bool EffectComposerView::hasWidget() const +{ + return true; +} + +QmlDesigner::WidgetInfo EffectComposerView::widgetInfo() +{ + if (m_widget.isNull()) { + m_widget = new EffectComposerWidget{this}; + + connect(m_widget->effectComposerModel(), &EffectComposerModel::assignToSelectedTriggered, this, + [&] (const QString &effectPath) { + executeInTransaction("EffectComposerView::widgetInfo", [&] { + const QList selectedNodes = selectedModelNodes(); + for (const QmlDesigner::ModelNode &node : selectedNodes) + QmlDesigner::ModelNodeOperations::handleItemLibraryEffectDrop(effectPath, node); + }); + }); + + auto context = new EffectComposerContext(m_widget.data()); + Core::ICore::addContextObject(context); + } + + return createWidgetInfo(m_widget.data(), "EffectComposer", + QmlDesigner::WidgetInfo::LeftPane, 0, tr("Effect Composer [beta]")); +} + +void EffectComposerView::customNotification([[maybe_unused]] const AbstractView *view, + const QString &identifier, + [[maybe_unused]] const QList &nodeList, + const QList &data) +{ + if (identifier == "open_effectcomposer_composition" && data.count() > 0) { + const QString compositionPath = data[0].toString(); + m_widget->openComposition(compositionPath); + } +} + +void EffectComposerView::modelAttached(QmlDesigner::Model *model) +{ + AbstractView::modelAttached(model); + + m_widget->effectComposerNodesModel()->loadModel(); + + QString currProjectPath = QmlDesigner::DocumentManager::currentProjectDirPath().toString(); + + if (m_currProjectPath != currProjectPath) { // starting a new project + m_widget->effectComposerModel()->clear(true); + m_widget->effectComposerModel()->setIsEnabled( + !QmlDesigner::DesignerMcuManager::instance().isMCUProject()); + } + + m_currProjectPath = currProjectPath; + + m_widget->initView(); +} + +void EffectComposerView::modelAboutToBeDetached(QmlDesigner::Model *model) +{ + AbstractView::modelAboutToBeDetached(model); +} + +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakerview.h b/src/plugins/effectcomposer/effectcomposerview.h similarity index 64% rename from src/plugins/effectmakernew/effectmakerview.h rename to src/plugins/effectcomposer/effectcomposerview.h index 297e5acc776..a16225dfec4 100644 --- a/src/plugins/effectmakernew/effectmakerview.h +++ b/src/plugins/effectcomposer/effectcomposerview.h @@ -9,24 +9,24 @@ #include -namespace EffectMaker { +namespace EffectComposer { -class EffectMakerWidget; +class EffectComposerWidget; -class EffectMakerContext : public Core::IContext +class EffectComposerContext : public Core::IContext { Q_OBJECT public: - EffectMakerContext(QWidget *widget); + EffectComposerContext(QWidget *widget); void contextHelp(const Core::IContext::HelpCallback &callback) const override; }; -class EffectMakerView : public QmlDesigner::AbstractView +class EffectComposerView : public QmlDesigner::AbstractView { public: - EffectMakerView(QmlDesigner::ExternalDependenciesInterface &externalDependencies); - ~EffectMakerView() override; + EffectComposerView(QmlDesigner::ExternalDependenciesInterface &externalDependencies); + ~EffectComposerView() override; bool hasWidget() const override; QmlDesigner::WidgetInfo widgetInfo() override; @@ -39,7 +39,8 @@ private: void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; - QPointer m_widget; + QPointer m_widget; + QString m_currProjectPath; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakerwidget.cpp b/src/plugins/effectcomposer/effectcomposerwidget.cpp similarity index 56% rename from src/plugins/effectmakernew/effectmakerwidget.cpp rename to src/plugins/effectcomposer/effectcomposerwidget.cpp index 5151c0568ca..9303fe0ac41 100644 --- a/src/plugins/effectmakernew/effectmakerwidget.cpp +++ b/src/plugins/effectcomposer/effectcomposerwidget.cpp @@ -1,21 +1,21 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "effectmakerwidget.h" +#include "effectcomposerwidget.h" -#include "effectmakercontextobject.h" -#include "effectmakermodel.h" -#include "effectmakernodesmodel.h" -#include "effectmakerview.h" +#include "effectcomposercontextobject.h" +#include "effectcomposermodel.h" +#include "effectcomposernodesmodel.h" +#include "effectcomposerview.h" #include "effectutils.h" #include "propertyhandler.h" //#include "qmldesigner/designercore/imagecache/midsizeimagecacheprovider.h" -#include "qmldesignerconstants.h" -#include "qmldesignerplugin.h" #include "theme.h" #include +#include +#include #include #include @@ -35,7 +35,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { static QString propertyEditorResourcesPath() { @@ -46,19 +46,19 @@ static QString propertyEditorResourcesPath() return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } -EffectMakerWidget::EffectMakerWidget(EffectMakerView *view) - : m_effectMakerModel{new EffectMakerModel(this)} - , m_effectMakerNodesModel{new EffectMakerNodesModel(this)} - , m_effectMakerView(view) +EffectComposerWidget::EffectComposerWidget(EffectComposerView *view) + : m_effectComposerModel{new EffectComposerModel(this)} + , m_effectComposerNodesModel{new EffectComposerNodesModel(this)} + , m_effectComposerView(view) , m_quickWidget{new StudioQuickWidget(this)} { - setWindowTitle(tr("Effect Maker", "Title of effect maker widget")); + setWindowTitle(tr("Effect Composer", "Title of effect composer widget")); setMinimumWidth(250); m_quickWidget->quickWidget()->installEventFilter(this); // create the inner widget - m_quickWidget->quickWidget()->setObjectName(QmlDesigner::Constants::OBJECT_NAME_EFFECT_MAKER); + m_quickWidget->quickWidget()->setObjectName(QmlDesigner::Constants::OBJECT_NAME_EFFECT_COMPOSER); m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); QmlDesigner::Theme::setupTheme(m_quickWidget->engine()); m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports"); @@ -74,7 +74,7 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view) setStyleSheet(QmlDesigner::Theme::replaceCssColors( QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")))); - QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(this, QmlDesigner::Constants::EVENT_EFFECTMAKER_TIME); + QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime(this, QmlDesigner::Constants::EVENT_EFFECTCOMPOSER_TIME); m_quickWidget->rootContext()->setContextProperty("g_propertyData", &g_propertyData); @@ -82,23 +82,21 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view) g_propertyData.insert(QString("blur_vs_path"), QString(blurPath + "bluritems.vert.qsb")); g_propertyData.insert(QString("blur_fs_path"), QString(blurPath + "bluritems.frag.qsb")); - auto map = m_quickWidget->registerPropertyMap("EffectMakerBackend"); - map->setProperties({{"effectMakerNodesModel", QVariant::fromValue(m_effectMakerNodesModel.data())}, - {"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())}, + auto map = m_quickWidget->registerPropertyMap("EffectComposerBackend"); + map->setProperties({{"effectComposerNodesModel", QVariant::fromValue(m_effectComposerNodesModel.data())}, + {"effectComposerModel", QVariant::fromValue(m_effectComposerModel.data())}, {"rootView", QVariant::fromValue(this)}}); - QmlDesigner::QmlDesignerPlugin::trackWidgetFocusTime( - this, QmlDesigner::Constants::EVENT_NEWEFFECTMAKER_TIME); - connect(m_effectMakerModel.data(), &EffectMakerModel::nodesChanged, this, [this]() { - m_effectMakerNodesModel->updateCanBeAdded(m_effectMakerModel->uniformNames()); + connect(m_effectComposerModel.data(), &EffectComposerModel::nodesChanged, this, [this]() { + m_effectComposerNodesModel->updateCanBeAdded(m_effectComposerModel->uniformNames()); }); - connect(m_effectMakerModel.data(), &EffectMakerModel::resourcesSaved, + connect(m_effectComposerModel.data(), &EffectComposerModel::resourcesSaved, this, [this](const QmlDesigner::TypeName &type, const Utils::FilePath &path) { if (!m_importScan.timer) { m_importScan.timer = new QTimer(this); connect(m_importScan.timer, &QTimer::timeout, - this, &EffectMakerWidget::handleImportScanTimer); + this, &EffectComposerWidget::handleImportScanTimer); } if (m_importScan.timer->isActive() && !m_importScan.future.isFinished()) @@ -110,10 +108,27 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view) m_importScan.timer->start(100); }); + + connect(m_effectComposerModel.data(), &EffectComposerModel::hasUnsavedChangesChanged, + this, [this]() { + if (m_effectComposerModel->hasUnsavedChanges() && !m_effectComposerModel->currentComposition().isEmpty()) { + if (auto doc = QmlDesigner::QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()) + doc->setModified(); + } + }); + + connect(Core::EditorManager::instance(), &Core::EditorManager::aboutToSave, + this, [this](Core::IDocument *document) { + if (m_effectComposerModel->hasUnsavedChanges()) { + QString compName = m_effectComposerModel->currentComposition(); + if (!compName.isEmpty()) + m_effectComposerModel->saveComposition(compName); + } + }); } -bool EffectMakerWidget::eventFilter(QObject *obj, QEvent *event) +bool EffectComposerWidget::eventFilter(QObject *obj, QEvent *event) { Q_UNUSED(obj) Q_UNUSED(event) @@ -123,70 +138,76 @@ bool EffectMakerWidget::eventFilter(QObject *obj, QEvent *event) return false; } -void EffectMakerWidget::contextHelp(const Core::IContext::HelpCallback &callback) const +void EffectComposerWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { Q_UNUSED(callback) } -StudioQuickWidget *EffectMakerWidget::quickWidget() const +StudioQuickWidget *EffectComposerWidget::quickWidget() const { return m_quickWidget.data(); } -QPointer EffectMakerWidget::effectMakerModel() const +QPointer EffectComposerWidget::effectComposerModel() const { - return m_effectMakerModel; + return m_effectComposerModel; } -QPointer EffectMakerWidget::effectMakerNodesModel() const +QPointer EffectComposerWidget::effectComposerNodesModel() const { - return m_effectMakerNodesModel; + return m_effectComposerNodesModel; } -void EffectMakerWidget::addEffectNode(const QString &nodeQenPath) +void EffectComposerWidget::addEffectNode(const QString &nodeQenPath) { - m_effectMakerModel->addNode(nodeQenPath); + m_effectComposerModel->addNode(nodeQenPath); + + if (!nodeQenPath.isEmpty()) { + using namespace QmlDesigner; + QString id = nodeQenPath.split('/').last().chopped(4).prepend('_'); + QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_EFFECTCOMPOSER_NODE + id); + } } -void EffectMakerWidget::focusSection(int section) +void EffectComposerWidget::focusSection(int section) { Q_UNUSED(section) } -QRect EffectMakerWidget::screenRect() const +QRect EffectComposerWidget::screenRect() const { if (m_quickWidget && m_quickWidget->screen()) return m_quickWidget->screen()->availableGeometry(); return {}; } -QPoint EffectMakerWidget::globalPos(const QPoint &point) const +QPoint EffectComposerWidget::globalPos(const QPoint &point) const { if (m_quickWidget) return m_quickWidget->mapToGlobal(point); return point; } -QSize EffectMakerWidget::sizeHint() const +QSize EffectComposerWidget::sizeHint() const { return {420, 420}; } -QString EffectMakerWidget::qmlSourcesPath() +QString EffectComposerWidget::qmlSourcesPath() { #ifdef SHARE_QML_PATH if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) - return QLatin1String(SHARE_QML_PATH) + "/effectMakerQmlSources"; + return QLatin1String(SHARE_QML_PATH) + "/effectComposerQmlSources"; #endif - return Core::ICore::resourcePath("qmldesigner/effectMakerQmlSources").toString(); + return Core::ICore::resourcePath("qmldesigner/effectComposerQmlSources").toString(); } -void EffectMakerWidget::initView() +void EffectComposerWidget::initView() { - auto ctxObj = new EffectMakerContextObject(m_quickWidget->rootContext()); + auto ctxObj = new EffectComposerContextObject(m_quickWidget->rootContext()); m_quickWidget->rootContext()->setContextObject(ctxObj); - m_backendModelNode.setup(m_effectMakerView->rootModelNode()); + m_backendModelNode.setup(m_effectComposerView->rootModelNode()); m_quickWidget->rootContext()->setContextProperty("anchorBackend", &m_backendAnchorBinding); m_quickWidget->rootContext()->setContextProperty("modelNodeBackend", &m_backendModelNode); m_quickWidget->rootContext()->setContextProperty("activeDragSuffix", ""); @@ -200,29 +221,29 @@ void EffectMakerWidget::initView() reloadQmlSource(); } -void EffectMakerWidget::openComposition(const QString &path) +void EffectComposerWidget::openComposition(const QString &path) { m_compositionPath = path; - if (effectMakerModel()->hasUnsavedChanges()) + if (effectComposerModel()->hasUnsavedChanges()) QMetaObject::invokeMethod(quickWidget()->rootObject(), "promptToSaveBeforeOpen"); else doOpenComposition(); } -void EffectMakerWidget::doOpenComposition() +void EffectComposerWidget::doOpenComposition() { - effectMakerModel()->openComposition(m_compositionPath); + effectComposerModel()->openComposition(m_compositionPath); } -void EffectMakerWidget::reloadQmlSource() +void EffectComposerWidget::reloadQmlSource() { - const QString effectMakerQmlPath = qmlSourcesPath() + "/EffectMaker.qml"; - QTC_ASSERT(QFileInfo::exists(effectMakerQmlPath), return); - m_quickWidget->setSource(QUrl::fromLocalFile(effectMakerQmlPath)); + const QString effectComposerQmlPath = qmlSourcesPath() + "/EffectComposer.qml"; + QTC_ASSERT(QFileInfo::exists(effectComposerQmlPath), return); + m_quickWidget->setSource(QUrl::fromLocalFile(effectComposerQmlPath)); } -void EffectMakerWidget::handleImportScanTimer() +void EffectComposerWidget::handleImportScanTimer() { ++m_importScan.counter; @@ -247,24 +268,24 @@ void EffectMakerWidget::handleImportScanTimer() m_importScan.timer->stop(); m_importScan.counter = 0; } else if (m_importScan.counter == 101) { - if (m_effectMakerView->model() && m_effectMakerView->model()->rewriterView()) { + if (m_effectComposerView->model() && m_effectComposerView->model()->rewriterView()) { QmlDesigner::QmlDesignerPlugin::instance()->documentManager().resetPossibleImports(); - m_effectMakerView->model()->rewriterView()->forceAmend(); + m_effectComposerView->model()->rewriterView()->forceAmend(); } } else if (m_importScan.counter == 102) { - if (m_effectMakerView->model()) { + if (m_effectComposerView->model()) { // If type is in use, we have to reset puppet to update 2D view - if (!m_effectMakerView->allModelNodesOfType( - m_effectMakerView->model()->metaInfo(m_importScan.type)).isEmpty()) { - m_effectMakerView->resetPuppet(); + if (!m_effectComposerView->allModelNodesOfType( + m_effectComposerView->model()->metaInfo(m_importScan.type)).isEmpty()) { + m_effectComposerView->resetPuppet(); } } } else if (m_importScan.counter >= 103) { // Refresh property view by resetting selection if any selected node is of updated type - if (m_effectMakerView->model() && m_effectMakerView->hasSelectedModelNodes()) { - const auto nodes = m_effectMakerView->selectedModelNodes(); + if (m_effectComposerView->model() && m_effectComposerView->hasSelectedModelNodes()) { + const auto nodes = m_effectComposerView->selectedModelNodes(); QmlDesigner::MetaInfoType metaType - = m_effectMakerView->model()->metaInfo(m_importScan.type).type(); + = m_effectComposerView->model()->metaInfo(m_importScan.type).type(); bool match = false; for (const QmlDesigner::ModelNode &node : nodes) { if (node.metaInfo().type() == metaType) { @@ -273,8 +294,8 @@ void EffectMakerWidget::handleImportScanTimer() } } if (match) { - m_effectMakerView->clearSelectedModelNodes(); - m_effectMakerView->setSelectedModelNodes(nodes); + m_effectComposerView->clearSelectedModelNodes(); + m_effectComposerView->setSelectedModelNodes(nodes); } } m_importScan.timer->stop(); @@ -282,5 +303,5 @@ void EffectMakerWidget::handleImportScanTimer() } } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakerwidget.h b/src/plugins/effectcomposer/effectcomposerwidget.h similarity index 67% rename from src/plugins/effectmakernew/effectmakerwidget.h rename to src/plugins/effectcomposer/effectcomposerwidget.h index 35f43f99b3e..c7349f30336 100644 --- a/src/plugins/effectmakernew/effectmakerwidget.h +++ b/src/plugins/effectcomposer/effectcomposerwidget.h @@ -3,8 +3,8 @@ #pragma once -#include "qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h" -#include "qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h" +#include +#include #include @@ -17,19 +17,19 @@ QT_BEGIN_NAMESPACE class QTimer; QT_END_NAMESPACE -namespace EffectMaker { +namespace EffectComposer { -class EffectMakerView; -class EffectMakerModel; -class EffectMakerNodesModel; +class EffectComposerView; +class EffectComposerModel; +class EffectComposerNodesModel; -class EffectMakerWidget : public QFrame +class EffectComposerWidget : public QFrame { Q_OBJECT public: - EffectMakerWidget(EffectMakerView *view); - ~EffectMakerWidget() = default; + EffectComposerWidget(EffectComposerView *view); + ~EffectComposerWidget() = default; void contextHelp(const Core::IContext::HelpCallback &callback) const; @@ -42,8 +42,8 @@ public: void openComposition(const QString &path); StudioQuickWidget *quickWidget() const; - QPointer effectMakerModel() const; - QPointer effectMakerNodesModel() const; + QPointer effectComposerModel() const; + QPointer effectComposerNodesModel() const; Q_INVOKABLE void addEffectNode(const QString &nodeQenPath); Q_INVOKABLE void focusSection(int section); @@ -60,9 +60,9 @@ private: void reloadQmlSource(); void handleImportScanTimer(); - QPointer m_effectMakerModel; - QPointer m_effectMakerNodesModel; - QPointer m_effectMakerView; + QPointer m_effectComposerModel; + QPointer m_effectComposerNodesModel; + QPointer m_effectComposerView; QPointer m_quickWidget; QmlDesigner::QmlModelNodeProxy m_backendModelNode; QmlDesigner::QmlAnchorBindingProxy m_backendAnchorBinding; @@ -79,5 +79,5 @@ private: QString m_compositionPath; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectnode.cpp b/src/plugins/effectcomposer/effectnode.cpp similarity index 85% rename from src/plugins/effectmakernew/effectnode.cpp rename to src/plugins/effectcomposer/effectnode.cpp index fc9d8ae7bfd..73b00681542 100644 --- a/src/plugins/effectmakernew/effectnode.cpp +++ b/src/plugins/effectcomposer/effectnode.cpp @@ -8,15 +8,15 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { EffectNode::EffectNode(const QString &qenPath) : m_qenPath(qenPath) { const QFileInfo fileInfo = QFileInfo(qenPath); - m_name = fileInfo.baseName(); - QString iconPath = QStringLiteral("%1/icon/%2.svg").arg(fileInfo.absolutePath(), m_name); + QString iconPath = QStringLiteral("%1/icon/%2.svg").arg(fileInfo.absolutePath(), + fileInfo.baseName()); if (!QFileInfo::exists(iconPath)) { QDir parentDir = QDir(fileInfo.absolutePath()); parentDir.cdUp(); @@ -26,8 +26,11 @@ EffectNode::EffectNode(const QString &qenPath) m_iconPath = QUrl::fromLocalFile(iconPath); CompositionNode node({}, qenPath); - const QList uniforms = node.uniforms(); + m_name = node.name(); + m_description = node.description(); + + const QList uniforms = node.uniforms(); for (const Uniform *uniform : uniforms) m_uniformNames.insert(uniform->name()); } @@ -60,5 +63,5 @@ bool EffectNode::hasUniform(const QString &name) return m_uniformNames.contains(name); } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectnode.h b/src/plugins/effectcomposer/effectnode.h similarity index 94% rename from src/plugins/effectmakernew/effectnode.h rename to src/plugins/effectcomposer/effectnode.h index 864904e088c..6322ff29f85 100644 --- a/src/plugins/effectmakernew/effectnode.h +++ b/src/plugins/effectcomposer/effectnode.h @@ -7,7 +7,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { class EffectNode : public QObject { @@ -42,5 +42,5 @@ private: QSet m_uniformNames; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectnodescategory.cpp b/src/plugins/effectcomposer/effectnodescategory.cpp similarity index 89% rename from src/plugins/effectmakernew/effectnodescategory.cpp rename to src/plugins/effectcomposer/effectnodescategory.cpp index 7f89766cca1..824eecaa2b6 100644 --- a/src/plugins/effectmakernew/effectnodescategory.cpp +++ b/src/plugins/effectcomposer/effectnodescategory.cpp @@ -3,7 +3,7 @@ #include "effectnodescategory.h" -namespace EffectMaker { +namespace EffectComposer { EffectNodesCategory::EffectNodesCategory(const QString &name, const QList &nodes) : m_name(name), @@ -19,5 +19,5 @@ QList EffectNodesCategory::nodes() const return m_categoryNodes; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectnodescategory.h b/src/plugins/effectcomposer/effectnodescategory.h similarity index 91% rename from src/plugins/effectmakernew/effectnodescategory.h rename to src/plugins/effectcomposer/effectnodescategory.h index 25f5d8d4bd6..7f92dcd6fce 100644 --- a/src/plugins/effectmakernew/effectnodescategory.h +++ b/src/plugins/effectcomposer/effectnodescategory.h @@ -7,7 +7,7 @@ #include -namespace EffectMaker { +namespace EffectComposer { class EffectNodesCategory : public QObject { @@ -27,5 +27,5 @@ private: QList m_categoryNodes; }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectutils.cpp b/src/plugins/effectcomposer/effectutils.cpp similarity index 75% rename from src/plugins/effectmakernew/effectutils.cpp rename to src/plugins/effectcomposer/effectutils.cpp index a0159c520da..157b3c191be 100644 --- a/src/plugins/effectmakernew/effectutils.cpp +++ b/src/plugins/effectcomposer/effectutils.cpp @@ -7,7 +7,7 @@ #include -namespace EffectMaker { +namespace EffectComposer { QString EffectUtils::codeFromJsonArray(const QJsonArray &codeArray) { @@ -26,10 +26,9 @@ QString EffectUtils::nodesSourcesPath() { #ifdef SHARE_QML_PATH if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) - return QLatin1String(SHARE_QML_PATH) + "/effectMakerNodes"; + return QLatin1String(SHARE_QML_PATH) + "/effectComposerNodes"; #endif - return Core::ICore::resourcePath("qmldesigner/effectMakerNodes").toString(); + return Core::ICore::resourcePath("qmldesigner/effectComposerNodes").toString(); } -} // namespace EffectMaker - +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectutils.h b/src/plugins/effectcomposer/effectutils.h similarity index 86% rename from src/plugins/effectmakernew/effectutils.h rename to src/plugins/effectcomposer/effectutils.h index eede7952c5c..5b9c99d4968 100644 --- a/src/plugins/effectmakernew/effectutils.h +++ b/src/plugins/effectcomposer/effectutils.h @@ -7,7 +7,7 @@ QT_FORWARD_DECLARE_CLASS(QJsonArray) -namespace EffectMaker { +namespace EffectComposer { class EffectUtils { @@ -19,5 +19,5 @@ public: static QString nodesSourcesPath(); }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/propertyhandler.cpp b/src/plugins/effectcomposer/propertyhandler.cpp similarity index 86% rename from src/plugins/effectmakernew/propertyhandler.cpp rename to src/plugins/effectcomposer/propertyhandler.cpp index 9382c9a1f67..b440410a0bf 100644 --- a/src/plugins/effectmakernew/propertyhandler.cpp +++ b/src/plugins/effectcomposer/propertyhandler.cpp @@ -3,7 +3,7 @@ #include "propertyhandler.h" -namespace EffectMaker { +namespace EffectComposer { QQmlPropertyMap g_propertyData; diff --git a/src/plugins/effectmakernew/propertyhandler.h b/src/plugins/effectcomposer/propertyhandler.h similarity index 91% rename from src/plugins/effectmakernew/propertyhandler.h rename to src/plugins/effectcomposer/propertyhandler.h index 82e2f7212d0..96bc49f78e0 100644 --- a/src/plugins/effectmakernew/propertyhandler.h +++ b/src/plugins/effectcomposer/propertyhandler.h @@ -5,7 +5,7 @@ #include -namespace EffectMaker { +namespace EffectComposer { // This will be used for binding dynamic properties // changes between C++ and QML. diff --git a/src/plugins/effectmakernew/shaderfeatures.cpp b/src/plugins/effectcomposer/shaderfeatures.cpp similarity index 94% rename from src/plugins/effectmakernew/shaderfeatures.cpp rename to src/plugins/effectcomposer/shaderfeatures.cpp index 03aea9c1f15..fc1cf95a34b 100644 --- a/src/plugins/effectmakernew/shaderfeatures.cpp +++ b/src/plugins/effectcomposer/shaderfeatures.cpp @@ -5,7 +5,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { ShaderFeatures::ShaderFeatures() { @@ -73,8 +73,12 @@ void ShaderFeatures::checkLine(const QString &line, Features &features) if (m_gridMeshWidth > 1 || m_gridMeshHeight > 1) features.setFlag(GridMesh, true); } + if (line.contains("@blursources")) features.setFlag(BlurSources, true); + + if (line.contains("textureLod(")) + features.setFlag(Mipmap, true); } int ShaderFeatures::gridMeshHeight() const @@ -87,5 +91,5 @@ int ShaderFeatures::gridMeshWidth() const return m_gridMeshWidth; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/shaderfeatures.h b/src/plugins/effectcomposer/shaderfeatures.h similarity index 89% rename from src/plugins/effectmakernew/shaderfeatures.h rename to src/plugins/effectcomposer/shaderfeatures.h index 4e9f09eeae2..30bf9e68516 100644 --- a/src/plugins/effectmakernew/shaderfeatures.h +++ b/src/plugins/effectcomposer/shaderfeatures.h @@ -6,7 +6,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { class ShaderFeatures { @@ -19,7 +19,8 @@ public: Mouse = 1 << 4, FragCoord = 1 << 5, GridMesh = 1 << 6, - BlurSources = 1 << 7 + BlurSources = 1 << 7, + Mipmap = 1 << 8 }; Q_DECLARE_FLAGS(Features, Feature) @@ -40,5 +41,5 @@ private: }; Q_DECLARE_OPERATORS_FOR_FLAGS(ShaderFeatures::Features) -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/syntaxhighlighterdata.cpp b/src/plugins/effectcomposer/syntaxhighlighterdata.cpp similarity index 98% rename from src/plugins/effectmakernew/syntaxhighlighterdata.cpp rename to src/plugins/effectcomposer/syntaxhighlighterdata.cpp index 4a6face8196..bac3eceb348 100644 --- a/src/plugins/effectmakernew/syntaxhighlighterdata.cpp +++ b/src/plugins/effectcomposer/syntaxhighlighterdata.cpp @@ -3,7 +3,7 @@ #include "syntaxhighlighterdata.h" -namespace EffectMaker { +namespace EffectComposer { static constexpr QByteArrayView shader_arg_names[] { { "gl_Position" }, @@ -186,6 +186,6 @@ QList SyntaxHighlighterData::reservedFunctionNames() return { std::begin(shader_function_names), std::end(shader_function_names) }; } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/syntaxhighlighterdata.h b/src/plugins/effectcomposer/syntaxhighlighterdata.h similarity index 87% rename from src/plugins/effectmakernew/syntaxhighlighterdata.h rename to src/plugins/effectcomposer/syntaxhighlighterdata.h index bce1100e05c..748948083b2 100644 --- a/src/plugins/effectmakernew/syntaxhighlighterdata.h +++ b/src/plugins/effectcomposer/syntaxhighlighterdata.h @@ -6,7 +6,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { class SyntaxHighlighterData { @@ -18,6 +18,6 @@ public: static QList reservedFunctionNames(); }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/uniform.cpp b/src/plugins/effectcomposer/uniform.cpp similarity index 95% rename from src/plugins/effectmakernew/uniform.cpp rename to src/plugins/effectcomposer/uniform.cpp index e9084f27991..e8fd77d631f 100644 --- a/src/plugins/effectmakernew/uniform.cpp +++ b/src/plugins/effectcomposer/uniform.cpp @@ -12,7 +12,7 @@ #include #include -namespace EffectMaker { +namespace EffectComposer { Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QString &qenPath) : m_qenPath(qenPath) @@ -28,11 +28,15 @@ Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QS if (m_displayName.isEmpty()) m_displayName = m_name; - QString resPath; + value = propObj.contains("value") ? propObj.value("value").toString() : defaultValue; + if (m_type == Type::Sampler) { - resPath = getResourcePath(effectName, defaultValue, qenPath); if (!defaultValue.isEmpty()) - defaultValue = resPath; + defaultValue = getResourcePath(effectName, defaultValue, qenPath); + if (!value.isEmpty()) + value = getResourcePath(effectName, value, qenPath); + if (value.isEmpty()) + value = defaultValue; if (propObj.contains("enableMipmap")) m_enableMipmap = getBoolValue(propObj.value("enableMipmap"), false); // Update the mipmap property @@ -40,14 +44,6 @@ Uniform::Uniform(const QString &effectName, const QJsonObject &propObj, const QS g_propertyData[mipmapProperty] = m_enableMipmap; } - if (propObj.contains("value")) { - value = propObj.value("value").toString(); - if (m_type == Type::Sampler) - value = resPath; - } else { - // QEN files don't store the current value, so with those use default value - value = defaultValue; - } m_customValue = propObj.value("customValue").toString(); m_useCustomValue = getBoolValue(propObj.value("useCustomValue"), false); @@ -346,4 +342,4 @@ QString Uniform::typeToProperty(Uniform::Type type) return QString(); } -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/uniform.h b/src/plugins/effectcomposer/uniform.h similarity index 98% rename from src/plugins/effectmakernew/uniform.h rename to src/plugins/effectcomposer/uniform.h index 2aa35d499d9..83f15224aec 100644 --- a/src/plugins/effectmakernew/uniform.h +++ b/src/plugins/effectcomposer/uniform.h @@ -12,7 +12,7 @@ QT_FORWARD_DECLARE_CLASS(QColor) QT_FORWARD_DECLARE_CLASS(QJsonObject) QT_FORWARD_DECLARE_CLASS(QVector2D) -namespace EffectMaker { +namespace EffectComposer { class Uniform : public QObject { @@ -109,4 +109,4 @@ private: } }; -} // namespace EffectMaker +} // namespace EffectComposer diff --git a/src/plugins/effectmakernew/effectmakerplugin.cpp b/src/plugins/effectmakernew/effectmakerplugin.cpp deleted file mode 100644 index 5d36035e2f6..00000000000 --- a/src/plugins/effectmakernew/effectmakerplugin.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "effectmakerview.h" - -#include -#include - -#include -#include - -namespace EffectMaker { - -static bool enableEffectMaker() -{ - Utils::QtcSettings *settings = Core::ICore::settings(); - const Utils::Key enableModelManagerKey = "QML/Designer/UseExperimentalFeatures44"; - - return settings->value(enableModelManagerKey, false).toBool(); -} - -class EffectMakerPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "EffectMakerNew.json") - - bool delayedInitialize() final - { - if (enableEffectMaker()) { - auto *designerPlugin = QmlDesigner::QmlDesignerPlugin::instance(); - auto &viewManager = designerPlugin->viewManager(); - - viewManager.registerView(std::make_unique( - QmlDesigner::QmlDesignerPlugin::externalDependenciesForPluginInitializationOnly())); - } - return true; - } -}; - -} // namespace EffectMaker - -#include "effectmakerplugin.moc" diff --git a/src/plugins/effectmakernew/effectmakerview.cpp b/src/plugins/effectmakernew/effectmakerview.cpp deleted file mode 100644 index 42624826943..00000000000 --- a/src/plugins/effectmakernew/effectmakerview.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "effectmakerview.h" - -#include "effectmakermodel.h" -#include "effectmakernodesmodel.h" -#include "effectmakerwidget.h" - -#include "qmldesignerconstants.h" - -#include - -#include - -namespace EffectMaker { - -EffectMakerContext::EffectMakerContext(QWidget *widget) - : IContext(widget) -{ - setWidget(widget); - setContext(Core::Context(QmlDesigner::Constants::C_QMLEFFECTMAKER, - QmlDesigner::Constants::C_QT_QUICK_TOOLS_MENU)); -} - -void EffectMakerContext::contextHelp(const HelpCallback &callback) const -{ - qobject_cast(m_widget)->contextHelp(callback); -} - -EffectMakerView::EffectMakerView(QmlDesigner::ExternalDependenciesInterface &externalDependencies) - : AbstractView{externalDependencies} -{ -} - -EffectMakerView::~EffectMakerView() -{} - -bool EffectMakerView::hasWidget() const -{ - return true; -} - -QmlDesigner::WidgetInfo EffectMakerView::widgetInfo() -{ - if (m_widget.isNull()) { - m_widget = new EffectMakerWidget{this}; - - connect(m_widget->effectMakerModel(), &EffectMakerModel::assignToSelectedTriggered, this, - [&] (const QString &effectPath) { - executeInTransaction("EffectMakerView::widgetInfo", [&] { - const QList selectedNodes = selectedModelNodes(); - for (const QmlDesigner::ModelNode &node : selectedNodes) - QmlDesigner::ModelNodeOperations::handleItemLibraryEffectDrop(effectPath, node); - }); - }); - - auto context = new EffectMakerContext(m_widget.data()); - Core::ICore::addContextObject(context); - } - - return createWidgetInfo(m_widget.data(), "Effect Maker", - QmlDesigner::WidgetInfo::LeftPane, 0, tr("Effect Maker")); -} - -void EffectMakerView::customNotification([[maybe_unused]] const AbstractView *view, - const QString &identifier, - [[maybe_unused]] const QList &nodeList, - const QList &data) -{ - if (identifier == "open_effectmaker_composition" && data.count() > 0) { - const QString compositionPath = data[0].toString(); - m_widget->openComposition(compositionPath); - } -} - -void EffectMakerView::modelAttached(QmlDesigner::Model *model) -{ - AbstractView::modelAttached(model); - - m_widget->effectMakerNodesModel()->loadModel(); - m_widget->effectMakerModel()->clear(); - m_widget->initView(); -} - -void EffectMakerView::modelAboutToBeDetached(QmlDesigner::Model *model) -{ - AbstractView::modelAboutToBeDetached(model); -} - -} // namespace EffectMaker diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index d20312baa49..7bfea271e5d 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -503,7 +503,6 @@ add_qtc_plugin(QmlDesigner ${CMAKE_CURRENT_LIST_DIR}/components/propertyeditor ${CMAKE_CURRENT_LIST_DIR}/components/stateseditor ${CMAKE_CURRENT_LIST_DIR}/components/texteditor - ${CMAKE_CURRENT_LIST_DIR}/components/effectmaker PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/designercore #can not be a public dependency -> EXCLUDE_FROM_INSTALL in QmlDesignerCore diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 1d6fc0dd77d..c2359409eb5 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -114,13 +114,28 @@ void AssetsLibraryModel::deleteFiles(const QStringList &filePaths, bool dontAskA if (dontAskAgain) QmlDesignerPlugin::settings().insert(DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, false); + QStringList deletedEffects; + for (const QString &filePath : filePaths) { - if (QFileInfo::exists(filePath) && !QFile::remove(filePath)) { - QMessageBox::warning(Core::ICore::dialogParent(), - tr("Failed to Delete File"), - tr("Could not delete \"%1\".").arg(filePath)); + QFileInfo fi(filePath); + if (fi.exists()) { + if (QFile::remove(filePath)) { + if (Asset(filePath).isEffect()) { + // If an effect composer effect was removed, also remove effect module from project + QString effectName = fi.baseName(); + if (!effectName.isEmpty()) + deletedEffects.append(effectName); + } + } else { + QMessageBox::warning(Core::ICore::dialogParent(), + tr("Failed to Delete File"), + tr("Could not delete \"%1\".").arg(filePath)); + } } } + + if (!deletedEffects.isEmpty()) + emit effectsDeleted(deletedEffects); } bool AssetsLibraryModel::renameFolder(const QString &folderPath, const QString &newName) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index e37bf8a109a..9334e86e9b2 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -64,6 +64,7 @@ signals: void rootPathChanged(); void haveFilesChanged(); void fileChanged(const QString &path); + void effectsDeleted(const QStringList &effectNames); private: void setHaveFiles(bool value); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 13178c6dd2e..5f33036b40e 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -8,6 +8,8 @@ #include "assetslibrarymodel.h" #include "assetslibraryview.h" #include "designeractionmanager.h" +#include "import.h" +#include "nodemetainfo.h" #include "modelnodeoperations.h" #include "qmldesignerconstants.h" #include "qmldesignerplugin.h" @@ -27,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +121,9 @@ AssetsLibraryWidget::AssetsLibraryWidget(AsynchronousImageCache &asynchronousFon connect(m_assetsModel, &AssetsLibraryModel::fileChanged, QmlDesignerPlugin::instance(), &QmlDesignerPlugin::assetChanged); + connect(m_assetsModel, &AssetsLibraryModel::effectsDeleted, + this, &AssetsLibraryWidget::handleDeleteEffects); + auto layout = new QVBoxLayout(this); layout->setContentsMargins({}); layout->setSpacing(0); @@ -184,12 +190,12 @@ QString AssetsLibraryWidget::getUniqueEffectPath(const QString &parentFolder, co return path; } -bool AssetsLibraryWidget::createNewEffect(const QString &effectPath, bool openInEffectMaker) +bool AssetsLibraryWidget::createNewEffect(const QString &effectPath, bool openInEffectComposer) { bool created = QFile(effectPath).open(QIODevice::WriteOnly); - if (created && openInEffectMaker) { - openEffectMaker(effectPath); + if (created && openInEffectComposer) { + openEffectComposer(effectPath); emit directoryCreated(QFileInfo(effectPath).absolutePath()); } @@ -263,6 +269,73 @@ void AssetsLibraryWidget::setHasSceneEnv(bool b) emit hasSceneEnvChanged(); } +void AssetsLibraryWidget::handleDeleteEffects(const QStringList &effectNames) +{ + DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); + if (!document) + return; + + bool clearStacks = false; + + // Remove usages of deleted effects from the current document + m_assetsView->executeInTransaction(__FUNCTION__, [&]() { + QList allNodes = m_assetsView->allModelNodes(); + const QString typeTemplate = "Effects.%1.%1"; + const QString importUrlTemplate = "Effects.%1"; + const Imports imports = m_assetsView->model()->imports(); + Imports removedImports; + for (const QString &effectName : effectNames) { + if (effectName.isEmpty()) + continue; + const TypeName type = typeTemplate.arg(effectName).toUtf8(); + for (ModelNode &node : allNodes) { + if (node.metaInfo().typeName() == type) { + clearStacks = true; + node.destroy(); + } + } + + const QString importPath = importUrlTemplate.arg(effectName); + Import removedImport = Utils::findOrDefault(imports, [&importPath](const Import &import) { + return import.url() == importPath; + }); + if (!removedImport.isEmpty()) + removedImports.append(removedImport); + } + + if (!removedImports.isEmpty()) { + m_assetsView->model()->changeImports({}, removedImports); + clearStacks = true; + } + }); + + // The size check here is to weed out cases where project path somehow resolves + // to just slash. Shortest legal currentProjectDirPath() would be "/a/". + if (m_assetsModel->currentProjectDirPath().size() < 3) + return; + + Utils::FilePath effectsDir = ModelNodeOperations::getEffectsImportDirectory(); + + // Delete the effect modules + for (const QString &effectName : effectNames) { + Utils::FilePath eDir = effectsDir.pathAppended(effectName); + if (eDir.exists() && eDir.toString().startsWith(m_assetsModel->currentProjectDirPath())) { + QString error; + eDir.removeRecursively(&error); + if (!error.isEmpty()) { + QMessageBox::warning(Core::ICore::dialogParent(), + tr("Failed to Delete Effect Resources"), + tr("Could not delete \"%1\".").arg(eDir.toString())); + } + } + } + + // Reset undo stack as removing effect components cannot be undone, and thus the stack will + // contain only unworkable states. + if (clearStacks) + document->clearUndoRedoStacks(); +} + void AssetsLibraryWidget::invalidateThumbnail(const QString &id) { m_assetsIconProvider->invalidateThumbnail(id); @@ -359,9 +432,9 @@ QSet AssetsLibraryWidget::supportedAssetSuffixes(bool complex) return suffixes; } -void AssetsLibraryWidget::openEffectMaker(const QString &filePath) +void AssetsLibraryWidget::openEffectComposer(const QString &filePath) { - ModelNodeOperations::openEffectMaker(filePath); + ModelNodeOperations::openEffectComposer(filePath); } QString AssetsLibraryWidget::qmlSourcesPath() @@ -440,7 +513,7 @@ QPair AssetsLibraryWidget::getAssetTypeAndData(const QStrin // Data: Image format (suffix) return {Constants::MIME_TYPE_ASSET_TEXTURE3D, asset.suffix().toUtf8()}; } else if (asset.isEffect()) { - // Data: Effect Maker format (suffix) + // Data: Effect Composer format (suffix) return {Constants::MIME_TYPE_ASSET_EFFECT, asset.suffix().toUtf8()}; } } diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h index 4b3976ebae2..ed987d14deb 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h @@ -80,7 +80,7 @@ public: const QString &targetDirPath = {}); Q_INVOKABLE QSet supportedAssetSuffixes(bool complex); - Q_INVOKABLE void openEffectMaker(const QString &filePath); + Q_INVOKABLE void openEffectComposer(const QString &filePath); Q_INVOKABLE int qtVersion() const; Q_INVOKABLE void invalidateThumbnail(const QString &id); Q_INVOKABLE QSize imageSize(const QString &id); @@ -92,7 +92,7 @@ public: Q_INVOKABLE void updateContextMenuActionsEnableState(); Q_INVOKABLE QString getUniqueEffectPath(const QString &parentFolder, const QString &effectName); - Q_INVOKABLE bool createNewEffect(const QString &effectPath, bool openInEffectMaker = true); + Q_INVOKABLE bool createNewEffect(const QString &effectPath, bool openInEffectComposer = true); Q_INVOKABLE bool canCreateEffects() const; @@ -124,6 +124,8 @@ private: void setHasMaterialLibrary(bool enable); void setHasSceneEnv(bool b); + void handleDeleteEffects(const QStringList &effectNames); + QSize m_itemIconSize; SynchronousImageCache &m_fontImageCache; diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp index 90f0061c87c..f35e9f2ed26 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp @@ -42,6 +42,79 @@ public: bool isValidRowId(int row) const { return row > -1 && row < elements.size(); } }; +inline static bool isValidColorName(const QString &colorName) +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) + return QColor::isValidColorName(colorName); +#else + constexpr QStringView colorPattern( + u"(?^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|(?:[0-9a-fA-F]){3,4}))$)"); + static const QRegularExpression colorRegex(colorPattern.toString()); + return colorRegex.match(colorName).hasMatch(); +#endif // >= Qt 6.4 +} + +/** + * @brief getCustomUrl + * MimeType = + * Address = + * + * @param value The input value to be evaluated + * @param dataType if the value is a valid url or image, the data type + * will be stored to this parameter, otherwise, it will be Unknown + * @param urlResult if the value is a valid url or image, the address + * will be stored in this parameter, otherwise it will be empty. + * @param subType if the value is a valid image, the image subtype + * will be stored in this parameter, otherwise it will be empty. + * @return true if the result is either url or image + */ +inline static bool getCustomUrl(const QString &value, + CollectionDetails::DataType &dataType, + QUrl *urlResult = nullptr, + QString *subType = nullptr) +{ + constexpr QStringView urlPattern( + u"^(?" + u"(?image)\\/" + u"(?apng|avif|gif|jpeg|png|(?:svg\\+xml)|webp|xyz)\\:)?" // end of MimeType + u"(?
" + u"(?https?:\\/\\/" + u"(?:www\\.|(?!www))[A-z0-9][A-z0-9-]+[A-z0-9]\\.[^\\s]{2,}|www\\.[A-z0-9][A-z0-9-]+" + u"[A-z0-9]\\.[^\\s]{2,}|https?:\\/\\/" + u"(?:www\\.|(?!www))[A-z0-9]+\\.[^\\s]{2,}|www\\.[A-z0-9]+\\.[^\\s]{2,})|" // end of Url + u"(?(" + u"?:(?:[A-z]:)|(?:(?:\\\\|\\/){1,2}\\w+)\\$?)(?:(?:\\\\|\\/)(?:\\w[\\w ]*.*))+)" // end of LocalFile + u"){1}$"); // end of Address + static const QRegularExpression urlRegex(urlPattern.toString()); + + const QRegularExpressionMatch match = urlRegex.match(value); + if (match.hasMatch()) { + if (match.hasCaptured("Address")) { + if (match.hasCaptured("MimeType") && match.captured("MainType") == "image") + dataType = CollectionDetails::DataType::Image; + else + dataType = CollectionDetails::DataType::Url; + + if (urlResult) + urlResult->setUrl(match.captured("Address")); + + if (subType) + *subType = match.captured("SubType"); + + return true; + } + } + + if (urlResult) + urlResult->clear(); + + if (subType) + subType->clear(); + + dataType = CollectionDetails::DataType::Unknown; + return false; +} + static CollectionProperty::DataType collectionDataTypeFromJsonValue(const QJsonValue &value) { using DataType = CollectionDetails::DataType; @@ -53,10 +126,20 @@ static CollectionProperty::DataType collectionDataTypeFromJsonValue(const QJsonV return DataType::Unknown; case JsonType::Bool: return DataType::Boolean; - case JsonType::Double: - return DataType::Number; + case JsonType::Double: { + if (qFuzzyIsNull(std::remainder(value.toDouble(), 1))) + return DataType::Integer; + return DataType::Real; + } case JsonType::String: { - // TODO: Image, Color, Url + const QString stringValue = value.toString(); + if (isValidColorName(stringValue)) + return DataType::Color; + + DataType urlType; + if (getCustomUrl(stringValue, urlType)) + return urlType; + return DataType::String; } break; default: @@ -72,12 +155,21 @@ static QVariant valueToVariant(const QJsonValue &value, CollectionDetails::DataT switch (type) { case DataType::String: return variantValue.toString(); - case DataType::Number: + case DataType::Integer: + return variantValue.toInt(); + case DataType::Real: return variantValue.toDouble(); case DataType::Boolean: return variantValue.toBool(); case DataType::Color: return variantValue.value(); + case DataType::Image: { + DataType type; + QUrl url; + if (getCustomUrl(variantValue.toString(), type, &url)) + return url; + return variantValue.toString(); + } case DataType::Url: return variantValue.value(); default: @@ -85,19 +177,38 @@ static QVariant valueToVariant(const QJsonValue &value, CollectionDetails::DataT } } -static QJsonValue variantToJsonValue(const QVariant &variant) +static QJsonValue variantToJsonValue( + const QVariant &variant, CollectionDetails::DataType type = CollectionDetails::DataType::Unknown) { using VariantType = QVariant::Type; + using DataType = CollectionDetails::DataType; - switch (variant.type()) { - case VariantType::Bool: + if (type == CollectionDetails::DataType::Unknown) { + static const QHash typeMap = {{VariantType::Bool, DataType::Boolean}, + {VariantType::Double, DataType::Real}, + {VariantType::Int, DataType::Integer}, + {VariantType::String, DataType::String}, + {VariantType::Color, DataType::Color}, + {VariantType::Url, DataType::Url}}; + type = typeMap.value(variant.type(), DataType::Unknown); + } + + switch (type) { + case DataType::Boolean: return variant.toBool(); - case VariantType::Double: - case VariantType::Int: + case DataType::Real: return variant.toDouble(); - case VariantType::String: - case VariantType::Color: - case VariantType::Url: + case DataType::Integer: + return variant.toInt(); + case DataType::Image: { + const QUrl url(variant.toUrl()); + if (url.isValid()) + return QString("image/xyz:%1").arg(url.toString()); + return {}; + } + case DataType::String: + case DataType::Color: + case DataType::Url: default: return variant.toString(); } @@ -255,7 +366,7 @@ bool CollectionDetails::setPropertyValue(int row, int column, const QVariant &va if (value == currentValue) return false; - element.insert(d->properties.at(column).name, QJsonValue::fromVariant(value)); + element.insert(d->properties.at(column).name, variantToJsonValue(value, typeAt(column))); markChanged(); return true; } @@ -292,13 +403,14 @@ bool CollectionDetails::setPropertyType(int column, DataType type) if (property.type != type) changed = true; + const DataType formerType = property.type; property.type = type; for (QJsonObject &element : d->elements) { if (element.contains(property.name)) { const QJsonValue value = element.value(property.name); - const QVariant properTypedValue = valueToVariant(value, type); - const QJsonValue properTypedJsonValue = variantToJsonValue(properTypedValue); + const QVariant properTypedValue = valueToVariant(value, formerType); + const QJsonValue properTypedJsonValue = variantToJsonValue(properTypedValue, type); element.insert(property.name, properTypedJsonValue); changed = true; } @@ -334,10 +446,19 @@ QVariant CollectionDetails::data(int row, int column) const const QString &propertyName = d->properties.at(column).name; const QJsonObject &elementNode = d->elements.at(row); - if (elementNode.contains(propertyName)) - return elementNode.value(propertyName).toVariant(); + if (!elementNode.contains(propertyName)) + return {}; - return {}; + const QJsonValue cellValue = elementNode.value(propertyName); + + if (typeAt(column) == DataType::Image) { + const QUrl imageUrl = valueToVariant(cellValue, DataType::Image).toUrl(); + + if (imageUrl.isValid()) + return imageUrl; + } + + return cellValue.toVariant(); } QString CollectionDetails::propertyAt(int column) const @@ -375,13 +496,19 @@ DataTypeWarning::Warning CollectionDetails::cellWarningCheck(int row, int column const QString &propertyName = d->properties.at(column).name; const QJsonObject &element = d->elements.at(row); - if (typeAt(column) == DataType::Unknown || element.isEmpty() + const DataType columnType = typeAt(column); + const DataType cellType = typeAt(row, column); + if (columnType == DataType::Unknown || element.isEmpty() || data(row, column) == QVariant::fromValue(nullptr)) { return DataTypeWarning::Warning::None; } - if (element.contains(propertyName) && typeAt(column) != typeAt(row, column)) - return DataTypeWarning::Warning::CellDataTypeMismatch; + if (element.contains(propertyName)) { + if (columnType == DataType::Real && cellType == DataType::Integer) + return DataTypeWarning::Warning::None; + else if (columnType != cellType) + return DataTypeWarning::Warning::CellDataTypeMismatch; + } return DataTypeWarning::Warning::None; } @@ -430,6 +557,14 @@ void CollectionDetails::swap(CollectionDetails &other) d.swap(other.d); } +void CollectionDetails::resetReference(const CollectionReference &reference) +{ + if (d->reference != reference) { + d->reference = reference; + markChanged(); + } +} + void CollectionDetails::registerDeclarativeType() { typedef CollectionDetails::DataType DataType; @@ -463,16 +598,23 @@ void CollectionDetails::resetPropertyType(const QString &propertyName) void CollectionDetails::resetPropertyType(CollectionProperty &property) { const QString &propertyName = property.name; - DataType type = DataType::Unknown; + DataType columnType = DataType::Unknown; for (const QJsonObject &element : std::as_const(d->elements)) { if (element.contains(propertyName)) { - type = collectionDataTypeFromJsonValue(element.value(propertyName)); - if (type != DataType::Unknown) + const DataType cellType = collectionDataTypeFromJsonValue(element.value(propertyName)); + if (cellType != DataType::Unknown) { + if (columnType == DataType::Integer && cellType != DataType::Real) + continue; + + columnType = cellType; + if (columnType == DataType::Integer) + continue; + break; + } } } - - property.type = type; + property.type = columnType; } void CollectionDetails::resetPropertyTypes() diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h index 9d8eb7eca03..a18c557c52b 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h @@ -60,7 +60,7 @@ class CollectionDetails Q_GADGET public: - enum class DataType { Unknown, String, Url, Number, Boolean, Image, Color }; + enum class DataType { Unknown, String, Url, Integer, Real, Boolean, Image, Color }; Q_ENUM(DataType) explicit CollectionDetails(); @@ -103,6 +103,7 @@ public: bool markSaved(); void swap(CollectionDetails &other); + void resetReference(const CollectionReference &reference); QString getCollectionAsJsonString() const; QString getCollectionAsCsvString() const; diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp index 52d5a6e2bab..51e3be9ad6b 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp @@ -66,7 +66,7 @@ public: static QStringList typesStringList() { - static const QStringList typesList = typeToStringHash().values(); + static const QStringList typesList = orderedTypeNames(); return typesList; } @@ -79,7 +79,8 @@ private: {DataType::Unknown, "Unknown"}, {DataType::String, "String"}, {DataType::Url, "Url"}, - {DataType::Number, "Number"}, + {DataType::Real, "Real"}, + {DataType::Integer, "Integer"}, {DataType::Boolean, "Boolean"}, {DataType::Image, "Image"}, {DataType::Color, "Color"}, @@ -95,6 +96,29 @@ private: return stringTypeHash; } + + static QStringList orderedTypeNames() + { + const QList orderedtypes{ + DataType::String, + DataType::Integer, + DataType::Real, + DataType::Image, + DataType::Color, + DataType::Url, + DataType::Boolean, + DataType::Unknown, + }; + + QStringList orderedNames; + QHash typeStringHash = typeToStringHash(); + + for (const DataType &type : orderedtypes) + orderedNames.append(typeStringHash.take(type)); + + Q_ASSERT(typeStringHash.isEmpty()); + return orderedNames; + } }; } // namespace @@ -219,11 +243,16 @@ bool CollectionDetailsModel::removeColumns(int column, int count, const QModelIn bool columnsRemoved = m_currentCollection.removeColumns(column, count); endRemoveColumns(); + if (!columnCount(parent)) + removeRows(0, rowCount(parent), parent); + int nextColumn = column - 1; if (nextColumn < 0 && columnCount(parent) > 0) nextColumn = 0; selectColumn(nextColumn); + + ensureSingleCell(); return columnsRemoved; } @@ -237,6 +266,7 @@ bool CollectionDetailsModel::removeRows(int row, int count, const QModelIndex &p bool rowsRemoved = m_currentCollection.removeElements(row, count); endRemoveRows(); + ensureSingleCell(); return rowsRemoved; } @@ -317,8 +347,8 @@ bool CollectionDetailsModel::selectColumn(int section) const int columns = columnCount(); - if (m_selectedColumn >= columns) - return false; + if (section >= columns) + section = columns - 1; selectRow(-1); @@ -415,6 +445,7 @@ void CollectionDetailsModel::loadCollection(const ModelNode &sourceNode, const Q deselectAll(); beginResetModel(); switchToCollection(newReference); + ensureSingleCell(); endResetModel(); } } else { @@ -427,6 +458,42 @@ void CollectionDetailsModel::loadCollection(const ModelNode &sourceNode, const Q } } +void CollectionDetailsModel::removeCollection(const ModelNode &sourceNode, const QString &collection) +{ + CollectionReference collectionRef{sourceNode, collection}; + if (!m_openedCollections.contains(collectionRef)) + return; + + if (m_currentCollection.reference() == collectionRef) + loadCollection({}, {}); + + m_openedCollections.remove(collectionRef); +} + +void CollectionDetailsModel::removeAllCollections() +{ + loadCollection({}, {}); + m_openedCollections.clear(); +} + +void CollectionDetailsModel::renameCollection(const ModelNode &sourceNode, + const QString &oldName, + const QString &newName) +{ + CollectionReference oldRef{sourceNode, oldName}; + if (!m_openedCollections.contains(oldRef)) + return; + + CollectionReference newReference{sourceNode, newName}; + bool collectionIsSelected = m_currentCollection.reference() == oldRef; + CollectionDetails collection = m_openedCollections.take(oldRef); + collection.resetReference(newReference); + m_openedCollections.insert(newReference, collection); + + if (collectionIsSelected) + setCollectionName(newName); +} + bool CollectionDetailsModel::saveDataStoreCollections() { const ModelNode node = m_currentCollection.reference().node; @@ -583,6 +650,7 @@ void CollectionDetailsModel::loadJsonCollection(const QString &source, const QSt SourceFormat sourceFormat = jsonFileIsOk ? SourceFormat::Json : SourceFormat::Unknown; beginResetModel(); m_currentCollection.resetDetails(getJsonHeaders(collectionNodes), elements, sourceFormat); + ensureSingleCell(); endResetModel(); } @@ -635,9 +703,24 @@ void CollectionDetailsModel::loadCsvCollection(const QString &source, SourceFormat sourceFormat = csvFileIsOk ? SourceFormat::Csv : SourceFormat::Unknown; beginResetModel(); m_currentCollection.resetDetails(headers, elements, sourceFormat); + ensureSingleCell(); endResetModel(); } +void CollectionDetailsModel::ensureSingleCell() +{ + if (!m_currentCollection.isValid()) + return; + + if (!columnCount()) + addColumn(0, "Column 1", "String"); + + if (!rowCount()) + insertRow(0); + + updateEmpty(); +} + QVariant CollectionDetailsModel::variantFromString(const QString &value) { constexpr QStringView typesPattern{u"(?^(?:true|false)$)|" diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h index 4fef84a3df3..cef942b0448 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h @@ -61,6 +61,9 @@ public: static Q_INVOKABLE QStringList typesList(); void loadCollection(const ModelNode &sourceNode, const QString &collection); + void removeCollection(const ModelNode &sourceNode, const QString &collection); + void removeAllCollections(); + void renameCollection(const ModelNode &sourceNode, const QString &oldName, const QString &newName); Q_INVOKABLE bool saveDataStoreCollections(); Q_INVOKABLE bool exportCollection(const QUrl &url); @@ -81,6 +84,7 @@ private: void setCollectionName(const QString &newCollectionName); void loadJsonCollection(const QString &source, const QString &collection); void loadCsvCollection(const QString &source, const QString &collectionName); + void ensureSingleCell(); QVariant variantFromString(const QString &value); QHash m_openedCollections; diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp index 33867228d56..4b779c52fa5 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp @@ -7,14 +7,14 @@ #include "nodemetainfo.h" #include "propertymetainfo.h" -#include - #include -#include - #include #include #include +#include +#include + +#include #include #include @@ -26,7 +26,7 @@ namespace { -using CollectionDataVariant = std::variant; +using CollectionDataVariant = std::variant; inline bool operator<(const QColor &a, const QColor &b) { @@ -40,12 +40,15 @@ inline CollectionDataVariant valueToVariant(const QVariant &value, switch (type) { case DataType::String: return value.toString(); - case DataType::Number: + case DataType::Real: return value.toDouble(); + case DataType::Integer: + return value.toInt(); case DataType::Boolean: return value.toBool(); case DataType::Color: return value.value(); + case DataType::Image: case DataType::Url: return value.value(); default: @@ -290,6 +293,12 @@ bool ensureDataStoreExists(bool &justCreated) if (qmlDirSaver.finalize()) { justCreated = true; + + // Force code model reset to notice changes to existing module + auto modelManager = QmlJS::ModelManagerInterface::instance(); + if (modelManager) + modelManager->resetCodeModel(); + return true; } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp index 1f9c7aa5d7a..1d27f205489 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp @@ -498,8 +498,21 @@ void CollectionSourceModel::onCollectionNameChanged(CollectionListModel *collect return; } + CollectionListModel *list = m_collectionList.at(nodeIndex.row()).data(); + bool updateSelectedNames = list && list == m_previousSelectedList.data(); emit collectionRenamed(oldName, newName); updateCollectionList(nodeIndex); + + if (updateSelectedNames) { + list = m_collectionList.at(nodeIndex.row()).data(); + if (m_selectedCollectionName == oldName) { + list->selectCollectionName(newName); + setSelectedCollectionName(newName); + } else { + // reselect to update ID if it's changed due to renaming and order changes + list->selectCollectionName(m_selectedCollectionName); + } + } } } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp index 7f3ee7192ac..1b1d1a7d9fc 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp @@ -48,7 +48,11 @@ CollectionView::CollectionView(ExternalDependenciesInterface &externalDependenci connect(ProjectExplorer::ProjectManager::instance(), &ProjectExplorer::ProjectManager::startupProjectChanged, this, - &CollectionView::resetDataStoreNode); + [=] { + resetDataStoreNode(); + if (m_widget.get()) + m_widget->collectionDetailsModel()->removeAllCollections(); + }); resetDataStoreNode(); } @@ -91,6 +95,9 @@ QmlDesigner::WidgetInfo CollectionView::widgetInfo() this, [this](const QString &oldName, const QString &newName) { m_dataStore->renameCollection(oldName, newName); + m_widget->collectionDetailsModel()->renameCollection(dataStoreNode(), + oldName, + newName); }); connect(sourceModel, @@ -98,6 +105,8 @@ QmlDesigner::WidgetInfo CollectionView::widgetInfo() this, [this](const QString &collectionName) { m_dataStore->removeCollection(collectionName); + m_widget->collectionDetailsModel()->removeCollection(dataStoreNode(), + collectionName); }); } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp index 39097cbeb39..a123cf33617 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp @@ -144,7 +144,7 @@ void CollectionWidget::reloadQmlSource() QSize CollectionWidget::minimumSizeHint() const { - return {300, 400}; + return {300, 300}; } bool CollectionWidget::loadJsonFile(const QUrl &url, const QString &collectionName) diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index 44015d59fce..17ba5aa9707 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -251,7 +251,7 @@ const char add3DAssetsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResourc const char addQt3DSPresentationsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Qt 3D Studio Presentations"); const char addCustomEffectDialogDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", - "Effect Maker Files"); + "Effect Composer Files"); } //ComponentCoreConstants diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 24fff841b6d..a9bbd2ecdb8 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1623,22 +1623,22 @@ void updateImported3DAsset(const SelectionContext &selectionContext) } } -bool isNewEffectMakerActivated() +bool isEffectComposerActivated() { const QVector specs = ExtensionSystem::PluginManager::plugins(); return std::find_if(specs.begin(), specs.end(), [](ExtensionSystem::PluginSpec *spec) { - return spec->name() == "EffectMakerNew" && spec->isEffectivelyEnabled(); + return spec->name() == "EffectComposer" && spec->isEffectivelyEnabled(); }) != specs.end(); } -void openEffectMaker(const QString &filePath) +void openEffectComposer(const QString &filePath) { - if (ModelNodeOperations::isNewEffectMakerActivated()) { + if (ModelNodeOperations::isEffectComposerActivated()) { QmlDesignerPlugin::instance()->viewManager() - .emitCustomNotification("open_effectmaker_composition", {}, {filePath}); - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Effect Maker", true); + .emitCustomNotification("open_effectcomposer_composition", {}, {filePath}); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Effect Composer", true); } else { ModelNodeOperations::openOldEffectMaker(filePath); } @@ -1742,13 +1742,13 @@ bool validateEffect(const QString &effectPath) if (!qmlPath.exists()) { QMessageBox msgBox; msgBox.setText(QObject::tr("Effect %1 is not complete.").arg(effectName)); - msgBox.setInformativeText(QObject::tr("Ensure that you have saved it in Qt Quick Effect Maker." + msgBox.setInformativeText(QObject::tr("Ensure that you have saved it in the Effect Composer." "\nDo you want to edit this effect?")); msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); msgBox.setDefaultButton(QMessageBox::Yes); msgBox.setIcon(QMessageBox::Question); if (msgBox.exec() == QMessageBox::Yes) - ModelNodeOperations::openEffectMaker(effectPath); + ModelNodeOperations::openEffectComposer(effectPath); return false; } return true; diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index dec37f0f9ef..196dd4922c8 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -126,12 +126,12 @@ void updateImported3DAsset(const SelectionContext &selectionContext); QMLDESIGNERCOMPONENTS_EXPORT Utils::FilePath getEffectsImportDirectory(); QMLDESIGNERCOMPONENTS_EXPORT QString getEffectsDefaultDirectory(const QString &defaultDir = {}); -void openEffectMaker(const QString &filePath); +void openEffectComposer(const QString &filePath); void openOldEffectMaker(const QString &filePath); QString getEffectIcon(const QString &effectPath); bool useLayerEffect(); bool validateEffect(const QString &effectPath); -bool isNewEffectMakerActivated(); +bool isEffectComposerActivated(); Utils::FilePath getImagesDefaultDirectory(); diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp index c8f16cb3506..57ca619a70a 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp @@ -75,7 +75,7 @@ NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *mode return model->metaInfo("QML.string"); else if (typeName == "url") return model->metaInfo("QML.url"); - else if (typeName == "variant") + else if (typeName == "var" || typeName == "variant") return model->metaInfo("QML.variant"); else qWarning() << __FUNCTION__ << " type " << typeName << "not found"; @@ -212,7 +212,7 @@ bool isDynamicVariantPropertyType(const TypeName &type) { // "variant" is considered value type as it is initialized as one. // This may need to change if we provide any kind of proper editor for it. - static const QSet valueTypes{"int", "real", "color", "string", "bool", "url", "variant"}; + static const QSet valueTypes{"int", "real", "color", "string", "bool", "url", "var", "variant"}; return valueTypes.contains(type); } @@ -231,7 +231,7 @@ QVariant defaultValueForType(const TypeName &type) value = false; else if (type == "url") value = ""; - else if (type == "variant") + else if (type == "var" || type == "variant") value = ""; return value; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index 496f0e4b2c7..12da85e2c4e 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -74,11 +74,7 @@ FormEditorScene *FormEditorItem::scene() const { FormEditorItem::FormEditorItem(const QmlItemNode &qmlItemNode, FormEditorScene* scene) : QGraphicsItem(scene->formLayerItem()), m_snappingLineCreator(this), - m_qmlItemNode(qmlItemNode), - m_borderWidth(1.0), - m_highlightBoundingRect(false), - m_blurContent(false), - m_isContentVisible(true) + m_qmlItemNode(qmlItemNode) { setCacheMode(QGraphicsItem::NoCache); setup(); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h index b035699772e..3629d500e29 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h @@ -129,11 +129,11 @@ private: // variables QPointer m_attentionTimeLine; QTransform m_inverseAttentionTransform; - double m_borderWidth; - bool m_highlightBoundingRect; - bool m_blurContent; - bool m_isContentVisible; - bool m_hasEffect; + double m_borderWidth = 1.0; + bool m_highlightBoundingRect = false; + bool m_blurContent = false; + bool m_isContentVisible = true; + bool m_hasEffect = false; }; class FormEditorFlowItem : public FormEditorItem diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index fcc04ed0262..5836d25ad95 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -1013,7 +1013,8 @@ void FormEditorView::updateHasEffects() item->setHasEffect(false); if (qmlNode.isEffectItem()) { FormEditorItem *parentItem = m_scene->itemForQmlItemNode(qmlNode.modelParentItem()); - parentItem->setHasEffect(true); + if (parentItem) + parentItem->setHasEffect(true); } } } diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 9eca5f84b8e..7b7f4a51ef0 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -427,6 +427,12 @@ bool DesignDocument::hasProject() const return !DocumentManager::currentProjectDirPath().isEmpty(); } +void DesignDocument::setModified() +{ + if (!m_documentTextModifier.isNull()) + m_documentTextModifier->textDocument()->setModified(true); +} + void DesignDocument::changeToInFileComponentModel(ComponentTextModifier *textModifer) { m_inFileComponentTextModifier.reset(textModifer); @@ -514,6 +520,13 @@ bool DesignDocument::isRedoAvailable() const return false; } +void DesignDocument::clearUndoRedoStacks() const +{ + const QPlainTextEdit *edit = plainTextEdit(); + if (edit) + edit->document()->clearUndoRedoStacks(); +} + void DesignDocument::close() { m_documentLoaded = false; diff --git a/src/plugins/qmldesigner/components/integration/designdocument.h b/src/plugins/qmldesigner/components/integration/designdocument.h index c5c1bab27f9..0d75141205e 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.h +++ b/src/plugins/qmldesigner/components/integration/designdocument.h @@ -57,6 +57,7 @@ public: #endif bool isUndoAvailable() const; bool isRedoAvailable() const; + void clearUndoRedoStacks() const; Model *currentModel() const; Model *documentModel() const; @@ -88,6 +89,8 @@ public: Utils::FilePath projectFolder() const; bool hasProject() const; + void setModified(); + signals: void displayNameChanged(const QString &newFileName); void dirtyStateChanged(bool newState); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index c9aafc48fb7..eaf6f89b14a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -312,17 +312,13 @@ void ItemLibraryModel::update([[maybe_unused]] ItemLibraryInfo *itemLibraryInfo, beginResetModel(); clearSections(); - DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); - Utils::FilePath qmlFileName = document->fileName(); - ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::projectForFile(qmlFileName); - QString projectName = project ? project->displayName() : ""; - QStringList excludedImports { QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1) + ".MaterialBundle", QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1) + ".EffectBundle" }; // create import sections + const QString projectName = DocumentManager::currentProjectName(); const Imports usedImports = model->usedImports(); QHash importHash; for (const Import &import : model->imports()) { @@ -364,6 +360,7 @@ void ItemLibraryModel::update([[maybe_unused]] ItemLibraryInfo *itemLibraryInfo, itemLibImport->setImportExpanded(loadExpandedState(itemLibImport->importUrl())); } + DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); const bool blockNewImports = document->inFileComponentModelActive(); const QList itemLibEntries = model->itemLibraryEntries(); for (const ItemLibraryEntry &entry : itemLibEntries) { diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index ed54fc4c52a..3bfe26c74da 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -147,9 +147,6 @@ static bool isInLayoutable(NodeAbstractProperty &parentProperty) static void reparentModelNodeToNodeProperty(NodeAbstractProperty &parentProperty, const ModelNode &modelNode) { try { - if (parentProperty.parentModelNode().type().startsWith("Effects.")) - return; - if (!modelNode.hasParentProperty() || parentProperty != modelNode.parentProperty()) { if (isInLayoutable(parentProperty)) { removePosition(modelNode); @@ -160,12 +157,12 @@ static void reparentModelNodeToNodeProperty(NodeAbstractProperty &parentProperty parentProperty = parentProperty.parentModelNode().nodeAbstractProperty("layer.effect"); QmlItemNode::placeEffectNode(parentProperty, modelNode, true); } else { - QPointF scenePosition = QmlItemNode(modelNode).instanceScenePosition(); + QmlItemNode qmlNode(modelNode); + QPointF scenePosition = qmlNode.instanceScenePosition(); parentProperty.reparentHere(modelNode); - if (!scenePosition.isNull()) + if (!scenePosition.isNull() && !qmlNode.isEffectItem()) setScenePosition(modelNode, scenePosition); } - } else { parentProperty.reparentHere(modelNode); } @@ -550,28 +547,29 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, if (widget) widget->setDragType(""); + ModelNode targetNode = modelNodeForIndex(dropModelIndex); + if (!targetNode.isValid() || QmlItemNode(targetNode).isEffectItem()) + return true; + if (dropModelIndex.model() == this) { if (mimeData->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) { handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex); } else if (mimeData->hasFormat(Constants::MIME_TYPE_TEXTURE)) { const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0); - ModelNode targetNode = modelNodeForIndex(rowModelIndex); + targetNode = modelNodeForIndex(rowModelIndex); ModelNodeOperations::handleTextureDrop(mimeData, targetNode); } else if (mimeData->hasFormat(Constants::MIME_TYPE_MATERIAL)) { const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0); - ModelNode targetNode = modelNodeForIndex(rowModelIndex); + targetNode = modelNodeForIndex(rowModelIndex); ModelNodeOperations::handleMaterialDrop(mimeData, targetNode); } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { QByteArray filePath = mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE); - ModelNode targetNode(modelNodeForIndex(dropModelIndex)); if (targetNode.metaInfo().isQtQuick3DModel()) m_view->emitCustomNotification("apply_asset_to_model3D", {targetNode}, {filePath}); // To MaterialBrowserView } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) { - ModelNode targetNode(modelNodeForIndex(dropModelIndex)); if (targetNode.isValid()) m_view->emitCustomNotification("drop_bundle_material", {targetNode}); // To ContentLibraryView } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_EFFECT)) { - ModelNode targetNode(modelNodeForIndex(dropModelIndex)); if (targetNode.isValid()) m_view->emitCustomNotification("drop_bundle_effect", {targetNode}); // To ContentLibraryView } else if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) { @@ -888,6 +886,20 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper // is the default property of the parent and is of Component type. // In that case an implicit component will be created. + // We can only have single effect item child + if (QmlItemNode(modelNode).isEffectItem()) { + const QList childNodes = parentProperty.parentModelNode().directSubModelNodes(); + bool skip = false; + for (const ModelNode &node : childNodes) { + if (QmlItemNode(node).isEffectItem()) { + skip = true; + break; + } + } + if (skip) + continue; + } + bool nodeCanBeMovedToParentProperty = removeModelNodeFromNodeProperty(parentProperty, modelNode); if (nodeCanBeMovedToParentProperty) { reparentModelNodeToNodeProperty(parentProperty, modelNode); diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index a0c5ebacd26..5cea0aab4ea 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -297,7 +297,7 @@ void NavigatorView::dragStarted(QMimeData *mimeData) auto assetTypeAndData = AssetsLibraryWidget::getAssetTypeAndData(assetsPaths[0]); QString assetType = assetTypeAndData.first; if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) { - // We use arbitrary type name because at this time we don't have effect maker + // We use arbitrary type name because at this time we don't have effect composer // specific type m_widget->update(); } else if (assetType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp index cdf09c14933..d400251648e 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp @@ -299,6 +299,7 @@ void TextEditorView::jumpToModelNode(const ModelNode &modelNode) m_widget->window()->windowHandle()->requestActivate(); m_widget->textEditor()->widget()->setFocus(); + m_widget->textEditor()->editorWidget()->updateFoldingHighlight(QTextCursor()); } void TextEditorView::instancePropertyChanged(const QList > &/*propertyList*/) diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index cd56af86643..f16acf380f8 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -625,7 +625,7 @@ void NodeInstanceView::nodeOrderChanged(const NodeListProperty &listProperty) void NodeInstanceView::importsChanged(const Imports &/*addedImports*/, const Imports &/*removedImports*/) { - restartProcess(); + delayedRestartProcess(); } void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node, diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 3fb5de210cc..c695f488b1f 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -3108,7 +3108,12 @@ bool NodeMetaInfo::isVariant() const using namespace Storage::Info; return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId()); } else { - return isValid() && simplifiedTypeName() == "QVariant"; + if (!isValid()) + return false; + + const auto type = simplifiedTypeName(); + + return type == "QVariant" || type == "var" || type == "variant"; } } diff --git a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp index 7c57e8ac355..141548047e5 100644 --- a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp @@ -311,7 +311,7 @@ QVariant BindingProperty::convertToLiteral(const TypeName &typeName, const QStri qreal realValue = testExpression.toDouble(&ok); if (ok) return realValue; - } else if ("QVariant" == typeName || "variant" == typeName) { + } else if ("QVariant" == typeName || "variant" == typeName || "var" == typeName) { bool ok; qreal realValue = testExpression.toDouble(&ok); if (ok) { diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index e01bdaaec35..e524e91c70f 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -182,11 +182,8 @@ QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view, const QString effectName = QFileInfo(effectPath).baseName(); Import import = Import::createLibraryImport("Effects." + effectName, "1.0"); try { - if (!view->model()->hasImport(import, true, true)) { + if (!view->model()->hasImport(import, true, true)) view->model()->changeImports({import}, {}); - // Trigger async reset puppet to ensure full transaction is done before reset - view->resetPuppet(); - } } catch (const Exception &) { QTC_ASSERT(false, return); } @@ -209,6 +206,17 @@ void QmlItemNode::placeEffectNode(NodeAbstractProperty &parentProperty, const Qm QmlObjectNode(oldEffect).destroy(); } + if (!isLayerEffect) { + // Delete previous effect child if one already exists + ModelNode parentNode = parentProperty.parentModelNode(); + QList children = parentNode.directSubModelNodes(); + for (ModelNode &child : children) { + QmlItemNode qmlChild(child); + if (qmlChild.isEffectItem()) + qmlChild.destroy(); + } + } + parentProperty.reparentHere(effectNode); if (isLayerEffect) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 037259e87e4..9ab009bd830 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -652,60 +652,6 @@ public: return value; } - QVariant convertToVariant(const QString &astValue, const QString &propertyPrefix, AST::UiQualifiedId *propertyId) - { - const bool hasQuotes = astValue.trimmed().left(1) == u"\"" - && astValue.trimmed().right(1) == u"\""; - const QString cleanedValue = fixEscapedUnicodeChar(deEscape(stripQuotes(astValue.trimmed()))); - const Value *property = nullptr; - const ObjectValue *containingObject = nullptr; - QString name; - if (!lookupProperty(propertyPrefix, propertyId, &property, &containingObject, &name)) { - qCInfo(texttomodelMergerDebug) << Q_FUNC_INFO << "Unknown property" - << propertyPrefix + QLatin1Char('.') + toString(propertyId) - << "on line" << propertyId->identifierToken.startLine - << "column" << propertyId->identifierToken.startColumn; - return hasQuotes ? QVariant(cleanedValue) : cleverConvert(cleanedValue); - } - - if (containingObject) - containingObject->lookupMember(name, m_context, &containingObject); - - if (const CppComponentValue * qmlObject = value_cast(containingObject)) { - const QString typeName = qmlObject->propertyType(name); - if (qmlObject->getEnum(typeName).isValid()) { - return QVariant(cleanedValue); - } else { - int type = QMetaType::type(typeName.toUtf8().constData()); - QVariant result; - if (type) - result = PropertyParser::read(type, cleanedValue); - if (result.isValid()) - return result; - } - } - - if (property->asColorValue()) - return PropertyParser::read(QVariant::Color, cleanedValue); - else if (property->asUrlValue()) - return PropertyParser::read(QVariant::Url, cleanedValue); - - QVariant value(cleanedValue); - if (property->asBooleanValue()) { - value.convert(QVariant::Bool); - return value; - } else if (property->asNumberValue()) { - value.convert(QVariant::Double); - return value; - } else if (property->asStringValue()) { - // nothing to do - } else { //property alias et al - if (!hasQuotes) - return cleverConvert(cleanedValue); - } - return value; - } - QVariant convertToEnum(AST::Statement *rhs, const NodeMetaInfo &metaInfo, const QString &propertyPrefix, diff --git a/src/plugins/qmldesigner/designermcumanager.h b/src/plugins/qmldesigner/designermcumanager.h index 56f5a493aca..59ea892d468 100644 --- a/src/plugins/qmldesigner/designermcumanager.h +++ b/src/plugins/qmldesigner/designermcumanager.h @@ -5,6 +5,8 @@ #include +#include "qmldesignercomponents_global.h" + #include #include #include @@ -12,7 +14,7 @@ namespace QmlDesigner { -class DesignerMcuManager +class QMLDESIGNERCOMPONENTS_EXPORT DesignerMcuManager { public: struct Version { diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index a26eada9118..a1f75b6205f 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -493,7 +493,8 @@ void DesignModeWidget::setup() static bool isMcuDisabledView(const QString viewId) { - static const QStringList mcuDisabledViews = {"Editor3D", "MaterialEditor", "MaterialBrowser", "TextureEditor"}; + static const QStringList mcuDisabledViews = {"Editor3D", "MaterialEditor", "MaterialBrowser", + "TextureEditor", "EffectComposer"}; return mcuDisabledViews.contains(viewId); } diff --git a/src/plugins/qmldesigner/documentmanager.cpp b/src/plugins/qmldesigner/documentmanager.cpp index 3d173842b45..fcaac762baf 100644 --- a/src/plugins/qmldesigner/documentmanager.cpp +++ b/src/plugins/qmldesigner/documentmanager.cpp @@ -358,6 +358,19 @@ Utils::FilePath DocumentManager::currentProjectDirPath() return {}; } +QString DocumentManager::currentProjectName() +{ + QTC_ASSERT(QmlDesignerPlugin::instance(), return {}); + + if (!QmlDesignerPlugin::instance()->currentDesignDocument()) + return {}; + + Utils::FilePath qmlFileName = QmlDesignerPlugin::instance()->currentDesignDocument()->fileName(); + ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::projectForFile(qmlFileName); + + return project ? project->displayName() : ""; +} + QStringList DocumentManager::isoIconsQmakeVariableValue(const QString &proPath) { ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(Utils::FilePath::fromString(proPath)); diff --git a/src/plugins/qmldesigner/documentmanager.h b/src/plugins/qmldesigner/documentmanager.h index fc020a2e393..090630e5fe4 100644 --- a/src/plugins/qmldesigner/documentmanager.h +++ b/src/plugins/qmldesigner/documentmanager.h @@ -48,6 +48,7 @@ public: static void addFileToVersionControl(const QString &directoryPath, const QString &newFilePath); static Utils::FilePath currentFilePath(); static Utils::FilePath currentProjectDirPath(); + static QString currentProjectName(); static QStringList isoIconsQmakeVariableValue(const QString &proPath); static bool setIsoIconsQmakeVariableValue(const QString &proPath, const QStringList &value); diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index dc545e06a8c..81108dee410 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -14,7 +14,7 @@ const char C_DUPLICATE[] = "QmlDesigner.Duplicate"; const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain"; const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor"; const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D"; -const char C_QMLEFFECTMAKER[] = "QmlDesigner::EffectMaker"; +const char C_QMLEFFECTCOMPOSER[] = "QmlDesigner::EffectComposer"; const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator"; const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor"; const char C_QMLMATERIALBROWSER[] = "QmlDesigner::MaterialBrowser"; @@ -126,7 +126,8 @@ const char EVENT_TEXTEDITOR_TIME[] = "textEditor"; const char EVENT_TEXTUREEDITOR_TIME[] = "textureEditor"; const char EVENT_PROPERTYEDITOR_TIME[] = "propertyEditor"; const char EVENT_ASSETSLIBRARY_TIME[] = "assetsLibrary"; -const char EVENT_EFFECTMAKER_TIME[] = "effectMaker"; +const char EVENT_EFFECTCOMPOSER_NODE[] = "effectComposerNode"; +const char EVENT_EFFECTCOMPOSER_TIME[] = "effectComposerTime"; const char EVENT_ITEMLIBRARY_TIME[] = "itemLibrary"; const char EVENT_TRANSLATIONVIEW_TIME[] = "translationView"; const char EVENT_NAVIGATORVIEW_TIME[] = "navigatorView"; @@ -136,7 +137,6 @@ const char EVENT_MATERIALBROWSER_TIME[] = "materialBrowser"; const char EVENT_CONTENTLIBRARY_TIME[] = "contentLibrary"; const char EVENT_INSIGHT_TIME[] = "insight"; const char EVENT_MODELEDITOR_TIME[] = "modelEditor"; -const char EVENT_NEWEFFECTMAKER_TIME[] = "newEffectMaker"; const char EVENT_TOOLBAR_MODE_CHANGE[] = "ToolBarTriggerModeChange"; const char EVENT_TOOLBAR_PROJECT_SETTINGS[] = "ToolBarTriggerProjectSettings"; const char EVENT_TOOLBAR_RUN_PROJECT[] = "ToolBarRunProject"; @@ -159,7 +159,7 @@ const char OBJECT_NAME_ASSET_LIBRARY[] = "QQuickWidgetAssetLibrary"; const char OBJECT_NAME_CONTENT_LIBRARY[] = "QQuickWidgetContentLibrary"; const char OBJECT_NAME_BUSY_INDICATOR[] = "QQuickWidgetBusyIndicator"; const char OBJECT_NAME_COMPONENT_LIBRARY[] = "QQuickWidgetComponentLibrary"; -const char OBJECT_NAME_EFFECT_MAKER[] = "QQuickWidgetEffectMaker"; +const char OBJECT_NAME_EFFECT_COMPOSER[] = "QQuickWidgetEffectComposer"; const char OBJECT_NAME_MATERIAL_BROWSER[] = "QQuickWidgetMaterialBrowser"; const char OBJECT_NAME_MATERIAL_EDITOR[] = "QQuickWidgetMaterialEditor"; const char OBJECT_NAME_PROPERTY_EDITOR[] = "QQuickWidgetPropertyEditor"; diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc index cb5346c0795..e71d6875554 100644 --- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc +++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc @@ -45,6 +45,7 @@ source/textinputv2.qml source/component.qml source/component3d.qml + source/extendedview3D_template.qml images/column-positioner-icon.png images/column-positioner-icon-16px.png images/default-icon.png diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index d3fdd6f55f0..e0ea712ebdc 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -850,4 +850,19 @@ MetaInfo { Property { name: "loadPrefix"; type: "string"; value: "lightmaps"; } } } + + Type { + name: "QtQuick3D.View3D" + icon: ":/qtquickplugin/images/default3d16.png" + + ItemLibraryEntry { + name: "Extended View3D" + category: "Items" + libraryIcon: ":/qtquickplugin/images/default3d.png" + version: "6.5" + requiredImport: "QtQuick3D" + QmlSource { source: ":/qtquickplugin/source/extendedview3D_template.qml" } + toolTip: qsTr("A 2D surface where a 3D scene can be rendered. Includes ExtendedSceneEnvironment.") + } + } } diff --git a/src/plugins/qmldesigner/qtquickplugin/source/extendedview3D_template.qml b/src/plugins/qmldesigner/qtquickplugin/source/extendedview3D_template.qml new file mode 100644 index 00000000000..b0b72c8d55d --- /dev/null +++ b/src/plugins/qmldesigner/qtquickplugin/source/extendedview3D_template.qml @@ -0,0 +1,39 @@ +// 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 QtQuick3D +import QtQuick3D.Helpers + +View3D { + width: 400 + height: 400 + environment: sceneEnvironment + + ExtendedSceneEnvironment { + id: sceneEnvironment + antialiasingMode: SceneEnvironment.MSAA + antialiasingQuality: SceneEnvironment.High + } + + Node { + id: scene + + DirectionalLight { + id: directionalLight + } + + PerspectiveCamera { + id: sceneCamera + z: 350 + } + + Model { + id: cubeModel + eulerRotation.x: 30 + eulerRotation.y: 45 + + source: "#Cube" + } + } +} diff --git a/src/plugins/qmldesigner/utils/asset.cpp b/src/plugins/qmldesigner/utils/asset.cpp index 5d6f42336c1..2984a4d8902 100644 --- a/src/plugins/qmldesigner/utils/asset.cpp +++ b/src/plugins/qmldesigner/utils/asset.cpp @@ -74,9 +74,9 @@ const QStringList &Asset::supportedTexture3DSuffixes() return retList; } -const QStringList &Asset::supportedEffectMakerSuffixes() +const QStringList &Asset::supportedEffectComposerSuffixes() { - // These are file types only supported by Effect Maker + // These are file types only supported by Effect Composer static QStringList retList {"*.qep"}; return retList; } @@ -95,7 +95,7 @@ const QSet &Asset::supportedSuffixes() insertSuffixes(supportedAudioSuffixes()); insertSuffixes(supportedVideoSuffixes()); insertSuffixes(supportedTexture3DSuffixes()); - insertSuffixes(supportedEffectMakerSuffixes()); + insertSuffixes(supportedEffectComposerSuffixes()); } return allSuffixes; } @@ -204,7 +204,7 @@ void Asset::resolveType() m_type = Asset::Type::Video; else if (supportedTexture3DSuffixes().contains(m_suffix)) m_type = Asset::Type::Texture3D; - else if (supportedEffectMakerSuffixes().contains(m_suffix)) + else if (supportedEffectComposerSuffixes().contains(m_suffix)) m_type = Asset::Type::Effect; } diff --git a/src/plugins/qmldesigner/utils/asset.h b/src/plugins/qmldesigner/utils/asset.h index e779d4a7343..cb09f3a5ee6 100644 --- a/src/plugins/qmldesigner/utils/asset.h +++ b/src/plugins/qmldesigner/utils/asset.h @@ -31,7 +31,7 @@ public: static const QStringList &supportedAudioSuffixes(); static const QStringList &supportedVideoSuffixes(); static const QStringList &supportedTexture3DSuffixes(); - static const QStringList &supportedEffectMakerSuffixes(); + static const QStringList &supportedEffectComposerSuffixes(); static const QSet &supportedSuffixes(); static bool isSupported(const QString &path); diff --git a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp index 703c1cf7605..11a180578f4 100644 --- a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp +++ b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp @@ -9,13 +9,13 @@ #include "utils/designersettings.h" #include +#include #include #include namespace QmlDesigner { - class QmlDesignerBasePlugin::Data { public: @@ -29,6 +29,9 @@ public: }; namespace { + +const char experimentalFeatures[] = "QML/Designer/UseExperimentalFeatures"; + QmlDesignerBasePlugin *global; } @@ -57,6 +60,19 @@ StudioConfigSettingsPage *QmlDesignerBasePlugin::studioConfigSettingsPage() return global->d->studioConfigSettingsPage.get(); } +bool QmlDesignerBasePlugin::experimentalFeaturesEnabled() +{ + return Core::ICore::settings()->value(experimentalFeaturesSettingsKey(), false).toBool(); +} + +QByteArray QmlDesignerBasePlugin::experimentalFeaturesSettingsKey() +{ + QString version = Utils::appInfo().displayVersion; + version.remove('.'); + + return QByteArray(experimentalFeatures) + version.toLatin1(); +} + bool QmlDesignerBasePlugin::initialize(const QStringList &, QString *) { d = std::make_unique(); diff --git a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.h b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.h index 997189dacf6..0820c1ef245 100644 --- a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.h +++ b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.h @@ -28,6 +28,9 @@ public: static QStyle *style(); static class StudioConfigSettingsPage *studioConfigSettingsPage(); + static bool experimentalFeaturesEnabled(); + static QByteArray experimentalFeaturesSettingsKey(); + private: bool initialize(const QStringList &arguments, QString *errorMessage) override; diff --git a/src/plugins/qmldesignerbase/studio/studiosettingspage.cpp b/src/plugins/qmldesignerbase/studio/studiosettingspage.cpp index 2f41a1a5eb0..d2dd472f1ba 100644 --- a/src/plugins/qmldesignerbase/studio/studiosettingspage.cpp +++ b/src/plugins/qmldesignerbase/studio/studiosettingspage.cpp @@ -31,6 +31,8 @@ namespace QmlDesigner { namespace { +const char experimentalFeatures[] = "QML/Designer/UseExperimentalFeatures44"; + bool hideBuildMenuSetting() { return Core::ICore::settings() @@ -57,6 +59,11 @@ bool hideToolsMenuSetting() return Core::ICore::settings()->value(Core::Constants::SETTINGS_MENU_HIDE_TOOLS, false).toBool(); } +bool showExperimentalFeatures() +{ + return Core::ICore::settings()->value(experimentalFeatures, false).toBool(); +} + void setSettingIfDifferent(const Key &key, bool value, bool &dirty) { QtcSettings *s = Core::ICore::settings(); @@ -69,12 +76,11 @@ void setSettingIfDifferent(const Key &key, bool value, bool &dirty) } // namespace StudioSettingsPage::StudioSettingsPage() - : m_buildCheckBox(new QCheckBox(tr("Build"))) - , m_debugCheckBox(new QCheckBox(tr("Debug"))) - , m_analyzeCheckBox(new QCheckBox(tr("Analyze"))) - , m_toolsCheckBox(new QCheckBox(tr("Tools"))) - , m_pathChooserExamples(new Utils::PathChooser()) - , m_pathChooserBundles(new Utils::PathChooser()) + : m_buildCheckBox(new QCheckBox(tr("Build"))), m_debugCheckBox(new QCheckBox(tr("Debug"))), + m_analyzeCheckBox(new QCheckBox(tr("Analyze"))), m_toolsCheckBox(new QCheckBox(tr("Tools"))), + m_pathChooserExamples(new Utils::PathChooser()), + m_pathChooserBundles(new Utils::PathChooser()), + m_experimentalCheckBox(new QCheckBox(tr("Enable Experimental Features"))) { const QString toolTip = tr( "Hide top-level menus with advanced functionality to simplify the UI. Build is " @@ -109,6 +115,7 @@ StudioSettingsPage::StudioSettingsPage() m_debugCheckBox->setChecked(hideDebugMenuSetting()); m_analyzeCheckBox->setChecked(hideAnalyzeMenuSetting()); m_toolsCheckBox->setChecked(hideToolsMenuSetting()); + m_experimentalCheckBox->setChecked(showExperimentalFeatures()); // Examples path setting auto examplesGroupBox = new QGroupBox(tr("Examples")); @@ -148,6 +155,18 @@ StudioSettingsPage::StudioSettingsPage() bundlesLayout->addWidget(m_pathChooserBundles); bundlesLayout->addWidget(bundlesResetButton); + auto experimentalGroupBox = new QGroupBox(tr("Experimental Features")); + boxLayout->addWidget(experimentalGroupBox); + + auto experimentalLayout = new QHBoxLayout(this); + experimentalGroupBox->setLayout(experimentalLayout); + + experimentalLayout->addWidget(m_experimentalCheckBox); + m_experimentalCheckBox->setToolTip( + tr("This option enables experimental features in Qt Design Studio. " + "Please provide feedback and bug reports at: %1") + .arg("https://bugreports.qt.io/projects/QDS")); + boxLayout->addSpacerItem( new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding)); } @@ -172,6 +191,8 @@ void StudioSettingsPage::apply() m_toolsCheckBox->isChecked(), dirty); + setSettingIfDifferent(experimentalFeatures, m_experimentalCheckBox->isChecked(), dirty); + if (dirty) { Core::ICore::askForRestart( tr("The menu visibility change will take effect after restart.")); diff --git a/src/plugins/qmldesignerbase/studio/studiosettingspage.h b/src/plugins/qmldesignerbase/studio/studiosettingspage.h index 075367e4bb1..bc2c038ebc6 100644 --- a/src/plugins/qmldesignerbase/studio/studiosettingspage.h +++ b/src/plugins/qmldesignerbase/studio/studiosettingspage.h @@ -32,6 +32,7 @@ private: QCheckBox *m_toolsCheckBox; Utils::PathChooser *m_pathChooserExamples; Utils::PathChooser *m_pathChooserBundles; + QCheckBox *m_experimentalCheckBox; }; class QMLDESIGNERBASE_EXPORT StudioConfigSettingsPage : public QObject, Core::IOptionsPage diff --git a/src/plugins/studiowelcome/qml/welcomepage/AccountImage.qml b/src/plugins/studiowelcome/qml/welcomepage/AccountImage.qml deleted file mode 100644 index b5d5b480937..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/AccountImage.qml +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.9 -import welcome 1.0 -import StudioFonts 1.0 - -Image { - id: account_icon - - source: "images/" + (mouseArea.containsMouse ? "icon_hover.png" : "icon_default.png") - - Text { - id: account - color: mouseArea.containsMouse ? Constants.textHoverColor - : Constants.textDefaultColor - text: qsTr("Account") - anchors.top: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - font.family: StudioFonts.titilliumWeb_regular - font.pixelSize: 16 - renderType: Text.NativeRendering - } - - MouseArea { - id: mouseArea - anchors.fill: parent - anchors.margins: -25 - hoverEnabled: true - - onClicked: Qt.openUrlExternally("https://login.qt.io/login/") - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml b/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml deleted file mode 100644 index 2c0852dcb28..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollBar.qml +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.15 -import QtQuick.Templates 2.15 as Controls -import welcome 1.0 - -Controls.ScrollBar { - id: scrollBar - - implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, - implicitContentWidth + leftPadding + rightPadding) - implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, - implicitContentHeight + topPadding + bottomPadding) - - padding: active ? 1 : 2 - visible: orientation === Qt.Horizontal ? contentWidth > width : contentHeight > height - minimumSize: orientation === Qt.Horizontal ? height / width : width / height - - contentItem: Rectangle { - implicitWidth: 13 - implicitHeight: 13 - color: active ? Constants.textHoverColor : Constants.textDefaultColor - } - - background: Rectangle { - implicitWidth: 16 - implicitHeight: 16 - color: "#3b3c3d" - visible: active - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml b/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml deleted file mode 100644 index 5c4665554c7..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/CustomScrollView.qml +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick.Templates 2.15 as Controls - -Controls.ScrollView { - id: control - - Controls.ScrollBar.vertical: CustomScrollBar { - parent: control - x: control.mirrored ? 0 : control.width - width - y: control.topPadding - height: control.availableHeight - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/ExamplesModel.qml b/src/plugins/studiowelcome/qml/welcomepage/ExamplesModel.qml deleted file mode 100644 index 0258ae2bab5..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/ExamplesModel.qml +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.0 - -ListModel { - ListElement { - projectName: "ClusterTutorial" - qmlFileName: "ClusterTutorial.qml" - thumbnail: "images/tutorialclusterdemo_thumbnail.png" - displayName: "Cluster Tutorial" - } - - ListElement { - projectName: "CoffeeMachine" - qmlFileName: "CoffeeMachine.qml" - thumbnail: "images/coffeemachinedemo_thumbnail.png" - displayName: "Coffee Machine" - } - - ListElement { - projectName: "SideMenu" - qmlFileName: "SideMenu.qml" - thumbnail: "images/sidemenu_demo.png" - displayName: "Side Menu" - } - - ListElement { - projectName: "WebinarDemo" - qmlFileName: "DesignStudioWebinar.qml" - thumbnail: "images/webinardemo_thumbnail.png" - displayName: "Webinar Demo" - } - - ListElement { - projectName: "EBikeDesign" - qmlFileName: "EBikeDesign.qml" - thumbnail: "images/ebike_demo_thumbnail.png" - displayName: "E-Bike Design" - } - - ListElement { - projectName: "ProgressBar" - qmlFileName: "ProgressBar.ui.qml" - thumbnail: "images/progressbar_demo.png" - displayName: "Progress Bar" - } - - ListElement { - projectName: "washingMachineUI" - qmlFileName: "washingMachineUI.qml" - thumbnail: "images/washingmachinedemo_thumbnail.png" - displayName: "Washing Machine" - } - - ListElement { - projectName: "SimpleKeyboard" - qmlFileName: "SimpleKeyboard.qml" - thumbnail: "images/virtualkeyboard_thumbnail.png" - displayName: "Virtual Keyboard" - } - - ListElement { - projectName: "highendivisystem" - qmlFileName: "Screen01.ui.qml" - thumbnail: "images/highendivi_thumbnail.png" - displayName: "Highend IVI System" - url: "https://download.qt.io/learning/examples/qtdesignstudio/highendivisystem.zip" - showDownload: true - } - - ListElement { - projectName: "digitalcluster" - qmlFileName: "Screen01.ui.qml" - thumbnail: "images/digital_cluster_thumbnail.png" - displayName: "Digital Cluster" - url: "https://download.qt.io/learning/examples/qtdesignstudio/digitalcluster.zip" - showDownload: true - } - - ListElement { - projectName: "effectdemo" - qmlFileName: "Screen01.ui.qml" - thumbnail: "images/effectdemo_thumbnail.png" - displayName: "Effect Demo" - url: "https://download.qt.io/learning/examples/qtdesignstudio/effectdemo.zip" - showDownload: true - } - - - ListElement { - projectName: "cppdemoproject" - explicitQmlproject: "qml/qdsproject.qmlproject" - qmlFileName: "Screen01.ui.qml" - thumbnail: "images/cppdemo_thumbnail.png" - displayName: "C++ Demo Project" - url: "https://download.qt.io/learning/examples/qtdesignstudio/cppdemoproject.zip" - showDownload: true - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/HoverOverDesaturate.qml b/src/plugins/studiowelcome/qml/welcomepage/HoverOverDesaturate.qml deleted file mode 100644 index 2973b4caf11..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/HoverOverDesaturate.qml +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.9 -import QtQuick.Timeline 1.0 -import welcome 1.0 -import StudioFonts 1.0 - -Item { - id: root - visible: true - width: 270 - height: 175 - property alias imageSource: image.source - property alias labelText: label.text - - property alias downloadIcon: downloadCloud.visible - - signal clicked() - - onVisibleChanged: { - animateOpacity.start() - animateScale.start() - } - - NumberAnimation { - id: animateOpacity - property: "opacity" - from: 0 - to: 1.0 - duration: 400 - } - NumberAnimation { - id: animateScale - property: "scale" - from: 0 - to: 1.0 - duration: 400 - } - - Rectangle { - id: rectangle - x: 0 - y: 0 - width: 270 - height: 146 - - MouseArea { - x: 17 - y: 12 - height: 125 - anchors.bottomMargin: -label.height - anchors.fill: parent - hoverEnabled: true - onHoveredChanged: { - if (saturationEffect.desaturation === 1) - saturationEffect.desaturation = 0 - if (saturationEffect.desaturation === 0) - saturationEffect.desaturation = 1 - if (saturationEffect.desaturation === 0) - rectangle.color = "#262728" - if (saturationEffect.desaturation === 1) - rectangle.color = "#404244" - if (saturationEffect.desaturation === 0) - label.color = "#686868" - if (saturationEffect.desaturation === 1) - label.color = Constants.textDefaultColor - } - - onExited: { - saturationEffect.desaturation = 1 - rectangle.color = "#262728" - label.color = "#686868" - } - - onClicked: root.clicked() - } - } - - SaturationEffect { - id: saturationEffect - x: 15 - y: 10 - width: 240 - height: 125 - desaturation: 0 - antialiasing: true - Behavior on desaturation { - PropertyAnimation { - } - } - - Image { - id: image - width: 240 - height: 125 - mipmap: true - fillMode: Image.PreserveAspectFit - } - } - - Timeline { - id: animation - startFrame: 0 - enabled: true - endFrame: 1000 - - KeyframeGroup { - target: saturationEffect - property: "desaturation" - - Keyframe { - frame: 0 - value: 1 - } - - Keyframe { - frame: 1000 - value: 0 - } - } - - KeyframeGroup { - target: label - property: "color" - - Keyframe { - value: "#686868" - frame: 0 - } - - Keyframe { - value: Constants.textDefaultColor - frame: 1000 - } - } - - KeyframeGroup { - target: rectangle - property: "color" - - Keyframe { - value: "#262728" - frame: 0 - } - - Keyframe { - value: "#404244" - frame: 1000 - } - } - } - - PropertyAnimation { - id: propertyAnimation - target: animation - property: "currentFrame" - running: false - duration: 1000 - to: animation.endFrame - from: animation.startFrame - loops: 1 - } - - Text { - id: label - x: 1 - y: 145 - color: "#686868" - - renderType: Text.NativeRendering - font.pixelSize: 14 - font.family: StudioFonts.titilliumWeb_regular - } - - Image { - id: downloadCloud - x: 210 - y: 118 - width: 60 - height: 60 - source: "images/downloadCloud.svg" - sourceSize.height: 60 - sourceSize.width: 60 - fillMode: Image.PreserveAspectFit - visible: false - } -} - -/*##^## -Designer { - D{i:0;formeditorZoom:1.3300000429153442}D{i:8} -} -##^##*/ diff --git a/src/plugins/studiowelcome/qml/welcomepage/MyButton.qml b/src/plugins/studiowelcome/qml/welcomepage/MyButton.qml deleted file mode 100644 index 8a4cec4ae59..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/MyButton.qml +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.9 -import QtQuick.Templates 2.3 -import welcome 1.0 -import StudioFonts 1.0 - -Button { - id: button - - property color hoverColor: Constants.textHoverColor - property color defaultColor: Constants.textDefaultColor - property color checkedColor: Constants.textDefaultColor - - text: "test" - - implicitWidth: background.width - implicitHeight: background.height - - contentItem: Text { - id: textButton - text: button.text - - color: checked ? button.checkedColor : - button.hovered ? button.hoverColor : - button.defaultColor - font.family: StudioFonts.titilliumWeb_regular - renderType: Text.NativeRendering - font.pixelSize: 18 - } - - background: Item { - width: textButton.implicitWidth - height: textButton.implicitHeight - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/MyTabButton.qml b/src/plugins/studiowelcome/qml/welcomepage/MyTabButton.qml deleted file mode 100644 index ca93ba47ee8..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/MyTabButton.qml +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.9 - -MyButton { - checkable: true - autoExclusive: true - defaultColor: "#686868" - hoverColor: "#79797C" -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/ProjectsGrid.qml b/src/plugins/studiowelcome/qml/welcomepage/ProjectsGrid.qml deleted file mode 100644 index f543d6bc640..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/ProjectsGrid.qml +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.9 -import welcome 1.0 - -GridView { - id: root - cellHeight: 180 - cellWidth: 285 - - clip: true - - signal itemSelected(int index, variant item) - - delegate: HoverOverDesaturate { - id: hoverOverDesaturate - imageSource: typeof(thumbnail) === "undefined" ? previewUrl : thumbnail - labelText: displayName - downloadIcon: typeof(showDownload) === "undefined" ? false : showDownload; - onClicked: root.itemSelected(index, root.model.get(index)) - - SequentialAnimation { - id: animation - running: hoverOverDesaturate.visible - - PropertyAction { - target: hoverOverDesaturate - property: "scale" - value: 0.0 - } - PauseAnimation { - duration: model.index > 0 ? 100 * model.index : 0 - } - NumberAnimation { - target: hoverOverDesaturate - property: "scale" - from: 0.0 - to: 1.0 - duration: 200 - easing.type: Easing.InOutExpo - } - } - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/SaturationEffect.qml b/src/plugins/studiowelcome/qml/welcomepage/SaturationEffect.qml deleted file mode 100644 index c21ad098e9d..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/SaturationEffect.qml +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.0 - -Item { - id: root - - property real desaturation: 1.0 - - Rectangle { - z: 10 - anchors.fill: parent - color: "#2d2e30" - anchors.margins: -16 - - opacity: root.desaturation * 0.6 - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/TutorialsModel.qml b/src/plugins/studiowelcome/qml/welcomepage/TutorialsModel.qml deleted file mode 100644 index afb4fe0d803..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/TutorialsModel.qml +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.0 - -ListModel { - ListElement { - displayName: "The Designer Tool Developers Love" - thumbnail: "images/webinar1.png" - url: "https://youtu.be/gU_tDbebAzM" - } - - ListElement { - displayName: "From Photoshop to Prototype" - thumbnail: "images/webinar2.png" - url: "https://youtu.be/ZzbucmQPU44" - } - - ListElement { - displayName: "Qt for Designers and Developers" - thumbnail: "images/designer_and_developers.png" - url: "https://www.youtube.com/watch?v=EgjCvZWEPWk" - } - - ListElement { - displayName: "QTWS - Designer and Developer Workflow" - thumbnail: "images/qtws_video_thumbnail.png" - url: "https://www.youtube.com/watch?v=4ug0EUdS2RM" - } - - ListElement { - displayName: "QTWS - Turn UI designs into working prototypes" - thumbnail: "images/bridging_the_gap.png" - url: "https://www.youtube.com/watch?v=qQM2oEWRBOw&feature=emb_logo" - } - - ListElement { - displayName: "What's New in Design Studio 1.5" - thumbnail: "images/what_is_new_15.png" - url: "https://www.youtube.com/watch?v=e-HAZrisi5o" - } - - ListElement { - displayName: "Qt Design Studio QuickTip: UI Navigation" - thumbnail: "images/Qt_QT_nav.png" - url: "https://youtu.be/RfEYO-5Mw6s" - } - - ListElement { - displayName: "Qt Design Studio QuickTip: Text Element" - thumbnail: "images/Qt_QT_textElement.png" - url: "https://youtu.be/yOUdg1o2KJM" - } - - ListElement { - displayName: "Qt Design Studio QuickTip: Animated Image" - thumbnail: "images/Qt_QT_animatedImage.png" - url: "https://youtu.be/DVWd_xMMgvg" - } - - ListElement { - displayName: "Qt Design Studio QuickTip: Slider Control" - thumbnail: "images/Qt_QT_sliderControl.png" - url: "https://youtu.be/Ed8WS03C-Vk" - } - - ListElement { - displayName: "Qt Design Studio QuickTip: Bindings" - thumbnail: "images/Qt_QT_bindings.png" - url: "https://youtu.be/UfvA04CIXv0" - } - - ListElement { - displayName: "Qt Design Studio QuickTip: Interactive 3D" - thumbnail: "images/Qt_QT_interactive3d.png" - url: "https://youtu.be/w1yhDl93YI0" - } - - ListElement { - displayName: "Sketch Bridge Tutorial - Part 1" - thumbnail: "images/sketchTutorial_1.png" - url: "https://www.qt.io/blog/qt-design-studio-sketch-bridge-tutorial-part-1" - } - - ListElement { - displayName: "Sketch Bridge Tutorial - Part 2" - thumbnail: "images/sketchTutorial_2.png" - url: "https://www.qt.io/blog/qt-design-studio-sketch-bridge-tutorial-part-2" - } - - ListElement { - displayName: "Create New Project" - thumbnail: "images/gettingStarted_newProject.png" - url: "https://youtu.be/9ihYeC0YJ0M" - } - - ListElement { - displayName: "Using Qt Quick 3D Components" - thumbnail: "images/gettingStarted_3dComponents.png" - url: "https://youtu.be/u3kZJjlk3CY" - } - - ListElement { - displayName: "Using Custom Shaders, Materials, and Effects" - thumbnail: "images/gettingStarted_shaders.png" - url: "https://youtu.be/bMXeeQw6BYs" - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_animatedImage.png b/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_animatedImage.png deleted file mode 100644 index b374319a3e9..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_animatedImage.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_bindings.png b/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_bindings.png deleted file mode 100644 index a750dce19a3..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_bindings.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_interactive3d.png b/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_interactive3d.png deleted file mode 100644 index 28c05655ceb..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_interactive3d.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_nav.png b/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_nav.png deleted file mode 100644 index 50cc98b56b3..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_nav.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_sliderControl.png b/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_sliderControl.png deleted file mode 100644 index 158dfa7dd73..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_sliderControl.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_textElement.png b/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_textElement.png deleted file mode 100644 index 784a3c57ba2..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/Qt_QT_textElement.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/bridging_the_gap.png b/src/plugins/studiowelcome/qml/welcomepage/images/bridging_the_gap.png deleted file mode 100644 index 2702abf417f..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/bridging_the_gap.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/coffeemachinedemo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/coffeemachinedemo_thumbnail.png deleted file mode 100644 index ced7ae80d1f..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/coffeemachinedemo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/cppdemo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/cppdemo_thumbnail.png deleted file mode 100644 index f92be7f50fb..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/cppdemo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/designer_and_developers.png b/src/plugins/studiowelcome/qml/welcomepage/images/designer_and_developers.png deleted file mode 100644 index 870a597282f..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/designer_and_developers.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/digital_cluster_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/digital_cluster_thumbnail.png deleted file mode 100644 index afad8c8c7b8..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/digital_cluster_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/downloadCloud.svg b/src/plugins/studiowelcome/qml/welcomepage/images/downloadCloud.svg deleted file mode 100644 index 3a527c3e54f..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/images/downloadCloud.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/ebike_demo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/ebike_demo_thumbnail.png deleted file mode 100644 index 67cf3b9bff0..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/ebike_demo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/effectdemo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/effectdemo_thumbnail.png deleted file mode 100644 index 505c02e88e9..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/effectdemo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_3dComponents.png b/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_3dComponents.png deleted file mode 100644 index 9708bff0832..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_3dComponents.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_newProject.png b/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_newProject.png deleted file mode 100644 index 812b412b0a5..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_newProject.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_shaders.png b/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_shaders.png deleted file mode 100644 index 70e17747049..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/gettingStarted_shaders.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/highendivi_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/highendivi_thumbnail.png deleted file mode 100644 index 5428c80776e..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/highendivi_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/icon_default.png b/src/plugins/studiowelcome/qml/welcomepage/images/icon_default.png deleted file mode 100644 index 82b852a408c..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/icon_default.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/icon_hover.png b/src/plugins/studiowelcome/qml/welcomepage/images/icon_hover.png deleted file mode 100644 index 693fdaf7b5a..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/icon_hover.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/progressbar_demo.png b/src/plugins/studiowelcome/qml/welcomepage/images/progressbar_demo.png deleted file mode 100644 index b1af2d8f410..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/progressbar_demo.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/qtws_video_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/qtws_video_thumbnail.png deleted file mode 100644 index e24783aee01..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/qtws_video_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/sidemenu_demo.png b/src/plugins/studiowelcome/qml/welcomepage/images/sidemenu_demo.png deleted file mode 100644 index b577ed4a0db..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/sidemenu_demo.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/sketchTutorial_1.png b/src/plugins/studiowelcome/qml/welcomepage/images/sketchTutorial_1.png deleted file mode 100644 index 2285b93d642..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/sketchTutorial_1.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/sketchTutorial_2.png b/src/plugins/studiowelcome/qml/welcomepage/images/sketchTutorial_2.png deleted file mode 100644 index fec8c65ea39..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/sketchTutorial_2.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/thumbnail_test.png b/src/plugins/studiowelcome/qml/welcomepage/images/thumbnail_test.png deleted file mode 100644 index 3c4834e6448..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/thumbnail_test.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/tutorialclusterdemo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/tutorialclusterdemo_thumbnail.png deleted file mode 100644 index 925a1247ca6..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/tutorialclusterdemo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/virtualkeyboard_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/virtualkeyboard_thumbnail.png deleted file mode 100644 index 20471299a9a..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/virtualkeyboard_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/washingmachinedemo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/washingmachinedemo_thumbnail.png deleted file mode 100644 index b5246626c50..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/washingmachinedemo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/webinar1.png b/src/plugins/studiowelcome/qml/welcomepage/images/webinar1.png deleted file mode 100644 index ba24ffc3bf2..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/webinar1.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/webinar2.png b/src/plugins/studiowelcome/qml/welcomepage/images/webinar2.png deleted file mode 100644 index 325c7cdc33e..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/webinar2.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/webinardemo_thumbnail.png b/src/plugins/studiowelcome/qml/welcomepage/images/webinardemo_thumbnail.png deleted file mode 100644 index 3cd777ab3fc..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/webinardemo_thumbnail.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/images/what_is_new_15.png b/src/plugins/studiowelcome/qml/welcomepage/images/what_is_new_15.png deleted file mode 100644 index 8fb3f072872..00000000000 Binary files a/src/plugins/studiowelcome/qml/welcomepage/images/what_is_new_15.png and /dev/null differ diff --git a/src/plugins/studiowelcome/qml/welcomepage/imports/welcome/Constants.qml b/src/plugins/studiowelcome/qml/welcomepage/imports/welcome/Constants.qml deleted file mode 100644 index a6d040aded8..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/imports/welcome/Constants.qml +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -pragma Singleton - -import QtQuick 2.6 -import StudioFonts 1.0 - -QtObject { - readonly property color backgroundColor: "#443224" - - readonly property color textDefaultColor: "#b9b9ba" - - readonly property color textHoverColor: "#ffffff" -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/imports/welcome/qmldir b/src/plugins/studiowelcome/qml/welcomepage/imports/welcome/qmldir deleted file mode 100644 index 616ac203530..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/imports/welcome/qmldir +++ /dev/null @@ -1 +0,0 @@ -singleton Constants 1.0 Constants.qml diff --git a/src/plugins/studiowelcome/qml/welcomepage/main.qml b/src/plugins/studiowelcome/qml/welcomepage/main.qml deleted file mode 100644 index 6fb5763d7f4..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/main.qml +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.10 -import QtQuick.Controls 2.4 -import QtQuick.Layouts 1.3 -import welcome 1.0 -import projectmodel 1.0 -import StudioFonts 1.0 - -Item { - width: 1024 - height: 786 - - Rectangle { - id: rectangle - anchors.fill: parent - visible: true - color: "#2d2e30" - - StackLayout { - id: stackLayout - anchors.margins: 10 - anchors.top: topLine.bottom - anchors.bottom: bottomLine.top - anchors.right: parent.right - anchors.left: parent.left - - CustomScrollView { - ProjectsGrid { - model: ProjectModel { - id: projectModel - } - onItemSelected: function(index, item) { projectModel.openProjectAt(index) } - } - } - - CustomScrollView { - ProjectsGrid { - model: ExamplesModel {} - onItemSelected: function(index, item) { - projectModel.openExample(item.projectName, item.qmlFileName, item.url, item.explicitQmlproject) - } - } - } - - CustomScrollView{ - ProjectsGrid { - model: TutorialsModel {} - onItemSelected: function(index, item) { Qt.openUrlExternally(item.url) } - } - } - } - Rectangle { - id: topLine - height: 1 - color: "#bababa" - anchors.right: parent.right - anchors.rightMargin: 10 - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.top: parent.top - anchors.topMargin: 200 - } - - Rectangle { - id: bottomLine - height: 1 - color: "#bababa" - anchors.left: topLine.left - anchors.right: topLine.right - anchors.bottom: parent.bottom - anchors.bottomMargin: 60 - } - - Row { - x: 8 - y: 160 - spacing: 26 - - MyTabButton { - text: qsTr("Recent Projects") - checked: true - onClicked: stackLayout.currentIndex = 0 - } - - MyTabButton { - text: qsTr("Examples") - onClicked: stackLayout.currentIndex = 1 - } - - MyTabButton { - text: qsTr("Tutorials") - onClicked: stackLayout.currentIndex = 2 - } - } - - AccountImage { - id: account - x: 946 - y: 29 - anchors.right: parent.right - anchors.rightMargin: 40 - } - - GridLayout { - y: 78 - anchors.horizontalCenter: parent.horizontalCenter - columnSpacing: 10 - rows: 2 - columns: 2 - - Text { - id: welcomeTo - color: Constants.textDefaultColor - text: qsTr("Welcome to") - renderType: Text.NativeRendering - font.pixelSize: 22 - font.family: StudioFonts.titilliumWeb_regular - } - - Text { - id: qtDesignStudio - color: "#4cd265" - text: qsTr("Qt Design Studio") - renderType: Text.NativeRendering - font.family: StudioFonts.titilliumWeb_regular - font.pixelSize: 22 - } - - MyButton { - text: qsTr("Create New") - onClicked: projectModel.createProject() - } - - MyButton { - text: qsTr("Open Project") - onClicked: projectModel.openProject() - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - } - } - - RowLayout { - y: 732 - height: 28 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottom: parent.bottom - anchors.bottomMargin: 26 - spacing: 50 - - MyButton { - text: qsTr("Help") - onClicked: projectModel.showHelp() - } - - MyButton { - text: qsTr("Community") - onClicked: Qt.openUrlExternally("https://forum.qt.io/") - } - - MyButton { - text: qsTr("Blog") - onClicked: Qt.openUrlExternally("http://blog.qt.io/") - } - } - - Text { - id: qtDesignStudio1 - x: 891 - y: 171 - color: "#ffffff" - text: qsTr("Community Edition") - anchors.right: parent.right - anchors.rightMargin: 23 - font.weight: Font.Light - font.pixelSize: 14 - font.family: StudioFonts.titilliumWeb_regular - renderType: Text.NativeRendering - visible: projectModel.communityVersion - } - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/mockData/projectmodel/ProjectModel.qml b/src/plugins/studiowelcome/qml/welcomepage/mockData/projectmodel/ProjectModel.qml deleted file mode 100644 index 2ebd25183ea..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/mockData/projectmodel/ProjectModel.qml +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.0 - -ListModel { - - property bool communityVersion: true - ListElement { - displayName: "Project 01" - prettyFilePath: "my_file_1" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 02" - prettyFilePath: "my_file_2" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 03" - prettyFilePath: "my_file_3" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 04" - prettyFilePath: "my_file_4" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 05" - prettyFilePath: "my_file_5" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 06" - prettyFilePath: "my_file_6" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 07" - prettyFilePath: "my_file_7" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 08" - filename: "my_file_8" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 09" - filename: "my_file_9" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 10" - prettyFilePath: "my_file_10" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 11" - filename: "my_file_11" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 12" - prettyFilePath: "my_file_12" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 13" - filename: "my_file_13" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 14" - prettyFilePath: "my_file_14" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 15" - filename: "my_file_15" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 16" - filename: "my_file_16" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 17" - filename: "my_file_17" - thumbnail: "images/thumbnail_test.png" - } - - ListElement { - displayName: "Project 18" - prettyFilePath: "my_file_18" - thumbnail: "images/thumbnail_test.png" - } -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/mockData/projectmodel/qmldir b/src/plugins/studiowelcome/qml/welcomepage/mockData/projectmodel/qmldir deleted file mode 100644 index 0d7bc345c2b..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/mockData/projectmodel/qmldir +++ /dev/null @@ -1 +0,0 @@ -ProjectModel 1.0 ProjectModel.qml diff --git a/src/plugins/studiowelcome/qml/welcomepage/mockData/usagestatistics/UsageStatisticModel.qml b/src/plugins/studiowelcome/qml/welcomepage/mockData/usagestatistics/UsageStatisticModel.qml deleted file mode 100644 index 26795b93753..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/mockData/usagestatistics/UsageStatisticModel.qml +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (C) 2020 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QtQuick 2.0 - -QtObject { - property bool usageStatisticEnabled: false - property string version: "3.3.0" -} diff --git a/src/plugins/studiowelcome/qml/welcomepage/mockData/usagestatistics/qmldir b/src/plugins/studiowelcome/qml/welcomepage/mockData/usagestatistics/qmldir deleted file mode 100644 index c83a43a8ae7..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/mockData/usagestatistics/qmldir +++ /dev/null @@ -1 +0,0 @@ -UsageStatisticModel 1.0 UsageStatisticModel.qml diff --git a/src/plugins/studiowelcome/qml/welcomepage/welcomepage.qmlproject b/src/plugins/studiowelcome/qml/welcomepage/welcomepage.qmlproject deleted file mode 100644 index c28a3e390d5..00000000000 --- a/src/plugins/studiowelcome/qml/welcomepage/welcomepage.qmlproject +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -import QmlProject 1.1 - -Project { - mainFile: "main.qml" - - /* Include .qml, .js, and image files from current directory and subdirectories */ - QmlFiles { - directory: "." - } - JavaScriptFiles { - directory: "." - } - ImageFiles { - directory: "." - } - /* List of plugin directories passed to QML runtime */ - importPaths: [ "imports", "mockData", "../../../../share/3rdparty/studiofonts" ] - - Environment { - QT_AUTO_SCREEN_SCALE_FACTOR: "1" - } -} diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index f5760b8e6bb..ac6a17de874 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -72,14 +72,6 @@ using namespace Utils; namespace StudioWelcome { namespace Internal { -static bool useNewWelcomePage() -{ - QtcSettings *settings = Core::ICore::settings(); - const Key newWelcomePageEntry = "QML/Designer/NewWelcomePage"; //entry from qml settings - - return settings->value(newWelcomePageEntry, false).toBool(); -} - static void openOpenProjectDialog() { const FilePath path = Core::DocumentManager::useProjectsDirectory() @@ -809,19 +801,6 @@ WelcomeMode::~WelcomeMode() void WelcomeMode::setupQuickWidget(const QString &welcomePagePath) { - if (!useNewWelcomePage()) { - -#ifdef QT_DEBUG - m_quickWidget->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH) - + "welcomepage/imports"); - m_quickWidget->setSource( - QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH) + "welcomepage/main.qml")); -#else - m_quickWidget->rootContext()->setContextProperty("$dataModel", m_dataModelDownloader); - m_quickWidget->engine()->addImportPath("qrc:/qml/welcomepage/imports"); - m_quickWidget->setSource(QUrl("qrc:/qml/welcomepage/main.qml")); -#endif - } else { m_quickWidget->rootContext()->setContextProperty("$dataModel", m_dataModelDownloader); m_quickWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString()); @@ -838,7 +817,6 @@ void WelcomeMode::setupQuickWidget(const QString &welcomePagePath) connect(updateShortcut, &QShortcut::activated, this, [this, welcomePagePath](){ m_quickWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml")); }); - } } void WelcomeMode::createQuickWidget() diff --git a/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp b/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp index c1817e934d5..4435d0e9f42 100644 --- a/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp +++ b/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp @@ -32,7 +32,7 @@ static void registerFonts(const QDir &projectDir) static QDir findProjectFolder(const QDir ¤tDir, int ret = 0) { if (ret > 2) - QDir::current(); + return QDir::current(); QDirIterator it{currentDir.absolutePath(), {"*.qmlproject"},