summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2023-01-12 09:07:27 +0100
committerEike Ziller <eike.ziller@qt.io>2023-01-12 09:07:27 +0100
commit211d6507c338f63ebcf1ed58a3206c565bc6cb5c (patch)
treec1ba641cdb143b0f8696f847c7cc5834376e570c
parent69a79010d6eecb9411385ba4000dd0d088963c54 (diff)
parenta61f8b02d30d2dfd8716e2ed7b7a23d287b68677 (diff)
downloadqt-creator-211d6507c338f63ebcf1ed58a3206c565bc6cb5c.tar.gz
Merge remote-tracking branch 'origin/qds/dev'
Conflicts: src/plugins/updateinfo/updateinfoplugin.cpp Change-Id: Ie1bf2ad434f0224fb91caf91b443daae3d5b5ec0
-rw-r--r--doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc2
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc2
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc2
-rw-r--r--share/qtcreator/qmldesigner/designericons.json81
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetDelegate.qml34
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml18
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayerSection.qml7
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml26
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml18
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml46
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml179
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttfbin24432 -> 29604 bytes
-rw-r--r--src/plugins/qmldesigner/CMakeLists.txt1
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp83
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h18
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp5
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h1
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp16
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h4
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp90
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.h5
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designericons.cpp418
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designericons.h133
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp2
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h3
-rw-r--r--src/plugins/qmldesigner/components/componentcore/theme.h27
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp38
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h5
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dview.cpp18
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dview.h4
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp43
-rw-r--r--src/plugins/qmldesigner/components/edit3d/edit3dwidget.h2
-rw-r--r--src/plugins/qmldesigner/components/eventlist/eventlistpluginview.cpp2
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp2
-rw-r--r--src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp84
-rw-r--r--src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp13
-rw-r--r--src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp30
-rw-r--r--src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp3
-rw-r--r--src/plugins/qmldesigner/components/navigator/navigatorview.cpp21
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp2
-rw-r--r--src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/include/nodemetainfo.h2
-rw-r--r--src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp14
-rw-r--r--src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp41
-rw-r--r--src/plugins/qmldesigner/designercore/model/modelnode.cpp3
-rw-r--r--src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp3
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h1
-rw-r--r--src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp1
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/quick.metainfo8
-rw-r--r--src/plugins/qmldesigner/utils/asset.cpp5
-rw-r--r--src/plugins/qmldesigner/utils/asset.h3
-rw-r--r--src/plugins/updateinfo/updateinfoplugin.cpp3
-rw-r--r--src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp45
-rw-r--r--src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h1
-rw-r--r--src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp2
-rw-r--r--src/tools/qml2puppet/qml2puppet/qmlbase.h21
-rw-r--r--src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp3
-rw-r--r--src/tools/qml2puppet/runnerconf/qmlruntime/content/resizeItemToWindow.qml44
58 files changed, 1378 insertions, 312 deletions
diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc
index 6faef0cfc8..f4728fa415 100644
--- a/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc
+++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-xd-using.qdoc
@@ -84,7 +84,7 @@
\list
\li \uicontrol Component exports the layer as a separate UI file
that contains all the exportable artwork and text in it. Only
- Artboards can be exported as components.
+ Artboards and XD component layers can be exported as components.
\li \uicontrol Child exports each asset of the selected group
or layer a separate PNG file, with references
to the images in the component file.
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
index f2063e6a05..6d1fbc5bd1 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
@@ -181,7 +181,7 @@
Aside from the size, an area light has the same properties as a directional
light.
- The image below shows an example on how to light a component with different
+ The image shows an example on how to light a component with different
colors using two different area lights.
You can rotate, scale, and move area lights.
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc
index 8d001071cb..5f2f53ca96 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc
@@ -32,7 +32,7 @@
By default, a directional light and a perspective camera are used in a 3D
scene created by using the wizard template mentioned above. To use other
light and camera types, select the component in the \uicontrol{3D} or
- \uicontrol Navigatorn view and change the type of the component in the \uicontrol
+ \uicontrol Navigator view and change the type of the component in the \uicontrol
Type field in \l Properties. For example, to use a point light, enter
\e {PointLight}.
diff --git a/share/qtcreator/qmldesigner/designericons.json b/share/qtcreator/qmldesigner/designericons.json
new file mode 100644
index 0000000000..e4201291c6
--- /dev/null
+++ b/share/qtcreator/qmldesigner/designericons.json
@@ -0,0 +1,81 @@
+{
+ "ContextMenuArea": {
+ "size": "28x28",
+ "Off": {
+ "Disabled": { "color": "DSiconColorDisabled" },
+ "Hovered": { "color": "DSnavigatorIconHover" },
+ "Normal": { "color": "DSnavigatorIcon" },
+ "Selected": { "color": "DSnavigatorIconSelected" }
+ },
+ "On": {
+ "Disabled": { "color": "DSiconColorDisabled" },
+ "Hovered": { "color": "DSnavigatorIconHover" },
+ "Normal": { "color": "DSnavigatorIcon" },
+ "Selected": { "color": "DSnavigatorIconSelected" }
+ }
+ },
+ "AddMouseAreaIcon": {
+ "iconName": "s_mouseArea"
+ },
+ "AnchorsIcon": {
+ "iconName": "s_anchors"
+ },
+ "AnnotationIcon": {
+ "iconName": "s_annotations"
+ },
+ "ArrangeIcon": {
+ "iconName": "s_arrange"
+ },
+ "ConnectionsIcon": {
+ "iconName": "s_connections"
+ },
+ "EditIcon": {
+ "iconName": "s_edit"
+ },
+ "EnterComponentIcon": {
+ "iconName": "s_enterComponent"
+ },
+ "EventListIcon": {
+ "iconName": "s_eventList"
+ },
+ "GroupSelectionIcon": {
+ "iconName": "s_group"
+ },
+ "LayoutsIcon": {
+ "iconName": "s_layouts"
+ },
+ "MakeComponentIcon": {
+ "iconName": "s_component"
+ },
+ "MergeWithTemplateIcon": {
+ "iconName": "s_merging"
+ },
+ "PositionsersIcon": {
+ "iconName": "s_positioners"
+ },
+ "SelecionIcon": {
+ "iconName": "s_selection"
+ },
+ "ShowBoundsIcon": {
+ "Off": {
+ "iconName": "visibilityOff"
+ },
+ "On": {
+ "iconName": "visibilityOn"
+ }
+ },
+ "SnappingIcon": {
+ "iconName": "s_snapping"
+ },
+ "TimelineIcon": {
+ "iconName": "s_timeline"
+ },
+ "VisibilityIcon": {
+ "Off": {
+ "iconName": "visibilityOff"
+ },
+ "On": {
+ "iconName": "visibilityOn"
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetDelegate.qml
index c717852649..1d5d2434c6 100644
--- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetDelegate.qml
+++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetDelegate.qml
@@ -182,9 +182,36 @@ TreeViewDelegate {
}
ToolTip {
+ id: assetTooltip
visible: !root.isFont && mouseArea.containsMouse && !root.assetsView.contextMenu.visible
- text: model.filePath
+ text: assetTooltip.__computeText()
delay: 1000
+
+ function __computeText()
+ {
+ let filePath = model.filePath.replace(assetsModel.contentDirPath(), "")
+ let fileSize = rootView.assetFileSize(model.filePath)
+ let fileExtMatches = model.filePath.match(/\.(.*)$/)
+ let fileExt = fileExtMatches ? "(" + fileExtMatches[1] + ")" : ""
+
+ if (rootView.assetIsImage(model.filePath)) {
+ let size = rootView.imageSize(model.filePath)
+
+ return filePath + "\n"
+ + size.width + " x " + size.height
+ + "\n" + fileSize
+ + " " + fileExt
+ } else {
+ return filePath + "\n"
+ + fileSize
+ + " " + fileExt
+ }
+ }
+
+ function refresh()
+ {
+ text = assetTooltip.__computeText()
+ }
}
Timer {
@@ -293,5 +320,10 @@ TreeViewDelegate {
: "image://qmldesigner_assets/" + model.filePath
}
+ onStatusChanged: {
+ if (thumbnailImage.status === Image.Ready)
+ assetTooltip.refresh()
+ }
+
} // Image
} // TreeViewDelegate
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml
index 5e5d283a81..edf56c9b52 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/GeometrySection.qml
@@ -47,6 +47,7 @@ Section {
SectionLayout {
PropertyLabel {
text: qsTr("Position")
+ tooltip: qsTr("Sets the position of the component relative to its parent.")
enabled: xSpinBox.enabled || ySpinBox.enabled
}
@@ -66,7 +67,7 @@ Section {
ControlLabel {
text: "X"
- tooltip: xSpinBox.enabled ? "X" : root.disabledTooltip
+ tooltip: xSpinBox.enabled ? qsTr("X-coordinate") : root.disabledTooltip
enabled: xSpinBox.enabled
}
@@ -87,7 +88,7 @@ Section {
ControlLabel {
text: "Y"
- tooltip: xSpinBox.enabled ? "Y" : root.disabledTooltip
+ tooltip: xSpinBox.enabled ? qsTr("Y-coordinate") : root.disabledTooltip
enabled: ySpinBox.enabled
}
/*
@@ -101,6 +102,7 @@ Section {
PropertyLabel {
text: qsTr("Size")
+ tooltip: qsTr("Sets the width and height of the component.")
enabled: widthSpinBox.enabled || heightSpinBox.enabled
}
@@ -157,11 +159,13 @@ Section {
PropertyLabel {
text: qsTr("Rotation")
+ tooltip: qsTr("Rotate the component at an angle.")
blockedByTemplate: !backendValues.rotation.isAvailable
}
SecondColumnLayout {
SpinBox {
+ id: rotationSpinBox
implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
backendValue: backendValues.rotation
@@ -175,6 +179,7 @@ Section {
ControlLabel {
text: "°"
+ tooltip: rotationSpinBox.enabled ? qsTr("Angle (in degree)") : root.disabledTooltip
enabled: backendValues.rotation.isAvailable
}
/*
@@ -210,11 +215,13 @@ Section {
PropertyLabel {
text: qsTr("Scale")
+ tooltip: qsTr("Sets the scale of the component by percentage.")
blockedByTemplate: !backendValues.scale.isAvailable
}
SecondColumnLayout {
SpinBox {
+ id: scaleSpinBox
implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
sliderIndicatorVisible: true
@@ -230,13 +237,17 @@ Section {
ControlLabel {
text: "%"
+ tooltip: scaleSpinBox.enabled ? qsTr("Percentage") : root.disabledTooltip
enabled: backendValues.scale.isAvailable
}
ExpandingSpacer {}
}
- PropertyLabel { text: qsTr("Z stack") }
+ PropertyLabel {
+ text: qsTr("Z stack")
+ tooltip: qsTr("Sets the stacking order of the component.")
+ }
SecondColumnLayout {
SpinBox {
@@ -252,6 +263,7 @@ Section {
PropertyLabel {
text: qsTr("Origin")
+ tooltip: qsTr("Sets the modification point of the component.")
blockedByTemplate: !backendValues.transformOrigin.isAvailable
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayerSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayerSection.qml
index 42805f6a79..e340ea9283 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayerSection.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/LayerSection.qml
@@ -235,10 +235,10 @@ Section {
ExpandingSpacer {}
}
-/*
+
PropertyLabel {
- text: qsTr("Source Rectangle")
- tooltip: qsTr("TODO.")
+ text: qsTr("Source rectangle")
+ tooltip: qsTr("Sets the rectangular area of the component that should be rendered into the texture.")
}
SecondColumnLayout {
@@ -313,6 +313,5 @@ Section {
ExpandingSpacer {}
}
-*/
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml
index 09858baef3..d8520d5cad 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml
@@ -38,12 +38,21 @@ SecondColumnLayout {
property alias spacer: spacer
+ property bool __block: false
+
function resetShapeColor() {
colorEditor.backendValue.resetValue()
}
function initEditor() {
+ colorEditor.syncColor()
+ }
+
+ // Syncing color from backend to frontend and block reflection
+ function syncColor() {
+ colorEditor.__block = true
colorEditor.color = colorEditor.value
+ colorEditor.__block = false
}
Connections {
@@ -52,12 +61,12 @@ SecondColumnLayout {
function onValueChanged() {
if (popupLoader.isNotInGradientMode())
- colorEditor.color = colorEditor.value
+ colorEditor.syncColor()
}
function onBackendValueChanged() {
if (popupLoader.isNotInGradientMode())
- colorEditor.color = colorEditor.value
+ colorEditor.syncColor()
}
}
@@ -83,6 +92,9 @@ SecondColumnLayout {
}
onColorChanged: {
+ if (colorEditor.__block)
+ return
+
if (!popupLoader.isInValidState)
return
@@ -211,24 +223,20 @@ SecondColumnLayout {
if (popupLoader.active && popupLoader.dialog)
popupLoader.dialog.determineActiveColorMode()
else
- colorEditor.color = colorEditor.value
+ colorEditor.syncColor()
}
property alias active: popupLoader.loader.active
property Loader loader: Loader {
- parent: colorEditor
+ parent: preview
active: colorEditor.supportGradient
- anchors.left: parent.left
- anchors.leftMargin: 0
sourceComponent: ColorEditorPopup {
id: cePopup
x: cePopup.__defaultX
y: cePopup.__defaultY
}
- onLoaded: {
- popupLoader.dialog.initEditor()
- }
+ onLoaded: popupLoader.dialog.initEditor()
}
}
}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml
index 5a9d5f5fe3..839c656d8a 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml
@@ -19,7 +19,10 @@ Section {
property bool showState: false
SectionLayout {
- PropertyLabel { text: qsTr("Type") }
+ PropertyLabel {
+ text: qsTr("Type")
+ tooltip: qsTr("Sets the QML type of the component.")
+ }
SecondColumnLayout {
z: 2
@@ -44,7 +47,7 @@ Section {
typeLineEdit.visible = !typeLineEdit.visible
typeLineEdit.forceActiveFocus()
}
- tooltip: qsTr("Changes the type of this component.")
+ tooltip: qsTr("Sets the QML type of the component.")
enabled: !modelNodeBackend.multiSelection
}
@@ -83,7 +86,10 @@ Section {
ExpandingSpacer {}
}
- PropertyLabel { text: qsTr("ID") }
+ PropertyLabel {
+ text: qsTr("ID")
+ tooltip: qsTr("Sets a unique identification or name.")
+ }
SecondColumnLayout {
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
@@ -167,7 +173,10 @@ Section {
ExpandingSpacer {}
}
- PropertyLabel { text: qsTr("Name") }
+ PropertyLabel {
+ text: qsTr("Name")
+ tooltip: qsTr("Adds a note with a title to explain the component.")
+ }
SecondColumnLayout {
enabled: !modelNodeBackend.multiSelection
@@ -247,6 +256,7 @@ Section {
PropertyLabel {
visible: root.showState
text: qsTr("State")
+ tooltip: qsTr("Sets the state of the component.")
}
SecondColumnLayout {
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml
index b5e001d64a..446bfc1c26 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBoxInput.qml
@@ -51,33 +51,6 @@ TextInput {
border.width: 0
}
- DragHandler {
- id: dragHandler
- target: null
- acceptedDevices: PointerDevice.Mouse
- enabled: true
-
- property int initialValue: 0
-
- onActiveChanged: {
- if (active) {
- initialValue = myControl.value
- mouseArea.cursorShape = Qt.ClosedHandCursor
- myControl.drag = true
- } else {
- mouseArea.cursorShape = Qt.PointingHandCursor
- myControl.drag = false
- }
- }
- onTranslationChanged: {
- var currValue = myControl.value
- myControl.value = initialValue + translation.x
-
- if (currValue !== myControl.value)
- myControl.valueModified()
- }
- }
-
Item {
id: dragModifierWorkaround
Keys.onPressed: function(event) {
@@ -86,17 +59,20 @@ TextInput {
if (event.modifiers & Qt.ControlModifier) {
mouseArea.stepSize = myControl.minStepSize
mouseArea.calcValue()
+ myControl.valueModified()
}
if (event.modifiers & Qt.ShiftModifier) {
mouseArea.stepSize = myControl.maxStepSize
mouseArea.calcValue()
+ myControl.valueModified()
}
}
Keys.onReleased: function(event) {
event.accepted = true
- mouseArea.stepSize = myControl.realStepSize
+ mouseArea.stepSize = myControl.stepSize
mouseArea.calcValue()
+ myControl.valueModified()
}
}
@@ -117,13 +93,13 @@ TextInput {
property int initialValue: myControl.value // value on drag operation starts
- property int pressStartX: 0
- property int dragStartX: 0
- property int translationX: 0
+ property real pressStartX: 0.0
+ property real dragStartX: 0.0
+ property real translationX: 0.0
- property int dragDirection: 0
- property int totalUnits: 0 // total number of units dragged
- property int units: 0
+ property real dragDirection: 0.0
+ property real totalUnits: 0.0 // total number of units dragged
+ property real units: 0.0
property real __pixelsPerUnit: textInput.devicePixelRatio * textInput.pixelsPerUnit
@@ -176,7 +152,7 @@ TextInput {
mouseArea.translationX += translationX
mouseArea.calcValue()
- //myControl.realValueModified()
+ myControl.valueModified()
}
onClicked: function(mouse) {
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml
index 412e1328ee..3df7a9e5dd 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml
@@ -95,82 +95,109 @@ QtObject {
readonly property string gridView: "\u0070"
readonly property string idAliasOff: "\u0071"
readonly property string idAliasOn: "\u0072"
- readonly property string infinity: "\u0073"
- readonly property string keyframe: "\u0074"
- readonly property string linkTriangle: "\u0075"
- readonly property string linked: "\u0076"
- readonly property string listView: "\u0077"
- readonly property string lockOff: "\u0078"
- readonly property string lockOn: "\u0079"
- readonly property string materialPreviewEnvironment: "\u007A"
- readonly property string materialPreviewModel: "\u007B"
- readonly property string mergeCells: "\u007C"
- readonly property string minus: "\u007D"
- readonly property string mirror: "\u007E"
- readonly property string newMaterial: "\u007F"
- readonly property string openLink: "\u0080"
- readonly property string openMaterialBrowser: "\u0081"
- readonly property string orientation: "\u0082"
- readonly property string paddingEdge: "\u0083"
- readonly property string paddingFrame: "\u0084"
- readonly property string pasteStyle: "\u0085"
- readonly property string pause: "\u0086"
- readonly property string pin: "\u0087"
- readonly property string play: "\u0088"
- readonly property string plus: "\u0089"
- readonly property string promote: "\u008A"
- readonly property string readOnly: "\u008B"
- readonly property string redo: "\u008C"
- readonly property string rotationFill: "\u008D"
- readonly property string rotationOutline: "\u008E"
- readonly property string search: "\u008F"
- readonly property string sectionToggle: "\u0090"
- readonly property string splitColumns: "\u0091"
- readonly property string splitRows: "\u0092"
- readonly property string startNode: "\u0093"
- readonly property string testIcon: "\u0094"
- readonly property string textAlignBottom: "\u0095"
- readonly property string textAlignCenter: "\u0096"
- readonly property string textAlignJustified: "\u0097"
- readonly property string textAlignLeft: "\u0098"
- readonly property string textAlignMiddle: "\u0099"
- readonly property string textAlignRight: "\u009A"
- readonly property string textAlignTop: "\u009B"
- readonly property string textBulletList: "\u009D"
- readonly property string textFullJustification: "\u009E"
- readonly property string textNumberedList: "\u009F"
- readonly property string tickIcon: "\u00A0"
- readonly property string translationCreateFiles: "\u00A1"
- readonly property string translationCreateReport: "\u00A2"
- readonly property string translationExport: "\u00A3"
- readonly property string translationImport: "\u00A4"
- readonly property string translationSelectLanguages: "\u00A5"
- readonly property string translationTest: "\u00A6"
- readonly property string transparent: "\u00A7"
- readonly property string triState: "\u00A8"
- readonly property string triangleArcA: "\u00A9"
- readonly property string triangleArcB: "\u00AA"
- readonly property string triangleCornerA: "\u00AB"
- readonly property string triangleCornerB: "\u00AC"
- readonly property string unLinked: "\u00AE"
- readonly property string undo: "\u00AF"
- readonly property string unpin: "\u00B0"
- readonly property string upDownIcon: "\u00B1"
- readonly property string upDownSquare2: "\u00B2"
- readonly property string visibilityOff: "\u00B3"
- readonly property string visibilityOn: "\u00B4"
- readonly property string wildcard: "\u00B5"
- readonly property string wizardsAutomotive: "\u00B6"
- readonly property string wizardsDesktop: "\u00B7"
- readonly property string wizardsGeneric: "\u00B8"
- readonly property string wizardsMcuEmpty: "\u00B9"
- readonly property string wizardsMcuGraph: "\u00BA"
- readonly property string wizardsMobile: "\u00BB"
- readonly property string wizardsUnknown: "\u00BC"
- readonly property string zoomAll: "\u00BD"
- readonly property string zoomIn: "\u00BE"
- readonly property string zoomOut: "\u00BF"
- readonly property string zoomSelection: "\u00C0"
+ readonly property string imported: "\u0073"
+ readonly property string infinity: "\u0074"
+ readonly property string keyframe: "\u0075"
+ readonly property string linkTriangle: "\u0076"
+ readonly property string linked: "\u0077"
+ readonly property string listView: "\u0078"
+ readonly property string lockOff: "\u0079"
+ readonly property string lockOn: "\u007A"
+ readonly property string materialPreviewEnvironment: "\u007B"
+ readonly property string materialPreviewModel: "\u007C"
+ readonly property string mergeCells: "\u007D"
+ readonly property string minus: "\u007E"
+ readonly property string mirror: "\u007F"
+ readonly property string newMaterial: "\u0080"
+ readonly property string openLink: "\u0081"
+ readonly property string openMaterialBrowser: "\u0082"
+ readonly property string orientation: "\u0083"
+ readonly property string paddingEdge: "\u0084"
+ readonly property string paddingFrame: "\u0085"
+ readonly property string pasteStyle: "\u0086"
+ readonly property string pause: "\u0087"
+ readonly property string pin: "\u0088"
+ readonly property string play: "\u0089"
+ readonly property string plus: "\u008A"
+ readonly property string promote: "\u008B"
+ readonly property string readOnly: "\u008C"
+ readonly property string redo: "\u008D"
+ readonly property string rotationFill: "\u008E"
+ readonly property string rotationOutline: "\u008F"
+ readonly property string s_anchors: "\u0090"
+ readonly property string s_annotations: "\u0091"
+ readonly property string s_arrange: "\u0092"
+ readonly property string s_boundingBox: "\u0093"
+ readonly property string s_component: "\u0094"
+ readonly property string s_connections: "\u0095"
+ readonly property string s_edit: "\u0096"
+ readonly property string s_enterComponent: "\u0097"
+ readonly property string s_eventList: "\u0098"
+ readonly property string s_group: "\u0099"
+ readonly property string s_layouts: "\u009A"
+ readonly property string s_merging: "\u009B"
+ readonly property string s_mouseArea: "\u009D"
+ readonly property string s_positioners: "\u009E"
+ readonly property string s_selection: "\u009F"
+ readonly property string s_snapping: "\u00A0"
+ readonly property string s_timeline: "\u00A1"
+ readonly property string s_visibility: "\u00A2"
+ readonly property string search: "\u00A3"
+ readonly property string sectionToggle: "\u00A4"
+ readonly property string splitColumns: "\u00A5"
+ readonly property string splitRows: "\u00A6"
+ readonly property string startNode: "\u00A7"
+ readonly property string testIcon: "\u00A8"
+ readonly property string textAlignBottom: "\u00A9"
+ readonly property string textAlignCenter: "\u00AA"
+ readonly property string textAlignJustified: "\u00AB"
+ readonly property string textAlignLeft: "\u00AC"
+ readonly property string textAlignMiddle: "\u00AE"
+ readonly property string textAlignRight: "\u00AF"
+ readonly property string textAlignTop: "\u00B0"
+ readonly property string textBulletList: "\u00B1"
+ readonly property string textFullJustification: "\u00B2"
+ readonly property string textNumberedList: "\u00B3"
+ readonly property string tickIcon: "\u00B4"
+ readonly property string topToolbar_annotations: "\u00B5"
+ readonly property string topToolbar_closeFile: "\u00B6"
+ readonly property string topToolbar_designMode: "\u00B7"
+ readonly property string topToolbar_enterComponent: "\u00B8"
+ readonly property string topToolbar_home: "\u00B9"
+ readonly property string topToolbar_makeComponent: "\u00BA"
+ readonly property string topToolbar_navFile: "\u00BB"
+ readonly property string topToolbar_runProject: "\u00BC"
+ readonly property string translationCreateFiles: "\u00BD"
+ readonly property string translationCreateReport: "\u00BE"
+ readonly property string translationExport: "\u00BF"
+ readonly property string translationImport: "\u00C0"
+ readonly property string translationSelectLanguages: "\u00C1"
+ readonly property string translationTest: "\u00C2"
+ readonly property string transparent: "\u00C3"
+ readonly property string triState: "\u00C4"
+ readonly property string triangleArcA: "\u00C5"
+ readonly property string triangleArcB: "\u00C6"
+ readonly property string triangleCornerA: "\u00C7"
+ readonly property string triangleCornerB: "\u00C8"
+ readonly property string unLinked: "\u00C9"
+ readonly property string undo: "\u00CA"
+ readonly property string unpin: "\u00CB"
+ readonly property string upDownIcon: "\u00CC"
+ readonly property string upDownSquare2: "\u00CD"
+ readonly property string visibilityOff: "\u00CE"
+ readonly property string visibilityOn: "\u00CF"
+ readonly property string wildcard: "\u00D0"
+ readonly property string wizardsAutomotive: "\u00D1"
+ readonly property string wizardsDesktop: "\u00D2"
+ readonly property string wizardsGeneric: "\u00D3"
+ readonly property string wizardsMcuEmpty: "\u00D4"
+ readonly property string wizardsMcuGraph: "\u00D5"
+ readonly property string wizardsMobile: "\u00D6"
+ readonly property string wizardsUnknown: "\u00D7"
+ readonly property string zoomAll: "\u00D8"
+ readonly property string zoomIn: "\u00D9"
+ readonly property string zoomOut: "\u00DA"
+ readonly property string zoomSelection: "\u00DB"
readonly property font iconFont: Qt.font({
"family": controlIcons.name,
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf
index acd8df6ce3..cacd0c3cb9 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf
Binary files differ
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 3916a55929..40bc1dfa06 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -613,6 +613,7 @@ extend_qtc_plugin(QmlDesigner
crumblebar.cpp crumblebar.h
designeractionmanager.cpp designeractionmanager.h
designeractionmanagerview.cpp designeractionmanagerview.h
+ designericons.cpp designericons.h
findimplementation.cpp findimplementation.h
layoutingridlayout.cpp layoutingridlayout.h
modelnodecontextmenu.cpp modelnodecontextmenu.h
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp
index 3667a9f330..6fc9bd4a26 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp
@@ -22,20 +22,13 @@ QPixmap AssetsLibraryIconProvider::requestPixmap(const QString &id, QSize *size,
QPixmap pixmap;
if (m_thumbnails.contains(id)) {
- pixmap = m_thumbnails[id];
+ pixmap = m_thumbnails[id].pixmap;
} else {
- pixmap = fetchPixmap(id, requestedSize);
- bool haveValidImage = true;
- if (pixmap.isNull()) {
- pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/AssetsLibrary/images/assets_default.png");
- haveValidImage = false;
- }
-
- if (requestedSize.isValid())
- pixmap = pixmap.scaled(requestedSize, Qt::KeepAspectRatio);
-
- if (haveValidImage)
- m_thumbnails[id] = pixmap;
+ Thumbnail thumbnail = createThumbnail(id, requestedSize);
+ pixmap = thumbnail.pixmap;
+
+ if (thumbnail.assetType != Asset::MissingImage)
+ m_thumbnails[id] = thumbnail;
}
if (size) {
@@ -46,6 +39,25 @@ QPixmap AssetsLibraryIconProvider::requestPixmap(const QString &id, QSize *size,
return pixmap;
}
+Thumbnail AssetsLibraryIconProvider::createThumbnail(const QString &id, const QSize &requestedSize)
+{
+ auto [pixmap, fileSize] = fetchPixmap(id, requestedSize);
+ QSize originalSize = pixmap.size();
+ Asset::Type assetType = Asset(id).type();
+
+ if (pixmap.isNull()) {
+ pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/AssetsLibrary/images/assets_default.png");
+
+ if (assetType == Asset::Image)
+ assetType = Asset::MissingImage;
+ }
+
+ if (requestedSize.isValid())
+ pixmap = pixmap.scaled(requestedSize, Qt::KeepAspectRatio);
+
+ return Thumbnail{pixmap, originalSize, assetType, fileSize};
+}
+
QPixmap AssetsLibraryIconProvider::generateFontIcons(const QString &filePath, const QSize &requestedSize) const
{
QSize reqSize = requestedSize.isValid() ? requestedSize : QSize{48, 48};
@@ -55,18 +67,25 @@ QPixmap AssetsLibraryIconProvider::generateFontIcons(const QString &filePath, co
"Abc"}).pixmap(reqSize);
}
-QPixmap AssetsLibraryIconProvider::fetchPixmap(const QString &id, const QSize &requestedSize) const
+QPair<QPixmap, qint64> AssetsLibraryIconProvider::fetchPixmap(const QString &id, const QSize &requestedSize) const
{
Asset asset(id);
if (id == "browse") {
- return Utils::StyleHelper::dpiSpecificImageFile(":/AssetsLibrary/images/browse.png");
+ QString filePath = Utils::StyleHelper::dpiSpecificImageFile(":/AssetsLibrary/images/browse.png");
+ return {QPixmap{filePath}, 0};
} else if (asset.isFont()) {
- return generateFontIcons(id, requestedSize);
+ qint64 size = QFileInfo(id).size();
+ QPixmap pixmap = generateFontIcons(id, requestedSize);
+ return {pixmap, size};
} else if (asset.isImage()) {
- return Utils::StyleHelper::dpiSpecificImageFile(id);
- } else if (asset.isTexture3D()) {
- return HdrImage{id}.toPixmap();
+ QString filePath = Utils::StyleHelper::dpiSpecificImageFile(id);
+ qint64 size = QFileInfo(filePath).size();
+ return {QPixmap{filePath}, size};
+ } else if (asset.isHdrFile()) {
+ qint64 size = QFileInfo(id).size();
+ QPixmap pixmap = HdrImage{id}.toPixmap();
+ return {pixmap, size};
} else {
QString type;
if (asset.isShader())
@@ -81,9 +100,11 @@ QPixmap AssetsLibraryIconProvider::fetchPixmap(const QString &id, const QSize &r
QString pathTemplate = QString(":/AssetsLibrary/images/asset_%1%2.png").arg(type);
QString path = pathTemplate.arg('_' + QString::number(requestedSize.width()));
- return Utils::StyleHelper::dpiSpecificImageFile(QFileInfo::exists(path)
- ? path
- : pathTemplate.arg(""));
+ QString filePath = Utils::StyleHelper::dpiSpecificImageFile(QFileInfo::exists(path)
+ ? path
+ : pathTemplate.arg(""));
+ qint64 size = QFileInfo(filePath).size();
+ return {QPixmap{filePath}, size};
}
}
@@ -97,5 +118,23 @@ void AssetsLibraryIconProvider::invalidateThumbnail(const QString &id)
m_thumbnails.remove(id);
}
+QSize AssetsLibraryIconProvider::imageSize(const QString &id)
+{
+ static QSize invalidSize = {};
+ return m_thumbnails.contains(id) ? m_thumbnails[id].originalSize : invalidSize;
+}
+
+qint64 AssetsLibraryIconProvider::fileSize(const QString &id)
+{
+ return m_thumbnails.contains(id) ? m_thumbnails[id].fileSize : 0;
+}
+
+bool AssetsLibraryIconProvider::assetIsImage(const QString &id)
+{
+ return m_thumbnails.contains(id)
+ ? (m_thumbnails[id].assetType == Asset::Type::Image || Asset(id).isHdrFile())
+ : false;
+}
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h
index 61caba537a..b1a611d641 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.h
@@ -7,8 +7,18 @@
#include <QQuickImageProvider>
+#include "asset.h"
+
namespace QmlDesigner {
+struct Thumbnail
+{
+ QPixmap pixmap;
+ QSize originalSize;
+ Asset::Type assetType;
+ qint64 fileSize;
+};
+
class AssetsLibraryIconProvider : public QQuickImageProvider
{
public:
@@ -17,10 +27,14 @@ public:
QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
void clearCache();
void invalidateThumbnail(const QString &id);
+ QSize imageSize(const QString &id);
+ qint64 fileSize(const QString &id);
+ bool assetIsImage(const QString &id);
private:
QPixmap generateFontIcons(const QString &filePath, const QSize &requestedSize) const;
- QPixmap fetchPixmap(const QString &id, const QSize &requestedSize) const;
+ QPair<QPixmap, qint64> fetchPixmap(const QString &id, const QSize &requestedSize) const;
+ Thumbnail createThumbnail(const QString &id, const QSize &requestedSize);
SynchronousImageCache &m_fontImageCache;
@@ -29,7 +43,7 @@ private:
std::vector<QSize> iconSizes = {{128, 128}, // Drag
{96, 96}, // list @2x
{48, 48}}; // list
- QHash<QString, QPixmap> m_thumbnails;
+ QHash<QString, Thumbnail> m_thumbnails;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp
index 2a49012359..8a4a25c18d 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp
@@ -91,6 +91,11 @@ QString AssetsLibraryModel::currentProjectDirPath() const
return DocumentManager::currentProjectDirPath().toString().append('/');
}
+QString AssetsLibraryModel::contentDirPath() const
+{
+ return DocumentManager::currentResourcePath().toString().append('/');
+}
+
bool AssetsLibraryModel::requestDeleteFiles(const QStringList &filePaths)
{
bool askBeforeDelete = QmlDesignerPlugin::settings()
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h
index 9239a97668..ff9832ee3c 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h
@@ -40,6 +40,7 @@ public:
Q_INVOKABLE QList<QModelIndex> parentIndices(const QModelIndex &index) const;
Q_INVOKABLE bool indexIsValid(const QModelIndex &index) const;
Q_INVOKABLE QString currentProjectDirPath() const;
+ Q_INVOKABLE QString contentDirPath() const;
Q_INVOKABLE bool requestDeleteFiles(const QStringList &filePaths);
Q_INVOKABLE void deleteFiles(const QStringList &filePaths, bool dontAskAgain);
Q_INVOKABLE bool renameFolder(const QString &folderPath, const QString &newName);
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
index d19ede82d5..d2c208929c 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
@@ -165,6 +165,22 @@ void AssetsLibraryWidget::invalidateThumbnail(const QString &id)
m_assetsIconProvider->invalidateThumbnail(id);
}
+QSize AssetsLibraryWidget::imageSize(const QString &id)
+{
+ return m_assetsIconProvider->imageSize(id);
+}
+
+QString AssetsLibraryWidget::assetFileSize(const QString &id)
+{
+ qint64 fileSize = m_assetsIconProvider->fileSize(id);
+ return QLocale::system().formattedDataSize(fileSize, 2, QLocale::DataSizeTraditionalFormat);
+}
+
+bool AssetsLibraryWidget::assetIsImage(const QString &id)
+{
+ return m_assetsIconProvider->assetIsImage(id);
+}
+
QList<QToolButton *> AssetsLibraryWidget::createToolBarWidgets()
{
return {};
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
index 60e9b165ee..980cae69dc 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
@@ -74,6 +74,10 @@ public:
Q_INVOKABLE void openEffectMaker(const QString &filePath);
Q_INVOKABLE bool qtVersionIsAtLeast6_4() const;
Q_INVOKABLE void invalidateThumbnail(const QString &id);
+ Q_INVOKABLE QSize imageSize(const QString &id);
+ Q_INVOKABLE QString assetFileSize(const QString &id);
+ Q_INVOKABLE bool assetIsImage(const QString &id);
+
Q_INVOKABLE void addTextures(const QStringList &filePaths);
Q_INVOKABLE void addLightProbe(const QString &filePaths);
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 378a51d970..535703ac5f 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -6,6 +6,7 @@
#include "anchoraction.h"
#include "changestyleaction.h"
#include "designeractionmanagerview.h"
+#include "designericons.h"
#include "designermcumanager.h"
#include "formatoperation.h"
#include "modelnodecontextmenu_helper.h"
@@ -286,14 +287,19 @@ QHash<QString, QStringList> DesignerActionManager::handleExternalAssetsDrop(cons
return addedCategoryFiles;
}
+QIcon DesignerActionManager::contextIcon(int contextId) const
+{
+ return m_designerIcons->icon(DesignerIcons::IconId(contextId), DesignerIcons::ContextMenuArea);
+}
+
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
{
public:
- VisiblityModelNodeAction(const QByteArray &id, const QString &description, const QByteArray &category, const QKeySequence &key, int priority,
+ VisiblityModelNodeAction(const QByteArray &id, const QString &description, const QIcon &icon, const QByteArray &category, const QKeySequence &key, int priority,
SelectionContextOperation action,
SelectionContextPredicate enabled = &SelectionContextFunctors::always,
SelectionContextPredicate visibility = &SelectionContextFunctors::always) :
- ModelNodeContextMenuAction(id, description, {}, category, key, priority, action, enabled, visibility)
+ ModelNodeContextMenuAction(id, description, icon, category, key, priority, action, enabled, visibility)
{}
void updateContext() override
@@ -376,9 +382,9 @@ public:
class SelectionModelNodeAction : public ActionGroup
{
public:
- SelectionModelNodeAction(const QString &displayName, const QByteArray &menuId, int priority) :
- ActionGroup(displayName, menuId, priority,
- &SelectionContextFunctors::always, &SelectionContextFunctors::selectionEnabled)
+ SelectionModelNodeAction(const QString &displayName, const QByteArray &menuId, const QIcon &icon, int priority) :
+ ActionGroup(displayName, menuId, icon, priority,
+ &SelectionContextFunctors::always, &SelectionContextFunctors::selectionEnabled)
{}
@@ -599,9 +605,10 @@ void removeSignal(SignalHandlerProperty signalHandler)
class ConnectionsModelNodeActionGroup : public ActionGroup
{
public:
- ConnectionsModelNodeActionGroup(const QString &displayName, const QByteArray &menuId, int priority)
+ ConnectionsModelNodeActionGroup(const QString &displayName, const QByteArray &menuId, const QIcon &icon, int priority)
: ActionGroup(displayName,
menuId,
+ icon,
priority,
&SelectionContextFunctors::always,
&SelectionContextFunctors::selectionEnabled)
@@ -968,8 +975,8 @@ bool isFlowTargetOrTransition(const SelectionContext &context)
class FlowActionConnectAction : public ActionGroup
{
public:
- FlowActionConnectAction(const QString &displayName, const QByteArray &menuId, int priority) :
- ActionGroup(displayName, menuId, priority,
+ FlowActionConnectAction(const QString &displayName, const QByteArray &menuId, const QIcon &icon, int priority) :
+ ActionGroup(displayName, menuId, icon, priority,
&isFlowActionItemItem, &flowOptionVisible)
{}
@@ -1341,16 +1348,19 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new SelectionModelNodeAction(
selectionCategoryDisplayName,
selectionCategory,
+ contextIcon(DesignerIcons::SelecionIcon),
Priorities::SelectionCategory));
addDesignerAction(new ConnectionsModelNodeActionGroup(
connectionsCategoryDisplayName,
connectionsCategory,
+ contextIcon(DesignerIcons::ConnectionsIcon),
Priorities::ConnectionsCategory));
addDesignerAction(new ActionGroup(
arrangeCategoryDisplayName,
arrangeCategory,
+ contextIcon(DesignerIcons::ArrangeIcon),
Priorities::ArrangeCategory,
&selectionNotEmpty));
@@ -1408,7 +1418,11 @@ void DesignerActionManager::createDefaultDesignerActions()
&reverse,
&multiSelectionAndHasSameParent));
- addDesignerAction(new ActionGroup(editCategoryDisplayName, editCategory, Priorities::EditCategory, &selectionNotEmpty));
+ addDesignerAction(new ActionGroup(editCategoryDisplayName,
+ editCategory,
+ contextIcon(DesignerIcons::EditIcon),
+ Priorities::EditCategory,
+ &selectionNotEmpty));
addDesignerAction(new SeperatorDesignerAction(editCategory, 30));
@@ -1491,6 +1505,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new VisiblityModelNodeAction(
visiblityCommandId,
visibilityDisplayName,
+ contextIcon(DesignerIcons::VisibilityIcon),
rootCategory,
QKeySequence("Ctrl+g"),
Priorities::Visibility,
@@ -1499,6 +1514,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ActionGroup(anchorsCategoryDisplayName,
anchorsCategory,
+ contextIcon(DesignerIcons::AnchorsIcon),
Priorities::AnchorsCategory,
&anchorsMenuEnabled));
@@ -1596,18 +1612,21 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ActionGroup(
positionerCategoryDisplayName,
positionerCategory,
+ contextIcon(DesignerIcons::PositionsersIcon),
Priorities::PositionCategory,
&positionOptionVisible));
addDesignerAction(new ActionGroup(
layoutCategoryDisplayName,
layoutCategory,
+ contextIcon(DesignerIcons::LayoutsIcon),
Priorities::LayoutCategory,
&layoutOptionVisible));
addDesignerAction(new ActionGroup(
snappingCategoryDisplayName,
snappingCategory,
+ contextIcon(DesignerIcons::SnappingIcon),
Priorities::SnappingCategory,
&selectionEnabled,
&selectionEnabled));
@@ -1615,12 +1634,14 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ActionGroup(
groupCategoryDisplayName,
groupCategory,
+ contextIcon(DesignerIcons::GroupSelectionIcon),
Priorities::Group,
&studioComponentsAvailableAndSelectionCanBeLayouted));
addDesignerAction(new ActionGroup(
flowCategoryDisplayName,
flowCategory,
+ {},
Priorities::FlowCategory,
&isFlowTargetOrTransition,
&flowOptionVisible));
@@ -1629,6 +1650,7 @@ void DesignerActionManager::createDefaultDesignerActions()
auto effectMenu = new ActionGroup(
flowEffectCategoryDisplayName,
flowEffectCategory,
+ {},
Priorities::FlowCategory,
&isFlowTransitionItem,
&flowOptionVisible);
@@ -1660,9 +1682,10 @@ void DesignerActionManager::createDefaultDesignerActions()
&flowOptionVisible));
addDesignerAction(new FlowActionConnectAction(
- flowConnectionCategoryDisplayName,
- flowConnectionCategory,
- Priorities::FlowCategory));
+ flowConnectionCategoryDisplayName,
+ flowConnectionCategory,
+ {},
+ Priorities::FlowCategory));
const QList<TypeName> transitionTypes = {"FlowFadeEffect",
@@ -1688,6 +1711,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ActionGroup(
stackedContainerCategoryDisplayName,
stackedContainerCategory,
+ {},
Priorities::StackedContainerCategory,
&isStackedContainer));
@@ -1888,7 +1912,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ModelNodeContextMenuAction(
goIntoComponentCommandId,
enterComponentDisplayName,
- {},
+ contextIcon(DesignerIcons::EnterComponentIcon),
rootCategory,
QKeySequence(Qt::Key_F2),
Priorities::ComponentActions + 2,
@@ -1898,7 +1922,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ModelNodeContextMenuAction(
editAnnotationsCommandId,
editAnnotationsDisplayName,
- {},
+ contextIcon(DesignerIcons::AnnotationIcon),
rootCategory,
QKeySequence(),
Priorities::EditAnnotations,
@@ -1907,15 +1931,15 @@ void DesignerActionManager::createDefaultDesignerActions()
&singleSelection));
addDesignerAction(new ModelNodeContextMenuAction(
- addMouseAreaFillCommandId,
- addMouseAreaFillDisplayName,
- {},
- rootCategory,
- QKeySequence(),
- Priorities::AddMouseArea,
- &addMouseAreaFill,
- &addMouseAreaFillCheck,
- &singleSelection));
+ addMouseAreaFillCommandId,
+ addMouseAreaFillDisplayName,
+ contextIcon(DesignerIcons::AddMouseAreaIcon),
+ rootCategory,
+ QKeySequence(),
+ Priorities::AddMouseArea,
+ &addMouseAreaFill,
+ &addMouseAreaFillCheck,
+ &singleSelection));
const bool standaloneMode = QmlProjectManager::QmlProject::isQtDesignStudio();
@@ -1943,7 +1967,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ModelNodeContextMenuAction(
makeComponentCommandId,
makeComponentDisplayName,
- {},
+ contextIcon(DesignerIcons::MakeComponentIcon),
rootCategory,
QKeySequence(),
Priorities::ComponentActions + 1,
@@ -1954,7 +1978,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ModelNodeContextMenuAction(
editMaterialCommandId,
editMaterialDisplayName,
- {},
+ contextIcon(DesignerIcons::EditIcon),
rootCategory,
QKeySequence(),
44,
@@ -1974,6 +1998,7 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ActionGroup(
"",
genericToolBarCategory,
+ {},
Priorities::GenericToolBar));
addDesignerAction(new ChangeStyleAction());
@@ -2114,6 +2139,7 @@ DesignerActionManager::DesignerActionManager(DesignerActionManagerView *designer
: m_designerActionManagerView(designerActionManagerView)
, m_externalDependencies(externalDependencies)
{
+ setupIcons();
}
DesignerActionManager::~DesignerActionManager() = default;
@@ -2145,6 +2171,20 @@ void DesignerActionManager::addCustomTransitionEffectAction()
&isFlowTransitionItem));
}
+void DesignerActionManager::setupIcons()
+{
+ m_designerIcons.reset(new DesignerIcons("qtds_propertyIconFont.ttf", designerIconResourcesPath()));
+}
+
+QString DesignerActionManager::designerIconResourcesPath() const
+{
+#ifdef SHARE_QML_PATH
+ if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
+ return QLatin1String(SHARE_QML_PATH) + "/designericons.json";
+#endif
+ return Core::ICore::resourcePath("qmldesigner/designericons.json").toString();
+}
+
DesignerActionToolBar::DesignerActionToolBar(QWidget *parentWidget) : Utils::StyledBar(parentWidget),
m_toolBar(new QToolBar("ActionToolBar", this))
{
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
index 10b9eb6ae1..569c495f88 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h
@@ -23,6 +23,7 @@ QT_END_NAMESPACE
namespace QmlDesigner {
class DesignerActionManagerView;
+class DesignerIcons;
using AddResourceOperation = std::function<AddFilesResult(const QStringList &, const QString &, bool)>;
using ModelNodePreviewImageOperation = std::function<QVariant(const ModelNode &)>;
@@ -118,16 +119,20 @@ public:
ModelNodePreviewImageOperation modelNodePreviewOperation(const ModelNode &node) const;
bool externalDragHasSupportedAssets(const QMimeData *data) const;
QHash<QString, QStringList> handleExternalAssetsDrop(const QMimeData *data) const;
+ QIcon contextIcon(int contextId) const;
private:
void addTransitionEffectAction(const TypeName &typeName);
void addCustomTransitionEffectAction();
+ void setupIcons();
+ QString designerIconResourcesPath() const;
QList<QSharedPointer<ActionInterface> > m_designerActions;
DesignerActionManagerView *m_designerActionManagerView;
QList<AddResourceHandler> m_addResourceHandler;
QList<ModelNodePreviewImageHandler> m_modelNodePreviewImageHandlers;
ExternalDependenciesInterface &m_externalDependencies;
+ QScopedPointer<DesignerIcons> m_designerIcons;
};
} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/designericons.cpp b/src/plugins/qmldesigner/components/componentcore/designericons.cpp
new file mode 100644
index 0000000000..ce604d6d8c
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/designericons.cpp
@@ -0,0 +1,418 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "designericons.h"
+
+#include <invalidargumentexception.h>
+
+#include <QCache>
+#include <QFile>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QMetaEnum>
+#include <QRegularExpression>
+
+using namespace QmlDesigner;
+namespace { // Blank namespace
+
+template <typename EType>
+struct DesignerIconEnums
+{
+ typedef EType EnumType;
+ static QString toString(const EnumType &enumValue);
+ static EnumType value(const QString &keyStr, bool *ok = nullptr);
+
+ static const QMetaEnum metaEnum;
+ static const QString keyName;
+};
+
+template <typename EType>
+struct DesignerEnumConfidentType
+{
+ typedef EType EnumType;
+};
+
+template <>
+struct DesignerEnumConfidentType<QIcon::Mode>
+{
+ typedef DesignerIcons::Mode EnumType;
+};
+
+template <>
+struct DesignerEnumConfidentType<QIcon::State>
+{
+ typedef DesignerIcons::State EnumType;
+};
+
+template <typename T>
+QString getEnumName() {
+ QMetaEnum metaEnum = QMetaEnum::fromType<T>();
+ QString enumName = QString::fromLatin1(metaEnum.enumName());
+ if (enumName.size() && enumName.at(0).isUpper())
+ enumName.replace(0, 1, enumName.at(0).toLower());
+ return enumName;
+};
+
+template <>
+QString getEnumName<Theme::Icon>() {
+ return QLatin1String("iconName");
+};
+
+template <typename EType>
+const QMetaEnum DesignerIconEnums<EType>::metaEnum =
+ QMetaEnum::fromType<typename DesignerEnumConfidentType<EType>::EnumType>();
+
+template <typename EType>
+const QString DesignerIconEnums<EType>::keyName =
+ getEnumName<typename DesignerEnumConfidentType<EType>::EnumType>();
+
+template <typename EType>
+QString DesignerIconEnums<EType>::toString(const EType &enumValue)
+{
+ return QString::fromLatin1(metaEnum.valueToKey(enumValue));
+}
+
+template <typename EType>
+EType DesignerIconEnums<EType>::value(const QString &keyStr, bool *ok)
+{
+ return static_cast<EType>(metaEnum.keyToValue(keyStr.toLatin1(), ok));
+}
+
+Q_GLOBAL_STATIC(QStringList, _iconFontMandatoryKeys);
+
+const QStringList & iconFontMandatoryKeys()
+{
+ if (_iconFontMandatoryKeys->isEmpty()) {
+ *_iconFontMandatoryKeys
+ << DesignerIconEnums<Theme::Icon>::keyName
+ << DesignerIconEnums<Theme::Color>::keyName
+ << DesignerIconEnums<QIcon::Mode>::keyName
+ << DesignerIconEnums<QIcon::State>::keyName
+ << "size";
+ }
+ return *_iconFontMandatoryKeys;
+}
+
+QJsonObject mergeJsons(const QJsonObject &prior, const QJsonObject &joiner)
+{
+ QJsonObject object = prior;
+ const QStringList joinerKeys = joiner.keys();
+ for (const QString &joinerKey : joinerKeys) {
+ if (!object.contains(joinerKey)) {
+ object.insert(joinerKey, joiner.value(joinerKey));
+ } else {
+ QJsonValue ov = object.value(joinerKey);
+ QJsonValue jv = joiner.value(joinerKey);
+ if (ov.isObject() && jv.isObject()) {
+ QJsonObject mg = mergeJsons(ov.toObject(), jv.toObject());
+ object.insert(joinerKey, mg);
+ }
+ }
+ }
+ return object;
+}
+
+inline QString toJsonSize(const QSize &size)
+{
+ return QString::fromLatin1("%1x%2").arg(size.width()).arg(size.height());
+}
+
+template <typename EnumType>
+void pushSimpleEnumValue(QJsonObject &object, const EnumType &enumVal)
+{
+ const QString &enumKey = DesignerIconEnums<EnumType>::keyName;
+ QString enumValue = DesignerIconEnums<EnumType>::toString(enumVal);
+ object.insert(enumKey, enumValue);
+}
+
+template <typename T>
+T jsonSafeValue(const QJsonObject &jsonObject, const QString &symbolName,
+ std::function<bool (const T&)> validityCheck = [](const T&) -> bool {return true;})
+{
+ if (!jsonObject.contains(symbolName))
+ throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, symbolName.toLatin1());
+
+ QVariant symbolVar = jsonObject.value(symbolName);
+ T extractedVal = symbolVar.value<T>();
+ if (!validityCheck(extractedVal))
+ throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, symbolName.toLatin1());
+
+ return extractedVal;
+}
+
+QSize jsonSafeSize(const QJsonObject &jsonObject, const QString &symbolName)
+{
+ QString extractedVal = jsonSafeValue<QString>(jsonObject, symbolName);
+ QStringList dims = extractedVal.split("x");
+ if (dims.size() == 2) {
+ bool wOk;
+ bool hOk;
+ int cWidth = dims.first().toInt(&wOk);
+ int cHeight = dims.last().toInt(&hOk);
+ if (wOk && hOk)
+ return {cWidth, cHeight};
+ }
+ throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, symbolName.toLatin1());
+ return {};
+}
+
+template <typename T>
+T jsonSafeMetaEnum(const QJsonObject &jsonObject, const QString &symbolName = DesignerIconEnums<T>::keyName)
+{
+ QString extractedVal = jsonSafeValue<QString>(jsonObject, symbolName);
+ bool ok;
+ T enumIndex = static_cast<T> (DesignerIconEnums<T>::value(extractedVal, &ok));
+ if (ok)
+ return enumIndex;
+
+ throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, symbolName.toLatin1());
+ return {};
+}
+
+template <typename T>
+struct JsonMap
+{};
+
+template <>
+struct JsonMap<IconFontHelper>
+{
+ static IconFontHelper value(const QJsonObject &jsonObject, const QJsonObject &telescopingMap)
+ {
+ QJsonObject fontHelperJson = mergeJsons(jsonObject, telescopingMap);
+ return IconFontHelper::fromJson(fontHelperJson);
+ }
+
+ static QJsonObject json(const IconFontHelper &iconFontHelper)
+ {
+ QJsonObject object;
+ pushSimpleEnumValue(object, iconFontHelper.themeIcon());
+ pushSimpleEnumValue(object, iconFontHelper.themeColor());
+ object.insert("size", toJsonSize(iconFontHelper.size()));
+ return object;
+ }
+};
+
+template <typename Key, typename Value>
+struct JsonMap<QMap<Key, Value>>
+{
+ typedef QMap<Key, Value> MapType;
+ static MapType value(const QJsonObject &mapObject, const QJsonObject &telescopingMap)
+ {
+ typedef typename MapType::key_type KeyType;
+ typedef typename MapType::mapped_type ValueType;
+
+ QMap<KeyType, ValueType> output;
+ QJsonObject curObject = mergeJsons(mapObject, telescopingMap);
+ const QStringList keyList = curObject.keys();
+ QStringList validKeys;
+ QString keyTypeStr = DesignerIconEnums<KeyType>::keyName;
+ QJsonObject nextTelescopingMap = telescopingMap;
+
+ for (const QString &jsonKey : keyList) {
+ bool keyAvailable = false;
+ DesignerIconEnums<KeyType>::value(jsonKey, &keyAvailable);
+ if (keyAvailable)
+ validKeys.append(jsonKey);
+ else
+ nextTelescopingMap.insert(jsonKey, curObject.value(jsonKey));
+ }
+
+ for (const QString &jsonKey : validKeys) {
+ bool keyAvailable = false;
+ const KeyType key = DesignerIconEnums<KeyType>::value(jsonKey, &keyAvailable);
+ QJsonValue jsonValue = curObject.value(jsonKey);
+
+ nextTelescopingMap.insert(keyTypeStr, jsonKey);
+ if (!jsonValue.isObject()) {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Value of the" << jsonKey << "should be a json object.";
+ continue;
+ }
+ output.insert(key, JsonMap<ValueType>::value(jsonValue.toObject(), nextTelescopingMap));
+ }
+
+ return output;
+ }
+
+ static QJsonObject json(const QMap<Key, Value> &map)
+ {
+ QJsonObject output;
+ for (const auto &[key, val] : map.asKeyValueRange())
+ output[DesignerIconEnums<Key>::toString(key)] = JsonMap<Value>::json(val);
+
+ return output;
+ }
+};
+
+} // End of blank namespace
+
+class QmlDesigner::DesignerIconsPrivate
+{
+public:
+ DesignerIconsPrivate(const QString &fontName)
+ : mFontName(fontName) {}
+
+ QString mFontName;
+ DesignerIcons::IconsMap icons;
+ static QCache<QString, DesignerIcons::IconsMap> cache;
+};
+
+QCache<QString, DesignerIcons::IconsMap> DesignerIconsPrivate::cache(100);
+
+IconFontHelper::IconFontHelper(Theme::Icon themeIcon, Theme::Color color, const QSize &size, QIcon::Mode mode, QIcon::State state)
+ : Super(Theme::getIconUnicode(themeIcon),
+ Theme::getColor(color),
+ size,
+ mode, state)
+ , mThemeIcon(themeIcon)
+ , mThemeColor(color)
+{}
+
+IconFontHelper IconFontHelper::fromJson(const QJsonObject &jsonObject)
+{
+ try {
+ Theme::Icon iconName = jsonSafeMetaEnum<Theme::Icon>(jsonObject);
+ Theme::Color iconColor = jsonSafeMetaEnum<Theme::Color>(jsonObject);
+ QSize iconSize = jsonSafeSize(jsonObject, "size");
+ QIcon::Mode iconMode = jsonSafeMetaEnum<QIcon::Mode>(jsonObject);
+ QIcon::State iconState = jsonSafeMetaEnum<QIcon::State>(jsonObject);
+ return IconFontHelper(iconName, iconColor, iconSize, iconMode, iconState);
+ } catch (const Exception &exception) {
+ exception.showException("Faild to load IconFontHelper");
+ return {};
+ }
+}
+
+QJsonObject IconFontHelper::toJson() const
+{
+ QJsonObject jsonObject;
+ pushSimpleEnumValue(jsonObject, themeIcon());
+ pushSimpleEnumValue(jsonObject, themeColor());
+ pushSimpleEnumValue(jsonObject, mode());
+ pushSimpleEnumValue(jsonObject, state());
+ jsonObject.insert("size", toJsonSize(size()));
+ return jsonObject;
+}
+
+Theme::Icon IconFontHelper::themeIcon() const
+{
+ return mThemeIcon;
+}
+
+Theme::Color IconFontHelper::themeColor() const
+{
+ return mThemeColor;
+}
+
+IconFontHelper::IconFontHelper()
+ : IconFontHelper({}, {}, {}, {}, {}) {}
+
+DesignerIcons::DesignerIcons(const QString &fontName, const QString &iconDatabase)
+ : d(new DesignerIconsPrivate(fontName))
+{
+ if (iconDatabase.size())
+ loadIconSettings(iconDatabase);
+}
+
+DesignerIcons::~DesignerIcons()
+{
+ delete d;
+}
+
+QIcon DesignerIcons::icon(IconId icon, Area area) const
+{
+ return Utils::StyleHelper::getIconFromIconFont(d->mFontName, helperList(icon, area));
+}
+
+void DesignerIcons::loadIconSettings(const QString &fileName)
+{
+ if (d->cache.contains(fileName)) {
+ d->icons = *d->cache.object(fileName);
+ return;
+ }
+
+ QFile designerIconFile(fileName);
+
+ if (!designerIconFile.open(QFile::ReadOnly)) {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Can not open file:" << fileName << designerIconFile.errorString();
+ return;
+ }
+
+ if (designerIconFile.size() > 100e3) {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Large File:" << fileName;
+ return;
+ }
+
+ QJsonParseError parseError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(designerIconFile.readAll(), &parseError);
+
+ if (parseError.error != QJsonParseError::NoError) {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Json Parse Error - " << parseError.errorString() << "---\t File: " << fileName;
+ return;
+ }
+
+ if (!jsonDoc.isObject()) {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Invalid Json Array in file: " << fileName;
+ return;
+ }
+
+ clearAll();
+ d->icons = JsonMap<IconsMap>::value(jsonDoc.object(), {});
+ d->cache.insert(fileName, new IconsMap(d->icons), 1);
+}
+
+void DesignerIcons::exportSettings(const QString &fileName) const
+{
+ QFile outFile(fileName);
+ if (!outFile.open(QFile::WriteOnly)) {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Can not open file for writing:" << fileName;
+ return;
+ }
+
+ QJsonDocument jsonDocument;
+ jsonDocument.setObject(JsonMap<IconsMap>::json(d->icons));
+
+ outFile.write(jsonDocument.toJson());
+ outFile.close();
+}
+
+void DesignerIcons::clearAll()
+{
+ d->icons.clear();
+}
+
+void DesignerIcons::addIcon(const IconId &iconId, const Area &area, const IconFontHelper &fontHelper)
+{
+ AreaMap &areaMap = d->icons[iconId];
+ IconMap &iconMap = areaMap[area];
+ ModeMap &modeMap = iconMap[static_cast<State>(fontHelper.state())];
+ modeMap.insert(static_cast<Mode>(fontHelper.mode()), fontHelper);
+}
+
+void DesignerIcons::addIcon(IconId iconId,
+ Area area,
+ QIcon::Mode mode,
+ QIcon::State state,
+ Theme::Icon themeIcon,
+ Theme::Color color,
+ const QSize &size)
+{
+ addIcon(iconId, area, {themeIcon, color, size, mode, state});
+}
+
+void DesignerIcons::addIcon(IconId iconId, Area area, Theme::Icon themeIcon, Theme::Color color, const QSize &size)
+{
+ addIcon(iconId, area, {themeIcon, color, size});
+}
+
+QList<Utils::StyleHelper::IconFontHelper> DesignerIcons::helperList(const IconId &iconId,
+ const Area &area) const
+{
+ QList<Utils::StyleHelper::IconFontHelper> helperList;
+ const IconMap &iconMap = d->icons.value(iconId).value(area);
+ for (const ModeMap &modMap : iconMap) {
+ for (const IconFontHelper &iconFontHelper : modMap)
+ helperList.append(iconFontHelper);
+ }
+ return helperList;
+}
diff --git a/src/plugins/qmldesigner/components/componentcore/designericons.h b/src/plugins/qmldesigner/components/componentcore/designericons.h
new file mode 100644
index 0000000000..342016b77c
--- /dev/null
+++ b/src/plugins/qmldesigner/components/componentcore/designericons.h
@@ -0,0 +1,133 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "theme.h"
+
+#include <utils/stylehelper.h>
+
+#include <QIcon>
+
+namespace QmlDesigner {
+
+class DesignerIconsPrivate;
+
+class IconFontHelper : public Utils::StyleHelper::IconFontHelper
+{
+ typedef Utils::StyleHelper::IconFontHelper Super;
+
+public:
+ IconFontHelper(Theme::Icon themeIcon,
+ Theme::Color color,
+ const QSize &size,
+ QIcon::Mode mode = QIcon::Normal,
+ QIcon::State state = QIcon::Off);
+
+ static IconFontHelper fromJson(const QJsonObject &jsonObject);
+ QJsonObject toJson() const;
+ Theme::Icon themeIcon() const;
+ Theme::Color themeColor() const;
+
+private:
+ IconFontHelper();
+
+ Theme::Icon mThemeIcon;
+ Theme::Color mThemeColor;
+};
+
+class DesignerIcons
+{
+ Q_GADGET
+ friend DesignerIconsPrivate;
+
+public:
+ enum IconId {
+ AddMouseAreaIcon,
+ AlignBottomIcon,
+ AlignLeftIcon,
+ AlignRightIcon,
+ AlignTopIcon,
+ AnchorsIcon,
+ AnnotationIcon,
+ ArrangeIcon,
+ ConnectionsIcon,
+ EditIcon,
+ EnterComponentIcon,
+ EventListIcon,
+ GroupSelectionIcon,
+ LayoutsIcon,
+ MakeComponentIcon,
+ MergeWithTemplateIcon,
+ PositionsersIcon,
+ SelecionIcon,
+ SnappingIcon,
+ TimelineIcon,
+ ShowBoundsIcon,
+ VisibilityIcon
+ };
+ Q_ENUM(IconId)
+
+ enum Area {
+ TopToolbarArea,
+ ContextMenuArea
+ };
+ Q_ENUM(Area)
+
+ enum Mode {
+ Normal = QIcon::Normal,
+ Disabled = QIcon::Disabled,
+ Hovered = QIcon::Active,
+ Selected = QIcon::Selected
+ };
+
+ Q_ENUM(Mode)
+
+ enum State {
+ Off = QIcon::Off,
+ On = QIcon::On
+ };
+ Q_ENUM(State)
+
+ typedef QMap<Mode, IconFontHelper> ModeMap;
+ typedef QMap<State, ModeMap> IconMap;
+ typedef QMap<Area, IconMap> AreaMap;
+ typedef QMap<IconId, AreaMap> IconsMap;
+
+ explicit DesignerIcons(const QString &fontName,
+ const QString &iconDatabase = QString());
+
+ ~DesignerIcons();
+
+ QIcon icon(IconId icon, Area area) const;
+
+ void loadIconSettings(const QString &fileName);
+ void exportSettings(const QString &fileName) const;
+
+ void clearAll();
+ void addIcon(const IconId &iconId,
+ const Area &area,
+ const IconFontHelper &fontHelper);
+
+ void addIcon(IconId iconId,
+ Area area,
+ QIcon::Mode mode,
+ QIcon::State state,
+ Theme::Icon themeIcon,
+ Theme::Color color,
+ const QSize &size);
+
+ void addIcon(IconId iconId,
+ Area area,
+ Theme::Icon themeIcon,
+ Theme::Color color,
+ const QSize &size);
+
+private:
+ QList<Utils::StyleHelper::IconFontHelper> helperList(const IconId &iconId,
+ const Area &area) const;
+
+ DesignerIconsPrivate *d = nullptr;
+};
+
+}
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
index 31a996b5be..eac545b2ef 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu.cpp
@@ -60,7 +60,7 @@ void populateMenu(QSet<ActionInterface* > &actionInterfaces,
|| actionInterface->type() == ActionInterface::FormEditorAction) {
QAction* action = actionInterface->action();
actionInterface->currentContextChanged(selectionContext);
- action->setIconVisibleInMenu(false);
+ action->setIconVisibleInMenu(true);
menu->addAction(action);
}
}
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h
index ed1de892f9..50f5e83bd8 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h
@@ -141,7 +141,7 @@ public:
class ActionGroup : public AbstractActionGroup
{
public:
- ActionGroup(const QString &displayName, const QByteArray &menuId, int priority,
+ ActionGroup(const QString &displayName, const QByteArray &menuId, const QIcon &icon, int priority,
SelectionContextPredicate enabled = &SelectionContextFunctors::always,
SelectionContextPredicate visibility = &SelectionContextFunctors::always) :
AbstractActionGroup(displayName),
@@ -150,6 +150,7 @@ public:
m_enabled(enabled),
m_visibility(visibility)
{
+ menu()->setIcon(icon);
}
bool isVisible(const SelectionContext &m_selectionState) const override { return m_visibility(m_selectionState); }
diff --git a/src/plugins/qmldesigner/components/componentcore/theme.h b/src/plugins/qmldesigner/components/componentcore/theme.h
index 85163b985a..f6bc8cc0bf 100644
--- a/src/plugins/qmldesigner/components/componentcore/theme.h
+++ b/src/plugins/qmldesigner/components/componentcore/theme.h
@@ -103,6 +103,7 @@ public:
gridView,
idAliasOff,
idAliasOn,
+ imported,
infinity,
keyframe,
linkTriangle,
@@ -131,6 +132,24 @@ public:
redo,
rotationFill,
rotationOutline,
+ s_anchors,
+ s_annotations,
+ s_arrange,
+ s_boundingBox,
+ s_component,
+ s_connections,
+ s_edit,
+ s_enterComponent,
+ s_eventList,
+ s_group,
+ s_layouts,
+ s_merging,
+ s_mouseArea,
+ s_positioners,
+ s_selection,
+ s_snapping,
+ s_timeline,
+ s_visibility,
search,
sectionToggle,
splitColumns,
@@ -148,6 +167,14 @@ public:
textFullJustification,
textNumberedList,
tickIcon,
+ topToolbar_annotations,
+ topToolbar_closeFile,
+ topToolbar_designMode,
+ topToolbar_enterComponent,
+ topToolbar_home,
+ topToolbar_makeComponent,
+ topToolbar_navFile,
+ topToolbar_runProject,
translationCreateFiles,
translationCreateReport,
translationExport,
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp
index 20bb6b3419..cb03b5906c 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp
@@ -5,9 +5,6 @@
#include "edit3dview.h"
#include "edit3dwidget.h"
-#include "nodehints.h"
-#include "qmlvisualnode.h"
-
#include <bindingproperty.h>
#include <nodemetainfo.h>
#include <nodelistproperty.h>
@@ -143,41 +140,6 @@ void Edit3DCanvas::resizeEvent(QResizeEvent *e)
m_parent->view()->edit3DViewResized(e->size());
}
-void Edit3DCanvas::dragEnterEvent(QDragEnterEvent *e)
-{
- // Block all drags if scene root node is locked
- ModelNode node;
- if (m_parent->view()->hasModelNodeForInternalId(m_activeScene))
- node = m_parent->view()->modelNodeForInternalId(m_activeScene);
-
- // Allow drop when there is no valid active scene, as the drop goes under the root node of
- // the document in that case.
- if (!ModelNode::isThisOrAncestorLocked(node)) {
- QByteArray data = e->mimeData()->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO);
- if (!data.isEmpty()) {
- QDataStream stream(data);
- stream >> m_itemLibraryEntry;
- if (NodeHints::fromItemLibraryEntry(m_itemLibraryEntry).canBeDroppedInView3D())
- e->accept();
- }
- }
-}
-
-void Edit3DCanvas::dropEvent(QDropEvent *e)
-{
- m_parent->view()->executeInTransaction(__FUNCTION__, [&] {
- auto modelNode = QmlVisualNode::createQml3DNode(m_parent->view(), m_itemLibraryEntry, m_activeScene).modelNode();
- QTC_ASSERT(modelNode.isValid(), return);
-
- e->accept();
- m_parent->view()->setSelectedModelNode(modelNode);
-
- // if added node is a Model, assign it a material
- if (modelNode.metaInfo().isQtQuick3DModel())
- m_parent->view()->assignMaterialTo3dModel(modelNode);
- });
-}
-
void Edit3DCanvas::focusOutEvent(QFocusEvent *focusEvent)
{
QmlDesignerPlugin::emitUsageStatisticsTime(Constants::EVENT_3DEDITOR_TIME,
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h
index a755fbff98..d575e68c13 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h
@@ -2,8 +2,6 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
-#include "itemlibraryinfo.h"
-
#include <QtWidgets/qwidget.h>
#include <QtGui/qimage.h>
#include <QtGui/qevent.h>
@@ -38,8 +36,6 @@ protected:
void keyReleaseEvent(QKeyEvent *e) override;
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
- void dragEnterEvent(QDragEnterEvent *e) override;
- void dropEvent(QDropEvent *e) override;
void focusOutEvent(QFocusEvent *focusEvent) override;
void focusInEvent(QFocusEvent *focusEvent) override;
@@ -49,7 +45,6 @@ private:
QPointer<Edit3DWidget> m_parent;
QImage m_image;
qint32 m_activeScene = -1;
- ItemLibraryEntry m_itemLibraryEntry;
QElapsedTimer m_usageTimer;
qreal m_opacity = 1.0;
QWidget *m_busyIndicator = nullptr;
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
index 7a3f7cd3cd..afd4558f5c 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
@@ -16,6 +16,7 @@
#include "qmldesignerconstants.h"
#include "qmldesignericons.h"
#include "qmldesignerplugin.h"
+#include "qmlvisualnode.h"
#include "seekerslider.h"
#include <coreplugin/icore.h>
@@ -304,6 +305,16 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos
if (modelNode.isValid() && !modelNode.isSelected())
setSelectedModelNode(modelNode);
m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode, pos3d);
+ } else if (m_nodeAtPosReqType == NodeAtPosReqType::ComponentDrop) {
+ ModelNode createdNode;
+ executeInTransaction(__FUNCTION__, [&] {
+ createdNode = QmlVisualNode::createQml3DNode(
+ this, m_droppedEntry, edit3DWidget()->canvas()->activeScene(), pos3d).modelNode();
+ if (createdNode.metaInfo().isQtQuick3DModel())
+ assignMaterialTo3dModel(createdNode);
+ });
+ if (createdNode.isValid())
+ setSelectedModelNode(createdNode);
} else if (m_nodeAtPosReqType == NodeAtPosReqType::MaterialDrop) {
bool isModel = modelNode.metaInfo().isQtQuick3DModel();
if (m_droppedModelNode.isValid() && modelNode.isValid() && isModel) {
@@ -895,4 +906,11 @@ void Edit3DView::dropTexture(const ModelNode &textureNode, const QPointF &pos)
emitView3DAction(View3DActionType::GetNodeAtPos, pos);
}
+void Edit3DView::dropComponent(const ItemLibraryEntry &entry, const QPointF &pos)
+{
+ m_nodeAtPosReqType = NodeAtPosReqType::ComponentDrop;
+ m_droppedEntry = entry;
+ emitView3DAction(View3DActionType::GetNodeAtPos, pos);
+}
+
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h
index 236fd10aa6..03dc13b4ac 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
+#include "itemlibraryinfo.h"
#include <qmldesignercomponents_global.h>
#include <abstractview.h>
@@ -65,6 +66,7 @@ public:
void dropMaterial(const ModelNode &matNode, const QPointF &pos);
void dropBundleMaterial(const QPointF &pos);
void dropTexture(const ModelNode &textureNode, const QPointF &pos);
+ void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos);
private slots:
void onEntriesChanged();
@@ -72,6 +74,7 @@ private slots:
private:
enum class NodeAtPosReqType {
BundleMaterialDrop,
+ ComponentDrop,
MaterialDrop,
TextureDrop,
ContextMenu,
@@ -122,6 +125,7 @@ private:
int particlemode;
ModelCache<QImage> m_canvasCache;
ModelNode m_droppedModelNode;
+ ItemLibraryEntry m_droppedEntry;
NodeAtPosReqType m_nodeAtPosReqType;
QPoint m_contextMenuPos;
QTimer m_compressionTimer;
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
index 40b524614b..701237dd71 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "edit3dwidget.h"
-#include "designdocumentview.h"
+#include "designdocument.h"
#include "edit3dactions.h"
#include "edit3dcanvas.h"
#include "edit3dview.h"
@@ -10,10 +10,10 @@
#include "metainfo.h"
#include "modelnodeoperations.h"
#include "nodeabstractproperty.h"
+#include "nodehints.h"
#include "qmldesignerconstants.h"
#include "qmldesignerplugin.h"
#include "qmlvisualnode.h"
-#include "timelineactions.h"
#include "viewmanager.h"
#include <auxiliarydataproperties.h>
@@ -249,6 +249,16 @@ bool Edit3DWidget::isPasteAvailable() const
return QApplication::clipboard()->text().startsWith(Constants::HEADER_3DPASTE_CONTENT);
}
+bool Edit3DWidget::isSceneLocked() const
+{
+ if (m_view && m_view->hasModelNodeForInternalId(m_canvas->activeScene())) {
+ ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene());
+ if (ModelNode::isThisOrAncestorLocked(node))
+ return true;
+ }
+ return false;
+}
+
// Called by the view to update the "create" sub-menu when the Quick3D entries are ready.
void Edit3DWidget::updateCreateSubMenu(const QStringList &keys,
const QHash<QString, QList<ItemLibraryEntry>> &entriesMap)
@@ -287,7 +297,7 @@ void Edit3DWidget::updateCreateSubMenu(const QStringList &keys,
void Edit3DWidget::onCreateAction()
{
QAction *action = qobject_cast<QAction *>(sender());
- if (!action || !m_view || !m_view->model())
+ if (!action || !m_view || !m_view->model() || isSceneLocked())
return;
m_view->executeInTransaction(__FUNCTION__, [&] {
@@ -374,6 +384,9 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode
const bool anyNodeSelected = view()->hasSelectedModelNodes();
const bool selectionExcludingRoot = anyNodeSelected && !view()->rootModelNode().isSelected();
+ if (m_createSubMenu)
+ m_createSubMenu->setEnabled(!isSceneLocked());
+
m_editComponentAction->setEnabled(isSingleComponent);
m_editMaterialAction->setEnabled(isModel);
m_duplicateAction->setEnabled(selectionExcludingRoot);
@@ -407,6 +420,15 @@ Edit3DView *Edit3DWidget::view() const
void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
{
+ // Block all drags if scene root node is locked
+ if (m_view->hasModelNodeForInternalId(m_canvas->activeScene())) {
+ ModelNode node = m_view->modelNodeForInternalId(m_canvas->activeScene());
+ if (ModelNode::isThisOrAncestorLocked(node))
+ return;
+ }
+
+ m_draggedEntry = {};
+
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
->viewManager().designerActionManager();
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())
@@ -414,6 +436,14 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)
|| dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_TEXTURE)) {
dragEnterEvent->acceptProposedAction();
+ } else if (dragEnterEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
+ QByteArray data = dragEnterEvent->mimeData()->data(Constants::MIME_TYPE_ITEM_LIBRARY_INFO);
+ if (!data.isEmpty()) {
+ QDataStream stream(data);
+ stream >> m_draggedEntry;
+ if (NodeHints::fromItemLibraryEntry(m_draggedEntry).canBeDroppedInView3D())
+ dragEnterEvent->acceptProposedAction();
+ }
}
}
@@ -443,6 +473,13 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
return;
}
+ // handle dropping from component view
+ if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO)) {
+ if (!m_draggedEntry.name().isEmpty())
+ m_view->dropComponent(m_draggedEntry, pos);
+ return;
+ }
+
// handle dropping external assets
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
->viewManager().designerActionManager();
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
index 8a1304a016..728d81646d 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h
@@ -52,6 +52,7 @@ private:
void createContextMenu();
bool isPasteAvailable() const;
+ bool isSceneLocked() const;
QPointer<Edit3DView> m_edit3DView;
QPointer<Edit3DView> m_view;
@@ -77,6 +78,7 @@ private:
ModelNode m_contextMenuTarget;
QVector3D m_contextMenuPos3d;
QHash<QString, ItemLibraryEntry> m_nameToEntry;
+ ItemLibraryEntry m_draggedEntry;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/eventlist/eventlistpluginview.cpp b/src/plugins/qmldesigner/components/eventlist/eventlistpluginview.cpp
index fb9bba3fd1..9d57112747 100644
--- a/src/plugins/qmldesigner/components/eventlist/eventlistpluginview.cpp
+++ b/src/plugins/qmldesigner/components/eventlist/eventlistpluginview.cpp
@@ -3,6 +3,7 @@
#include "eventlistpluginview.h"
#include "assigneventdialog.h"
#include "connectsignaldialog.h"
+#include "designericons.h"
#include "eventlistactions.h"
#include "eventlistdialog.h"
@@ -45,6 +46,7 @@ void EventListPluginView::registerActions()
designerActionManager.addDesignerAction(new ActionGroup(tr("Event List"),
ComponentCoreConstants::eventListCategory,
+ designerActionManager.contextIcon(DesignerIcons::EventListIcon),
ComponentCoreConstants::Priorities::EventListCategory,
&SelectionContextFunctors::always,
&SelectionContextFunctors::always));
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
index 36a9970f58..648a51b91b 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
@@ -3,6 +3,7 @@
#include "formeditorwidget.h"
#include "designeractionmanager.h"
+#include "designericons.h"
#include "designersettings.h"
#include "formeditoritem.h"
#include "formeditorscene.h"
@@ -104,6 +105,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
m_showBoundingRectAction = new QAction(tr("Show Bounds"), this);
m_showBoundingRectAction->setCheckable(true);
m_showBoundingRectAction->setChecked(false);
+ m_showBoundingRectAction->setIcon(DesignerActionManager::instance().contextIcon(DesignerIcons::ShowBoundsIcon));
registerActionAsCommand(m_showBoundingRectAction,
Constants::FORMEDITOR_NO_SHOW_BOUNDING_RECTANGLE,
QKeySequence(Qt::Key_A),
diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp
index d17dbdbc71..a99d4133af 100644
--- a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp
+++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp
@@ -4,13 +4,16 @@
#include "materialeditorcontextobject.h"
#include <abstractview.h>
+#include <bindingproperty.h>
+#include <documentmanager.h>
#include <nodemetainfo.h>
#include <rewritingexception.h>
#include <qmldesignerplugin.h>
#include <qmlmodelnodeproxy.h>
#include <qmlobjectnode.h>
#include <qmltimeline.h>
-#include <documentmanager.h>
+#include <qmltimelinekeyframegroup.h>
+#include <variantproperty.h>
#include <coreplugin/messagebox.h>
#include <utils/algorithm.h>
@@ -129,6 +132,48 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName)
incompatibleProperties.append(property.name());
}
+ // When switching between material types, copy base (diffuse) color and map properties of
+ // source type into corresponding properties of the target type.
+ const QList<PropertyName> baseColors = {"baseColor", "diffuseColor", "albedoColor"};
+ const QList<PropertyName> baseMaps = {"baseColorMap", "diffuseMap", "albedoMap"};
+ int sourceIndex = -1;
+ int targetIndex = -1;
+ NodeMetaInfo oldMetaInfo = m_selectedMaterial.metaInfo();
+ struct CopyData {
+ CopyData() {};
+ CopyData(PropertyName n) : name(n) {}
+ PropertyName name;
+ QVariant value;
+ bool isBinding = false;
+ };
+ QHash<PropertyName, CopyData> copyMap;
+
+ if (oldMetaInfo.isQtQuick3DPrincipledMaterial())
+ sourceIndex = 0;
+ else if (oldMetaInfo.isQtQuick3DDefaultMaterial())
+ sourceIndex = 1;
+ else if (oldMetaInfo.isQtQuick3DSpecularGlossyMaterial())
+ sourceIndex = 2;
+
+ if (metaInfo.isQtQuick3DPrincipledMaterial())
+ targetIndex = 0;
+ else if (metaInfo.isQtQuick3DDefaultMaterial())
+ targetIndex = 1;
+ else if (metaInfo.isQtQuick3DSpecularGlossyMaterial())
+ targetIndex = 2;
+
+ if (sourceIndex >= 0 && targetIndex >= 0) {
+ if (incompatibleProperties.contains(baseColors[sourceIndex])) {
+ copyMap.insert(baseColors[sourceIndex], baseColors[targetIndex]);
+ incompatibleProperties.removeOne(baseColors[sourceIndex]);
+ }
+ if (incompatibleProperties.contains(baseMaps[sourceIndex])) {
+ copyMap.insert(baseMaps[sourceIndex], baseMaps[targetIndex]);
+ incompatibleProperties.removeOne(baseMaps[sourceIndex]);
+ }
+ }
+ const auto &copyKeys = copyMap.keys();
+
Utils::sort(incompatibleProperties);
// Create a dialog showing incompatible properties and signals
@@ -159,10 +204,47 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName)
m_selectedMaterial.removeProperty(p);
}
+ if (!copyKeys.isEmpty()) {
+ // Copy mapped properties to new name. Note that this will only copy the base
+ // property value and adjust the keyframe groups. Any other bindings related
+ // to the property will be ignored.
+ const QList<ModelNode> timeLines = QmlObjectNode(m_selectedMaterial).allTimelines();
+ for (const auto &key : std::as_const(copyKeys)) {
+ CopyData &copyData = copyMap[key];
+ for (const auto &timeLineNode : timeLines) {
+ QmlTimeline timeLine(timeLineNode);
+ if (timeLine.hasKeyframeGroup(m_selectedMaterial, key)) {
+ QmlTimelineKeyframeGroup group = timeLine.keyframeGroup(m_selectedMaterial,
+ key);
+ group.setPropertyName(copyData.name);
+ }
+ }
+ // Property value itself cannot be copied until type has been changed, so store it
+ AbstractProperty prop = m_selectedMaterial.property(key);
+ if (prop.isValid()) {
+ if (prop.isBindingProperty()) {
+ copyData.isBinding = true;
+ copyData.value = prop.toBindingProperty().expression();
+ } else {
+ copyData.value = prop.toVariantProperty().value();
+ }
+ }
+ m_selectedMaterial.removeProperty(key);
+ }
+ }
+
if (m_selectedMaterial.isRootNode())
rewriterView->changeRootNodeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
else
m_selectedMaterial.changeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
+
+ for (const auto &key : copyKeys) {
+ const CopyData &copyData = copyMap[key];
+ if (copyData.isBinding)
+ m_selectedMaterial.bindingProperty(copyData.name).setExpression(copyData.value.toString());
+ else
+ m_selectedMaterial.variantProperty(copyData.name).setValue(copyData.value);
+ }
});
}
diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp
index 91104b8c63..836e473f8a 100644
--- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp
+++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp
@@ -39,6 +39,8 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
// -> Model
// BundleMaterial
// -> Model
+ // Effect
+ // -> Item
if (insertInfo.isQtQuick3DTexture()) {
if (parentInfo.isQtQuick3DDefaultMaterial() || parentInfo.isQtQuick3DPrincipledMaterial()
@@ -88,11 +90,14 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
|| parentInfo.isQtQuick3DParticles3DAttractor3D())
propertyList.append("shape");
} else if (insertInfo.isQtQuick3DMaterial()) {
- if (parentInfo.isQtQuick3DParticles3DModel())
+ if (parentInfo.isQtQuick3DModel())
+ propertyList.append("materials");
+ } else if (insertInfo.typeName().startsWith("ComponentBundles.MaterialBundle")) {
+ if (parentInfo.isQtQuick3DModel())
propertyList.append("materials");
-// TODO merge conflict between Change-Id: If3c58f82797beabe76baf99ea2dddc59032729df and Change-Id: Iff2dea66e253b412105427134bd49cb16ed76193
-// } else if (insertInfo.typeName().startsWith("ComponentBundles.MaterialBundle")) {
-// if (parentInfo.isSubclassOf("QtQuick3D.Model"))
+ } else if (insertInfo.isEffectMaker()) {
+ if (parentInfo.isQtQuickItem())
+ propertyList.append("effect");
}
}
diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp
index 58e83d2060..9f2f0854b3 100644
--- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp
+++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp
@@ -211,21 +211,23 @@ void NameItemDelegate::paint(QPainter *painter,
}
ModelNode node = getModelNode(modelIndex);
- NavigatorWidget *widget = qobject_cast<NavigatorWidget *>(styleOption.widget->parent());
- if (widget && !widget->dragType().isEmpty()) {
- QByteArray dragType = widget->dragType();
- const NodeMetaInfo metaInfo = node.metaInfo();
- const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType);
- ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true);
-
- if (!filter->propertyList.isEmpty()) {
- painter->setOpacity(0.5);
- painter->fillRect(styleOption.rect.adjusted(0, delegateMargin, 0, -delegateMargin),
- Theme::getColor(Theme::Color::DSnavigatorDropIndicatorBackground));
- painter->setOpacity(1.0);
- painter->setPen(Theme::getColor(Theme::Color::DSnavigatorTextSelected));
+ if (!ModelNode::isThisOrAncestorLocked(node)) {
+ NavigatorWidget *widget = qobject_cast<NavigatorWidget *>(styleOption.widget->parent());
+ if (widget && !widget->dragType().isEmpty()) {
+ QByteArray dragType = widget->dragType();
+ const NodeMetaInfo metaInfo = node.metaInfo();
+ const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType);
+ ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true);
+
+ if (!filter->propertyList.isEmpty()) {
+ painter->setOpacity(0.5);
+ painter->fillRect(styleOption.rect.adjusted(0, delegateMargin, 0, -delegateMargin),
+ Theme::getColor(Theme::Color::DSnavigatorDropIndicatorBackground));
+ painter->setOpacity(1.0);
+ painter->setPen(Theme::getColor(Theme::Color::DSnavigatorTextSelected));
+ }
+ delete filter;
}
- delete filter;
}
iconOffset = drawIcon(painter, styleOption, modelIndex);
diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
index 0f8a21b68d..ccf9bafd9a 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
@@ -1019,7 +1019,8 @@ ModelNode NavigatorTreeModel::handleItemLibraryEffectDrop(const QString &effectP
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
ModelNode newModelNode;
- if (targetNode.hasParentProperty() && targetNode.parentProperty().name() == "layer.effect")
+ if ((targetNode.hasParentProperty() && targetNode.parentProperty().name() == "layer.effect")
+ || !targetNode.metaInfo().isQtQuickItem())
return newModelNode;
if (ModelNodeOperations::validateEffect(effectPath)) {
diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
index 9d080e9274..e6450d4562 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp
@@ -7,6 +7,8 @@
#include "qmldesignerconstants.h"
#include "qmldesignericons.h"
#include "qmldesignerplugin.h"
+#include "assetslibrarywidget.h"
+#include "commontypecache.h"
#include "nameitemdelegate.h"
#include "iconcheckboxitemdelegate.h"
@@ -266,6 +268,18 @@ void NavigatorView::dragStarted(QMimeData *mimeData)
m_widget->setDragType(bundleMatType);
m_widget->update();
+ } else if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) {
+ const QStringList assetsPaths = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',');
+ if (assetsPaths.count() > 0) {
+ 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
+ // specific type
+ m_widget->setDragType(Storage::Info::EffectMaker);
+ m_widget->update();
+ }
+ }
}
}
@@ -389,6 +403,13 @@ void NavigatorView::auxiliaryDataChanged(const ModelNode &modelNode,
[[maybe_unused]] const QVariant &data)
{
m_currentModelInterface->notifyDataChanged(modelNode);
+
+ if (key == lockedProperty) {
+ // Also notify data changed on child nodes to redraw them
+ const QList<ModelNode> childNodes = modelNode.allSubModelNodes();
+ for (const auto &childNode : childNodes)
+ m_currentModelInterface->notifyDataChanged(childNode);
+ }
}
void NavigatorView::instanceErrorChanged(const QVector<ModelNode> &errorNodeList)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp
index b7bfd88e5b..6cb65a9562 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorimageprovider.cpp
@@ -36,7 +36,7 @@ QQuickImageResponse *PropertyEditorImageProvider::requestImageResponse(const QSt
response->setImage(image.scaled(requestedSize, Qt::KeepAspectRatio));
return;
}
- } else if (asset.isTexture3D()) {
+ } else if (asset.isHdrFile()) {
HdrImage hdr{asset.id()};
if (!hdr.image().isNull()) {
response->setImage(hdr.image().scaled(requestedSize, Qt::KeepAspectRatio));
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp
index e35dd7dcd1..0ad9a8741b 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp
@@ -3,6 +3,7 @@
#include "timelineview.h"
+#include "designericons.h"
#include "easingcurve.h"
#include "timelineactions.h"
#include "timelineconstants.h"
@@ -584,6 +585,7 @@ void TimelineView::registerActions()
actionManager.addDesignerAction(new ActionGroup(TimelineConstants::timelineCategoryDisplayName,
TimelineConstants::timelineCategory,
+ actionManager.contextIcon(DesignerIcons::TimelineIcon),
ComponentCoreConstants::Priorities::TimelineCategory,
timelineEnabled,
&SelectionContextFunctors::always));
diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h
index ceb931b7d2..35f2c25f46 100644
--- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h
+++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h
@@ -100,6 +100,7 @@ public:
bool isAlias() const;
bool isBool() const;
bool isColor() const;
+ bool isEffectMaker() const;
bool isFloat() const;
bool isFlowViewFlowActionArea() const;
bool isFlowViewFlowDecision() const;
@@ -129,7 +130,6 @@ public:
bool isQtQuick3DNode() const;
bool isQtQuick3DParticles3DAffector3D() const;
bool isQtQuick3DParticles3DAttractor3D() const;
- bool isQtQuick3DParticles3DModel() const;
bool isQtQuick3DParticles3DParticle3D() const;
bool isQtQuick3DParticles3DParticleEmitter3D() const;
bool isQtQuick3DParticles3DSpriteParticle3D() const;
diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
index aa057533c8..7aaed70c9d 100644
--- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
+++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
@@ -640,14 +640,12 @@ void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node,
case AuxiliaryDataType::Document:
if ((key == lockedProperty || key == invisibleProperty) && hasInstanceForModelNode(node)) {
NodeInstance instance = instanceForModelNode(node);
- if (value.isValid()) {
- PropertyValueContainer container{instance.instanceId(),
- PropertyName{key.name},
- value,
- TypeName(),
- key.type};
- m_nodeInstanceServer->changeAuxiliaryValues({{container}});
- }
+ PropertyValueContainer container{instance.instanceId(),
+ PropertyName{key.name},
+ value,
+ TypeName(),
+ key.type};
+ m_nodeInstanceServer->changeAuxiliaryValues({{container}});
};
break;
diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
index ca78be4012..d15ef9227c 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
@@ -343,6 +343,8 @@ static inline bool isValueType(const TypeName &type)
"QPointF",
"QSize",
"QSizeF",
+ "QRect",
+ "QRectF",
"QVector2D",
"QVector3D",
"QVector4D",
@@ -361,6 +363,8 @@ static inline bool isValueType(const QString &type)
"QPointF",
"QSize",
"QSizeF",
+ "QRect",
+ "QRectF",
"QVector2D",
"QVector3D",
"QVector4D",
@@ -405,7 +409,7 @@ QVector<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Co
if (objectValue->className().isEmpty())
return propertyList;
- if (rec > 2)
+ if (rec > 4)
return propertyList;
PropertyMemberProcessor processor(context);
@@ -427,9 +431,14 @@ QVector<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Co
}
}
if (isValueType(objectValue->propertyType(nameAsString))) {
- const ObjectValue *dotObjectValue = value_cast<ObjectValue>(objectValue->lookupMember(nameAsString, context));
+ const ObjectValue *dotObjectValue = value_cast<ObjectValue>(
+ objectValue->lookupMember(nameAsString, context));
+
if (dotObjectValue) {
- const QVector<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue, context, false, rec + 1);
+ const QVector<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue,
+ context,
+ false,
+ rec + 1);
for (const PropertyInfo &propertyInfo : dotProperties) {
const PropertyName dotName = name + '.' + propertyInfo.first;
const TypeName type = propertyInfo.second;
@@ -521,7 +530,7 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
if (objectValue->className().isEmpty())
return propertyList;
- if (rec > 2)
+ if (rec > 4)
return propertyList;
PropertyMemberProcessor processor(context);
@@ -535,6 +544,7 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
if (isValueType(property.second)) {
const Value *dotValue = objectValue->lookupMember(nameAsString, context);
+
if (!dotValue)
continue;
@@ -542,7 +552,10 @@ QVector<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Conte
dotValue = context->lookupReference(ref);
if (const ObjectValue *dotObjectValue = dotValue->asObjectValue()) {
- const QVector<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue, context, false, rec + 1);
+ const QVector<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue,
+ context,
+ false,
+ rec + 1);
for (const PropertyInfo &propertyInfo : dotProperties) {
const PropertyName dotName = name + '.' + propertyInfo.first;
const TypeName type = propertyInfo.second;
@@ -2535,6 +2548,13 @@ bool NodeMetaInfo::isColor() const
}
}
+bool NodeMetaInfo::isEffectMaker() const
+{
+ // We use arbitrary type name because at this time we don't have effect maker
+ // specific type
+ return typeName() == QString::fromUtf8(Storage::Info::EffectMaker);
+}
+
bool NodeMetaInfo::isBool() const
{
if constexpr (useProjectStorage()) {
@@ -2724,17 +2744,6 @@ bool NodeMetaInfo::isQtQuick3DView3D() const
}
}
-bool NodeMetaInfo::isQtQuick3DParticles3DModel() const
-{
- if constexpr (useProjectStorage()) {
- using namespace Storage::Info;
- return isBasedOnCommonType<QtQuick3D_Particles3D, Storage::Info::Model>(m_projectStorage,
- m_typeId);
- } else {
- return isValid() && isSubclassOf("QtQuick3D.Particles3D.Model");
- }
-}
-
bool NodeMetaInfo::isQtQuick3DPrincipledMaterial() const
{
if constexpr (useProjectStorage()) {
diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
index 9b112d759e..af612ca3f4 100644
--- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp
@@ -1392,8 +1392,7 @@ ModelNode ModelNode::lowestCommonAncestor(const QList<ModelNode> &nodes)
ModelNode accumulatedNode = nodes.first();
int accumulatedNodeDepth = -1;
- Utils::span<const ModelNode> nodesExceptFirst(nodes.constBegin() + 1, nodes.constEnd());
- for (const ModelNode &node : nodesExceptFirst) {
+ for (const ModelNode &node : Utils::span<const ModelNode>(nodes).subspan(1)) {
accumulatedNode = QmlDesigner::lowestCommonAncestor(accumulatedNode,
node,
accumulatedNodeDepth,
diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
index 39d14fd545..ca321b5687 100644
--- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
@@ -280,7 +280,8 @@ bool isListElementType(const QmlDesigner::TypeName &type)
bool isComponentType(const QmlDesigner::TypeName &type)
{
return type == "Component" || type == "Qt.Component" || type == "QtQuick.Component"
- || type == "QtQml.Component" || type == "<cpp>.QQmlComponent" || type == "QQmlComponent";
+ || type == "QtQml.Component" || type == "<cpp>.QQmlComponent" || type == "QQmlComponent"
+ || type == "QML.Component";
}
bool isCustomParserType(const QmlDesigner::TypeName &type)
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h b/src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h
index 36f1b9bc98..4878b59783 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h
@@ -35,6 +35,7 @@ inline constexpr char DefaultMaterial[] = "DefaultMaterial";
inline constexpr char Dialog[] = "Dialog";
inline constexpr char DoubleType[] = "double";
inline constexpr char Effect[] = "Effect";
+inline constexpr char EffectMaker[] = "EffectMaker";
inline constexpr char FloatType[] = "float";
inline constexpr char FlowActionArea[] = "FlowActionArea";
inline constexpr char FlowDecision[] = "FlowDecision";
diff --git a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp
index ca5bff17e3..70d62f71c6 100644
--- a/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp
+++ b/src/plugins/qmldesigner/qmlpreviewplugin/qmlpreviewplugin.cpp
@@ -40,6 +40,7 @@ QmlPreviewWidgetPlugin::QmlPreviewWidgetPlugin()
designerActionManager.addDesignerAction(new ActionGroup(
QString(),
ComponentCoreConstants::qmlPreviewCategory,
+ {},
ComponentCoreConstants::Priorities::QmlPreviewCategory,
&SelectionContextFunctors::always));
s_previewPlugin = getPreviewPlugin();
diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
index ec420e2720..87b9edcbc0 100644
--- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
+++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
@@ -535,7 +535,7 @@ MetaInfo {
}
Type {
- name: "QtQml.Component"
+ name: "QML.Component"
icon: ":/qtquickplugin/images/component-icon16.png"
Hints {
@@ -547,7 +547,7 @@ MetaInfo {
name: "Component"
category: "e.Qt Quick - Component"
libraryIcon: ":/qtquickplugin/images/component-icon.png"
- version: "2.0"
+ version: "1.0"
QmlSource { source: ":/qtquickplugin/source/component.qml" }
toolTip: qsTr("Allows you to define components inline, within a QML document.")
@@ -555,7 +555,7 @@ MetaInfo {
}
Type {
- name: "QtQml.Component"
+ name: "QML.Component"
icon: ":/qtquickplugin/images/component-icon16.png"
Hints {
@@ -567,7 +567,7 @@ MetaInfo {
name: "Component 3D"
category: "Qt Quick 3D Component"
libraryIcon: ":/qtquickplugin/images/component-icon.png"
- version: "2.0"
+ version: "1.0"
requiredImport: "QtQuick3D"
QmlSource { source: ":/qtquickplugin/source/component3d.qml" }
diff --git a/src/plugins/qmldesigner/utils/asset.cpp b/src/plugins/qmldesigner/utils/asset.cpp
index 4b8eaaabf7..5ec84d5bbc 100644
--- a/src/plugins/qmldesigner/utils/asset.cpp
+++ b/src/plugins/qmldesigner/utils/asset.cpp
@@ -154,6 +154,11 @@ bool Asset::isTexture3D() const
return type() == Asset::Type::Texture3D;
}
+bool Asset::isHdrFile() const
+{
+ return m_suffix == "*.hdr";
+}
+
bool Asset::isEffect() const
{
return type() == Asset::Type::Effect;
diff --git a/src/plugins/qmldesigner/utils/asset.h b/src/plugins/qmldesigner/utils/asset.h
index 408131fa57..3e6d105ec4 100644
--- a/src/plugins/qmldesigner/utils/asset.h
+++ b/src/plugins/qmldesigner/utils/asset.h
@@ -8,7 +8,7 @@ namespace QmlDesigner {
class Asset
{
public:
- enum Type { Unknown, Image, FragmentShader, Font, Audio, Video, Texture3D, Effect, Shader };
+ enum Type { Unknown, Image, MissingImage, FragmentShader, Font, Audio, Video, Texture3D, Effect, Shader };
Asset(const QString &filePath);
@@ -34,6 +34,7 @@ public:
bool isAudio() const;
bool isVideo() const;
bool isTexture3D() const;
+ bool isHdrFile() const;
bool isEffect() const;
bool isSupported() const;
diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp
index 3ca420d60a..d9c9a25be3 100644
--- a/src/plugins/updateinfo/updateinfoplugin.cpp
+++ b/src/plugins/updateinfo/updateinfoplugin.cpp
@@ -223,8 +223,9 @@ static void showUpdateInfo(const QList<Update> &updates,
auto label = new QLabel;
label->setText("<qt><p>" + UpdateInfoPlugin::tr("Available updates:") + "<ul><li>"
+ qtText + updateText + "</li></ul></p></qt>");
- label->setContentsMargins(0, 0, 0, 8);
+ label->setContentsMargins(2, 2, 2, 2);
auto scrollArea = new QScrollArea;
+ scrollArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
scrollArea->setWidget(label);
scrollArea->setFrameShape(QFrame::NoFrame);
scrollArea->viewport()->setAutoFillBackground(false);
diff --git a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp
index b390b9d97f..281e6030a0 100644
--- a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp
+++ b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp
@@ -567,6 +567,15 @@ void ObjectNodeInstance::doResetProperty(const PropertyName &propertyName)
QmlPrivateGate::doResetProperty(object(), context(), propertyName);
}
+static bool isPropertyBlackListed(const PropertyName &propertyName)
+{
+ if (propertyName.contains(".") && propertyName.contains("__"))
+ return true;
+ if (propertyName.count(".") > 2)
+ return true;
+ return false;
+}
+
QVariant ObjectNodeInstance::property(const PropertyName &name) const
{
if (ignoredProperties().contains(name))
@@ -574,7 +583,7 @@ QVariant ObjectNodeInstance::property(const PropertyName &name) const
// TODO: handle model nodes
- if (QmlPrivateGate::isPropertyBlackListed(name))
+ if (isPropertyBlackListed(name))
return QVariant();
QQmlProperty property(object(), QString::fromUtf8(name), context());
@@ -612,6 +621,37 @@ void ObjectNodeInstance::ensureVector3DDotProperties(PropertyNameList &list) con
}
}
+void ObjectNodeInstance::ensureValueTypeProperties(PropertyNameList &list) const
+{
+ const PropertyNameList pointDotProperties = {"x", "y"};
+ const PropertyNameList sizeDotProperties = {"width", "height"};
+ const PropertyNameList rectDotProperties = {"x", "y", "width", "height"};
+
+ PropertyNameList valueTypeProperties;
+
+ for (const auto &property : list) {
+ const QString name = instanceType(property);
+ PropertyNameList dotProperties;
+
+ if (name == "QPoint" || name == "QPointF")
+ dotProperties = pointDotProperties;
+
+ if (name == "QSize" || name == "QSizeF")
+ dotProperties = sizeDotProperties;
+
+ if (name == "QRect" || name == "QRectF")
+ dotProperties = rectDotProperties;
+
+ for (const auto &dotProperty : dotProperties)
+ valueTypeProperties.append(property + "." + dotProperty);
+ }
+
+ for (const auto &valueTypeProperty : valueTypeProperties) {
+ if (!list.contains(valueTypeProperty))
+ list.append(valueTypeProperty);
+ }
+}
+
PropertyNameList ObjectNodeInstance::propertyNames() const
{
PropertyNameList list;
@@ -619,13 +659,14 @@ PropertyNameList ObjectNodeInstance::propertyNames() const
list = QmlPrivateGate::allPropertyNames(object());
ensureVector3DDotProperties(list);
+ ensureValueTypeProperties(list);
return list;
}
QString ObjectNodeInstance::instanceType(const PropertyName &name) const
{
- if (QmlPrivateGate::isPropertyBlackListed(name))
+ if (isPropertyBlackListed(name))
return QLatin1String("undefined");
QQmlProperty property(object(), QString::fromUtf8(name), context());
diff --git a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h
index 85e663e3ee..36abf66494 100644
--- a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h
+++ b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.h
@@ -199,6 +199,7 @@ protected:
void initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance);
void ensureVector3DDotProperties(PropertyNameList &list) const;
+ void ensureValueTypeProperties(PropertyNameList &list) const;
private:
QString m_id;
diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
index a96f4a4217..36c24d8573 100644
--- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
+++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
@@ -345,7 +345,7 @@ void Qt5InformationNodeInstanceServer::updateRotationBlocks(
if (helper) {
QSet<QQuick3DNode *> blockedNodes;
QSet<QQuick3DNode *> unblockedNodes;
- const PropertyName rotBlocked = "rotBlocked";
+ const PropertyName rotBlocked = "rotBlock";
for (const auto &container : valueChanges) {
if (container.name() == rotBlocked
&& container.auxiliaryDataType() == AuxiliaryDataType::NodeInstanceAuxiliary) {
diff --git a/src/tools/qml2puppet/qml2puppet/qmlbase.h b/src/tools/qml2puppet/qml2puppet/qmlbase.h
index a0f1fd345a..c73bd7fcc6 100644
--- a/src/tools/qml2puppet/qml2puppet/qmlbase.h
+++ b/src/tools/qml2puppet/qml2puppet/qmlbase.h
@@ -40,18 +40,22 @@ public:
, m_args({argc, argv})
{
m_argParser.setApplicationDescription("QML Runtime Provider for QDS");
- m_argParser.addOptions(
- {{"qml-puppet", "Run QML Puppet (default)"},
- {"qml-runtime", "Run QML Runtime"},
- {"appinfo", "Print build information"},
- {"test", "Run test mode"}
- });
+ m_argParser.addOptions({{"qml-puppet", "Run QML Puppet (default)"},
+ {"qml-runtime", "Run QML Runtime"},
+ {"appinfo", "Print build information"},
+ {"test", "Run test mode"}});
}
int run()
{
populateParser();
initCoreApp();
+
+ if (!m_coreApp) { //default to QGuiApplication
+ createCoreApp<QGuiApplication>();
+ qWarning() << "CoreApp is not initialized! Falling back to QGuiApplication!";
+ }
+
initParser();
initQmlRunner();
return m_coreApp->exec();
@@ -88,11 +92,6 @@ private:
QCommandLineOption optHelp = m_argParser.addHelpOption();
QCommandLineOption optVers = m_argParser.addVersionOption();
- if (!m_coreApp) {
- qCritical() << "Cannot initialize coreapp!";
- m_argParser.showHelp();
- }
-
if (!m_argParser.parse(m_coreApp->arguments())) {
std::cout << "Error: " << m_argParser.errorText().toStdString() << std::endl
<< std::endl;
diff --git a/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp b/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp
index d53531d44c..a4ade2b2b4 100644
--- a/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp
+++ b/src/tools/qml2puppet/qml2puppet/runner/qmlruntime.cpp
@@ -241,7 +241,8 @@ void QmlRuntime::initQmlRunner()
loadConf(confFile, !m_verboseMode);
// Load files
- QScopedPointer<LoadWatcher> lw(new LoadWatcher(m_qmlEngine.data(), files.size(), m_conf.data()));
+ LoadWatcher *lw = new LoadWatcher(m_qmlEngine.data(), files.size(), m_conf.data());
+ lw->setParent(this);
for (const QString &path : std::as_const(files)) {
QUrl url = QUrl::fromUserInput(path, QDir::currentPath(), QUrl::AssumeLocalFile);
diff --git a/src/tools/qml2puppet/runnerconf/qmlruntime/content/resizeItemToWindow.qml b/src/tools/qml2puppet/runnerconf/qmlruntime/content/resizeItemToWindow.qml
index ca4618ba73..7b99d4530a 100644
--- a/src/tools/qml2puppet/runnerconf/qmlruntime/content/resizeItemToWindow.qml
+++ b/src/tools/qml2puppet/runnerconf/qmlruntime/content/resizeItemToWindow.qml
@@ -4,22 +4,46 @@ import QtQuick.Window 2.0
import QtQuick 2.0
Window {
+ id: window
property Item containedObject: null
- property bool __resizeGuard: false
+
+ readonly property Item firstChild: window.contentItem.children.length > 0 ? window.contentItem.children[0] : null
+
+ property bool writeGuard: false
+
+ onFirstChildChanged: {
+ window.writeGuard = true
+ window.containedObject = window.firstChild
+ window.writeGuard = false
+ }
+
onContainedObjectChanged: {
+ if (window.writeGuard)
+ return
+
if (containedObject == undefined || containedObject == null) {
visible = false
return
}
- __resizeGuard = true
- width = containedObject.width
- height = containedObject.height
+
+ window.width = containedObject.width
+ window.height = containedObject.height
+
containedObject.parent = contentItem
- visible = true
- __resizeGuard = false
+ window.visible = true
+ }
+
+ Binding {
+ target: window.firstChild
+ when: window.firstChild
+ property: "height"
+ value: window.height
+ }
+
+ Binding {
+ target: window.firstChild
+ when: window.firstChild
+ property: "width"
+ value: window.width
}
- onWidthChanged: if (!__resizeGuard && containedObject)
- containedObject.width = width
- onHeightChanged: if (!__resizeGuard && containedObject)
- containedObject.height = height
}