Merge remote-tracking branch 'origin/4.13' into master

Change-Id: I8a2dca29595a0770f4162786b15a145f3f4133af
This commit is contained in:
Orgad Shaneh
2020-09-04 16:11:12 +03:00
49 changed files with 1254 additions and 128 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -101,6 +101,7 @@
\li The \uicontrol {GNU ARM Embedded Toolchain} path. \li The \uicontrol {GNU ARM Embedded Toolchain} path.
\li The \uicontrol {STM32CubeProgrammer} install path. \li The \uicontrol {STM32CubeProgrammer} install path.
\li The \uicontrol {MCU SDK} for the chosen target. \li The \uicontrol {MCU SDK} for the chosen target.
\li The \uicontrol {FreeRTOS Sources} for the chosen target.
\endlist \endlist
\li For NXP targets: \li For NXP targets:
\list \list

View File

@@ -148,6 +148,7 @@
\li \l {Browsing ISO 7000 Icons} \li \l {Browsing ISO 7000 Icons}
\li \l {Using QML Modules with Plugins} \li \l {Using QML Modules with Plugins}
\li \l {Converting UI Projects to Applications} \li \l {Converting UI Projects to Applications}
\li \l {Exporting QML}
\endlist \endlist
\li \l{Developing Widget Based Applications} \li \l{Developing Widget Based Applications}
\list \list

View File

@@ -96,6 +96,11 @@
convert them to Qt Quick Application projects that contain .pro, convert them to Qt Quick Application projects that contain .pro,
.cpp, and .qrc files. .cpp, and .qrc files.
\li \l {Exporting QML}
\l{Qt Quick UI Forms}{UI forms} (ui.qml files) can be exported to
JSON metadata format and PNG assets.
\endlist \endlist
*/ */

View File

@@ -0,0 +1,71 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/
/*!
\page creator-exporting-qml.html
\previouspage quick-converting-ui-projects.html
\nextpage creator-using-qt-designer.html
\title Exporting QML
\l{Qt Quick UI Forms}{UI forms} (ui.qml files) can be exported to
JSON metadata format and PNG assets.
To export the \l{Qt Quick UI Forms}{UI forms} (ui.qml files) from the
current project, select \uicontrol Build > \uicontrol {Export QML}.
The primary use of exported metadata and assets is to generate native file
formats in content creation tools, such as Adobe Photoshop, using \QB. \QBPS
can generate PSD files by importing the metadata and assets.
QML is exported as follows:
\list
\li QML types inherited from \l [QML]{Item}{Item} are exported, other
types are ignored.
\li \l [QML]{Text}{Text} components are exported as metadata only
and no assets are generated.
\li \l [QML]{Rectangle}{Rectangle} and \l [QML]{Image}{Image} types
generate assets as PNG files.
\endlist
\section1 Configuring QML Export
You can configure the export in the \uicontrol {Export QML} dialog, which
lists the \l{Qt Quick UI Forms}{UI forms} (ui.qml files) of the current
project.
\image qtquick-qml-export-dialog.png "QML Export Dialog"
\list 1
\li In the \uicontrol {Export path} field, specify the path where
the metadata file and assets are exported.
\li Deselect the \uicontrol {Export assets} check box to disable
exporting assets and only generate the metadata file.
\li In the file list, select the \l{Qt Quick UI Forms}{UI forms}
to be exported.
\li Select \uicontrol {Export} export to start the export process.
\endlist
*/

View File

@@ -26,11 +26,11 @@
/*! /*!
\page quick-converting-ui-projects.html \page quick-converting-ui-projects.html
\if defined(qtdesignstudio) \if defined(qtdesignstudio)
\previouspage studio-importing-designs.html \previouspage studio-importing-3d.html
\nextpage quick-uis.html \nextpage quick-uis.html
\else \else
\previouspage creator-qml-modules-with-plugins.html \previouspage creator-qml-modules-with-plugins.html
\nextpage creator-using-qt-designer.html \nextpage creator-exporting-qml.html
\endif \endif
\title Converting UI Projects to Applications \title Converting UI Projects to Applications

View File

@@ -30,7 +30,7 @@
// ********************************************************************** // **********************************************************************
/*! /*!
\previouspage quick-converting-ui-projects.html \previouspage creator-exporting-qml.html
\page creator-using-qt-designer.html \page creator-using-qt-designer.html
\nextpage adding-plugins.html \nextpage adding-plugins.html

View File

@@ -8,7 +8,7 @@
<li><a href="studio-getting-started.html">Getting Started</a></li> <li><a href="studio-getting-started.html">Getting Started</a></li>
<li><a href="studio-projects-managing.html">Managing Projects</a></li> <li><a href="studio-projects-managing.html">Managing Projects</a></li>
<li><a href="quick-uis.html">Creating UIs</a></li> <li><a href="quick-uis.html">Creating UIs</a></li>
<li><a href="studio-adding-dynamics.html">Adding Dynamics</a></li> <li><a href="qtquick-adding-dynamics.html">Adding Dynamics</a></li>
<li><a href="studio-3d.html">Editing 3D Scenes</a></li> <li><a href="studio-3d.html">Editing 3D Scenes</a></li>
<li><a href="creator-live-preview.html">Previewing</a></li> <li><a href="creator-live-preview.html">Previewing</a></li>
<li><a href="studio-advanced.html">Advanced Topics</a></li> <li><a href="studio-advanced.html">Advanced Topics</a></li>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -107,6 +107,7 @@
\li \l{Adding Models} \li \l{Adding Models}
\li \l{Using Materials and Shaders} \li \l{Using Materials and Shaders}
\li \l{Attaching Textures to Materials} \li \l{Attaching Textures to Materials}
\li \l{Using 3D Materials}
\li \l{Applying 3D Effects} \li \l{Applying 3D Effects}
\li \l{Using Custom Shaders} \li \l{Using Custom Shaders}
\li \l{Creating Custom Effects and Materials} \li \l{Creating Custom Effects and Materials}

View File

@@ -32,16 +32,27 @@
\title Creating Custom Effects and Materials \title Creating Custom Effects and Materials
The \l{Applying 3D Effects}{Qt Quick 3D Effects} and \l{Using 3D Materials}
{Qt Quick 3D Materials} modules contain a set of ready-made effects and
materials that you can apply to 3D models. If the ready-made effects and
materials don't meet your needs, you can create custom effects and
materials. Each effect or material must have a fragment shader that
implements all the functions needed to calculate the shaded color. The
material system also offers ready-made functions to help you implement
the material.
The material system supports dielectric, metallic, and transparent
materials, point lights, area lights, ambient occlusion, shadowing,
two-sided polygons, index-of-refraction, and fragment cutoff (masking).
For more information, see \l {Qt Quick 3D Custom Material Reference}.
You can use the QML types in the \uicontrol {Qt Quick 3D Custom Shader Utils} You can use the QML types in the \uicontrol {Qt Quick 3D Custom Shader Utils}
tab of \uicontrol Library to create custom effects and materials. To make tab of \uicontrol Library to create custom effects and materials. To make
the \uicontrol Effect and \uicontrol {Custom Material} types appear in the the \uicontrol Effect and \uicontrol {Custom Material} types appear in the
tab, you must select \uicontrol {Add Import} in the \uicontrol {QML Imports} tab, you must select \uicontrol {Add Import} in the \uicontrol {QML Imports}
tab, and then select \uicontrol QtQuick3D.Effects and tab, and then select \uicontrol QtQuick3D.Effects and
\uicontrol QtQuick3D.Materials to import the QML types in the \uicontrol QtQuick3D.Materials to import the QML types in those modules to
\l{Qt Quick 3D Effects QML Types}{Qt Quick 3D Effects} and your project.
\l{Qt Quick 3D Materials QML Types}{Qt Quick 3D Materials} modules to your
project. These modules contain a set of ready-made effects and materials
that you can apply to 3D models.
For more information about the shader utilities and commands and their For more information about the shader utilities and commands and their
properties, see \l {Using Custom Shaders}. properties, see \l {Using Custom Shaders}.
@@ -50,7 +61,10 @@
\note You must create the actual shader source files with some other tool \note You must create the actual shader source files with some other tool
and copy them to your project folder. You can then specify the source file and copy them to your project folder. You can then specify the source file
names in the custom effect or material properties. names in the custom effect or material properties. To use custom \e uniforms
in the shader files, you must specify them as QML properties for the custom
effect or material component. \QDS automatically generates the uniforms for
the shaders based on the property values.
\section1 Creating Custom Effects \section1 Creating Custom Effects
@@ -160,4 +174,42 @@
\uicontrol Properties. \uicontrol Properties.
\image studio-qtquick-3d-shader-properties.png "Shader properties" \image studio-qtquick-3d-shader-properties.png "Shader properties"
\endlist \endlist
\section1 Creating Shader Files
The requirements set for shaders that you can use in custom effects and
materials are described in \l {Qt Quick 3D Custom Material Reference}.
If you use custom uniforms in the shader files, you must specify them
as QML properties for the custom effect or material component. \QDS
automatically generates the uniforms based on the property values.
For example, the following code snippet shows fragment shader code that
uses two uniforms: \c uTextureInUse and \c uInputTexture.
\code
out vec4 fragColor;
in vec3 pos;
in vec3 texCoord0;
void main() {
vec4 textCol;
if (uTextureInUse)
textCol = texture( uInputTexture, texCoord0.xy );
fragColor = vec4(pos.x * 0.02 * textCol.x, pos.y * 0.02 * textCol.y, pos.z * 0.02, 1.0);
}
\endcode
To use the above fragment shader in a custom effect or material component,
you must remove the uniforms from the shader code and define them as
properties for the component in \uicontrol {Connection View} >
\uicontrol Properties.
\image studio-custom-material-uniform-properties.png "Uniforms as properties in Connection View Properties tab"
For more information about adding properties, see
\l{Specifying Dynamic Properties}.
*/ */

