Merge remote-tracking branch 'origin/8.0' into 9.0
resolved conflicts: * doc/qtdesignstudio/src/developers/studio-designer-developer-workflow.qdoc * src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp * src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp * src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp and compile fix in materialbrowserview.cpp Change-Id: I686e7e93ded8ac1afc792942ded47cd9fe4341ed
245
doc/qtdesignstudio/examples/doc/animationTutorial.qdoc
Normal file
@@ -0,0 +1,245 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Design Studio 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 animation-tutorial.html
|
||||
\ingroup gstutorials
|
||||
\sa {Creating Timeline Animations}
|
||||
|
||||
\title Timeline Animation Tutorial
|
||||
\brief Illustrates how to create timeline animations and bind them to
|
||||
properties in \QDS.
|
||||
|
||||
\image animation-tutorial.gif
|
||||
|
||||
The \e{Timeline Animation} tutorial illustrates how to create timeline animations
|
||||
and bind them to properties in \QDS. First you create a keyframe animation
|
||||
which you control the running state of with a switch in the UI. Next, you
|
||||
create another keyframe animation where you use a slider in the UI to
|
||||
control the position of the playhead.
|
||||
|
||||
The starting point of this tutorial is the Animation Tutorial project,
|
||||
you can download it from
|
||||
\l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/animation-tutorial/AnimationTutorial/Start}
|
||||
{here}.
|
||||
|
||||
You can download the completed project from
|
||||
\l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/animation-tutorial/AnimationTutorial/Completed}
|
||||
{here}.
|
||||
|
||||
This tutorial requires that you know the basics of \QDS, see
|
||||
\l{Getting Started}.
|
||||
|
||||
\section1 Creating a Timeline Animation
|
||||
|
||||
First, you create an animation where the ball bearing continuously rotates
|
||||
around its Y axis.
|
||||
|
||||
\section2 Adding a Timeline and an Animation
|
||||
|
||||
To add a timeline to your project:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Timeline view, select
|
||||
\inlineimage icons/plus.png
|
||||
.
|
||||
This creates a timeline and one animation.
|
||||
\li On the \uicontrol {Animation Settings} tab in the
|
||||
\uicontrol {Timeline Settings} dialog:
|
||||
\list
|
||||
\li Set \uicontrol Duration to 7500.
|
||||
This sets the duration of the animation in milliseconds.
|
||||
\li Select \uicontrol {Contiunous}.
|
||||
This sets the animation to start over again when it reaches the
|
||||
end.
|
||||
\endlist
|
||||
\image animation-tutorial-timeline-1.png
|
||||
\li Select \uicontrol {Close}.
|
||||
\endlist
|
||||
|
||||
You can see the timeline in the \uicontrol Timeline and
|
||||
\uicontrol Navigator views.
|
||||
|
||||
\section2 Adding Keyframes
|
||||
|
||||
Next, you add keyframes to animate the rotation of the ball bearing:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Navigator view, select \e {ballbearing1}.
|
||||
\li In the \uicontrol Properties view, select
|
||||
\inlineimage icons/action-icon.png (Actions)
|
||||
next to \uicontrol Rotation > \uicontrol {Y}.
|
||||
\li Select \uicontrol {Insert Keyframe}.
|
||||
\image animation-tutorial-insert-keyframe.png
|
||||
\li In the \uicontrol Timeline view, select the
|
||||
\uicontrol {Per Property Recording} button to start recording property
|
||||
changes.
|
||||
\image animation-tutorial-per-property-recording.png
|
||||
\li In the \uicontrol Timeline view, move the playhead to the end of the
|
||||
animation (frame 1000).
|
||||
\li In the \uicontrol Properties view, set \uicontrol Rotation >
|
||||
\uicontrol Z to 360.
|
||||
This creates a second keyframe.
|
||||
\li Select the \uicontrol {Per Property Recording} button to end the per
|
||||
property recording. To preview the animation, drag the playhead along the
|
||||
timeline.
|
||||
\endlist
|
||||
|
||||
\section2 Controlling the Running State of the Animation
|
||||
|
||||
There is a toggle switch in the UI of this project. To use this switch to
|
||||
control the running state of the animation:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Navigator view, select \e {timelineAnimation}.
|
||||
\li In the \uicontrol Connections view, go to the \uicontrol Bindings tab.
|
||||
\li Select \inlineimage icons/plus.png
|
||||
to create a binding.
|
||||
\li For the binding you created, set:
|
||||
\list
|
||||
\li \uicontrol Property to \e {paused}.
|
||||
\li \uicontrol {Source Item} to \e {switch1}.
|
||||
\li \uicontrol {Source Property} to \e {checked}.
|
||||
\endlist
|
||||
\image animation-tutorial-binding.png
|
||||
\endlist
|
||||
|
||||
You can preview the animation and try the toggle switch in the live preview.
|
||||
To run the live preview, select \key Alt + \key{P}.
|
||||
|
||||
\section1 Creating a Timeline and Binding it to a Property
|
||||
|
||||
Next, you create the exploded view animation of the ball bearing. You don't
|
||||
want this animation to run automatically but instead you want to control it
|
||||
with a slider in the UI.
|
||||
|
||||
\section2 Adding a Timeline Inside a Component
|
||||
|
||||
You create this animation inside the ball bearing component, to do this:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Navigator view, select \e {ballBearing1}.
|
||||
\li Select \key {F2} to go into the component.
|
||||
\li In the \uicontrol Timeline view, select
|
||||
\inlineimage icons/plus.png
|
||||
to add a timeline and open the \uicontrol {Timeline Settings} dialog.
|
||||
\li Select \inlineimage icons/minus.png
|
||||
next to the \uicontrol {Animation Settings} tab to remove the animation
|
||||
in this timeline.
|
||||
You do not need an animation when you bind the timeline to a property.
|
||||
\li Select \uicontrol {Close}.
|
||||
\endlist
|
||||
|
||||
\image animation-tutorial-timeline-2.png
|
||||
|
||||
\section2 Adding Keyframes
|
||||
|
||||
Now, you add keyframes for the different parts of the ball bearing:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol{Navigator} view, select \e{inner_race}.
|
||||
\li In the \uicontrol Properties view, select
|
||||
\inlineimage icons/action-icon.png (Actions)
|
||||
next to \uicontrol Translation > \uicontrol Y.
|
||||
\li Select \uicontrol {Insert Keyframe}.
|
||||
\li In the \uicontrol Timeline view, select the
|
||||
\uicontrol {Per Property Recording} button to start recording property
|
||||
changes.
|
||||
\li In the \uicontrol Timeline view, move the playhead to the end of the
|
||||
animation (frame 1000).
|
||||
\li In the \uicontrol Properties view, set \uicontrol Translation >
|
||||
\uicontrol Y to 0,50.
|
||||
\li Select the \uicontrol {Per Property Recording} button to end the per
|
||||
property recording.
|
||||
\li Next, you set the keyframe values for the other parts of the ball
|
||||
bearing. For the following parts, set the \uicontrol Translation >
|
||||
\uicontrol Y value for frame 1000:
|
||||
\list
|
||||
\li \e balls to 1,00.
|
||||
\li \e retainer to 1,50.
|
||||
\li \e shield_left to 1,80.
|
||||
\li \e shield_right to -0,30.
|
||||
\endlist
|
||||
\image animation-tutorial-ballbearing-animation.png
|
||||
\endlist
|
||||
|
||||
You can preview the animation by dragging the playhead in the
|
||||
\uicontrol Timeline view.
|
||||
|
||||
\section2 Controlling the Animation with a Slider
|
||||
|
||||
Now, you use the slider on the main screen to control the exploded
|
||||
view animation that you created.
|
||||
|
||||
To do this, you first need to define a property for the slider:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Navigator view, select \e Node.
|
||||
\li On the \uicontrol Properties tab in the \uicontrol Connections view,
|
||||
select \inlineimage icons/plus.png
|
||||
.
|
||||
\li In the \uicontrol {Property Type} field, enter \e {Item}.
|
||||
This field is a drop-down list, but you can also type text.
|
||||
\li In the \uicontrol {Property Value} field, enter \e {null}.
|
||||
\endlist
|
||||
\image animation-tutorial-property.png
|
||||
|
||||
Next, you set the property you just created to control the timeline
|
||||
animation:
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol {Timeline} view, select
|
||||
\inlineimage icons/animation.png
|
||||
.
|
||||
\li In the \uicontrol {Expression binding field}, enter
|
||||
\c {property0.value}.
|
||||
\li Select \uicontrol {Close}.
|
||||
\endlist
|
||||
|
||||
Next, you go out from the component back to the main project and bind the
|
||||
property to the slider:
|
||||
|
||||
\list 1
|
||||
\li In the toolbar, select the \e {Screen01.ui.qml} breadcrumb.
|
||||
\image animation-tutorial-breadcrumb.png
|
||||
\li In the \uicontrol {Navigator} view, select \e {ballbearing1}.
|
||||
\li In the \uicontrol {Connections} view, go to the
|
||||
\uicontrol {Bindings} tab.
|
||||
\li Select \inlineimage icons/plus.png
|
||||
.
|
||||
\li For the binding you just created:
|
||||
\list
|
||||
\li Set \uicontrol {Source Item} to \e {slider}.
|
||||
\li Remove the value from \uicontrol {Source Property}.
|
||||
\endlist
|
||||
\image animation-tutorial-binding-2.png
|
||||
\endlist
|
||||
|
||||
\section1 Previewing
|
||||
|
||||
Now, the animations are done. To preview and test your application,
|
||||
select \key Alt + \key{P}.
|
||||
|
||||
*/
|
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 15 KiB |
BIN
doc/qtdesignstudio/examples/doc/images/animation-tutorial.gif
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
doc/qtdesignstudio/images/add-local-custom-property.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
doc/qtdesignstudio/images/add-new-property-dialog.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
doc/qtdesignstudio/images/custom-properties.png
Normal file
After Width: | Height: | Size: 13 KiB |
@@ -29,7 +29,7 @@
|
||||
custom properties on the \uicontrol {Properties} tab in the
|
||||
\l {Connections} view.
|
||||
\image qmldesigner-dynamicprops.png "Connections View Properties tab"
|
||||
For more information, see \l{Specifying Dynamic Properties}.
|
||||
For more information, see \l{Specifying Custom Properties}.
|
||||
\li To enable users to interact with the component instances, connect
|
||||
the instances to signals on the \uicontrol Connections tab in the
|
||||
\uicontrol {Connections} view. For example, you can specify what
|
||||
|
@@ -41,7 +41,7 @@
|
||||
\uicontrol Navigator or the \uicontrol {2D} view.
|
||||
\li Edit component properties in the \uicontrol Properties view.
|
||||
The available properties depend on the component type. You can
|
||||
\l{Specifying Dynamic Properties}{add properties for
|
||||
\l{Specifying Custom Properties}{add properties for
|
||||
components} on the \uicontrol {Properties} tab in the
|
||||
\uicontrol Connections view.
|
||||
\li To change the appearance and behavior of the component instances
|
||||
|
@@ -139,7 +139,7 @@
|
||||
When you add a \l{GridView}{Grid View}, \l{ListView}{List View}, or
|
||||
\l{PathView}{Path View}, the ListModel and the delegate component that
|
||||
creates an instance for each item in the model are added automatically.
|
||||
For grid and list views, you can edit the list model in \QC.
|
||||
For grid and list views, you can edit the list model in \QDS.
|
||||
|
||||
\image qtquick-designer-listview-preview.png "Preview of a list view"
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
\image qtquick-designer-image-type.png "Image component in different views"
|
||||
|
||||
When you drag-and-drop an image file from \uicontrol Assets to \l Navigator
|
||||
or the \l {2D} view, \QC automatically
|
||||
or the \l {2D} view, \QDS automatically
|
||||
creates an instance of the Image component for you with the path to the
|
||||
image file set as the value of the \uicontrol Source field in
|
||||
\uicontrol Properties.
|
||||
|
@@ -73,7 +73,7 @@
|
||||
For more information on the JavaScript environment provided, see
|
||||
\l{Integrating QML and JavaScript}.
|
||||
|
||||
Bindings are a black box for \QC and using them might have a
|
||||
Bindings are a black box for \QDS and using them might have a
|
||||
negative impact on performance, so consider setting anchors and margins for
|
||||
components, instead. For example, instead of setting \c {parent.width} for a
|
||||
component, you could anchor the component to its sibling components on the
|
||||
@@ -342,7 +342,7 @@
|
||||
to right and top to bottom. Each component is positioned at the top-left
|
||||
corner of its cell with position (0, 0).
|
||||
|
||||
\QC generates the grid based on the positions of the child components in
|
||||
\QDS generates the grid based on the positions of the child components in
|
||||
the \l {2D} view. You can modify the number of rows and columns in the
|
||||
\uicontrol Rows and \uicontrol Columns fields.
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
working Qt 6 application that you can build and run in Qt Creator using
|
||||
CMake. Therefore, you can open, build, and run the projects with Qt Creator.
|
||||
|
||||
\QDS continues to use the \e .qmlproject file format, while \QC uses a
|
||||
\QDS continues to use the \e .qmlproject file format, while Qt Creator uses a
|
||||
\e CMakeLists.txt file as the project file. This enables you to share
|
||||
your project as a fully working C++ application with developers.
|
||||
|
||||
@@ -46,9 +46,10 @@
|
||||
|
||||
\section1 Converting Project Structure for CMake
|
||||
|
||||
\QDS can generate \e CMakeLists.txt and other related files to use with \QC and to compile into
|
||||
an executable application but only if the project has a certain folder structure. If you have a
|
||||
\QDS QML project that doesn't have the CMake configuration, follow these steps to convert its
|
||||
\QDS can generate \e CMakeLists.txt and other related files to use with
|
||||
Qt Creator and to compile into an executable application but only if the
|
||||
project has a certain folder structure. If you have a \QDS QML project that
|
||||
doesn't have the CMake configuration, follow these steps to convert its
|
||||
file structure to the correct format.
|
||||
|
||||
\list 1
|
||||
|
@@ -46,7 +46,7 @@
|
||||
|
||||
\section2 Timeline and Keyframe Based Animation
|
||||
|
||||
Timeline animation is based on \e keyframes. In \QC, keyframes determine the
|
||||
Timeline animation is based on \e keyframes. In \QDS, keyframes determine the
|
||||
value of the property of a \l{glossary_component}{component} at a certain
|
||||
time. Animating properties enables their values to move through intermediate
|
||||
values instead of immediately changing to the target value.
|
||||
|
@@ -114,7 +114,7 @@
|
||||
\endif
|
||||
\row
|
||||
\li Adding custom properties for a particular component type
|
||||
\li \l{Specifying Dynamic Properties}
|
||||
\li \l{Specifying Custom Properties}
|
||||
\omit
|
||||
\row
|
||||
\li Adding properties for controlling states
|
||||
|
@@ -48,7 +48,7 @@
|
||||
\section1 Profiling UI Code
|
||||
|
||||
You can use \l{Profiling QML Applications}{QML Profiler} that is integrated
|
||||
into \QC to find causes for typical performance problems in your UI. For
|
||||
into \QDS to find causes for typical performance problems in your UI. For
|
||||
example, your UI might be slow, unresponsive, or stuttering. Typically, such
|
||||
problems are caused by executing too much JavaScript in too few frames. All
|
||||
JavaScript must return before the GUI thread can proceed, and frames are
|
||||
|
@@ -73,7 +73,7 @@
|
||||
|
||||
\li \l {Importing 3D Assets}
|
||||
|
||||
You can import exported assets into \QC. For a list of formats
|
||||
You can import exported assets into \QDS. For a list of formats
|
||||
supported by each \l{Qt Quick 3D} version, see the module
|
||||
documentation.
|
||||
|
||||
|
@@ -20,14 +20,14 @@
|
||||
components, and states, you need. Create a descriptive wireframe
|
||||
and acquire a detailed UI specification before you start to make
|
||||
the process of creating the UI more efficient.
|
||||
\QC enables you to turn your UI concept into a wireframe with
|
||||
\QDS enables you to turn your UI concept into a wireframe with
|
||||
a scalable layout where all your screens and controls are in
|
||||
place. You can present your wireframe to developers and other
|
||||
stakeholders for discussion, review, and approval before
|
||||
continuing into the prototyping phase.
|
||||
\endtable
|
||||
|
||||
In \QC, you build UIs around the behavior of \l{glossary-component}
|
||||
In \QDS, you build UIs around the behavior of \l{glossary-component}
|
||||
{components} and how they connect with one another. You can use preset
|
||||
components available in the \l Components view or combine them to create
|
||||
your own components. You can specify values for the \e properties of a
|
||||
|
@@ -49,7 +49,7 @@
|
||||
\li Edit component properties in the \l Properties view.
|
||||
|
||||
The available properties depend on the component type. You can
|
||||
\l{Specifying Dynamic Properties}{add properties for components} on
|
||||
\l{Specifying Custom Properties}{add properties for components} on
|
||||
the \uicontrol Properties tab in the {Connections} view.
|
||||
\endlist
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
\li \l{Converting UI Projects to Applications}
|
||||
|
||||
\QDS projects are useful for creating UIs. To use them for
|
||||
application development in \QC, you have to convert
|
||||
application development in Qt Creator, you have to convert
|
||||
them to Qt Quick Application projects that contain .pro,
|
||||
.cpp, and .qrc files.
|
||||
\li \l{Using External Tools}
|
||||
|
@@ -19,7 +19,7 @@
|
||||
\li \l {FAQ - Assets}{Assets}
|
||||
\li \l {FAQ - Components}{Components}
|
||||
\li \l {FAQ - Views}{Views}
|
||||
\li \l {FAQ - Integration Between \QDS and \QC}{Integration Between \QDS and \QC}
|
||||
\li \l {FAQ - Integration Between \QDS and Qt Creator}{Integration Between \QDS and Qt Creator}
|
||||
\li \l {FAQ - Performance}{Performance}
|
||||
\li \l {FAQ - Data Simulation}{Data Simulation}
|
||||
\endlist
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
\section1 FAQ - Components
|
||||
|
||||
\section2 Can custom components be used?
|
||||
\section2 Can I use custom components?
|
||||
|
||||
Yes, you can create custom components and controls by using wizard templates
|
||||
or move component instances into separate files to turn them into new
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
For more information, see \l {Importing 3D Assets}.
|
||||
|
||||
\section2 How to integrate custom C++ components into QDS?
|
||||
\section2 How can I integrate custom C++ components into QDS?
|
||||
|
||||
You must create your own QML module that contains the components and
|
||||
provides additional information about your components. For more information,
|
||||
@@ -99,21 +99,21 @@
|
||||
|
||||
For more information, see the \l {3D} view.
|
||||
|
||||
\section1 FAQ - Integration Between \QDS and \QC
|
||||
\section1 FAQ - Integration Between \QDS and Qt Creator
|
||||
|
||||
\section2 Is there a way to automatically propagate name changes between \QDS and \QC?
|
||||
\section2 Can I automatically propagate name changes between \QDS and Qt Creator?
|
||||
|
||||
Unfortunately we do not automate renaming files between tools at the moment.
|
||||
If you decide to change the name of a property, alias, or signal in \QDS,
|
||||
you need to manually change the name in \QC to maintain the connection.
|
||||
you need to manually change the name in Qt Creator to maintain the connection.
|
||||
However, you can rename symbols in all files within a project. To rename a
|
||||
QML type in a project, select \uicontrol Tools > \uicontrol QML/JS >
|
||||
\uicontrol {Rename Symbol Under Cursor} or press \key Ctrl+Shift+R. For more
|
||||
information, see \l {Renaming Symbols}.
|
||||
|
||||
\section2 When turning your \QDS project into application in \QC, what is the best way to add .qml files?
|
||||
\section2 How can I add .qml files to my project in Qt Creator?
|
||||
|
||||
Use the project wizard templates to create an application in \QC and copy
|
||||
Use the project wizard templates to create an application in \QDS and copy
|
||||
your .qml files to the project folder. Then make some changes to the project
|
||||
configuration and source files, as instructed in
|
||||
\l {Converting UI Projects to Applications}.
|
||||
|
@@ -143,7 +143,7 @@
|
||||
Navigator to add the properties on the \uicontrol Properties tab in the
|
||||
\l Connections view.
|
||||
|
||||
See \l {Specifying Dynamic Properties} for a detailed description of how
|
||||
See \l {Specifying Custom Properties} for a detailed description of how
|
||||
to add a custom property. The name of the property and the data type
|
||||
need to match those of the send or receive property of the Simulink model.
|
||||
|
||||
|
@@ -197,7 +197,7 @@
|
||||
\li \l{Preset Components}
|
||||
\li \l{Specifying Component Properties}
|
||||
\li \l{Adding Bindings Between Properties}
|
||||
\li \l{Specifying Dynamic Properties}
|
||||
\li \l{Specifying Custom Properties}
|
||||
\endlist
|
||||
|
||||
\section1 Signal
|
||||
@@ -294,7 +294,7 @@
|
||||
deploys it to the \l{glossary-device}{device} specified in the
|
||||
selected \l{glossary-buildandrun-kit}{kit}, and runs it there. However,
|
||||
if you have not made any changes to the project since you last deployed
|
||||
it, \QC simply runs it again.
|
||||
it, \QDS simply runs it again.
|
||||
|
||||
\endomit
|
||||
*/
|
||||
|
@@ -122,7 +122,7 @@
|
||||
\list
|
||||
\li\l{Connecting Components to Signals}
|
||||
\li\l{Adding Bindings Between Properties}
|
||||
\li\l{Specifying Dynamic Properties}
|
||||
\li\l{Specifying Custom Properties}
|
||||
\endlist
|
||||
\li \l{Adding States}
|
||||
\endlist
|
||||
|
@@ -193,5 +193,5 @@
|
||||
\image studio-custom-material-uniform-properties.png "Uniforms as properties in Connections view Properties tab"
|
||||
|
||||
For more information about adding properties, see
|
||||
\l{Specifying Dynamic Properties}.
|
||||
\l{Specifying Custom Properties}.
|
||||
*/
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
\title Creating Optimized 3D Scenes
|
||||
|
||||
In \QC, you can use various means to create a 3D scene. Your choice of
|
||||
In \QDS, you can use various means to create a 3D scene. Your choice of
|
||||
strategy should always depend on the target platform of your scene.
|
||||
The way the content of your scene is authored can have dramatic effects on
|
||||
the runtime performance of your UI. The Optimal 3D Scene described
|
||||
@@ -88,7 +88,7 @@
|
||||
The scene graph is the hierarchy of nodes that describe the scene to be
|
||||
rendered.
|
||||
|
||||
In \QC, the scene graph is represented by the tree-like view in
|
||||
In \QDS, the scene graph is represented by the tree-like view in
|
||||
\uicontrol Navigator. You can also view the hierarchy of nodes in the
|
||||
\l {Code} view. By minimizing the size of the scene graph,
|
||||
you can minimize the effort needed when running the scene. In terms of
|
||||
|
@@ -9,10 +9,10 @@
|
||||
\else
|
||||
\nextpage quick-connections-backend.html
|
||||
\endif
|
||||
\sa {Specifying Component Properties}
|
||||
\title Specifying Custom Properties
|
||||
|
||||
\title Specifying Dynamic Properties
|
||||
|
||||
Each preset \l{glossary-component}{component} has a set of preset properties
|
||||
Each \l{Preset Components}{preset component }has a set of preset properties
|
||||
that you can specify values for. You can add custom properties that would
|
||||
not otherwise exist for a particular \l{Component Types}{component type}.
|
||||
You bind the properties to dynamic expressions to define global properties
|
||||
@@ -33,50 +33,36 @@
|
||||
should have an \e int or \e real property for speed to which the UI is
|
||||
bound.
|
||||
|
||||
You can add properties for components on the \uicontrol Properties tab in
|
||||
in the \l {Connections} view.
|
||||
\section1 Adding Properties for a Component
|
||||
|
||||
\image qmldesigner-dynamicprops.png "Custom properties in the Connections view Custom Properties tab"
|
||||
|
||||
To add properties for a component:
|
||||
To add a custom property for a component:
|
||||
|
||||
\list 1
|
||||
\li Go to the \uicontrol Properties tab in the \l Connections view.
|
||||
\li Go to the \uicontrol {Local Custom Properties} section in the
|
||||
\uicontrol Properties view.
|
||||
\li Select the \inlineimage icons/plus.png
|
||||
(\uicontrol Add) button to add a dynamic property for the currently
|
||||
selected component. The component ID is displayed in the \uicontrol Item
|
||||
column.
|
||||
\li Double-click the value in the \uicontrol Property column to give a
|
||||
name to the property. Property names must begin with a lower case
|
||||
letter and can only contain letters, numbers, and underscores.
|
||||
JavaScript \e {reserved words} are not valid property names.
|
||||
\li Double-click the value in the \uicontrol {Property Type} column to
|
||||
specify the \l{Supported Property Types}{type of the property}.
|
||||
\li Double-click the value in the \uicontrol {Property Value} column
|
||||
to specify the value of the property.
|
||||
(\uicontrol Add) button to add a custom property for the currently
|
||||
selected component.
|
||||
\image add-local-custom-property.png
|
||||
\li Set the \uicontrol Name and \uicontrol Type for the property.
|
||||
\image add-new-property-dialog.png
|
||||
\endlist
|
||||
|
||||
\section1 Binding a Property Value
|
||||
|
||||
To bind the value of the property to that of another one or to data
|
||||
accessible in the application.
|
||||
|
||||
\list 1
|
||||
\li In the \uicontrol Properties view, select
|
||||
\inlineimage icons/action-icon.png
|
||||
next to the property.
|
||||
\li Select \uicontrol {Set Binding}.
|
||||
\image qmldesigner-binding-editor.png "Binding Editor"
|
||||
\endlist
|
||||
|
||||
Right-click a property and select \uicontrol {Open Binding Editor} in
|
||||
the context menu to bind the value of the property to that of another one
|
||||
or to data accessible in the application in \uicontrol {Binding Editor}.
|
||||
For more information, see \l{Setting Bindings}.
|
||||
|
||||
\image qmldesigner-binding-editor.png "Binding Editor"
|
||||
|
||||
The properties you add for a component are displayed in the \l Properties
|
||||
view when you select a component of that type in the \l Navigator or
|
||||
\l {2D} view.
|
||||
|
||||
\image qtquick-custom-properties.png "Custom properties in Properties view"
|
||||
|
||||
For more information about setting property values in the
|
||||
\l Properties view, see \l{Specifying Component Properties}.
|
||||
|
||||
\if defined(qtcreator)
|
||||
For an example of using custom properties in an application, see
|
||||
\l{Creating a Mobile Application}.
|
||||
\endif
|
||||
|
||||
\section1 Supported Property Types
|
||||
|
||||
The following table describes the supported property types:
|
||||
@@ -112,6 +98,9 @@
|
||||
\row
|
||||
\li string
|
||||
\li Free form text string
|
||||
\row
|
||||
\li TextureInput
|
||||
\li Specifies a texture exposed to the shaders of a CustomMaterial or Effect.
|
||||
\row
|
||||
\li url
|
||||
\li Resource locator, such as a file name. It can be either absolute,
|
||||
@@ -122,5 +111,14 @@
|
||||
\li variant
|
||||
\li Generic property type. For example, variant properties can store
|
||||
numbers, strings, objects, arrays, and functions.
|
||||
\row
|
||||
\li vector2d
|
||||
\li Refers to a value with x and y attributes.
|
||||
\row
|
||||
\li vector3d
|
||||
\li Refers to a value with x, y, and z attributes.
|
||||
\row
|
||||
\li vector4d
|
||||
\li Refers to a value with x, y, z, and w attributes.
|
||||
\endtable
|
||||
*/
|
||||
|
@@ -26,7 +26,7 @@
|
||||
the value of a property changes, the values of any properties that
|
||||
are bound to it are automatically updated accordingly.
|
||||
|
||||
\li \l{Specifying Dynamic Properties}
|
||||
\li \l{Specifying Custom Properties}
|
||||
|
||||
Each preset component has a set of preset properties that you
|
||||
can specify values for. You can add custom properties that would
|
||||
|
@@ -63,7 +63,7 @@
|
||||
\li \uicontrol Properties
|
||||
\li Add custom properties that would not otherwise exist for a
|
||||
particular preset component or your own custom component.
|
||||
\li \l{Specifying Dynamic Properties}
|
||||
\li \l{Specifying Custom Properties}
|
||||
\if defined(qtcreator)
|
||||
\row
|
||||
\li \uicontrol Backends
|
||||
|
@@ -107,7 +107,7 @@
|
||||
\section1 Locking Components
|
||||
|
||||
When designing complex applications, it is easy to accidentally modify
|
||||
the properties of a component in one of the \QC views in ways that lead to
|
||||
the properties of a component in one of the \QDS views in ways that lead to
|
||||
surprising results. For example, the \uicontrol {2D} view can become
|
||||
crowded and other components can get in the way when you are trying to
|
||||
select or transform a particular component, so that you end up transforming
|
||||
@@ -115,7 +115,7 @@
|
||||
|
||||
To lock components that you are not currently editing and their children,
|
||||
click \inlineimage icons/lockon.png
|
||||
in \uicontrol Navigator. Locked components cannot be handled in any \QC
|
||||
in \uicontrol Navigator. Locked components cannot be handled in any \QDS
|
||||
views. You can unlock the components when you want to edit them again.
|
||||
|
||||
\image qtquick-designer-navigator-lock.gif "Locking components in Navigator"
|
||||
|
@@ -22,6 +22,26 @@
|
||||
|
||||
\image qmldesigner-element-properties.png "Rectangle and Text properties"
|
||||
|
||||
\section1 Custom Properties
|
||||
|
||||
Custom Properties are properties that the user has added to the component.
|
||||
|
||||
There are two types of custom properties:
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Custom Property Type
|
||||
\li Description
|
||||
\row
|
||||
\li Local Custom Property
|
||||
\li A property that has been added for a \l{Preset Components}{preset component}.
|
||||
\row
|
||||
\li Exposed Custom Property
|
||||
\li A property that has been added inside a component.
|
||||
\endtable
|
||||
|
||||
\image custom-properties.png
|
||||
|
||||
\section1 Summary of Properties View Buttons
|
||||
|
||||
The following table lists the \uicontrol Properties view buttons:
|
||||
|
@@ -29,7 +29,7 @@
|
||||
another preset component in the field.
|
||||
|
||||
If you have specified values for properties that are not supported by the
|
||||
new component type, \QC offers to remove them for you. If you'd rather do
|
||||
new component type, \QDS offers to remove them for you. If you'd rather do
|
||||
this yourself, you can select the \inlineimage icons/action-icon.png
|
||||
(\uicontrol Actions) menu next to the property name, and then select
|
||||
\uicontrol Reset to remove the property values before trying again.
|
||||
|
@@ -8,7 +8,7 @@
|
||||
|
||||
\title Managing Workspaces
|
||||
|
||||
In the \uicontrol Design mode, you can arrange a set of \QC
|
||||
In the \uicontrol Design mode, you can arrange a set of \QDS
|
||||
views as a \e workspace on the screen.
|
||||
|
||||
To detach views:
|
||||
@@ -34,10 +34,10 @@
|
||||
|
||||
\section1 Saving Workspaces
|
||||
|
||||
The changes you make to a workspace are saved when you exit \QC.
|
||||
The changes you make to a workspace are saved when you exit \QDS.
|
||||
Select \uicontrol View > \uicontrol Workspaces >
|
||||
\uicontrol Manage > \uicontrol {Restore last workspace on startup}
|
||||
to restore the current workspace the next time you start \QC.
|
||||
to restore the current workspace the next time you start \QDS.
|
||||
|
||||
\image qtcreator-workspace-manager.png "Workspace Manager"
|
||||
|
||||
|
@@ -17,6 +17,7 @@ Item {
|
||||
property var currentMaterial: null
|
||||
property int currentMaterialIdx: 0
|
||||
property var currentBundleMaterial: null
|
||||
property int copiedMaterialInternalId: -1
|
||||
|
||||
property var matSectionsModel: []
|
||||
|
||||
@@ -125,15 +126,20 @@ Item {
|
||||
StudioControls.MenuItem {
|
||||
text: modelData
|
||||
enabled: root.currentMaterial
|
||||
onTriggered: materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData)
|
||||
onTriggered: {
|
||||
root.copiedMaterialInternalId = root.currentMaterial.materialInternalId
|
||||
materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Paste properties")
|
||||
enabled: root.currentMaterial && root.currentMaterial.materialType
|
||||
=== materialBrowserModel.copiedMaterialType
|
||||
enabled: root.currentMaterial
|
||||
&& root.copiedMaterialInternalId !== root.currentMaterial.materialInternalId
|
||||
&& root.currentMaterial.materialType === materialBrowserModel.copiedMaterialType
|
||||
&& materialBrowserModel.isCopiedMaterialValid()
|
||||
onTriggered: materialBrowserModel.pasteMaterialProperties(root.currentMaterialIdx)
|
||||
}
|
||||
|
||||
@@ -213,7 +219,22 @@ Item {
|
||||
|
||||
width: root.width - addMaterialButton.width
|
||||
|
||||
onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText)
|
||||
onSearchChanged: (searchText) => {
|
||||
rootView.handleSearchFilterChanged(searchText)
|
||||
|
||||
// make sure searched categories that have matches are expanded
|
||||
if (!materialBrowserModel.isEmpty && !userMaterialsSection.expanded)
|
||||
userMaterialsSection.expanded = true
|
||||
|
||||
if (!materialBrowserBundleModel.isEmpty && !bundleMaterialsSection.expanded)
|
||||
bundleMaterialsSection.expanded = true
|
||||
|
||||
for (let i = 0; i < bundleMaterialsSectionRepeater.count; ++i) {
|
||||
let sec = bundleMaterialsSectionRepeater.itemAt(i)
|
||||
if (sec.visible && !sec.expanded)
|
||||
sec.expanded = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconButton {
|
||||
@@ -282,10 +303,8 @@ Item {
|
||||
height: root.cellHeight
|
||||
|
||||
onShowContextMenu: {
|
||||
if (searchBox.isEmpty()) {
|
||||
root.currentMaterial = model
|
||||
cxtMenu.popup()
|
||||
}
|
||||
root.currentMaterial = model
|
||||
cxtMenu.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -312,6 +331,8 @@ Item {
|
||||
}
|
||||
|
||||
Section {
|
||||
id: bundleMaterialsSection
|
||||
|
||||
width: root.width
|
||||
caption: qsTr("Material Library")
|
||||
addTopPadding: noMatchText.visible
|
||||
@@ -319,6 +340,8 @@ Item {
|
||||
|
||||
Column {
|
||||
Repeater {
|
||||
id: bundleMaterialsSectionRepeater
|
||||
|
||||
model: materialBrowserBundleModel
|
||||
|
||||
delegate: Section {
|
||||
@@ -343,10 +366,8 @@ Item {
|
||||
height: root.cellHeight
|
||||
|
||||
onShowContextMenu: {
|
||||
if (searchBox.isEmpty()) {
|
||||
root.currentBundleMaterial = modelData
|
||||
cxtMenuBundle.popup()
|
||||
}
|
||||
root.currentBundleMaterial = modelData
|
||||
cxtMenuBundle.popup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -303,18 +303,50 @@ Rectangle {
|
||||
|
||||
width: Math.min(300, root.width)
|
||||
|
||||
onApplied: {
|
||||
function apply() {
|
||||
let renamed = statesEditorModel.renameActiveStateGroup(editTextField.text)
|
||||
if (renamed)
|
||||
editDialog.close()
|
||||
}
|
||||
|
||||
onApplied: editDialog.accept()
|
||||
|
||||
StudioControls.TextField {
|
||||
id: editTextField
|
||||
text: statesEditorModel.activeStateGroup
|
||||
actionIndicatorVisible: false
|
||||
translationIndicatorVisible: false
|
||||
anchors.fill: parent
|
||||
|
||||
onTextChanged: {
|
||||
let btn = editDialog.standardButton(Dialog.Apply)
|
||||
if (!btn)
|
||||
return
|
||||
|
||||
if (editDialog.previousString !== editTextField.text) {
|
||||
btn.enabled = true
|
||||
} else {
|
||||
btn.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: editDialog.accept()
|
||||
onRejected: editDialog.reject()
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
let renamed = statesEditorModel.renameActiveStateGroup(editTextField.text)
|
||||
if (renamed)
|
||||
editDialog.close()
|
||||
}
|
||||
|
||||
property string previousString
|
||||
|
||||
onAboutToShow: {
|
||||
editTextField.text = statesEditorModel.activeStateGroup
|
||||
editDialog.previousString = statesEditorModel.activeStateGroup
|
||||
|
||||
let btn = editDialog.standardButton(Dialog.Apply)
|
||||
btn.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,8 +779,7 @@ Rectangle {
|
||||
height: extendGap.portraitOneColumn ? root.innerGridSpacing : Constants.thumbnailSize
|
||||
+ 2 * root.extend
|
||||
color: StudioTheme.Values.themeStateHighlight
|
||||
visible: extendBackground.radius !== 0
|
||||
&& extendBackground.visible
|
||||
visible: extendBackground.visible
|
||||
}
|
||||
|
||||
StateThumbnail {
|
||||
|
@@ -35,7 +35,7 @@ Section {
|
||||
id: root
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
caption: qsTr("User Added Properties")
|
||||
caption: qsTr("Local Custom Properties")
|
||||
|
||||
property DynamicPropertiesModel propertiesModel: null
|
||||
|
||||
|
@@ -11,8 +11,6 @@ import StudioTheme 1.0 as StudioTheme
|
||||
StudioControls.TextField {
|
||||
id: textField
|
||||
|
||||
signal rejected
|
||||
|
||||
translationIndicator.visible: false
|
||||
actionIndicator.visible: false
|
||||
|
||||
@@ -136,6 +134,11 @@ StudioControls.TextField {
|
||||
|
||||
onPressed: listView.model = null
|
||||
|
||||
onRejected: {
|
||||
if (textField.completionActive)
|
||||
listView.model = null
|
||||
}
|
||||
|
||||
Keys.priority: Keys.BeforeItem
|
||||
Keys.onPressed: function(event) {
|
||||
var text = textField.text
|
||||
@@ -222,15 +225,6 @@ StudioControls.TextField {
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: function(event) {
|
||||
event.accepted = true
|
||||
if (textField.completionActive) {
|
||||
listView.model = null
|
||||
} else {
|
||||
textField.rejected()
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onUpPressed: function(event) {
|
||||
listView.decrementCurrentIndex()
|
||||
event.accepted = false
|
||||
|
@@ -60,7 +60,7 @@ T.Button {
|
||||
states: [
|
||||
State {
|
||||
name: "default"
|
||||
when: !root.down && !root.hovered && !root.checked
|
||||
when: root.enabled && !root.down && !root.hovered && !root.checked
|
||||
|
||||
PropertyChanges {
|
||||
target: background
|
||||
@@ -75,7 +75,7 @@ T.Button {
|
||||
},
|
||||
State {
|
||||
name: "hover"
|
||||
when: root.hovered && !root.checked && !root.down
|
||||
when: root.enabled && root.hovered && !root.checked && !root.down
|
||||
|
||||
PropertyChanges {
|
||||
target: background
|
||||
@@ -88,8 +88,8 @@ T.Button {
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "pressed"
|
||||
when: root.checked || root.down
|
||||
name: "press"
|
||||
when: root.enabled && (root.checked || root.down)
|
||||
|
||||
PropertyChanges {
|
||||
target: background
|
||||
@@ -100,6 +100,19 @@ T.Button {
|
||||
target: textItem
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "disable"
|
||||
when: !root.enabled
|
||||
PropertyChanges {
|
||||
target: background
|
||||
color: StudioTheme.Values.themeControlBackgroundDisabled
|
||||
border.color: StudioTheme.Values.themeControlOutlineDisabled
|
||||
}
|
||||
PropertyChanges {
|
||||
target: textItem
|
||||
color: StudioTheme.Values.themeTextColorDisabled
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@@ -30,6 +30,8 @@ T.TextField {
|
||||
|
||||
property bool contextMenuAboutToShow: false
|
||||
|
||||
signal rejected
|
||||
|
||||
horizontalAlignment: Qt.AlignLeft
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
|
||||
@@ -225,10 +227,10 @@ T.TextField {
|
||||
}
|
||||
]
|
||||
|
||||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
root.text = root.preFocusText
|
||||
root.focus = false
|
||||
}
|
||||
Keys.onEscapePressed: function(event) {
|
||||
event.accepted = true
|
||||
root.text = root.preFocusText
|
||||
root.rejected()
|
||||
root.focus = false
|
||||
}
|
||||
}
|
||||
|
@@ -567,14 +567,16 @@ bool AndroidBuildApkStep::init()
|
||||
if (m_buildAAB)
|
||||
arguments << "--aab" << "--jarsigner";
|
||||
|
||||
if (buildType() == BuildConfiguration::Release) {
|
||||
arguments << "--release";
|
||||
}
|
||||
|
||||
QStringList argumentsPasswordConcealed = arguments;
|
||||
|
||||
if (m_signPackage) {
|
||||
arguments << "--release"
|
||||
<< "--sign" << m_keystorePath.toString() << m_certificateAlias
|
||||
arguments << "--sign" << m_keystorePath.toString() << m_certificateAlias
|
||||
<< "--storepass" << m_keystorePasswd;
|
||||
argumentsPasswordConcealed << "--release"
|
||||
<< "--sign" << "******"
|
||||
argumentsPasswordConcealed << "--sign" << "******"
|
||||
<< "--storepass" << "******";
|
||||
if (!m_certificatePasswd.isEmpty()) {
|
||||
arguments << "--keypass" << m_certificatePasswd;
|
||||
|
@@ -240,6 +240,9 @@ bool AndroidDeployQtStep::init()
|
||||
|
||||
m_androiddeployqtArgs.addArg("--gradle");
|
||||
|
||||
if (buildType() == BuildConfiguration::Release)
|
||||
m_androiddeployqtArgs.addArgs({"--release"});
|
||||
|
||||
if (androidBuildApkStep && androidBuildApkStep->signPackage()) {
|
||||
// The androiddeployqt tool is not really written to do stand-alone installations.
|
||||
// This hack forces it to use the correct filename for the apk file when installing
|
||||
|
@@ -576,6 +576,8 @@ public:
|
||||
{
|
||||
menu()->clear();
|
||||
|
||||
menu()->setEnabled(true);
|
||||
|
||||
const auto selection = selectionContext();
|
||||
if (!selection.isValid())
|
||||
return;
|
||||
@@ -585,11 +587,19 @@ public:
|
||||
return;
|
||||
|
||||
ModelNode currentNode = selection.currentSingleSelectedNode();
|
||||
|
||||
if (!currentNode.isValid())
|
||||
return;
|
||||
|
||||
QmlObjectNode currentObjectNode(currentNode);
|
||||
|
||||
QStringList signalsList = getSignalsList(currentNode);
|
||||
QList<SlotEntry> slotsList = getSlotsLists(currentNode);
|
||||
currentNode.validId();
|
||||
|
||||
if (!currentNode.hasId()) {
|
||||
menu()->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const ModelNode &connectionNode : currentObjectNode.getAllConnections()) {
|
||||
for (const AbstractProperty &property : connectionNode.properties()) {
|
||||
|
@@ -1631,6 +1631,7 @@ void addMouseAreaFill(const SelectionContext &selectionContext)
|
||||
|
||||
QmlDesigner::ModelNode mouseAreaNode =
|
||||
selectionContext.view()->createModelNode("QtQuick.MouseArea", itemMetaInfo.majorVersion(), itemMetaInfo.minorVersion());
|
||||
mouseAreaNode.validId();
|
||||
|
||||
modelNode.defaultNodeListProperty().reparentHere(mouseAreaNode);
|
||||
QmlItemNode mouseAreaItemNode(mouseAreaNode);
|
||||
|
@@ -315,6 +315,8 @@ void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
||||
|
||||
void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
||||
{
|
||||
const QPointF pos = m_canvas->mapFrom(this, dropEvent->position());
|
||||
|
||||
// handle dropping materials
|
||||
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
|
||||
QByteArray data = dropEvent->mimeData()->data(Constants::MIME_TYPE_MATERIAL);
|
||||
@@ -323,13 +325,13 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
||||
stream >> internalId;
|
||||
|
||||
if (ModelNode matNode = m_view->modelNodeForInternalId(internalId))
|
||||
m_view->dropMaterial(matNode, dropEvent->position());
|
||||
m_view->dropMaterial(matNode, pos);
|
||||
return;
|
||||
}
|
||||
|
||||
// handle dropping bundle materials
|
||||
if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
|
||||
m_view->dropBundleMaterial(dropEvent->position());
|
||||
m_view->dropBundleMaterial(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,8 @@
|
||||
#include <designmodewidget.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmlobjectnode.h>
|
||||
#include "variantproperty.h"
|
||||
#include <variantproperty.h>
|
||||
#include <qmltimelinekeyframegroup.h>
|
||||
#include "utils/qtcassert.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -326,40 +327,84 @@ void MaterialBrowserModel::duplicateMaterial(int idx)
|
||||
|
||||
void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §ion)
|
||||
{
|
||||
ModelNode mat = m_materialList.at(idx);
|
||||
QString matType = QString::fromLatin1(mat.type());
|
||||
m_copiedMaterial = m_materialList.at(idx);
|
||||
|
||||
QTC_ASSERT(m_copiedMaterial.isValid(), return);
|
||||
|
||||
QString matType = QString::fromLatin1(m_copiedMaterial.type());
|
||||
|
||||
if (matType.startsWith("QtQuick3D."))
|
||||
matType.remove("QtQuick3D.");
|
||||
|
||||
setCopiedMaterialType(matType);
|
||||
m_allPropsCopied = section == "All";
|
||||
QmlObjectNode mat(m_copiedMaterial);
|
||||
|
||||
QSet<PropertyName> validProps;
|
||||
PropertyNameList copiedProps;
|
||||
|
||||
// Base state properties are always valid
|
||||
const auto baseProps = m_copiedMaterial.propertyNames();
|
||||
for (const auto &baseProp : baseProps)
|
||||
validProps.insert(baseProp);
|
||||
|
||||
if (!mat.isInBaseState()) {
|
||||
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
|
||||
if (changes.isValid()) {
|
||||
const QList<AbstractProperty> changedProps = changes.targetProperties();
|
||||
for (const auto &changedProp : changedProps)
|
||||
validProps.insert(changedProp.name());
|
||||
}
|
||||
}
|
||||
|
||||
if (mat.timelineIsActive()) {
|
||||
const QList<QmlTimelineKeyframeGroup> keyframeGroups
|
||||
= mat.currentTimeline().keyframeGroupsForTarget(m_copiedMaterial);
|
||||
for (const auto &kfg : keyframeGroups)
|
||||
validProps.insert(kfg.propertyName());
|
||||
}
|
||||
|
||||
if (m_allPropsCopied || m_propertyGroupsObj.empty()) {
|
||||
m_copiedMaterialProps = mat.properties();
|
||||
copiedProps = validProps.values();
|
||||
} else {
|
||||
QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject();
|
||||
if (propsSpecObj.contains(section)) { // should always be true
|
||||
m_copiedMaterialProps.clear();
|
||||
const QJsonArray propNames = propsSpecObj.value(section).toArray();
|
||||
// auto == QJsonValueConstRef after 04dc959d49e5e3 / Qt 6.4, QJsonValueRef before
|
||||
for (const auto &propName : propNames)
|
||||
m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
|
||||
copiedProps.append(propName.toString().toLatin1());
|
||||
|
||||
if (section == "Base") { // add QtQuick3D.Material base props as well
|
||||
QJsonObject propsMatObj = m_propertyGroupsObj.value("Material").toObject();
|
||||
const QJsonArray propNames = propsMatObj.value("Base").toArray();
|
||||
// auto == QJsonValueConstRef after 04dc959d49e5e3 / Qt 6.4, QJsonValueRef before
|
||||
for (const auto &propName : propNames)
|
||||
m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
|
||||
copiedProps.append(propName.toString().toLatin1());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_copiedMaterialProps.clear();
|
||||
for (const auto &propName : copiedProps) {
|
||||
PropertyCopyData data;
|
||||
data.name = propName;
|
||||
data.isValid = m_allPropsCopied || validProps.contains(propName);
|
||||
data.isBinding = mat.hasBindingProperty(propName);
|
||||
if (data.isValid) {
|
||||
if (data.isBinding)
|
||||
data.value = mat.expression(propName);
|
||||
else
|
||||
data.value = mat.modelValue(propName);
|
||||
}
|
||||
m_copiedMaterialProps.append(data);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialBrowserModel::pasteMaterialProperties(int idx)
|
||||
{
|
||||
emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps, m_allPropsCopied);
|
||||
ModelNode targetMat = m_materialList.at(idx);
|
||||
if (targetMat.isValid() && m_copiedMaterial.isValid() && targetMat != m_copiedMaterial)
|
||||
emit pasteMaterialPropertiesTriggered(targetMat, m_copiedMaterialProps, m_allPropsCopied);
|
||||
}
|
||||
|
||||
void MaterialBrowserModel::deleteMaterial(int idx)
|
||||
@@ -396,4 +441,11 @@ void MaterialBrowserModel::openMaterialEditor()
|
||||
QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true);
|
||||
}
|
||||
|
||||
// This is provided as invokable instead of property, as it is difficult to know when ModelNode
|
||||
// becomes invalid. Much simpler to evaluate this on demand.
|
||||
bool MaterialBrowserModel::isCopiedMaterialValid() const
|
||||
{
|
||||
return m_copiedMaterial.isValid();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -70,6 +70,15 @@ public:
|
||||
Q_INVOKABLE void addNewMaterial();
|
||||
Q_INVOKABLE void applyToSelected(qint64 internalId, bool add = false);
|
||||
Q_INVOKABLE void openMaterialEditor();
|
||||
Q_INVOKABLE bool isCopiedMaterialValid() const;
|
||||
|
||||
struct PropertyCopyData
|
||||
{
|
||||
PropertyName name;
|
||||
QVariant value;
|
||||
bool isBinding = false;
|
||||
bool isValid = false;
|
||||
};
|
||||
|
||||
signals:
|
||||
void isEmptyChanged();
|
||||
@@ -83,9 +92,10 @@ signals:
|
||||
void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
|
||||
void addNewMaterialTriggered();
|
||||
void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material);
|
||||
void pasteMaterialPropertiesTriggered(const QmlDesigner::ModelNode &material,
|
||||
const QList<QmlDesigner::AbstractProperty> &props,
|
||||
bool all);
|
||||
void pasteMaterialPropertiesTriggered(
|
||||
const QmlDesigner::ModelNode &material,
|
||||
const QList<QmlDesigner::MaterialBrowserModel::PropertyCopyData> &props,
|
||||
bool all);
|
||||
|
||||
private:
|
||||
bool isMaterialVisible(int idx) const;
|
||||
@@ -96,7 +106,8 @@ private:
|
||||
QStringList m_defaultMaterialSections;
|
||||
QStringList m_principledMaterialSections;
|
||||
QStringList m_customMaterialSections;
|
||||
QList<AbstractProperty> m_copiedMaterialProps;
|
||||
ModelNode m_copiedMaterial;
|
||||
QList<PropertyCopyData> m_copiedMaterialProps;
|
||||
QHash<qint32, int> m_materialIndexHash; // internalId -> index
|
||||
QJsonObject m_propertyGroupsObj;
|
||||
|
||||
|
@@ -72,29 +72,43 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
||||
});
|
||||
|
||||
connect(matBrowserModel, &MaterialBrowserModel::pasteMaterialPropertiesTriggered, this,
|
||||
[&] (const ModelNode &material, const QList<AbstractProperty> &props, bool all) {
|
||||
[&] (const ModelNode &material,
|
||||
const QList<QmlDesigner::MaterialBrowserModel::PropertyCopyData> &propDatas,
|
||||
bool all) {
|
||||
QmlObjectNode mat(material);
|
||||
executeInTransaction(__FUNCTION__, [&] {
|
||||
if (all) { // all material properties copied
|
||||
// remove current properties
|
||||
const PropertyNameList propNames = material.propertyNames();
|
||||
for (const PropertyName &propName : propNames) {
|
||||
PropertyNameList propNames;
|
||||
if (mat.isInBaseState()) {
|
||||
propNames = material.propertyNames();
|
||||
} else {
|
||||
QmlPropertyChanges changes = mat.propertyChangeForCurrentState();
|
||||
if (changes.isValid()) {
|
||||
const QList<AbstractProperty> changedProps = changes.targetProperties();
|
||||
for (const auto &changedProp : changedProps)
|
||||
propNames.append(changedProp.name());
|
||||
}
|
||||
}
|
||||
for (const PropertyName &propName : qAsConst(propNames)) {
|
||||
if (propName != "objectName")
|
||||
mat.removeProperty(propName);
|
||||
}
|
||||
}
|
||||
|
||||
// apply pasted properties
|
||||
for (const AbstractProperty &prop : props) {
|
||||
if (prop.name() == "objectName")
|
||||
for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) {
|
||||
if (propData.name == "objectName")
|
||||
continue;
|
||||
|
||||
if (prop.isVariantProperty())
|
||||
mat.setVariantProperty(prop.name(), prop.toVariantProperty().value());
|
||||
else if (prop.isBindingProperty())
|
||||
mat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
|
||||
else if (!all)
|
||||
mat.removeProperty(prop.name());
|
||||
if (propData.isValid) {
|
||||
if (propData.isBinding)
|
||||
mat.setBindingProperty(propData.name, propData.value.toString());
|
||||
else
|
||||
mat.setVariantProperty(propData.name, propData.value);
|
||||
} else {
|
||||
mat.removeProperty(propData.name);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -164,7 +178,8 @@ void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundl
|
||||
newMatNode = bundleMat;
|
||||
}
|
||||
|
||||
if (m_bundleMaterialDropTarget.isValid()) {
|
||||
if (m_bundleMaterialDropTarget.isValid()
|
||||
&& m_bundleMaterialDropTarget.metaInfo().isQtQuick3DModel()) {
|
||||
QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget);
|
||||
if (m_bundleMaterialAddToSelected) {
|
||||
// TODO: unify this logic as it exist elsewhere also
|
||||
@@ -211,12 +226,12 @@ void MaterialBrowserView::modelAttached(Model *model)
|
||||
rootModelNode().metaInfo().isQtQuick3DMaterial());
|
||||
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
||||
|
||||
loadPropertyGroups();
|
||||
|
||||
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
|
||||
// before refreshing the model
|
||||
QTimer::singleShot(1000, this, [this]() {
|
||||
refreshModel(true);
|
||||
loadPropertyGroups(); // Needs the delay because it uses metaInfo
|
||||
});
|
||||
}
|
||||
|
||||
@@ -429,7 +444,6 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
|
||||
} else if (identifier == "drop_bundle_material") {
|
||||
m_bundleMaterialDropTarget = nodeList.first();
|
||||
|
||||
|
||||
ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type());
|
||||
if (defaultMat.isValid())
|
||||
applyBundleMaterialToDropTarget(defaultMat);
|
||||
|
@@ -110,15 +110,21 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
} else if (m_bundleMaterialToDrag != nullptr) {
|
||||
QMouseEvent *me = static_cast<QMouseEvent *>(event);
|
||||
if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) {
|
||||
QByteArray data;
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, {});
|
||||
QDataStream stream(&data, QIODevice::WriteOnly);
|
||||
stream << m_bundleMaterialToDrag->type();
|
||||
mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, data);
|
||||
mimeData->removeFormat("text/plain");
|
||||
|
||||
model->startDrag(mimeData, m_bundleMaterialToDrag->icon().toLocalFile());
|
||||
emit bundleMaterialDragStarted(m_bundleMaterialToDrag);
|
||||
model->startDrag(mimeData, m_bundleMaterialToDrag->icon().toLocalFile());
|
||||
m_bundleMaterialToDrag = {};
|
||||
}
|
||||
}
|
||||
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
||||
m_materialToDrag = {};
|
||||
m_bundleMaterialToDrag = {};
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
|
@@ -36,6 +36,8 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
|
||||
// -> Attractor3D
|
||||
// Material
|
||||
// -> Model
|
||||
// BundleMaterial
|
||||
// -> Model
|
||||
|
||||
if (insertInfo.isQtQuick3DTexture()) {
|
||||
if (parentInfo.isQtQuick3DDefaultMaterial() || parentInfo.isQtQuick3DPrincipledMaterial()) {
|
||||
@@ -83,6 +85,9 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
|
||||
} else if (insertInfo.isQtQuick3DMaterial()) {
|
||||
if (parentInfo.isQtQuick3DParticles3DModel())
|
||||
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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -443,6 +443,7 @@ QStringList NavigatorTreeModel::mimeTypes() const
|
||||
const static QStringList types({Constants::MIME_TYPE_MODELNODE_LIST,
|
||||
Constants::MIME_TYPE_ITEM_LIBRARY_INFO,
|
||||
Constants::MIME_TYPE_MATERIAL,
|
||||
Constants::MIME_TYPE_BUNDLE_MATERIAL,
|
||||
Constants::MIME_TYPE_ASSETS});
|
||||
|
||||
return types;
|
||||
@@ -540,6 +541,10 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
||||
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
|
||||
} else if (mimeData->hasFormat(Constants::MIME_TYPE_MATERIAL)) {
|
||||
handleMaterialDrop(mimeData, rowNumber, dropModelIndex);
|
||||
} else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
|
||||
ModelNode targetNode(modelNodeForIndex(dropModelIndex));
|
||||
if (targetNode.isValid())
|
||||
m_view->emitCustomNotification("drop_bundle_material", {targetNode}); // To MaterialBrowserView
|
||||
} else if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) {
|
||||
const QStringList assetsPaths = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',');
|
||||
NodeAbstractProperty targetProperty;
|
||||
|
@@ -260,6 +260,14 @@ void NavigatorView::dragStarted(QMimeData *mimeData)
|
||||
|
||||
m_widget->setDragType(matNode.metaInfo().typeName());
|
||||
m_widget->update();
|
||||
} else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) {
|
||||
QByteArray data = mimeData->data(Constants::MIME_TYPE_BUNDLE_MATERIAL);
|
||||
QDataStream stream(data);
|
||||
TypeName bundleMatType;
|
||||
stream >> bundleMatType;
|
||||
|
||||
m_widget->setDragType(bundleMatType);
|
||||
m_widget->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -335,7 +335,8 @@ void DynamicPropertyRow::commitValue(const QVariant &value)
|
||||
QByteArrayLiteral("DynamicPropertiesModel::commitValue"));
|
||||
try {
|
||||
QmlObjectNode objectNode = variantProperty.parentQmlObjectNode();
|
||||
if (view->currentState().isBaseState() && !objectNode.timelineIsActive()) {
|
||||
if (view->currentState().isBaseState()
|
||||
&& !(objectNode.timelineIsActive() && objectNode.currentTimeline().isRecording())) {
|
||||
if (variantProperty.value() != value)
|
||||
variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(), value);
|
||||
} else {
|
||||
|
@@ -446,7 +446,7 @@ QmlDesigner::AbstractView *GradientModel::view() const
|
||||
|
||||
void GradientModel::resetPuppet()
|
||||
{
|
||||
QTimer::singleShot(1000, [this]() { view()->resetPuppet(); });
|
||||
QTimer::singleShot(1000, view(), &QmlDesigner::AbstractView::resetPuppet);
|
||||
}
|
||||
|
||||
QmlDesigner::ModelNode GradientModel::createGradientNode()
|
||||
|
@@ -704,7 +704,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp
|
||||
QString qmlInnerTemplate = "";
|
||||
|
||||
qmlInnerTemplate += "Section {\n";
|
||||
qmlInnerTemplate += "caption: \""+ QObject::tr("User Added Properties") + "\"\n";
|
||||
qmlInnerTemplate += "caption: \"" + QObject::tr("Exposed Custom Properties") + "\"\n";
|
||||
qmlInnerTemplate += anchorLeftRight;
|
||||
qmlInnerTemplate += "leftPadding: 0\n";
|
||||
qmlInnerTemplate += "rightPadding: 0\n";
|
||||
|
@@ -95,6 +95,7 @@ void StatesEditorModel::reset()
|
||||
QAbstractListModel::endResetModel();
|
||||
|
||||
evaluateExtend();
|
||||
emit baseStateChanged();
|
||||
}
|
||||
|
||||
QVariant StatesEditorModel::data(const QModelIndex &index, int role) const
|
||||
|
@@ -122,7 +122,6 @@ public slots:
|
||||
void removeState(int nodeId);
|
||||
|
||||
private:
|
||||
StatesEditorWidget *statesEditorWidget() const;
|
||||
void resetModel();
|
||||
void resetPropertyChangesModels();
|
||||
void resetExtend();
|
||||
|
@@ -34,9 +34,8 @@ void DesignerSettings::insert(const QHash<QByteArray, QVariant> &settingsHash)
|
||||
|
||||
QVariant DesignerSettings::value(const QByteArray &key, const QVariant &defaultValue) const
|
||||
{
|
||||
Q_UNUSED(defaultValue)
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_cache.value(key);
|
||||
return m_cache.value(key, defaultValue);
|
||||
}
|
||||
|
||||
void DesignerSettings::restoreValue(QSettings *settings, const QByteArray &key, const QVariant &defaultValue)
|
||||
|
@@ -11,7 +11,7 @@ namespace Internal {
|
||||
|
||||
DebugMessagesModel::DebugMessagesModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, DebugMessage, MaximumRangeType, ProfileDebugMessages, parent),
|
||||
QmlProfilerTimelineModel(manager, DebugMessage, UndefinedRangeType, ProfileDebugMessages, parent),
|
||||
m_maximumMsgType(-1)
|
||||
{
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ namespace Internal {
|
||||
|
||||
InputEventsModel::InputEventsModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, Event, MaximumRangeType, ProfileInputEvents, parent),
|
||||
QmlProfilerTimelineModel(manager, Event, UndefinedRangeType, ProfileInputEvents, parent),
|
||||
m_keyTypeId(-1), m_mouseTypeId(-1)
|
||||
{
|
||||
}
|
||||
@@ -128,6 +128,8 @@ int InputEventsModel::collapsedRow(int index) const
|
||||
|
||||
void InputEventsModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
{
|
||||
if (type.detailType() >= MaximumInputEventType)
|
||||
return;
|
||||
m_data.insert(insert(event.timestamp(), 0, type.detailType()),
|
||||
Item(static_cast<InputEventType>(event.number<qint32>(0)),
|
||||
event.number<qint32>(1), event.number<qint32>(2)));
|
||||
|
@@ -14,7 +14,7 @@ class InputEventsModel : public QmlProfilerTimelineModel
|
||||
|
||||
public:
|
||||
struct Item {
|
||||
Item(InputEventType type = MaximumInputEventType, int a = 0, int b = 0);
|
||||
Item(InputEventType type = UndefinedInputEventType, int a = 0, int b = 0);
|
||||
InputEventType type;
|
||||
int a;
|
||||
int b;
|
||||
|
@@ -13,7 +13,7 @@ namespace Internal {
|
||||
|
||||
MemoryUsageModel::MemoryUsageModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, MemoryAllocation, MaximumRangeType, ProfileMemory, parent)
|
||||
QmlProfilerTimelineModel(manager, MemoryAllocation, UndefinedRangeType, ProfileMemory, parent)
|
||||
{
|
||||
// Register additional features. The base class already registers the main feature.
|
||||
// Don't register initializer, finalizer, or clearer as the base class has done so already.
|
||||
@@ -121,7 +121,7 @@ QVariantMap MemoryUsageModel::details(int index) const
|
||||
void MemoryUsageModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
{
|
||||
if (type.message() != MemoryAllocation) {
|
||||
if (type.rangeType() != MaximumRangeType) {
|
||||
if (type.rangeType() != UndefinedRangeType) {
|
||||
m_continuation = ContinueNothing;
|
||||
if (event.rangeStage() == RangeStart)
|
||||
m_rangeStack.push(RangeStackFrame(event.typeIndex(), event.timestamp()));
|
||||
|
@@ -13,7 +13,7 @@ namespace Internal {
|
||||
|
||||
PixmapCacheModel::PixmapCacheModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, PixmapCacheEvent, MaximumRangeType, ProfilePixmapCache,
|
||||
QmlProfilerTimelineModel(manager, PixmapCacheEvent, UndefinedRangeType, ProfilePixmapCache,
|
||||
parent)
|
||||
{
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ static ProfileFeature qmlFeatureFromType(Message message, RangeType rangeType, i
|
||||
case AnimationFrame:
|
||||
return ProfileAnimations;
|
||||
default:
|
||||
return MaximumProfileFeature;
|
||||
return UndefinedProfileFeature;
|
||||
}
|
||||
}
|
||||
case PixmapCacheEvent:
|
||||
@@ -29,7 +29,11 @@ static ProfileFeature qmlFeatureFromType(Message message, RangeType rangeType, i
|
||||
case DebugMessage:
|
||||
return ProfileDebugMessages;
|
||||
case Quick3DEvent:
|
||||
return ProfileQuick3D;
|
||||
// Check if it's actually Quick3DEvent since old traces used MaximumMessage
|
||||
// (whose value is now Quick3DEvent value) as undefined value
|
||||
if (rangeType == UndefinedRangeType)
|
||||
return ProfileQuick3D;
|
||||
return featureFromRangeType(rangeType);
|
||||
default:
|
||||
return featureFromRangeType(rangeType);
|
||||
}
|
||||
@@ -46,6 +50,9 @@ QDataStream &operator>>(QDataStream &stream, QmlEventType &type)
|
||||
type.m_message = static_cast<Message>(message);
|
||||
type.m_rangeType = static_cast<RangeType>(rangeType);
|
||||
type.setFeature(qmlFeatureFromType(type.m_message, type.m_rangeType, type.m_detailType));
|
||||
// Update message if qmlFeatureFromType determined it is not Quick3D event
|
||||
if (type.m_message == Quick3DEvent && type.feature() != ProfileQuick3D)
|
||||
type.m_message = UndefinedMessage;
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,7 @@ class QmlEventType : public Timeline::TraceEventType {
|
||||
public:
|
||||
static const qint32 staticClassId = 0x716d6c74; // 'qmlt';
|
||||
|
||||
QmlEventType(Message message = MaximumMessage, RangeType rangeType = MaximumRangeType,
|
||||
QmlEventType(Message message = UndefinedMessage, RangeType rangeType = UndefinedRangeType,
|
||||
int detailType = -1, const QmlEventLocation &location = QmlEventLocation(),
|
||||
const QString &data = QString(), const QString &displayName = QString());
|
||||
|
||||
|
@@ -21,7 +21,7 @@ namespace Internal {
|
||||
|
||||
QmlProfilerAnimationsModel::QmlProfilerAnimationsModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, Event, MaximumRangeType, ProfileAnimations, parent)
|
||||
QmlProfilerTimelineModel(manager, Event, UndefinedRangeType, ProfileAnimations, parent)
|
||||
{
|
||||
m_minNextStartTimes[0] = m_minNextStartTimes[1] = 0;
|
||||
}
|
||||
|
@@ -8,7 +8,8 @@
|
||||
namespace QmlProfiler {
|
||||
|
||||
enum Message {
|
||||
Event,
|
||||
UndefinedMessage = 0xff,
|
||||
Event = 0,
|
||||
RangeStart,
|
||||
RangeData,
|
||||
RangeLocation,
|
||||
@@ -24,7 +25,8 @@ enum Message {
|
||||
};
|
||||
|
||||
enum EventType {
|
||||
FramePaint, // unused
|
||||
UndefinedEventType = 0xff,
|
||||
FramePaint = 0, // unused
|
||||
Mouse,
|
||||
Key,
|
||||
AnimationFrame, // new Qt5 paint events
|
||||
@@ -35,7 +37,8 @@ enum EventType {
|
||||
};
|
||||
|
||||
enum Quick3DEventType {
|
||||
Quick3DRenderFrame,
|
||||
UndefinedQuick3DEventType = 0xff,
|
||||
Quick3DRenderFrame = 0,
|
||||
Quick3DSynchronizeFrame,
|
||||
Quick3DPrepareFrame,
|
||||
Quick3DMeshLoad,
|
||||
@@ -50,7 +53,8 @@ enum Quick3DEventType {
|
||||
};
|
||||
|
||||
enum RangeType {
|
||||
Painting, // old Qt4 paint events
|
||||
UndefinedRangeType = 0xff,
|
||||
Painting = 0, // old Qt4 paint events
|
||||
Compiling,
|
||||
Creating,
|
||||
Binding,
|
||||
@@ -61,7 +65,8 @@ enum RangeType {
|
||||
};
|
||||
|
||||
enum BindingType {
|
||||
QmlBinding,
|
||||
UndefinedBindingType = 0xff,
|
||||
QmlBinding = 0,
|
||||
V8Binding,
|
||||
OptimizedBinding,
|
||||
QPainterEvent,
|
||||
@@ -70,7 +75,8 @@ enum BindingType {
|
||||
};
|
||||
|
||||
enum PixmapEventType {
|
||||
PixmapSizeKnown,
|
||||
UndefinedPixmapEventType = 0xff,
|
||||
PixmapSizeKnown = 0,
|
||||
PixmapReferenceCountChanged,
|
||||
PixmapCacheCountChanged,
|
||||
PixmapLoadingStarted,
|
||||
@@ -81,7 +87,8 @@ enum PixmapEventType {
|
||||
};
|
||||
|
||||
enum InputEventType {
|
||||
InputKeyPress,
|
||||
UndefinedInputEventType = 0xff,
|
||||
InputKeyPress = 0,
|
||||
InputKeyRelease,
|
||||
InputKeyUnknown,
|
||||
|
||||
@@ -96,7 +103,8 @@ enum InputEventType {
|
||||
};
|
||||
|
||||
enum SceneGraphFrameType {
|
||||
SceneGraphRendererFrame, // Render Thread
|
||||
UndefinedSceheGraphFrameType = 0xff,
|
||||
SceneGraphRendererFrame = 0, // Render Thread
|
||||
SceneGraphAdaptationLayerFrame, // Render Thread
|
||||
SceneGraphContextFrame, // Render Thread
|
||||
SceneGraphRenderLoopFrame, // Render Thread
|
||||
@@ -111,7 +119,8 @@ enum SceneGraphFrameType {
|
||||
};
|
||||
|
||||
enum MemoryType {
|
||||
HeapPage,
|
||||
UndefinedMemoryType = 0xff,
|
||||
HeapPage = 0,
|
||||
LargeItem,
|
||||
SmallItem,
|
||||
|
||||
@@ -119,14 +128,16 @@ enum MemoryType {
|
||||
};
|
||||
|
||||
enum AnimationThread {
|
||||
GuiThread,
|
||||
UndefinedAnimationThread = 0xff,
|
||||
GuiThread = 0,
|
||||
RenderThread,
|
||||
|
||||
MaximumAnimationThread
|
||||
};
|
||||
|
||||
enum ProfileFeature {
|
||||
ProfileJavaScript,
|
||||
UndefinedProfileFeature = 0xff,
|
||||
ProfileJavaScript = 0,
|
||||
ProfileMemory,
|
||||
ProfilePixmapCache,
|
||||
ProfileSceneGraph,
|
||||
@@ -159,7 +170,7 @@ inline ProfileFeature featureFromRangeType(RangeType range)
|
||||
case Javascript:
|
||||
return ProfileJavaScript;
|
||||
default:
|
||||
return MaximumProfileFeature;
|
||||
return UndefinedProfileFeature;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -377,7 +377,7 @@ QmlProfilerModelManager::rangeFilter(qint64 rangeStart, qint64 rangeEnd) const
|
||||
// Double-check if rangeStart has been crossed. Some versions of Qt send dirty data.
|
||||
qint64 adjustedTimestamp = event.timestamp();
|
||||
if (event.timestamp() < rangeStart && !crossedRangeStart) {
|
||||
if (type.rangeType() != MaximumRangeType) {
|
||||
if (type.rangeType() != UndefinedRangeType) {
|
||||
if (event.rangeStage() == RangeStart)
|
||||
stack.push(event);
|
||||
else if (event.rangeStage() == RangeEnd && !stack.isEmpty())
|
||||
@@ -398,7 +398,7 @@ QmlProfilerModelManager::rangeFilter(qint64 rangeStart, qint64 rangeEnd) const
|
||||
crossedRangeStart = true;
|
||||
}
|
||||
if (event.timestamp() > rangeEnd) {
|
||||
if (type.rangeType() != MaximumRangeType) {
|
||||
if (type.rangeType() != UndefinedRangeType) {
|
||||
if (event.rangeStage() == RangeEnd) {
|
||||
if (stack.isEmpty()) {
|
||||
QmlEvent endEvent(event);
|
||||
|
@@ -23,7 +23,7 @@ namespace Internal {
|
||||
|
||||
QmlProfilerRangeModel::QmlProfilerRangeModel(QmlProfilerModelManager *manager, RangeType range,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, MaximumMessage, range, featureFromRangeType(range), parent)
|
||||
QmlProfilerTimelineModel(manager, UndefinedMessage, range, featureFromRangeType(range), parent)
|
||||
{
|
||||
m_expandedRowTypes << -1;
|
||||
}
|
||||
|
@@ -148,7 +148,7 @@ void QmlProfilerTraceClientPrivate::processCurrentEvent()
|
||||
// all ranges are perfectly nested. This is why we can defer the type resolution until either
|
||||
// the range ends or a child range starts. With only the information in RangeStart we wouldn't
|
||||
// be able to uniquely identify the event type.
|
||||
Message rangeStage = currentEvent.type.rangeType() == MaximumRangeType ?
|
||||
Message rangeStage = currentEvent.type.rangeType() == UndefinedRangeType ?
|
||||
currentEvent.type.message() : currentEvent.event.rangeStage();
|
||||
switch (rangeStage) {
|
||||
case RangeStart:
|
||||
@@ -311,7 +311,7 @@ void QmlProfilerTraceClient::setRequestedFeatures(quint64 features)
|
||||
d->currentEvent.event.setTimestamp(context.timestamp > 0 ? context.timestamp : 0);
|
||||
d->currentEvent.event.setTypeIndex(-1);
|
||||
d->currentEvent.event.setString(text);
|
||||
d->currentEvent.type = QmlEventType(DebugMessage, MaximumRangeType, type,
|
||||
d->currentEvent.type = QmlEventType(DebugMessage, UndefinedRangeType, type,
|
||||
QmlEventLocation(context.file, context.line, 1));
|
||||
d->currentEvent.serverTypeId = 0;
|
||||
d->processCurrentEvent();
|
||||
@@ -328,6 +328,8 @@ void QmlProfilerTraceClient::setFlushInterval(quint32 flushInterval)
|
||||
|
||||
bool QmlProfilerTraceClientPrivate::updateFeatures(quint8 feature)
|
||||
{
|
||||
if (feature == UndefinedProfileFeature)
|
||||
return true;
|
||||
quint64 flag = 1ULL << feature;
|
||||
if (!(requestedFeatures & flag))
|
||||
return false;
|
||||
|
@@ -59,7 +59,7 @@ Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) == MaximumMessage * sizeof(const char *)
|
||||
|
||||
static QPair<Message, RangeType> qmlTypeAsEnum(const QString &typeString)
|
||||
{
|
||||
QPair<Message, RangeType> ret(MaximumMessage, MaximumRangeType);
|
||||
QPair<Message, RangeType> ret(UndefinedMessage, UndefinedRangeType);
|
||||
|
||||
for (int i = 0; i < MaximumMessage; ++i) {
|
||||
if (typeString == _(MESSAGE_STRINGS[i])) {
|
||||
@@ -75,7 +75,7 @@ static QPair<Message, RangeType> qmlTypeAsEnum(const QString &typeString)
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.first == MaximumMessage && ret.second == MaximumRangeType) {
|
||||
if (ret.first == UndefinedMessage && ret.second == UndefinedRangeType) {
|
||||
bool isNumber = false;
|
||||
int type = typeString.toUInt(&isNumber);
|
||||
if (isNumber && type < MaximumRangeType)
|
||||
@@ -288,7 +288,7 @@ void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
|
||||
|
||||
int typeIndex = -1;
|
||||
|
||||
QPair<Message, RangeType> messageAndRange(MaximumMessage, MaximumRangeType);
|
||||
QPair<Message, RangeType> messageAndRange(UndefinedMessage, UndefinedRangeType);
|
||||
int detailType = -1;
|
||||
QString displayName;
|
||||
QString data;
|
||||
@@ -296,7 +296,7 @@ void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
|
||||
int line = 0, column = 0;
|
||||
|
||||
auto clearType = [&](){
|
||||
messageAndRange = QPair<Message, RangeType>(MaximumMessage, MaximumRangeType);
|
||||
messageAndRange = QPair<Message, RangeType>(UndefinedMessage, UndefinedRangeType);
|
||||
detailType = -1;
|
||||
displayName.clear();
|
||||
data.clear();
|
||||
@@ -368,7 +368,7 @@ void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
|
||||
// confusing), even though they clearly aren't ranges. Convert that to something
|
||||
// sane here.
|
||||
if (detailType == 4) {
|
||||
messageAndRange = QPair<Message, RangeType>(Event, MaximumRangeType);
|
||||
messageAndRange = QPair<Message, RangeType>(Event, UndefinedRangeType);
|
||||
detailType = AnimationFrame;
|
||||
}
|
||||
}
|
||||
@@ -674,13 +674,13 @@ void QmlProfilerTraceFile::saveQtd(QIODevice *device)
|
||||
QStack<QmlEvent> stack;
|
||||
qint64 lastProgressTimestamp = traceStart();
|
||||
modelManager()->replayQmlEvents([&](const QmlEvent &event, const QmlEventType &type) {
|
||||
if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeStart) {
|
||||
if (type.rangeType() != UndefinedRangeType && event.rangeStage() == RangeStart) {
|
||||
stack.push(event);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.writeStartElement(_("range"));
|
||||
if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeEnd) {
|
||||
if (type.rangeType() != UndefinedRangeType && event.rangeStage() == RangeEnd) {
|
||||
QmlEvent start = stack.pop();
|
||||
stream.writeAttribute(_("startTime"), QString::number(start.timestamp()));
|
||||
stream.writeAttribute(_("duration"),
|
||||
|
@@ -14,10 +14,10 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
|
||||
stream >> time >> messageType;
|
||||
|
||||
if (messageType < 0 || messageType > MaximumMessage)
|
||||
messageType = MaximumMessage;
|
||||
if (messageType < 0 || messageType >= MaximumMessage)
|
||||
messageType = UndefinedMessage;
|
||||
|
||||
RangeType rangeType = MaximumRangeType;
|
||||
RangeType rangeType = UndefinedRangeType;
|
||||
if (!stream.atEnd()) {
|
||||
stream >> subtype;
|
||||
if (subtype >= 0 && subtype < MaximumRangeType)
|
||||
@@ -32,7 +32,9 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
|
||||
switch (messageType) {
|
||||
case Event: {
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
|
||||
if (subtype >= MaximumEventType)
|
||||
subtype = UndefinedEventType;
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
|
||||
switch (subtype) {
|
||||
case StartTrace:
|
||||
case EndTrace: {
|
||||
@@ -76,7 +78,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
break;
|
||||
}
|
||||
case Complete: {
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
|
||||
break;
|
||||
}
|
||||
case SceneGraphFrame: {
|
||||
@@ -88,7 +90,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
params.push_back(param);
|
||||
}
|
||||
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
|
||||
event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
|
||||
break;
|
||||
}
|
||||
@@ -103,7 +105,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
refcount = 1;
|
||||
}
|
||||
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype,
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype,
|
||||
QmlEventLocation(filename, 0, 0));
|
||||
event.event.setNumbers<qint32>({width, height, refcount});
|
||||
break;
|
||||
@@ -112,7 +114,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
qint64 delta;
|
||||
stream >> delta;
|
||||
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
|
||||
event.event.setNumbers<qint64>({delta});
|
||||
break;
|
||||
}
|
||||
@@ -125,7 +127,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
// otherwise it's the old binding type of 4 bytes
|
||||
}
|
||||
|
||||
event.type = QmlEventType(MaximumMessage, rangeType, -1);
|
||||
event.type = QmlEventType(UndefinedMessage, rangeType, -1);
|
||||
event.event.setRangeStage(RangeStart);
|
||||
break;
|
||||
}
|
||||
@@ -133,7 +135,7 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
QString data;
|
||||
stream >> data;
|
||||
|
||||
event.type = QmlEventType(MaximumMessage, rangeType, -1, QmlEventLocation(), data);
|
||||
event.type = QmlEventType(UndefinedMessage, rangeType, -1, QmlEventLocation(), data);
|
||||
event.event.setRangeStage(RangeData);
|
||||
if (!stream.atEnd())
|
||||
stream >> event.serverTypeId;
|
||||
@@ -151,13 +153,13 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
stream >> event.serverTypeId;
|
||||
}
|
||||
|
||||
event.type = QmlEventType(MaximumMessage, rangeType, -1,
|
||||
event.type = QmlEventType(UndefinedMessage, rangeType, -1,
|
||||
QmlEventLocation(filename, line, column));
|
||||
event.event.setRangeStage(RangeLocation);
|
||||
break;
|
||||
}
|
||||
case RangeEnd: {
|
||||
event.type = QmlEventType(MaximumMessage, rangeType, -1);
|
||||
event.type = QmlEventType(UndefinedMessage, rangeType, -1);
|
||||
event.event.setRangeStage(RangeEnd);
|
||||
break;
|
||||
}
|
||||
@@ -170,13 +172,13 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
|
||||
stream >> param;
|
||||
params.push_back(param);
|
||||
}
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
|
||||
event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
event.event.setNumbers<char>({});
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), MaximumRangeType, subtype);
|
||||
event.type = QmlEventType(static_cast<Message>(messageType), UndefinedRangeType, subtype);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@ namespace Internal {
|
||||
|
||||
Quick3DModel::Quick3DModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, Quick3DEvent, MaximumRangeType, ProfileQuick3D, parent),
|
||||
QmlProfilerTimelineModel(manager, Quick3DEvent, UndefinedRangeType, ProfileQuick3D, parent),
|
||||
m_maximumMsgType(-1)
|
||||
{
|
||||
}
|
||||
@@ -135,7 +135,9 @@ int Quick3DModel::collapsedRow(int index) const
|
||||
|
||||
void Quick3DModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||
{
|
||||
auto detailType = type.detailType();
|
||||
int detailType = type.detailType();
|
||||
if (detailType >= MaximumQuick3DFrameType)
|
||||
return;
|
||||
qint64 eventDuration = event.number<qint64>(0);
|
||||
qint64 eventTime = event.timestamp() - eventDuration;
|
||||
QVector<quint64> numbers = event.numbers<QVector<quint64>>();
|
||||
|
@@ -56,7 +56,7 @@ Q_STATIC_ASSERT(sizeof(StageLabels) ==
|
||||
|
||||
SceneGraphTimelineModel::SceneGraphTimelineModel(QmlProfilerModelManager *manager,
|
||||
Timeline::TimelineModelAggregator *parent) :
|
||||
QmlProfilerTimelineModel(manager, SceneGraphFrame, MaximumRangeType, ProfileSceneGraph, parent)
|
||||
QmlProfilerTimelineModel(manager, SceneGraphFrame, UndefinedRangeType, ProfileSceneGraph, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@ void DebugMessagesModelTest::initTestCase()
|
||||
QmlEvent event;
|
||||
event.setTimestamp(i);
|
||||
event.setString(QString::fromLatin1("message %1").arg(i));
|
||||
QmlEventType type(DebugMessage, MaximumRangeType, i % (QtMsgType::QtInfoMsg + 1),
|
||||
QmlEventType type(DebugMessage, UndefinedRangeType, i % (QtMsgType::QtInfoMsg + 1),
|
||||
QmlEventLocation("somefile.js", i, 10 - i));
|
||||
event.setTypeIndex(manager.numEventTypes());
|
||||
manager.appendEventType(std::move(type));
|
||||
|
@@ -34,7 +34,7 @@ int FlameGraphModelTest::generateData(QmlProfilerModelManager *manager,
|
||||
QmlEvent event;
|
||||
if (i < 5) {
|
||||
typeIndex = manager->appendEventType(
|
||||
QmlEventType(MaximumMessage,
|
||||
QmlEventType(UndefinedMessage,
|
||||
static_cast<RangeType>(static_cast<int>(Javascript) - i), -1,
|
||||
QmlEventLocation("somefile.js", i, 20 - i),
|
||||
QString("funcfunc")));
|
||||
|
@@ -20,8 +20,8 @@ static InputEventType inputType(int i)
|
||||
InputEventsModelTest::InputEventsModelTest(QObject *parent) :
|
||||
QObject(parent), model(&manager, &aggregator)
|
||||
{
|
||||
keyTypeId = manager.appendEventType(QmlEventType(Event, MaximumRangeType, Key));
|
||||
mouseTypeId = manager.appendEventType(QmlEventType(Event, MaximumRangeType, Mouse));
|
||||
keyTypeId = manager.appendEventType(QmlEventType(Event, UndefinedRangeType, Key));
|
||||
mouseTypeId = manager.appendEventType(QmlEventType(Event, UndefinedRangeType, Mouse));
|
||||
}
|
||||
|
||||
void InputEventsModelTest::initTestCase()
|
||||
|
@@ -20,11 +20,11 @@ void MemoryUsageModelTest::initTestCase()
|
||||
|
||||
|
||||
heapPageTypeId = manager.numEventTypes();
|
||||
manager.appendEventType(QmlEventType(MemoryAllocation, MaximumRangeType, HeapPage));
|
||||
manager.appendEventType(QmlEventType(MemoryAllocation, UndefinedRangeType, HeapPage));
|
||||
smallItemTypeId = manager.numEventTypes();
|
||||
manager.appendEventType(QmlEventType(MemoryAllocation, MaximumRangeType, SmallItem));
|
||||
manager.appendEventType(QmlEventType(MemoryAllocation, UndefinedRangeType, SmallItem));
|
||||
largeItemTypeId = manager.numEventTypes();
|
||||
manager.appendEventType(QmlEventType(MemoryAllocation, MaximumRangeType, LargeItem));
|
||||
manager.appendEventType(QmlEventType(MemoryAllocation, UndefinedRangeType, LargeItem));
|
||||
|
||||
auto addMemoryEvents = [&]() {
|
||||
QmlEvent event;
|
||||
@@ -53,7 +53,7 @@ void MemoryUsageModelTest::initTestCase()
|
||||
addMemoryEvents();
|
||||
|
||||
rangeTypeId = manager.numEventTypes();
|
||||
manager.appendEventType(QmlEventType(MaximumMessage, Javascript, -1,
|
||||
manager.appendEventType(QmlEventType(UndefinedMessage, Javascript, -1,
|
||||
QmlEventLocation(QString("somefile.js"), 10, 20),
|
||||
QString("funcfunc")));
|
||||
|
||||
|
@@ -22,7 +22,7 @@ void PixmapCacheModelTest::initTestCase()
|
||||
|
||||
for (int i = 0; i < MaximumPixmapEventType; ++i) {
|
||||
eventTypeIndices[i] = manager.numEventTypes();
|
||||
manager.appendEventType(QmlEventType(PixmapCacheEvent, MaximumRangeType, i,
|
||||
manager.appendEventType(QmlEventType(PixmapCacheEvent, UndefinedRangeType, i,
|
||||
QmlEventLocation("dings.png", 0, 0)));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ void PixmapCacheModelTest::initTestCase()
|
||||
|
||||
for (int i = 0; i < MaximumPixmapEventType; ++i) {
|
||||
eventTypeIndices[i + MaximumPixmapEventType] = manager.numEventTypes();
|
||||
manager.appendEventType(QmlEventType(PixmapCacheEvent, MaximumRangeType, i,
|
||||
manager.appendEventType(QmlEventType(PixmapCacheEvent, UndefinedRangeType, i,
|
||||
QmlEventLocation("blah.png", 0, 0)));
|
||||
}
|
||||
|
||||
|
@@ -15,13 +15,13 @@ QmlEventTypeTest::QmlEventTypeTest(QObject *parent) : QObject(parent)
|
||||
void QmlEventTypeTest::testAccessors()
|
||||
{
|
||||
QmlEventType type;
|
||||
QCOMPARE(type.message(), MaximumMessage);
|
||||
QCOMPARE(type.rangeType(), MaximumRangeType);
|
||||
QCOMPARE(type.message(), UndefinedMessage);
|
||||
QCOMPARE(type.rangeType(), UndefinedMessage);
|
||||
QCOMPARE(type.detailType(), -1);
|
||||
QVERIFY(!type.location().isValid());
|
||||
QVERIFY(type.data().isEmpty());
|
||||
QVERIFY(type.displayName().isEmpty());
|
||||
QCOMPARE(static_cast<ProfileFeature>(type.feature()), MaximumProfileFeature);
|
||||
QCOMPARE(static_cast<ProfileFeature>(type.feature()), UndefinedProfileFeature);
|
||||
|
||||
type.setLocation(QmlEventLocation("blah.js", 12, 13));
|
||||
QCOMPARE(type.location().filename(), QString("blah.js"));
|
||||
@@ -34,9 +34,9 @@ void QmlEventTypeTest::testAccessors()
|
||||
type.setDisplayName("disdis");
|
||||
QCOMPARE(type.displayName(), QString("disdis"));
|
||||
|
||||
QmlEventType type2(MaximumMessage, Javascript, 12, QmlEventLocation("lala.js", 2, 3), "nehhh",
|
||||
QmlEventType type2(UndefinedMessage, Javascript, 12, QmlEventLocation("lala.js", 2, 3), "nehhh",
|
||||
"brbr");
|
||||
QCOMPARE(type2.message(), MaximumMessage);
|
||||
QCOMPARE(type2.message(), UndefinedMessage);
|
||||
QCOMPARE(type2.rangeType(), Javascript);
|
||||
QCOMPARE(type2.detailType(), 12);
|
||||
QCOMPARE(type2.location(), QmlEventLocation("lala.js", 2, 3));
|
||||
@@ -49,23 +49,23 @@ void QmlEventTypeTest::testFeature()
|
||||
{
|
||||
const quint8 features[][MaximumEventType] = {
|
||||
// Event
|
||||
{MaximumProfileFeature, ProfileInputEvents, ProfileInputEvents,
|
||||
ProfileAnimations, MaximumProfileFeature, MaximumProfileFeature},
|
||||
{UndefinedProfileFeature, ProfileInputEvents, ProfileInputEvents,
|
||||
ProfileAnimations, UndefinedProfileFeature, UndefinedProfileFeature},
|
||||
// RangeStart
|
||||
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
|
||||
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
|
||||
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
|
||||
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
|
||||
// RangeData
|
||||
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
|
||||
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
|
||||
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
|
||||
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
|
||||
// RangeLocation
|
||||
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
|
||||
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
|
||||
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
|
||||
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
|
||||
// RangeEnd
|
||||
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
|
||||
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
|
||||
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
|
||||
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
|
||||
// Complete
|
||||
{MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature,
|
||||
MaximumProfileFeature, MaximumProfileFeature, MaximumProfileFeature},
|
||||
{UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature,
|
||||
UndefinedProfileFeature, UndefinedProfileFeature, UndefinedProfileFeature},
|
||||
// PixmapCacheEvent
|
||||
{ProfilePixmapCache, ProfilePixmapCache, ProfilePixmapCache,
|
||||
ProfilePixmapCache, ProfilePixmapCache, ProfilePixmapCache},
|
||||
@@ -85,13 +85,13 @@ void QmlEventTypeTest::testFeature()
|
||||
|
||||
for (int i = 0; i < MaximumMessage; ++i) {
|
||||
for (int j = 0; j < MaximumEventType; ++j) {
|
||||
QmlEventType type(static_cast<Message>(i), MaximumRangeType, j);
|
||||
QmlEventType type(static_cast<Message>(i), UndefinedRangeType, j);
|
||||
QCOMPARE(type.feature(), features[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MaximumRangeType; ++i) {
|
||||
QmlEventType type(MaximumMessage, static_cast<RangeType>(i));
|
||||
QmlEventType type(UndefinedMessage, static_cast<RangeType>(i));
|
||||
QCOMPARE(static_cast<ProfileFeature>(type.feature()),
|
||||
featureFromRangeType(static_cast<RangeType>(i)));
|
||||
}
|
||||
@@ -99,7 +99,7 @@ void QmlEventTypeTest::testFeature()
|
||||
|
||||
void QmlEventTypeTest::testStreamOps()
|
||||
{
|
||||
QmlEventType type(MaximumMessage, Javascript, -1, QmlEventLocation("socken.js", 12, 13),
|
||||
QmlEventType type(UndefinedMessage, Javascript, -1, QmlEventLocation("socken.js", 12, 13),
|
||||
"lalala", "lelele");
|
||||
|
||||
QBuffer wbuffer;
|
||||
|
@@ -25,7 +25,7 @@ void QmlProfilerAnimationsModelTest::initTestCase()
|
||||
|
||||
QmlEvent event;
|
||||
event.setTypeIndex(manager.appendEventType(
|
||||
QmlEventType(Event, MaximumRangeType, AnimationFrame)));
|
||||
QmlEventType(Event, UndefinedRangeType, AnimationFrame)));
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
event.setTimestamp(i);
|
||||
|
@@ -27,7 +27,7 @@ DummyModel::DummyModel(QmlProfilerModelManager *manager,
|
||||
|
||||
void DummyModel::loadData()
|
||||
{
|
||||
QmlEventType type(MaximumMessage, Binding);
|
||||
QmlEventType type(UndefinedMessage, Binding);
|
||||
const int typeIndex = modelManager()->appendEventType(QmlEventType(type));
|
||||
QCOMPARE(typeIndex, 0);
|
||||
|
||||
|
@@ -57,9 +57,13 @@ void QmlProfilerTraceClientTest::testMessageReceived()
|
||||
|
||||
modelManager.replayQmlEvents([&](const QmlEvent &event, const QmlEventType &type) {
|
||||
qint64 timestamp;
|
||||
qint32 message;
|
||||
qint32 rangeType;
|
||||
quint8 message;
|
||||
quint8 rangeType;
|
||||
checkStream >> timestamp >> message >> rangeType;
|
||||
QVERIFY(message != MaximumMessage);
|
||||
QVERIFY(rangeType != MaximumRangeType);
|
||||
QVERIFY(type.message() != MaximumMessage);
|
||||
QVERIFY(type.rangeType() != MaximumRangeType);
|
||||
QCOMPARE(event.timestamp(), timestamp);
|
||||
QCOMPARE(type.message(), static_cast<Message>(message));
|
||||
QCOMPARE(type.rangeType(), static_cast<RangeType>(rangeType));
|
||||
|
@@ -120,7 +120,8 @@ void UpdateInfoPlugin::doAutoCheckForUpdates()
|
||||
|
||||
void UpdateInfoPlugin::startCheckForUpdates()
|
||||
{
|
||||
stopCheckForUpdates();
|
||||
if (d->m_maintenanceToolProcess)
|
||||
return; // do not trigger while update task is already running
|
||||
|
||||
QFutureInterface<void> futureIf;
|
||||
FutureProgress *futureProgress
|
||||
|