View File

@@ -30,8 +30,8 @@
\title Working in 3D Editor \title Working in 3D Editor
When editing a 3D scene, you view the scene in \uicontrol {3D Editor} by When editing a 3D scene, you view the scene in the \uicontrol {3D Editor}
using the \uicontrol {3D Editor} camera. You can switch between view. You can change the projection of the view by switching between
\e {perspective camera} and \e {orthographic camera} modes. When using the \e {perspective camera} and \e {orthographic camera} modes. When using the
perspective camera mode, objects that are far from the camera appear smaller perspective camera mode, objects that are far from the camera appear smaller
than those nearby. In the orthographic camera mode, all objects appear at than those nearby. In the orthographic camera mode, all objects appear at
@@ -61,7 +61,8 @@
Additional helpful features when editing 3D scenes are the \e {edit light}, Additional helpful features when editing 3D scenes are the \e {edit light},
which is a quick way to light the scene, and the grid that helps you to which is a quick way to light the scene, and the grid that helps you to
navigate in 3D space. Select the \inlineimage grid_on.png navigate in 3D space. Select the \inlineimage grid_on.png
(\uicontrol {Toggle Grid Visibility}) to show or hide the grid. (\uicontrol {Toggle Grid Visibility}) or press \key G to show or hide the
grid.
\image studio-3d-editor.png "3D Editor" \image studio-3d-editor.png "3D Editor"
@@ -78,10 +79,10 @@
camera: camera:
\list \list
\li To pan, press \key Alt and use the middle mouse button to click \li To pan, press \key Alt and use the middle mouse button to click and
anywhere in the rendered view to slide the view around. drag anywhere in the rendered view to slide the view around.
\li To orbit, press \key Alt and click anywhere in the rendered view to \li To orbit, press \key Alt and click and drag anywhere in the rendered
rotate the view. view to rotate the view.
\li To zoom, use the mouse wheel or press \key Alt and right-click \li To zoom, use the mouse wheel or press \key Alt and right-click
anywhere in the rendered view to zoom the view in or out as you drag anywhere in the rendered view to zoom the view in or out as you drag
up or down. up or down.
@@ -91,11 +92,12 @@
select \inlineimage fit_selected.png select \inlineimage fit_selected.png
(\uicontrol {Fit Selected}) or press \key F. (\uicontrol {Fit Selected}) or press \key F.
The world axis helper (1) shows the direction of the world axes in respect The world axis helper (1) shows the direction of the world axes in view.
to the 3D Editor camera. To point the camera at the currently selected To point the camera at the currently selected component in the direction of
component in the direction of an axis, click the axis. If no component an axis, click the axis. Clicking the dot at the end of the axis will point
is selected, the camera is pointed at the world origin. This does not the camera at the opposite direction of the axis. If no component is
affect the camera zoom level. selected, the camera is pointed at the world origin. This does not affect
the camera zoom level.
\image studio-3d-editor-axis-helper.png "Axis helper in 3D Editor" \image studio-3d-editor-axis-helper.png "Axis helper in 3D Editor"
@@ -128,8 +130,8 @@
\section1 Using Edit Light \section1 Using Edit Light
The edit light is an extra point light that follows the edit camera. The edit light is an extra point light that can be used to illuminate the
To switch the edit light on and off, select \inlineimage edit_light_on.png scene. To toggle the edit light on and off, select \inlineimage edit_light_on.png
or \inlineimage edit_light_off.png or \inlineimage edit_light_off.png
(\uicontrol {Toggle Edit Light}) (\uicontrol {Toggle Edit Light})
or press \key U. or press \key U.
@@ -160,7 +162,7 @@
You can move items in relation to their coordinate system, along the x, y, You can move items in relation to their coordinate system, along the x, y,
or z axis or on the top, bottom, left, and right clip planes of the or z axis or on the top, bottom, left, and right clip planes of the
\uicontrol {3D Editor} camera. \uicontrol {3D Editor} view.
To move items, select \inlineimage move_on.png To move items, select \inlineimage move_on.png
or press \key W: or press \key W:
@@ -170,8 +172,8 @@
drag the item along the axis. drag the item along the axis.
\li To move items on a plane, click the plane handle and drag the item \li To move items on a plane, click the plane handle and drag the item
on the plane. on the plane.
\li To move an item freely in the editor, click the gray handle at the \li To move an item freely in 3D editor, click and drag the gray handle
center of the item. at the center of the move gizmo.
\endlist \endlist
\section1 Rotating Items \section1 Rotating Items
@@ -182,9 +184,10 @@
or press \key E: or press \key E:
\list \list
\li To rotate an item around its rotation gizmo, click the axis and \li To rotate an item around its rotation gizmo, click the axis ring and
drag in the direction you want to rotate the item in. drag in the direction you want to rotate the item in.
\li To freely rotate the item, select the gray circle. \li To freely rotate the item, click and drag the inner center circle of
the gizmo.
\endlist \endlist
\section1 Scaling Items \section1 Scaling Items
@@ -203,7 +206,7 @@
attached to the axis. attached to the axis.
\li To adjust the scale across a plane, click the plane handle and drag \li To adjust the scale across a plane, click the plane handle and drag
the item on the plane. the item on the plane.
\li To uniformly scale an item across all axes, click and drag the \li To uniformly scale an item across all axes, click and drag the gray
handle at the center of the item. handle at the center of the item.
\endlist \endlist
*/ */

View File

@@ -27,7 +27,7 @@
/*! /*!
\page studio-3d-effects.html \page studio-3d-effects.html
\previouspage studio-3d-texture.html \previouspage studio-3d-materials-types.html
\nextpage studio-3d-custom-shaders.html \nextpage studio-3d-custom-shaders.html
\title Applying 3D Effects \title Applying 3D Effects

View File

@@ -0,0 +1,399 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Design Studio.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page studio-3d-materials-types.html
\previouspage studio-3d-texture.html
\nextpage studio-3d-effects.html
\title Using 3D Materials
\QDS provides a set of pregenerated Qt Quick 3D materials that can be used
to create good-looking models quickly and easily.
To apply a 3D material to a component, drag-and-drop a material from the
\uicontrol {Qt Quick 3D Materials} tab of \uicontrol Library to a model
component in \uicontrol Navigator. The materials you add to the model are
listed in the model component's \uicontrol Properties view.
Each material has its own set of properties that can be used to further
define the appearance of the material. For each material the \uicontrol
{Environment Map} property specifies whether or not
\l{Selecting the Mapping Method}{environment mapping} is used for
specular reflection. Use the \uicontrol Texture property to select
a texture for the environment map. The \uicontrol {Shadow Map} property
determine whether or not shadow mapping is used for generating realistic
shadows. You can also select a \uicontrol Texture for shadow mapping.
\section1 Metal Materials
The following describes properties of the metal-based materials, which
include \uicontrol Aluminum, \uicontrol {Aluminum Anod Emis}, \uicontrol
{Aluminum Anodized}, \uicontrol {Aluminum Brushed}, \uicontrol
{Aluminum Emissive}, \uicontrol Copper, and \uicontrol
{Steel Milled Concentric}.
\section2 Color
Set the surface tint of the material by specifying the
\uicontrol {Metal Color} and \uicontrol {Base Color} properties. Use
the \uicontrol {Emission Color} property to set the color of the glow for
emissive materials. You can either use the color picker or specify an
RBG value.
\section2 Reflection
Use the properties under the \uicontrol Reflection tab to specify the
reflective qualities of the material. For more information on the various
material properties related to reflection, see \l {Using Highlights and
Reflections}.
\list
\target tiling_metal
\li Use the \uicontrol {Map Offset} and \uicontrol {Map Scale}
properties to define offset and scale for the reflection map. You
can also define a texture for the reflection map by using the
\uicontrol Texture property, and set a the tiling repeat for it
by using the \uicontrol Tiling property.
\li To further define the reflective qualities of the material,
you can also set the \uicontrol Stretch and \uicontrol Texture
properties of \uicontrol Reflection, or define a numerical
value for \uicontrol Reflectivity.
\li Set the \uicontrol {Fresnel Power} property to decrease head-on
reflections (looking directly at the surface) while maintaining
reflections seen at grazing angles.
\endlist
\section2 Roughness
Use the \uicontrol Roughness properties to determine how light behaves when
it comes in contact with material. With zero roughness, light bounces off a
material, which makes it appear glossy. Increased roughness causes the light
reflected off the material to scatter, which results in a matte appearance.
\list
\li The \uicontrol {Map Offset} \uicontrol {Map Scale} and \uicontrol
Texture specify the quality of roughness applied to the material.
\li Use the numerical \uicontrol Roughness property to define how
glossy or matte the material appears.
\endlist
\target emission_metal
\section2 Emission
Use the properties under the \uicontrol Emission tab to specify the
emissive qualities of the material. For more information on properties
related to emission, see \l {Self-Illuminating Materials}.
\list
\li The \uicontrol Intensity property determines the quantity of light
the surface of material emits.
\li The \uicontrol {Map Texture} property defines a texture for
emissive map, while the \uicontrol {Mask Texture} defines a
texture for emissive mask. Use the \uicontrol {Mask Offset}
to set the mask offset for the emissive map.
\endlist
\target bump_metal
\section2 Bump
Specify the properties under the \uicontrol Bump tab to simulate fine
geometry displacement across the surface of the material. Use the
\uicontrol Amount property to set the quantity of displacement, and
the \uicontrol Texture property to define a texture for the bump map.
For more information, see \l {Simulating Geometry Displacement}.
\section2 Properties of the Steel Milled Concentric Material
Another metal, the \uicontrol {Steel Milled Concentric} Material has
certain properties that the other materials do not possess:
\list
\li The \uicontrol Anisotropy property stretches the highlight,
which simulates minuscule scratches. You can also use a
\uicontrol Texture property to define a texture for the anisotropy
map.
\li The \uicontrol {Index of Refraction} defines how much a ray of
transmitted light is bent when it reaches the surface of the
material.
\endlist
Under the \uicontrol Textures tab:
\list
\li The \uicontrol Tiling property to set the tiling repeat of the
texture maps.
\li Use the \uicontrol Diffuse property to set a texture for the
diffuse map, and the \uicontrol Anisotropy property to set a
texture for the anisotropy map.
\endlist
\section1 Glass Materials
The following describes properties related to glass-based materials, which
include \uicontrol Glass, \uicontrol {Frosted Glass}, \uicontrol
{Frosted Glass Single Pass}, and \uicontrol {Glass Refractive}.
\section2 Color
Set the surface tint of the material by specifying the
\uicontrol {Glass Color} property. You can also specify the \uicontrol
{Band Light Color} for the \uicontrol {Frosted Glass} material.
Use the \uicontrol {Glass Color} and \uicontrol {Band Light Color}
properties to set the color properties for glass-based materials.
\target general_glass
\section2 General
\list
\li Set the \uicontrol {Fresnel Power} property to decrease head-on
reflections (looking directly at the surface) while maintaining
reflections seen at grazing angles.
\li Use the \uicontrol Roughness property to determine how light
behaves when it comes in contact with material. With zero roughness,
light bounces off a material, which makes it appear glossy.
Increased roughness causes the light reflected off the material to
scatter, which results in a matte appearance.
\li The \uicontrol Reflectivity property specifies how much light is
reflected from the material.
\li The \uicontrol {Index of Refraction} defines reflectivity by
determinining how much a ray of transmitted light is bent when it
reaches the surface of the material.
\li The \uicontrol {Refract Depth} property sets the refraction depth
for the material.
\li Use the \uicontrol {Minimum Opacity} property to determine the
minimum level of opaqueness for the material.
\li The \uicontrol {Blur size} property sets the amount of blurring
behind the glass.
\endlist
\section2 Bump
For frosted glass materials, specify the properties under the
\uicontrol Bump tab to simulate fine geometry displacement across the
surface of the material:
\list
\li Use the \uicontrol Scale and \uicontrol Bands properties to define
the scale and number of the Bump Bands.
\li The \uicontrol Strength property sets the glass bump map strength.
\li Use the \uicontrol Internal property to specify whether the bump map
should only be used for internal lighting.
\li The \uicontrol Texture property to define a texture for the bump
map.
\li The \uicontrol Coordinates property sets the bump coordinates of the
refraction.
\endlist
For more information, see \l {Simulating Geometry Displacement}.
\target rgm_glass
\section2 Random Gradient Mapping
For frosted glass materials, you can also specify \uicontrol
{Random Gradient Maps} by using properties \uicontrol 1D, \uicontrol 2D,
\uicontrol 3D and \uicontrol 4D. Each of the properties defines a texture
map used to create the random bumpiness of the material.
\section2 Band Light
The outlook of the \uicontrol {Frosted Glass} material can be further
defined by specifying the \uicontrol {Band Light} properties:
\list
\li The \uicontrol Fallof property sets the light intensity falloff
rate.
\li The \uicontrol Angle property sets the angle of the light source to
which the band is perpendicular.
\li You can also set the \uicontrol Brightness of the band light.
\li Use the \uicontrol Position property to set the coordinates for
the band light in the UV space.
\endlist
\section2 Noise
For the \uicontrol {Frosted Glass Single Pass} material you can specify
the noise quality by defining the noise \uicontrol Scale property and
setting the noise \uicontrol Coordinates.
\section1 Plastic
The following describes properties for the available plastic materials,
which include \uicontrol {Plastic Structured} and \uicontrol {Plastic
Struct Emissive}.
\section2 Color
Use the \uicontrol {Diffuse Color} to set the color that the material
reflects when illuminated by direct light.
The \uicontrol {Emission Color} defines the color of emission for
the \uicontrol {Plastic Struct Emissive} material.
\section2 General
Plastic materials share some of the properties with glass materials. For
descriptions of \uicontrol Roughness and \uicontrol {Index of Refraction}
properties, see \l{general_glass} {general properties for glass materials}.
\list
\li The \uicontrol {Texture scaling} property determines how fast a
material is repeated on a surface.
\li The \uicontrol {Bump Factor} property sets the strength of bumpiness
for glass materials.
\endlist
\section2 Random Gradient Mapping
See \l {rgm_glass}{Random Gradient Mapping for Glass Materials}.
\section2 Emission
The properties of emission for glass materials are similar to those of
metal materials. For decription of emission properties, see
\l{emission_metal} {emission properties for metal materials}.
\section1 Paper Materials
The following describes properties for the available paper materials,
which include \uicontrol {Paper Artistic} and \uicontrol {Paper Office}.
\section2 Color
Set the surface tint for the \uicontrol {Paper Office} material by
specifying the \uicontrol {Paper Color} property.
\section2 Transmission
Specify the \uicontrol Transmission settings to define the outlook of light
passing through the material. The \uicontrol {Transmission Weight}
property specifies how much light scatters through the surface of the
material, while the \uicontrol {Reflection Weight} sets the luminance of
highlights and reflections.
\section2 General
\list
\li The \uicontrol {Translucency Falloff} sets the point of decline for
translucency of the material.
\li The \uicontrol Opacity property sets the material's level of
opaqueness.
\li For the description of \uicontrol {Texture Tiling} properties, see
\l {tiling_metal} {tiling for metal materials}.
\endlist
\section2 Diffuse Map
Use the \uicontrol {Light Wrap} property to set the diffuse light bend of
the material. The \uicontrol Texture property defines a texture for the
diffuse map.
\section2 Bump
For the description of \uicontrol Bump properties, see \l {bump_metal}
{properties for metal materials}.
\section1 Available Materials
See the following table for available materials.
\table
\header
\li Material
\li Example Image
\li Description
\row
\li Aluminum
\li \image material-aluminum.png "The Aluminum material"
\li A material with the appearance of aluminum.
\row
\li Aluminum Anod Emis
\li \image material-aluminum-anodized-emissive.png "The Aluminum Anodized Emissive material"
\li Anodized aluminum with emissive properties.
\row
\li Aluminum Anodized
\li \image material-aluminum-anodized.png "The Anodized Aluminum material"
\li Anodized aluminum.
\row
\li Aluminum Brushed
\li \image material-aluminum-brushed.png "The Brushed Aluminum material"
\li Brushed aluminum.
\row
\li Aluminum Emissive
\li \image material-aluminum-emissive.png "The Aluminum Emissive material"
\li Aluminum with emissive properties.
\row
\li Copper
\li \image material-copper.png "The Copper material"
\li A material with the appearance of copper.
\row
\li Glass
\li \image material-glass.png "The Glass material"
\li A material with the appearance of glass.
\row
\li Frosted glass
\li \image material-frosted-glass.png "The Frosted Glass material"
\li Frosted glass.
\row
\li Frosted Glass Single Pass
\li \image material-frosted-glass-single-pass.png "The Frosted Glass Single Pass material"
\li A single-pass frosted glass.
\row
\li Glass Refractive
\li \image material-refractive-glass.png "The Glass Refractive material"
\li Refractive glass.
\row
\li Paper Artistic
\li \image material-artistic-paper.png "The Paper Artistic material"
\li A paper material with an artistic finishing.
\row
\li Paper Office
\li \image material-office-paper.png "The Paper Office material"
\li A paper material with an office-style finishing.
\row
\li Plastic Struct Emissive
\li \image material-red-plastic-structured-emissive.png The Plastic Structured Emissive material"
\li A red structured plastic material with emissive properties.
\row
\li Plastic Structured
\li \image material-red-plastic-structured.png "The Plastic Structured material"
\li A red structured plastic material.
\row
\li Steel Milled Concentric
\li \image material-steel-milled-concentric.png "The Steel Milled Concentric material"
\li A milled concentric steel material.
\endtable
*/

View File

@@ -28,7 +28,7 @@
/*! /*!
\page studio-3d-texture.html \page studio-3d-texture.html
\previouspage studio-3d-materials.html \previouspage studio-3d-materials.html
\nextpage studio-3d-effects.html \nextpage studio-3d-materials-types.html
\title Attaching Textures to Materials \title Attaching Textures to Materials
@@ -112,9 +112,12 @@
\section1 Applying Textures to Materials \section1 Applying Textures to Materials
You drag and drop an image from \uicontrol Library > \uicontrol Assets Drag and drop an image from \uicontrol Library > \uicontrol Assets
on a material to create and set the texture automatically, or you can use on a material to create and set the texture automatically, or use
a Texture component. a Texture component. For a default material the created \uicontrol Texture
is assigned to the \uicontrol {Diffuse Map} property and for a principled
material to the \uicontrol {Base Color Map}. For a custom material, you
must assign the texture to a map.
To use Texture components to apply textures to materials: To use Texture components to apply textures to materials:

View File

@@ -35,11 +35,11 @@
\title Editing 3D Scenes \title Editing 3D Scenes
You can use the 3D editor in the Design mode to edit files you created You can use \uicontrol {3D Editor} in the Design mode to edit files you
using 3D graphics applications and stored in one of the supported formats. created using 3D graphics applications and stored in one of the supported
You cannot create 3D models or other assets in the editor, but you can formats. You cannot create 3D models or other assets in the editor, but you
\l{Importing 3D Assets}{import} the assets you need and work with them to can \l{Importing 3D Assets}{import} the assets you need and work with them
create scenes and states, as well as the transitions between them. to create scenes and states, as well as the transitions between them.
When you import 3D scenes from files that you exported from 3D graphics When you import 3D scenes from files that you exported from 3D graphics
tools, you also import the camera, light, model, and materials as 3D tools, you also import the camera, light, model, and materials as 3D
@@ -66,17 +66,17 @@
\li \l {Editing 3D Assets in Design Mode} \li \l {Editing 3D Assets in Design Mode}
\QDS opens QML files that contain 3D scenes in the Design mode and \QDS opens QML files that contain 3D scenes in the Design mode and
the scenes in the 3D editor. You can add imported 3D assets the scenes in \uicontrol {3D Editor}. You can add imported 3D assets
to projects as 3D components. to projects as 3D components.
\li \l {Working in 3D Editor} \li \l {Working in 3D Editor}
You can select 3D components in the 3D editor to move, rotate, and You can select 3D components in \uicontrol {3D Editor} to move,
scale them in the scene projected by the camera. rotate, and scale them in the scene projected by the camera.
\li \l{Adding 3D Views} \li \l{Adding 3D Views}
You can drag and drop 3D components from the \uicontrol Library You can drag and drop 3D components from \uicontrol Library
to the scene or to the \uicontrol Navigator. You must add all to the scene or to \uicontrol Navigator. You must add all 3D
3D components into a 3D view. components into a 3D view.
\li \l {Using 3D Components} \li \l {Using 3D Components}
You can speficy properties for 3D components, such as cameras, You can speficy properties for 3D components, such as cameras,

View File

@@ -58,10 +58,7 @@ public:
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
} }
QVector3D toVec3() const QVector3D toVec3() const { return {float(x), float(y), float(z)}; }
{
return QVector3D(float(x), float(y), float(z));
}
DoubleVec3D normalized() const DoubleVec3D normalized() const
{ {
@@ -82,6 +79,8 @@ public:
return std::sqrt(len); return std::sqrt(len);
} }
DoubleVec3D operator-() { return {-x, -y, -z}; }
double x = 0.; double x = 0.;
double y = 0.; double y = 0.;
double z = 0.; double z = 0.;
@@ -119,6 +118,268 @@ DoubleVec3D operator/(const DoubleVec3D &v1, const DoubleVec3D &v2)
return DoubleVec3D(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z); return DoubleVec3D(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
} }
// Limited functionality double precision matrix4x4 for cases where float calculations
// can suffer from rounding errors
class DoubleMat44 {
public:
DoubleMat44()
{
// Default is identity matrix
m[0][0] = 1.;
m[0][1] = 0.;
m[0][2] = 0.;
m[0][3] = 0.;
m[1][0] = 0.;
m[1][1] = 1.;
m[1][2] = 0.;
m[1][3] = 0.;
m[2][0] = 0.;
m[2][1] = 0.;
m[2][2] = 1.;
m[2][3] = 0.;
m[3][0] = 0.;
m[3][1] = 0.;
m[3][2] = 0.;
m[3][3] = 1.;
}
DoubleMat44(const QMatrix4x4 &mat)
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j)
m[i][j] = double(mat(j, i));
}
}
QMatrix4x4 toQMatrix4x4()
{
return QMatrix4x4(float(m[0][0]), float(m[1][0]), float(m[2][0]), float(m[3][0]),
float(m[0][1]), float(m[1][1]), float(m[2][1]), float(m[3][1]),
float(m[0][2]), float(m[1][2]), float(m[2][2]), float(m[3][2]),
float(m[0][3]), float(m[1][3]), float(m[2][3]), float(m[3][3]));
}
static inline double matrixDet2(const double m[4][4], int col0, int col1, int row0, int row1)
{
return m[col0][row0] * m[col1][row1] - m[col0][row1] * m[col1][row0];
}
static inline double matrixDet3(const double m[4][4], int col0, int col1, int col2,
int row0, int row1, int row2)
{
return m[col0][row0] * matrixDet2(m, col1, col2, row1, row2)
- m[col1][row0] * matrixDet2(m, col0, col2, row1, row2)
+ m[col2][row0] * matrixDet2(m, col0, col1, row1, row2);
}
DoubleMat44 inverted()
{
DoubleMat44 inv;
double det = matrixDet3(m, 0, 1, 2, 0, 1, 2);
if (det != 0.) {
det = 1. / det;
inv.m[0][0] = matrixDet2(m, 1, 2, 1, 2) * det;
inv.m[0][1] = -matrixDet2(m, 0, 2, 1, 2) * det;
inv.m[0][2] = matrixDet2(m, 0, 1, 1, 2) * det;
inv.m[0][3] = 0;
inv.m[1][0] = -matrixDet2(m, 1, 2, 0, 2) * det;
inv.m[1][1] = matrixDet2(m, 0, 2, 0, 2) * det;
inv.m[1][2] = -matrixDet2(m, 0, 1, 0, 2) * det;
inv.m[1][3] = 0;
inv.m[2][0] = matrixDet2(m, 1, 2, 0, 1) * det;
inv.m[2][1] = -matrixDet2(m, 0, 2, 0, 1) * det;
inv.m[2][2] = matrixDet2(m, 0, 1, 0, 1) * det;
inv.m[2][3] = 0;
inv.m[3][0] = -inv.m[0][0] * m[3][0] - inv.m[1][0] * m[3][1] - inv.m[2][0] * m[3][2];
inv.m[3][1] = -inv.m[0][1] * m[3][0] - inv.m[1][1] * m[3][1] - inv.m[2][1] * m[3][2];
inv.m[3][2] = -inv.m[0][2] * m[3][0] - inv.m[1][2] * m[3][1] - inv.m[2][2] * m[3][2];
inv.m[3][3] = 1;
}
return inv;
}
DoubleVec3D transform(const DoubleVec3D &v)
{
DoubleVec3D ret;
auto multCol = [&](int c, double d) {
ret.x += m[c][0] * d;
ret.y += m[c][1] * d;
ret.z += m[c][2] * d;
};
multCol(0, v.x);
multCol(1, v.y);
multCol(2, v.z);
multCol(3, 1.);
return ret;
}
static DoubleMat44 matrixMultiD(const QMatrix4x4& m1, const QMatrix4x4& m2)
{
DoubleMat44 m1d(m1);
DoubleMat44 m2d(m2);
return matrixMultiD(m1d, m2d);
}
static DoubleMat44 matrixMultiD(const DoubleMat44& m1, const DoubleMat44& m2)
{
DoubleMat44 m;
m.m[0][0] = m1.m[0][0] * m2.m[0][0]
+ m1.m[1][0] * m2.m[0][1]
+ m1.m[2][0] * m2.m[0][2]
+ m1.m[3][0] * m2.m[0][3];
m.m[0][1] = m1.m[0][1] * m2.m[0][0]
+ m1.m[1][1] * m2.m[0][1]
+ m1.m[2][1] * m2.m[0][2]
+ m1.m[3][1] * m2.m[0][3];
m.m[0][2] = m1.m[0][2] * m2.m[0][0]
+ m1.m[1][2] * m2.m[0][1]
+ m1.m[2][2] * m2.m[0][2]
+ m1.m[3][2] * m2.m[0][3];
m.m[0][3] = m1.m[0][3] * m2.m[0][0]
+ m1.m[1][3] * m2.m[0][1]
+ m1.m[2][3] * m2.m[0][2]
+ m1.m[3][3] * m2.m[0][3];
m.m[1][0] = m1.m[0][0] * m2.m[1][0]
+ m1.m[1][0] * m2.m[1][1]
+ m1.m[2][0] * m2.m[1][2]
+ m1.m[3][0] * m2.m[1][3];
m.m[1][1] = m1.m[0][1] * m2.m[1][0]
+ m1.m[1][1] * m2.m[1][1]
+ m1.m[2][1] * m2.m[1][2]
+ m1.m[3][1] * m2.m[1][3];
m.m[1][2] = m1.m[0][2] * m2.m[1][0]
+ m1.m[1][2] * m2.m[1][1]
+ m1.m[2][2] * m2.m[1][2]
+ m1.m[3][2] * m2.m[1][3];
m.m[1][3] = m1.m[0][3] * m2.m[1][0]
+ m1.m[1][3] * m2.m[1][1]
+ m1.m[2][3] * m2.m[1][2]
+ m1.m[3][3] * m2.m[1][3];
m.m[2][0] = m1.m[0][0] * m2.m[2][0]
+ m1.m[1][0] * m2.m[2][1]
+ m1.m[2][0] * m2.m[2][2]
+ m1.m[3][0] * m2.m[2][3];
m.m[2][1] = m1.m[0][1] * m2.m[2][0]
+ m1.m[1][1] * m2.m[2][1]
+ m1.m[2][1] * m2.m[2][2]
+ m1.m[3][1] * m2.m[2][3];
m.m[2][2] = m1.m[0][2] * m2.m[2][0]
+ m1.m[1][2] * m2.m[2][1]
+ m1.m[2][2] * m2.m[2][2]
+ m1.m[3][2] * m2.m[2][3];
m.m[2][3] = m1.m[0][3] * m2.m[2][0]
+ m1.m[1][3] * m2.m[2][1]
+ m1.m[2][3] * m2.m[2][2]
+ m1.m[3][3] * m2.m[2][3];
m.m[3][0] = m1.m[0][0] * m2.m[3][0]
+ m1.m[1][0] * m2.m[3][1]
+ m1.m[2][0] * m2.m[3][2]
+ m1.m[3][0] * m2.m[3][3];
m.m[3][1] = m1.m[0][1] * m2.m[3][0]
+ m1.m[1][1] * m2.m[3][1]
+ m1.m[2][1] * m2.m[3][2]
+ m1.m[3][1] * m2.m[3][3];
m.m[3][2] = m1.m[0][2] * m2.m[3][0]
+ m1.m[1][2] * m2.m[3][1]
+ m1.m[2][2] * m2.m[3][2]
+ m1.m[3][2] * m2.m[3][3];
m.m[3][3] = m1.m[0][3] * m2.m[3][0]
+ m1.m[1][3] * m2.m[3][1]
+ m1.m[2][3] * m2.m[3][2]
+ m1.m[3][3] * m2.m[3][3];
return m;
}
static DoubleMat44 rotationMatrix(const QQuaternion &rot)
{
DoubleMat44 rotMat;
double xp = double(rot.x());
double yp = double(rot.y());
double zp = double(rot.z());
double wp = double(rot.scalar());
const double f2x = xp + xp;
const double f2y = yp + yp;
const double f2z = zp + zp;
const double f2xw = f2x * wp;
const double f2yw = f2y * wp;
const double f2zw = f2z * wp;
const double f2xx = f2x * xp;
const double f2xy = f2x * yp;
const double f2xz = f2x * zp;
const double f2yy = f2y * yp;
const double f2yz = f2y * zp;
const double f2zz = f2z * zp;
rotMat.m[0][0] = 1. - (f2yy + f2zz);
rotMat.m[1][0] = f2xy - f2zw;
rotMat.m[2][0] = f2xz + f2yw;
rotMat.m[0][1] = f2xy + f2zw;
rotMat.m[1][1] = 1. - (f2xx + f2zz);
rotMat.m[2][1] = f2yz - f2xw;
rotMat.m[0][2] = f2xz - f2yw;
rotMat.m[1][2] = f2yz + f2xw;
rotMat.m[2][2] = 1. - (f2xx + f2yy);
return rotMat;
}
double m[4][4];
};
static DoubleMat44 calcLocalTransform(const QQuick3DNode *node)
{
DoubleVec3D pivotD(-node->pivot());
const DoubleVec3D scaleD(node->scale());
const DoubleVec3D posD(node->position());
pivotD = pivotD * scaleD;
DoubleMat44 localTransform;
localTransform.m[0][0] = scaleD.x;
localTransform.m[1][1] = scaleD.y;
localTransform.m[2][2] = scaleD.z;
localTransform.m[3][0] = pivotD.x;
localTransform.m[3][1] = pivotD.y;
localTransform.m[3][2] = pivotD.z;
DoubleMat44 rotMat = DoubleMat44::rotationMatrix(node->rotation());
localTransform = DoubleMat44::matrixMultiD(rotMat, localTransform);
localTransform.m[3][0] += posD.x;
localTransform.m[3][1] += posD.y;
localTransform.m[3][2] += posD.z;
return localTransform;
}
static DoubleMat44 calcGlobalTransform(const QQuick3DNode *node)
{
DoubleMat44 localTrans = calcLocalTransform(node);
QQuick3DNode *parent = node->parentNode();
if (parent) {
DoubleMat44 globalTrans = calcGlobalTransform(parent);
return DoubleMat44::matrixMultiD(globalTrans, localTrans);
}
return localTrans;
}
static DoubleVec3D getNormalD(const DoubleMat44 &m)
{
return DoubleVec3D(m.m[2][0], m.m[2][1], m.m[2][2]).normalized();
}
MouseArea3D *MouseArea3D::s_mouseGrab = nullptr; MouseArea3D *MouseArea3D::s_mouseGrab = nullptr;
MouseArea3D::MouseArea3D(QQuick3DNode *parent) MouseArea3D::MouseArea3D(QQuick3DNode *parent)
@@ -333,6 +594,36 @@ void MouseArea3D::componentComplete()
m_view3D->installEventFilter(this); m_view3D->installEventFilter(this);
} }
static DoubleVec3D rayIntersectsPlaneD(const DoubleVec3D &rayPos0,
const DoubleVec3D &rayPos1,
const DoubleVec3D &planePos,
const DoubleVec3D &planeNormal)
{
const DoubleVec3D rayDirection = rayPos1 - rayPos0;
const DoubleVec3D rayPos0RelativeToPlane = rayPos0 - planePos;
const double dotPlaneRayDirection = DoubleVec3D::dotProduct(planeNormal, rayDirection);
const double dotPlaneRayPos0 = -DoubleVec3D::dotProduct(planeNormal, rayPos0RelativeToPlane);
if (qFuzzyIsNull(dotPlaneRayDirection)) {
// The ray is is parallel to the plane. Note that if dotPlaneRayPos0 == 0, it
// additionally means that the line lies in plane as well. In any case, we
// signal that we cannot find a single intersection point.
return DoubleVec3D(0., 0., -1.);
}
// Since we work with a ray (that has a start), distanceFromRayPos0ToPlane
// must be above 0. If it was a line segment (with an end), it also need to be less than 1.
// (Note: a third option would be a "line", which is different from a ray or segment in that
// it has neither a start, nor an end). Then we wouldn't need to check the distance at all.
// But that would also mean that the line could intersect the plane behind the camera, if
// the line were directed away from the plane when looking forward.
const double distanceFromRayPos0ToPlane = dotPlaneRayPos0 / dotPlaneRayDirection;
if (distanceFromRayPos0ToPlane <= 0.)
return DoubleVec3D(0., 0., -1.);
return (rayPos0 + distanceFromRayPos0ToPlane * rayDirection);
}
QVector3D MouseArea3D::rayIntersectsPlane(const QVector3D &rayPos0, QVector3D MouseArea3D::rayIntersectsPlane(const QVector3D &rayPos0,
const QVector3D &rayPos1, const QVector3D &rayPos1,
const QVector3D &planePos, const QVector3D &planePos,
@@ -342,29 +633,8 @@ QVector3D MouseArea3D::rayIntersectsPlane(const QVector3D &rayPos0,
const DoubleVec3D rayPos1D(rayPos1); const DoubleVec3D rayPos1D(rayPos1);
const DoubleVec3D planePosD(planePos); const DoubleVec3D planePosD(planePos);
const DoubleVec3D planeNormalD(planeNormal); const DoubleVec3D planeNormalD(planeNormal);
const DoubleVec3D rayDirectionD = rayPos1D - rayPos0D;
const DoubleVec3D rayPos0RelativeToPlaneD = rayPos0D - planePosD;
const double dotPlaneRayDirection = DoubleVec3D::dotProduct(planeNormalD, rayDirectionD); return rayIntersectsPlaneD(rayPos0D, rayPos1D, planePosD, planeNormalD).toVec3();
const double dotPlaneRayPos0 = -DoubleVec3D::dotProduct(planeNormalD, rayPos0RelativeToPlaneD);
if (qFuzzyIsNull(dotPlaneRayDirection)) {
// The ray is is parallel to the plane. Note that if dotLinePos0 == 0, it
// additionally means that the line lies in plane as well. In any case, we
// signal that we cannot find a single intersection point.
return QVector3D(0.f, 0.f, -1.f);
}
// Since we work with a ray (that has a start), distanceFromLinePos0ToPlane
// must be above 0. If it was a line segment (with an end), it also need to be less than 1.
// (Note: a third option would be a "line", which is different from a ray or segment in that
// it has neither a start, nor an end). Then we wouldn't need to check the distance at all.
// But that would also mean that the line could intersect the plane behind the camera, if
// the line were directed away from the plane when looking forward.
const double distanceFromRayPos0ToPlane = dotPlaneRayPos0 / dotPlaneRayDirection;
if (distanceFromRayPos0ToPlane <= 0.)
return QVector3D(0.f, 0.f, -1.f);
return (rayPos0D + distanceFromRayPos0ToPlane * rayDirectionD).toVec3();
} }
// Get a new scale based on a relative scene distance along a drag axes. // Get a new scale based on a relative scene distance along a drag axes.
@@ -544,18 +814,28 @@ QVector3D MouseArea3D::getMousePosInPlane(const MouseArea3D *helper,
if (!helper) if (!helper)
helper = this; helper = this;
const QVector3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0); const DoubleVec3D mousePos1(float(mousePosInView.x()), float(mousePosInView.y()), 0);
const QVector3D rayPos0 = m_view3D->mapTo3DScene(mousePos1); const DoubleVec3D rayPos0 = m_view3D->mapTo3DScene(mousePos1.toVec3());
const QVector3D mousePos2(float(mousePosInView.x()), float(mousePosInView.y()), DoubleVec3D rayPos1;
rayPos0.length()); if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) {
const QVector3D rayPos1 = m_view3D->mapTo3DScene(mousePos2); rayPos1 = rayPos0 - rayPos0.length() * DoubleVec3D(m_view3D->camera()->cameraNode()->getDirection());
const QVector3D globalPlanePosition = helper->mapPositionToScene(QVector3D(0, 0, 0)); } else {
const QVector3D intersectGlobalPos = rayIntersectsPlane(rayPos0, rayPos1, DoubleVec3D dir;
globalPlanePosition, helper->forward()); DoubleVec3D camPos = m_view3D->camera()->scenePosition();
if (qFuzzyCompare(intersectGlobalPos.z(), -1)) dir = (rayPos0 - camPos).normalized();
return intersectGlobalPos; rayPos1 = rayPos0 + rayPos0.length() * dir;
}
return helper->mapPositionFromScene(intersectGlobalPos); const DoubleVec3D globalPlanePosition = helper->mapPositionToScene(QVector3D(0, 0, 0));
DoubleMat44 sceneTrans = calcGlobalTransform(helper);
const DoubleVec3D intersectGlobalPos = rayIntersectsPlaneD(rayPos0, rayPos1,
globalPlanePosition,
-getNormalD(sceneTrans));
if (qFuzzyCompare(intersectGlobalPos.z, -1.))
return intersectGlobalPos.toVec3();
return sceneTrans.inverted().transform(intersectGlobalPos).toVec3();
} }
bool MouseArea3D::eventFilter(QObject *, QEvent *event) bool MouseArea3D::eventFilter(QObject *, QEvent *event)

View File

@@ -51,11 +51,13 @@ Section {
Label { Label {
text: qsTr("Paused") text: qsTr("Paused")
tooltip: qsTr("Whether the animation is paused.") tooltip: qsTr("Whether the animation is paused.")
disabledState: !backendValues.paused.isAvailable
} }
CheckBox { CheckBox {
text: backendValues.paused.valueToString text: backendValues.paused.valueToString
backendValue: backendValues.paused backendValue: backendValues.paused
enabled: backendValue.isAvailable
} }
Label { Label {
text: qsTr("Loops") text: qsTr("Loops")

View File

@@ -56,6 +56,7 @@ Section {
LineEdit { LineEdit {
backendValue: backendValues.property backendValue: backendValues.property
Layout.fillWidth: true Layout.fillWidth: true
showTranslateCheckBox: false
} }
Label { Label {
text: qsTr("Properties") text: qsTr("Properties")
@@ -64,6 +65,7 @@ Section {
LineEdit { LineEdit {
backendValue: backendValues.properties backendValue: backendValues.properties
Layout.fillWidth: true Layout.fillWidth: true
showTranslateCheckBox: false
} }
} }

View File

@@ -1835,7 +1835,10 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
if (value) if (value)
break; break;
} }
if (!value) {
const bool isListElementScope = (!m_typeStack.isEmpty() && m_typeStack.last() == "ListElement");
if (!value && !isListElementScope) {
addMessage(ErrInvalidPropertyName, id->identifierToken, propertyName); addMessage(ErrInvalidPropertyName, id->identifierToken, propertyName);
return nullptr; return nullptr;
} }

View File

@@ -32,7 +32,7 @@ namespace ClangRefactoring {
BaseClangQueryTextEditorWidget::BaseClangQueryTextEditorWidget(QWidget *parent) BaseClangQueryTextEditorWidget::BaseClangQueryTextEditorWidget(QWidget *parent)
: TextEditor::TextEditorWidget(parent) : TextEditor::TextEditorWidget(parent)
{ {
setupFallBackEditor(Core::Id()); setupFallBackEditor(Utils::Id());
setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
setHighlightCurrentLine(false); setHighlightCurrentLine(false);
setLineNumbersVisible(false); setLineNumbersVisible(false);

View File

@@ -343,8 +343,8 @@ void CMakeToolItemModel::removeCMakeTool(const Utils::Id &id)
CMakeToolTreeItem *treeItem = cmakeToolItem(id); CMakeToolTreeItem *treeItem = cmakeToolItem(id);
QTC_ASSERT(treeItem, return); QTC_ASSERT(treeItem, return);
destroyItem(treeItem);
m_removedItems.append(id); m_removedItems.append(id);
destroyItem(treeItem);
} }
void CMakeToolItemModel::apply() void CMakeToolItemModel::apply()

View File

@@ -154,8 +154,10 @@ void TabWidget::slotContextMenuRequested(const QPoint &pos)
AppOutputPane::RunControlTab::RunControlTab(RunControl *runControl, Core::OutputWindow *w) : AppOutputPane::RunControlTab::RunControlTab(RunControl *runControl, Core::OutputWindow *w) :
runControl(runControl), window(w) runControl(runControl), window(w)
{ {
if (runControl && w) if (runControl && w) {
w->setLineParsers(runControl->createOutputParsers()); w->reset();
runControl->setupFormatter(w->outputFormatter());
}
} }
AppOutputPane::AppOutputPane() : AppOutputPane::AppOutputPane() :
@@ -405,7 +407,8 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
if (tab.runControl) if (tab.runControl)
tab.runControl->initiateFinish(); tab.runControl->initiateFinish();
tab.runControl = rc; tab.runControl = rc;
tab.window->setLineParsers(rc->createOutputParsers()); tab.window->reset();
rc->setupFormatter(tab.window->outputFormatter());
handleOldOutput(tab.window); handleOldOutput(tab.window);

View File

@@ -41,6 +41,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/checkablemessagebox.h> #include <utils/checkablemessagebox.h>
#include <utils/detailswidget.h> #include <utils/detailswidget.h>
#include <utils/fileinprojectfinder.h>
#include <utils/outputformatter.h> #include <utils/outputformatter.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
@@ -824,7 +825,7 @@ void RunControlPrivate::showError(const QString &msg)
q->appendMessage(msg + '\n', ErrorMessageFormat); q->appendMessage(msg + '\n', ErrorMessageFormat);
} }
QList<Utils::OutputLineParser *> RunControl::createOutputParsers() const void RunControl::setupFormatter(OutputFormatter *formatter) const
{ {
QList<Utils::OutputLineParser *> parsers = OutputFormatterFactory::createFormatters(target()); QList<Utils::OutputLineParser *> parsers = OutputFormatterFactory::createFormatters(target());
if (const auto customParsersAspect if (const auto customParsersAspect
@@ -834,7 +835,11 @@ QList<Utils::OutputLineParser *> RunControl::createOutputParsers() const
parsers << parser; parsers << parser;
} }
} }
return parsers; formatter->setLineParsers(parsers);
Utils::FileInProjectFinder fileFinder;
fileFinder.setProjectDirectory(project()->projectDirectory());
fileFinder.setProjectFiles(project()->files(Project::AllFiles));
formatter->setFileFinder(fileFinder);
} }
Utils::Id RunControl::runMode() const Utils::Id RunControl::runMode() const

View File

@@ -46,6 +46,7 @@
namespace Utils { namespace Utils {
class MacroExpander; class MacroExpander;
class OutputLineParser; class OutputLineParser;
class OutputFormatter;
} // Utils } // Utils
namespace ProjectExplorer { namespace ProjectExplorer {
@@ -238,7 +239,7 @@ public:
Utils::FilePath targetFilePath() const; Utils::FilePath targetFilePath() const;
Utils::FilePath projectFilePath() const; Utils::FilePath projectFilePath() const;
QList<Utils::OutputLineParser *> createOutputParsers() const; void setupFormatter(Utils::OutputFormatter *formatter) const;
Utils::Id runMode() const; Utils::Id runMode() const;
const Runnable &runnable() const; const Runnable &runnable() const;

View File

@@ -0,0 +1,91 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "choosetexturepropertydialog.h"
#include "nodemetainfo.h"
#include "ui_choosetexturepropertydialog.h"
namespace QmlDesigner {
// This dialog displays all texture properties of an object and allows the user to choose one
ChooseTexturePropertyDialog::ChooseTexturePropertyDialog(const ModelNode &node, QWidget *parent)
: QDialog(parent)
, m_ui(new Ui::ChooseTexturePropertyDialog)
{
m_ui->setupUi(this);
setWindowTitle(tr("Select Texture Property"));
m_ui->label->setText(tr("Set texture to property:"));
setFixedSize(size());
connect(m_ui->listProps, &QListWidget::itemClicked, this, [this](QListWidgetItem *item) {
m_selectedProperty = item->isSelected() ? item->data(Qt::DisplayRole).toByteArray() : QByteArray();
});
connect(m_ui->listProps, &QListWidget::itemDoubleClicked, this, [this](QListWidgetItem *item) {
Q_UNUSED(item)
QDialog::accept();
});
fillList(node);
}
ChooseTexturePropertyDialog::~ChooseTexturePropertyDialog()
{
delete m_ui;
}
TypeName ChooseTexturePropertyDialog::selectedProperty() const
{
return m_selectedProperty;
}
void ChooseTexturePropertyDialog::fillList(const ModelNode &node)
{
// Fill the list with all properties of type Texture
const auto metaInfo = node.metaInfo();
const auto propNames = metaInfo.propertyNames();
const TypeName textureProp("QtQuick3D.Texture");
QStringList nameList;
for (const auto &propName : propNames) {
if (metaInfo.propertyTypeName(propName) == textureProp)
nameList.append(QString::fromLatin1(propName));
}
if (!nameList.isEmpty()) {
QString defaultProp = nameList.first();
nameList.sort();
for (const auto &propName : qAsConst(nameList)) {
QListWidgetItem *newItem = new QListWidgetItem(propName);
m_ui->listProps->addItem(newItem);
}
// Select the default prop
m_ui->listProps->setCurrentRow(nameList.indexOf(defaultProp));
m_selectedProperty = defaultProp.toLatin1();
}
}
}

View File

@@ -0,0 +1,54 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <modelnode.h>
#include <nodeinstanceglobal.h>
#include <QtWidgets/qdialog.h>
namespace QmlDesigner {
namespace Ui {
class ChooseTexturePropertyDialog;
}
class ChooseTexturePropertyDialog : public QDialog
{
Q_OBJECT
public:
explicit ChooseTexturePropertyDialog(const ModelNode &node, QWidget *parent = 0);
~ChooseTexturePropertyDialog();
TypeName selectedProperty() const;
private:
void fillList(const ModelNode &node);
Ui::ChooseTexturePropertyDialog *m_ui;
TypeName m_selectedProperty;
};
}

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmlDesigner::ChooseTexturePropertyDialog</class>
<widget class="QDialog" name="QmlDesigner::ChooseTexturePropertyDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>250</width>
<height>250</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>150</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listProps"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QmlDesigner::ChooseTexturePropertyDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>240</x>
<y>240</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QmlDesigner::ChooseTexturePropertyDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>240</x>
<y>240</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -5,7 +5,8 @@ SOURCES += navigatorview.cpp \
navigatorwidget.cpp \ navigatorwidget.cpp \
nameitemdelegate.cpp \ nameitemdelegate.cpp \
iconcheckboxitemdelegate.cpp \ iconcheckboxitemdelegate.cpp \
navigatortreeview.cpp navigatortreeview.cpp \
choosetexturepropertydialog.cpp
HEADERS += navigatorview.h \ HEADERS += navigatorview.h \
navigatortreemodel.h \ navigatortreemodel.h \
@@ -13,6 +14,9 @@ HEADERS += navigatorview.h \
nameitemdelegate.h \ nameitemdelegate.h \
iconcheckboxitemdelegate.h \ iconcheckboxitemdelegate.h \
navigatortreeview.h \ navigatortreeview.h \
navigatormodelinterface.h navigatormodelinterface.h \
choosetexturepropertydialog.h
RESOURCES += navigator.qrc RESOURCES += navigator.qrc
FORMS += choosetexturepropertydialog.ui

View File

@@ -25,6 +25,7 @@
#include "navigatortreemodel.h" #include "navigatortreemodel.h"
#include "navigatorview.h" #include "navigatorview.h"
#include "choosetexturepropertydialog.h"
#include "qmldesignerplugin.h" #include "qmldesignerplugin.h"
#include <bindingproperty.h> #include <bindingproperty.h>
@@ -51,6 +52,7 @@
#include <QApplication> #include <QApplication>
#include <QPointF> #include <QPointF>
#include <QDir> #include <QDir>
#include <QFileInfo>
#include <coreplugin/messagebox.h> #include <coreplugin/messagebox.h>
@@ -649,6 +651,10 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
// create a texture // create a texture
newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {}, targetProp, false); newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {}, targetProp, false);
// Rename the node based on source image
QFileInfo fi(imagePath);
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(), "textureImage"));
return newModelNode.isValid(); return newModelNode.isValid();
} }
return false; return false;
@@ -656,16 +662,21 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
if (targetNode.isSubclassOf("QtQuick3D.Material")) { if (targetNode.isSubclassOf("QtQuick3D.Material")) {
// if dropping an image on a default material, create a texture instead of image // if dropping an image on a default material, create a texture instead of image
ChooseTexturePropertyDialog *dialog = nullptr;
if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial") || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
// Show texture property selection dialog
dialog = new ChooseTexturePropertyDialog(targetNode, Core::ICore::dialogParent());
dialog->exec();
}
if (!dialog || dialog->result() == QDialog::Accepted) {
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryImageDrop", [&] { m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryImageDrop", [&] {
if (createTextureNode(targetProperty)) { if (createTextureNode(targetProperty) && dialog) {
// Automatically set the texture to default property // Automatically set the texture to selected property
// TODO: allow the user to choose which map property to set the texture for (QDS-2326) targetNode.bindingProperty(dialog->selectedProperty()).setExpression(newModelNode.validId());
if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial"))
targetNode.bindingProperty("diffuseMap").setExpression(newModelNode.validId());
else if (targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial"))
targetNode.bindingProperty("baseColorMap").setExpression(newModelNode.validId());
} }
}); });
}
delete dialog;
} else if (targetNode.isSubclassOf("QtQuick3D.TextureInput")) { } else if (targetNode.isSubclassOf("QtQuick3D.TextureInput")) {
// If dropping an image on a TextureInput, create a texture on the same level as // If dropping an image on a TextureInput, create a texture on the same level as
// TextureInput, as the TextureInput doesn't support Texture children (QTBUG-86219) // TextureInput, as the TextureInput doesn't support Texture children (QTBUG-86219)

View File

@@ -276,6 +276,7 @@ static QList<QByteArray> prepareNonMcuProperties()
{ {
QList<QByteArray> result; QList<QByteArray> result;
//Builtins:
const QList<QByteArray> itemProperties = {"layer", "opacity", "gradient", "smooth", "antialiasing", const QList<QByteArray> itemProperties = {"layer", "opacity", "gradient", "smooth", "antialiasing",
"border", "baselineOffset", "focus", "activeFocusOnTab"}; "border", "baselineOffset", "focus", "activeFocusOnTab"};
const QList<QByteArray> mouseAreaProperties = {"propagateComposedEvents", "preventStealing", "cursorShape", const QList<QByteArray> mouseAreaProperties = {"propagateComposedEvents", "preventStealing", "cursorShape",
@@ -296,6 +297,19 @@ static QList<QByteArray> prepareNonMcuProperties()
"highlightResizeDuration", "preferredHighlightBegin", "layoutDirection", "highlightResizeDuration", "preferredHighlightBegin", "layoutDirection",
"preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps", "preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps",
"snapMode", "highlightMoveVelocity", "highlightResizeVelocity"}; "snapMode", "highlightMoveVelocity", "highlightResizeVelocity"};
//Animations:
const QList<QByteArray> animationProperties = {"paused"};
//QtQuick.Controls:
const QList<QByteArray> controlProperties = {"focusPolicy", "hoverEnabled", "wheelEnabled"};
const QList<QByteArray> abstractButtonProperties = {"display", "autoExclusive"};
const QList<QByteArray> buttonProperties = {"flat", "highlighted"};
const QList<QByteArray> dialProperties = {}; //nothing in propeditor
const QList<QByteArray> progressBarProperties = {"indeterminate"};
const QList<QByteArray> radioButton = {}; //nothing in propeditor
const QList<QByteArray> sliderProperties = {"live", "snapMode", "touchDragThreshold"};
const QList<QByteArray> swipeViewProperties = {}; //nothing in propeditor
const QList<QByteArray> switchProperties = {}; //nothing in propeditor
result.append(itemProperties); result.append(itemProperties);
result.append(mouseAreaProperties); result.append(mouseAreaProperties);
@@ -305,13 +319,25 @@ static QList<QByteArray> prepareNonMcuProperties()
result.append(paddingProperties); result.append(paddingProperties);
result.append(columnRowProperties); result.append(columnRowProperties);
result.append(listViewProperties); result.append(listViewProperties);
result.append(animationProperties);
result.append(controlProperties);
result.append(abstractButtonProperties);
result.append(buttonProperties);
result.append(dialProperties);
result.append(progressBarProperties);
result.append(radioButton);
result.append(sliderProperties);
result.append(swipeViewProperties);
result.append(switchProperties);
return result; return result;
} }
bool PropertyEditorValue::isAvailable() const bool PropertyEditorValue::isAvailable() const
{ {
if (!m_modelNode.isValid())
return true;
const QList<QByteArray> nonMcuProperties = prepareNonMcuProperties(); const QList<QByteArray> nonMcuProperties = prepareNonMcuProperties();
const QByteArray fontPrefix = {"font"}; const QByteArray fontPrefix = {"font"};

View File

@@ -160,6 +160,7 @@ public:
ModelNode modelNodeForId(const QString &id); ModelNode modelNodeForId(const QString &id);
bool hasId(const QString &id) const; bool hasId(const QString &id) const;
QString generateNewId(const QString &prefixName) const; QString generateNewId(const QString &prefixName) const;
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
ModelNode modelNodeForInternalId(qint32 internalId) const; ModelNode modelNodeForInternalId(qint32 internalId) const;
bool hasModelNodeForInternalId(qint32 internalId) const; bool hasModelNodeForInternalId(qint32 internalId) const;

View File

@@ -504,40 +504,36 @@ QString firstCharToLower(const QString &string)
return resultString; return resultString;
} }
QString AbstractView::generateNewId(const QString &prefixName) const QString AbstractView::generateNewId(const QString &prefixName, const QString &fallbackPrefix) const
{ {
QString fixedPrefix = firstCharToLower(prefixName); // First try just the prefixName without number as postfix, then continue with 2 and further
fixedPrefix.remove(' '); // as postfix until id does not already exist.
// Properties of the root node are not allowed for ids, because they are available in the
bool forceSuffix = false; // complete context without qualification.
if (!ModelNode::isValidId(fixedPrefix))
forceSuffix = true;
int counter = 0; int counter = 0;
/* First try just the prefixName without number as postfix, then continue with 2 and further as postfix QString newBaseId = QString(QStringLiteral("%1")).arg(firstCharToLower(prefixName));
* until id does not already exist. newBaseId.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9_]")));
* Properties of the root node are not allowed for ids, because they are available in the complete context
* without qualification.
* The id "item" is explicitly not allowed, because it is too likely to clash.
*/
QString newId = QString(QStringLiteral("%1")).arg(firstCharToLower(prefixName)); if (newBaseId.isEmpty())
if (forceSuffix) newBaseId = fallbackPrefix;
QString(QStringLiteral("%1%2")).arg(firstCharToLower(prefixName)).arg(1);
newId.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9_]"))); QString newId = newBaseId;
while (!ModelNode::isValidId(newId) || hasId(newId) || rootModelNode().hasProperty(newId.toUtf8()) || newId == "item") { while (!ModelNode::isValidId(newId) || hasId(newId) || rootModelNode().hasProperty(newId.toUtf8())) {
counter += 1; ++counter;
newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(prefixName)).arg(counter); newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter);
newId.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9_]")));
} }
return newId; return newId;
} }
QString AbstractView::generateNewId(const QString &prefixName) const
{
return generateNewId(prefixName, QStringLiteral("element"));
}
ModelNode AbstractView::modelNodeForInternalId(qint32 internalId) const ModelNode AbstractView::modelNodeForInternalId(qint32 internalId) const
{ {
return ModelNode(model()->d->nodeForInternalId(internalId), model(), this); return ModelNode(model()->d->nodeForInternalId(internalId), model(), this);

View File

@@ -106,7 +106,8 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS
newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList)); newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList));
parentproperty.reparentHere(newQmlItemNode); parentproperty.reparentHere(newQmlItemNode);
newQmlItemNode.setId(view->generateNewId(QLatin1String("image"))); QFileInfo fi(relativeImageName);
newQmlItemNode.setId(view->generateNewId(fi.baseName(), "image"));
newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit"); newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit");