Merge remote-tracking branch 'origin/5.0'
Conflicts: src/libs/utils/processreaper.cpp src/plugins/clangcodemodel/clangmodelmanagersupport.cpp src/plugins/cmakeprojectmanager/cmakeprocess.cpp Change-Id: Ie248bcb02a80f3e02ab19d73033ce2ba31e7fd83
Before Width: | Height: | Size: 11 KiB |
@@ -132,6 +132,7 @@
|
||||
\li \l{Animations}
|
||||
\li \l{3D Views}
|
||||
\li \l{Group}
|
||||
\li \l{Instanced Rendering}
|
||||
\li \l{Skeletal Animation}
|
||||
\li \l{3D Models}
|
||||
\li \l{Materials and Shaders}
|
||||
|
@@ -49,20 +49,19 @@
|
||||
\list 1
|
||||
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
||||
\if defined(qtcreator)
|
||||
\uicontrol Qt > \uicontrol {QML File (Qt Quick 2)} >
|
||||
\uicontrol Qt > \uicontrol {Qt Quick UI File} >
|
||||
\else
|
||||
\uicontrol {Qt Quick Files} > \uicontrol {Qt Quick File} >
|
||||
\uicontrol {Qt Quick Files} > \uicontrol {Qt Quick UI File} >
|
||||
\endif
|
||||
\uicontrol Choose to create a new .qml file.
|
||||
\uicontrol Choose to create a new \c .ui.qml file.
|
||||
\note Components are listed in \uicontrol Library >
|
||||
\uicontrol Components > \uicontrol {My Components} only
|
||||
if the filename begins with a capital letter.
|
||||
\li Click \uicontrol Design to open the component file (ui.qml) in
|
||||
\li Click \uicontrol Design to open the file in
|
||||
\uicontrol {Form Editor}.
|
||||
\li Drag-and-drop a component from \uicontrol Library to
|
||||
\uicontrol Navigator or \uicontrol {Form Editor}.
|
||||
\li Edit component properties in the \uicontrol Properties view.
|
||||
\image qmldesigner-custom-component-properties.png
|
||||
The available properties depend on the component type. You can
|
||||
\l{Specifying Dynamic Properties}{add properties for
|
||||
components} in \uicontrol {Connection View} > \uicontrol Properties.
|
||||
|
@@ -70,6 +70,7 @@
|
||||
\list
|
||||
\li \l {3D Views}
|
||||
\li \l {Group}
|
||||
\li \l {Instanced Rendering}
|
||||
\li \l {Skeletal Animation}
|
||||
\li \l {3D Models}
|
||||
\li \l {Materials and Shaders}
|
||||
|
@@ -94,6 +94,9 @@
|
||||
|
||||
\image qtquick-number-animation.gif "Number animation"
|
||||
|
||||
For an example of using property animation to animate the scale and opacity
|
||||
of components, see the \l{Coffee Machine} example.
|
||||
|
||||
\section2 Setting Non-Animated Properties
|
||||
|
||||
To immediately change a property value during an animation
|
||||
|
@@ -42,12 +42,12 @@
|
||||
|
||||
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
||||
\if defined(qtcreator)
|
||||
\uicontrol Qt > \uicontrol {QML File (Qt Quick 2)} >
|
||||
\uicontrol Qt > \uicontrol {Qt Quick UI File} >
|
||||
\else
|
||||
\uicontrol {Qt Quick Files} > \uicontrol {Qt Quick File} >
|
||||
\uicontrol {Qt Quick Files} > \uicontrol {Qt Quick UI File} >
|
||||
\endif
|
||||
\uicontrol Choose to create a QML file called Button.qml (for
|
||||
example).
|
||||
\uicontrol Choose to create a \l{UI Files}{UI file} called
|
||||
Button.ui.qml (for example).
|
||||
|
||||
\note Components are listed in \l Library > \uicontrol Components >
|
||||
\uicontrol {My Components} only if the filename begins with a
|
||||
@@ -160,11 +160,12 @@
|
||||
To create a button component, select \uicontrol File >
|
||||
\uicontrol {New File or Project} >
|
||||
\if defined(qtcreator)
|
||||
\uicontrol Qt > \uicontrol {QML File (Qt Quick 2)} >
|
||||
\uicontrol Qt > \uicontrol {Qt Quick UI File} >
|
||||
\else
|
||||
\uicontrol {Qt Quick Files} > \uicontrol {Qt Quick File} >
|
||||
\uicontrol {Qt Quick Files} > \uicontrol {Qt Quick UI File} >
|
||||
\endif
|
||||
\uicontrol Choose to create a file called Button.qml (for example).
|
||||
\uicontrol Choose to create a \l{UI Files}{UI file} called Button.ui.qml
|
||||
(for example).
|
||||
|
||||
\note Components are listed in \l Library > \uicontrol Components >
|
||||
\uicontrol {My Components} only if the filename begins with a
|
||||
@@ -175,8 +176,7 @@
|
||||
To construct the button component:
|
||||
|
||||
\list 1
|
||||
\li Click \uicontrol {Design} to edit the component file in
|
||||
\l {Form Editor}.
|
||||
\li Click \uicontrol {Design} to edit the UI file in \l {Form Editor}.
|
||||
\li Select \l Library > \uicontrol Assets > \inlineimage plus.png
|
||||
to copy the image files you want to use to the project folder.
|
||||
\li In \l Navigator, select the root component and set the
|
||||
|
@@ -156,8 +156,8 @@
|
||||
to rotate component instances in steps of 5 or 45 degrees, respectively.
|
||||
|
||||
You can set the \l{Managing 2D Transformations}{origin} in \l Properties >
|
||||
\uicontrol Advanced > \uicontrol Origin. There, you can also enter the value
|
||||
of the \uicontrol Rotation property in degrees.
|
||||
\uicontrol {Geometry - 2D} > \uicontrol Origin. There, you can also enter
|
||||
the value of the \uicontrol Rotation property in degrees.
|
||||
|
||||
\section1 Zooming
|
||||
|
||||
|
@@ -55,8 +55,10 @@
|
||||
from the Qt UI Quick project to the application project.
|
||||
|
||||
You can use the \c RESOURCES option in the project configuration file to
|
||||
automatically add all the QML files and related assets to a Qt resource
|
||||
file.
|
||||
automatically add all the QML files and related assets to a
|
||||
\l{The Qt Resource System}{Qt resource collection file (.qrc)}. However,
|
||||
large files should be included as external binary resources instead of
|
||||
compiling them into the binary.
|
||||
|
||||
The wizard automatically adds the \c QML_IMPORT_PATH option to the project
|
||||
file for specifying the required
|
||||
@@ -132,6 +134,21 @@
|
||||
|
||||
\quotefile progressbar/main.cpp
|
||||
|
||||
\section1 Handling Large Data Files
|
||||
|
||||
Graphical assets used in the UI, such as images, effects, or 3D scenes
|
||||
are a typical cause for performance problems in UIs. Even building the
|
||||
application requires huge amounts of memory if you try to include large
|
||||
asset files, such as 100-MB 3D models or 64-MB textures, into the \c .qrc
|
||||
file for compiling them into the binary.
|
||||
|
||||
First try to optimize your assets, as described in \l{Optimizing Designs}
|
||||
and \l {Creating Optimized 3D Scenes}.
|
||||
|
||||
If you really need large assets, they should either be loaded directly from
|
||||
the file system or use the Qt resource system in the dynamic way. For more
|
||||
information, see \l{The Qt Resource System} in the Qt documentation.
|
||||
|
||||
\section1 Adding Custom Fonts
|
||||
|
||||
To \l{Using Custom Fonts}{use custom fonts} from the Qt Quick UI project,
|
||||
|
@@ -71,6 +71,7 @@
|
||||
\li \l Animations
|
||||
\li \l{3D Views}
|
||||
\li \l{Group}
|
||||
\li \l{Instanced Rendering}
|
||||
\li \l{Skeletal Animation}
|
||||
\li \l{3D Models}
|
||||
\li \l{Materials and Shaders}
|
||||
|
@@ -52,10 +52,10 @@
|
||||
|
||||
To animate component properties in the \uicontrol Timeline view, you
|
||||
must \l{Setting Keyframe Values}{insert keyframes} for them. In the
|
||||
\l Properties view, select \uicontrol Settings >
|
||||
\uicontrol {Insert Keyframe} for a property that you want to animate.
|
||||
A keyframe track is generated for each component that you insert keyframes
|
||||
for.
|
||||
\l Properties view, select \inlineimage icons/action-icon.png
|
||||
(\uicontrol Actions) > \uicontrol {Insert Keyframe} for a property that you
|
||||
want to animate. A keyframe track is generated for each component that you
|
||||
insert keyframes for.
|
||||
|
||||
\image studio-timeline-with-empty-tracks.png "Timeline view with a property"
|
||||
|
||||
|
@@ -132,9 +132,9 @@
|
||||
|
||||
\list 1
|
||||
\li In the \l Navigator view, select the component to animate.
|
||||
\li In the \l Properties view, select \uicontrol Settings >
|
||||
\uicontrol {Insert Keyframe} for the property that you want to
|
||||
animate.
|
||||
\li In the \l Properties view, select \inlineimage icons/action-icon.png
|
||||
(\uicontrol Actions) > \uicontrol {Insert Keyframe} for the property
|
||||
that you want to animate.
|
||||
\li In the \l Timeline view, select the
|
||||
\uicontrol {Per Property Recording} button
|
||||
to start recording property changes.
|
||||
|
@@ -38,10 +38,10 @@
|
||||
sliders. The progress of the brewing process is displayed as
|
||||
an animation. When the coffee is ready, the startup screen appears again.
|
||||
|
||||
The \e {ApplicationFlow.ui.qml} file contains all the screens in the
|
||||
UI. We use states to display the appropriate screen in the
|
||||
viewport and the timeline to animate the transitions between and on
|
||||
the screens.
|
||||
The \e {ApplicationFlowForm.ui.qml} file contains all the screens in the
|
||||
UI. We use \l{glossary-state}{states} to display the appropriate screen in
|
||||
the viewport and the timeline to animate the \l{glossary-transition}
|
||||
{transitions} between and on the screens.
|
||||
|
||||
\section1 Application Flow
|
||||
|
||||
@@ -55,10 +55,10 @@
|
||||
\printuntil }
|
||||
\dots
|
||||
|
||||
Selecting the coffee type triggers the respective signal handler in
|
||||
\e {SideBar.qml}, which sets the default mix for the selected coffee type.
|
||||
The following code snippet displays the \c {cappuccinoButton.onClicked()}
|
||||
signal handler:
|
||||
Selecting the coffee type triggers the respective \l{glossary-signal}
|
||||
{signal handler} in \e {SideBar.qml}, which sets the default mix for
|
||||
the selected coffee type. The following code snippet displays the
|
||||
\c {cappuccinoButton.onClicked()} signal handler:
|
||||
|
||||
\quotefromfile CoffeeMachine/SideBar.qml
|
||||
\skipto cappuccinoButton.onClicked
|
||||
@@ -113,11 +113,11 @@
|
||||
\section1 Using Timelines to Animate Transitions
|
||||
|
||||
The Coffee Machine application screens for choosing coffee, empty cup, and
|
||||
brewing each use custom components specified in separate component files
|
||||
(.qml).
|
||||
brewing each use custom components specified in separate \l{UI Files}
|
||||
{UI files} (ui.qml).
|
||||
|
||||
We use the \uicontrol Timeline view to animate the transitions between
|
||||
the screens during the application flow in \e {ApplicationFlow.ui.qml}.
|
||||
We use the \l Timeline view to animate the transitions between the screens
|
||||
during the application flow in \e {ApplicationFlowForm.ui.qml}.
|
||||
|
||||
\image coffee-machine-timeline.png
|
||||
|
||||
@@ -132,9 +132,9 @@
|
||||
select the \inlineimage recordfill.png
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
At frame 0, we set the X coordinate to 0 in \l Properties > \uicontrol
|
||||
Geometry > \uicontrol Position. We then move the playhead to 400 frames and
|
||||
set the X coordinate to a negative value.
|
||||
At frame 0, we set the X coordinate to 0 in \l Properties >
|
||||
\uicontrol {Geometry - 2D} > \uicontrol Position. We then move the
|
||||
playhead to 400 frames and set the X coordinate to a negative value.
|
||||
|
||||
\image coffee-machine-properties.png
|
||||
|
||||
@@ -146,13 +146,13 @@
|
||||
|
||||
\section1 Using States to Move Between Screens
|
||||
|
||||
We use the \uicontrol States view to determine the contents of the
|
||||
We use the \l States view to determine the contents of the
|
||||
viewport. The animations are run when moving from one state to another.
|
||||
|
||||
\image coffee-machine-states.png
|
||||
|
||||
We create the states by moving from viewport to viewport in
|
||||
\e ApplicationFlow.ui.qml and clicking \inlineimage plus.png "Add button"
|
||||
\e ApplicationFlowForm.ui.qml and selecting \uicontrol {Create New State}
|
||||
in the \uicontrol States view.
|
||||
|
||||
We also create states for animations that are run when moving to the
|
||||
@@ -171,7 +171,7 @@
|
||||
the end frame to 200, because we are moving back on the timeline to display
|
||||
the selection sidebar.
|
||||
|
||||
In the \uicontrol {Transitions to states} field, we select the state to
|
||||
In the \uicontrol {Transition to state} field, we select the state to
|
||||
switch to when the animation ends. In the lower part of the dialog, we
|
||||
bind the states that don't have animations to fixed frames.
|
||||
*/
|
||||
|
@@ -34,9 +34,9 @@
|
||||
\image ebikedesign.png "Standard screen"
|
||||
|
||||
\e {E-Bike Design} is a control center application for electric bikes.
|
||||
The application contains a Standard screen that displays a speedometer,
|
||||
a Trip screen that displays statistics about the current trip, and a
|
||||
Navigator screen that displays a map.
|
||||
The application contains a \e Standard screen that displays a speedometer,
|
||||
a \e Trip screen that displays statistics about the current trip, and a
|
||||
\e Navigator screen that displays a map.
|
||||
|
||||
The Trip and Navigator screens display a small animated speedometer that
|
||||
the users can select to move back to the Standard screen.
|
||||
@@ -45,12 +45,13 @@
|
||||
|
||||
In the \e {Screen01.ui.qml} file, we place the screens in a row in the
|
||||
following order from left to right: Trip, Standard, Navigator. We will
|
||||
use states to show the appropriate screen in the viewport, and the timeline
|
||||
to animate the transitions between and on the screens.
|
||||
use \l{glossary-state}{states} to show the appropriate screen in the
|
||||
viewport, and the timeline to animate the \l{glossary-transition}
|
||||
{transitions} between and on the screens.
|
||||
|
||||
\section1 Using Timelines to Animate Transitions
|
||||
|
||||
We use the \uicontrol Timeline view to animate the transitions between
|
||||
We use the \l Timeline view to animate the transitions between
|
||||
the screens in \e {Screen01.ui.qml}.
|
||||
|
||||
Our viewport contains 1000 frames, so we select the
|
||||
@@ -67,7 +68,7 @@
|
||||
\image ebikedesign-timeline.png "Timeline view"
|
||||
|
||||
At frame 0, we set the X coordinate to 0 in \l Properties >
|
||||
\uicontrol Geometry > \uicontrol Position to display the Trip screen.
|
||||
\uicontrol {Geometry - 2D} > \uicontrol Position to display the Trip screen.
|
||||
We then move the playhead to frame 1000 and set the X coordinate to
|
||||
-1286 to display the Standard screen. We continue by moving the playhead
|
||||
to frame 2000 and setting the X coordinate to -2560 to display the
|
||||
@@ -84,8 +85,8 @@
|
||||
|
||||
\image ebikedesign-trip-properties.png "Properties view of the Trip component"
|
||||
|
||||
We set values for the \uicontrol Visibility,
|
||||
\uicontrol Opacity, \uicontrol currentFrame, and \uicontrol Scale properties
|
||||
We set values for the \uicontrol Scale, \uicontrol Visibility,
|
||||
\uicontrol Opacity, and \uicontrol currentFrame properties
|
||||
to fade out the current screen when moving to another one and to make the
|
||||
speedometer grow and shrink in size depending on its current position.
|
||||
|
||||
@@ -94,7 +95,7 @@
|
||||
|
||||
\section1 Using States to Move Between Screens
|
||||
|
||||
We use the \uicontrol States view to determine the contents of the viewport.
|
||||
We use the \l States view to determine the contents of the viewport.
|
||||
The animations are run in a particular state or when moving from one state
|
||||
to another.
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 4.7 KiB |
@@ -39,14 +39,16 @@
|
||||
First, we create an empty project, as described in \l {Creating Projects}.
|
||||
For the purposes of this example, we call the project \e progressbar.
|
||||
|
||||
In this example, we use two overlapping rectangles and a text label to
|
||||
create the progress bar. For another example of a progress bar, see the
|
||||
\l {progress-bar-control}{Progress Bar} component in Qt Quick Controls.
|
||||
In this example, we use two overlapping instances of the preset
|
||||
\l{basic-rectangle}{Rectangle} component and an instance of the preset
|
||||
\l{Text} component to create the progress bar. There is also a preset
|
||||
\l {progress-bar-control}{Progress Bar} component available in
|
||||
\uicontrol Library > \uicontrol Components > \uicontrol {Qt Quick Controls}.
|
||||
|
||||
In the \uicontrol Design mode, we drag-and-drop a \uicontrol Rectangle from
|
||||
\l Library > \uicontrol Components > \uicontrol {Default Components} >
|
||||
\uicontrol Basic to \l {Form Editor} and modify its size to create the
|
||||
background for the progress bar. We change its ID to \e background in
|
||||
background for the progress bar. We change its ID to \e pb_back in
|
||||
\l Properties.
|
||||
|
||||
We want to be able to control the background rectangle and the text label
|
||||
@@ -66,7 +68,7 @@
|
||||
\image progressbar-rectangle.png "Progress bar background in the Form Editor"
|
||||
|
||||
We now drag-and-drop another rectangle on top of the background rectangle in
|
||||
\uicontrol Navigator and change its ID to \e indicator in
|
||||
\uicontrol Navigator and change its ID to \e pb_front in
|
||||
\uicontrol Properties.
|
||||
We then anchor the left, top, and bottom of the indicator to its parent with
|
||||
5-pixel margins. We leave the right side free because its value needs to
|
||||
@@ -87,8 +89,8 @@
|
||||
|
||||
\section2 Adding Color Animation
|
||||
|
||||
First, we add a color animation to the \e root component. We select the
|
||||
\inlineimage plus.png
|
||||
First, we add a color animation to the \e root component in the \e Root.qml
|
||||
file. We select the \inlineimage plus.png
|
||||
button to add a 100-frame timeline to root. You can use the default
|
||||
values for all other fields.
|
||||
|
||||
@@ -103,8 +105,9 @@
|
||||
We then set the color at frame 0 to green (\e {#8de98d}) in
|
||||
\uicontrol Properties > \uicontrol Text > \uicontrol {Text Color}.
|
||||
We can either \l{Picking Colors}{pick a color} from the color selector
|
||||
or use the \uicontrol {Set Binding} command in the \inlineimage submenu.png
|
||||
(\uicontrol Settings) menu to open the \uicontrol {Binding Editor}.
|
||||
or use the \uicontrol {Set Binding} command in the
|
||||
\inlineimage icons/action-icon.png
|
||||
(\uicontrol Actions) menu to open the \uicontrol {Binding Editor}.
|
||||
|
||||
We then move the playhead to frame 50 and set the text color to red
|
||||
(\e {#de4f4f}). Finally, we move the playhead to frame 100 and set
|
||||
@@ -117,10 +120,11 @@
|
||||
|
||||
\section2 Animating the Indicator
|
||||
|
||||
We select \e indicator in \uicontrol Navigator and then select the record
|
||||
We select \e pb_front in \uicontrol Navigator and then select the record
|
||||
button again to animate the width of the indicator. At frame 0, we set the
|
||||
width to 0 in \uicontrol Properties > \uicontrol Geometry > \uicontrol Size.
|
||||
We then move the playhead to 100 frames and set the width to 590.
|
||||
width to 0 in \uicontrol Properties > \uicontrol {Geometry - 2D} >
|
||||
\uicontrol Size. We then move the playhead to 100 frames and set the width
|
||||
to 590.
|
||||
|
||||
\image progressbar-timeline-indicator.png "Indicator timeline"
|
||||
|
||||
@@ -160,9 +164,9 @@
|
||||
open \e Root.qml in \uicontrol {Form Editor}.
|
||||
|
||||
We want to be able to use the keyframe value as the value of the text label,
|
||||
so we will export it as a property alias. We select \e timeline in
|
||||
\uicontrol Navigator and then \uicontrol Properties > \uicontrol Timeline >
|
||||
\uicontrol {Current frame} > \uicontrol Settings >
|
||||
so we will export it as a \l{Adding Property Aliases}{property alias}. We
|
||||
select \e timeline in \uicontrol Navigator and then \uicontrol Properties >
|
||||
\uicontrol Timeline > \uicontrol {Current frame} > \uicontrol Actions >
|
||||
\uicontrol {Export Property as Alias}.
|
||||
|
||||
\image progressbar-root-export-property.png "Export keyframe group as a property"
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
\title Side Menu
|
||||
\brief Illustrates how to create reusable components and an animated menu
|
||||
for applying effects.
|
||||
for applying 2D visual effects in Qt 5 projects.
|
||||
|
||||
\image sidemenu.png "Side menu example application"
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
\l {2D Effects}{graphical effects}, such as hue, saturation,
|
||||
and blur, to the images.
|
||||
|
||||
\note Only a subset of effects is available if you select
|
||||
\uicontrol {Qt 6} when \l{Creating Projects}{creating the project}.
|
||||
|
||||
\section1 Creating Reusable Buttons
|
||||
|
||||
We select \uicontrol File > \uicontrol {New File or Project} >
|
||||
@@ -101,9 +104,9 @@
|
||||
We construct the menu bar in the \e {MainFile.ui.qml} file using the
|
||||
\l {Form Editor}. The CustomButton component is listed in
|
||||
\l Library > \uicontrol Components > \uicontrol {My Components}.
|
||||
We drag-and-drop several instances of the component to the
|
||||
\uicontrol {Form Editor} and enclose them in a RowLayout component instance
|
||||
to lay them out as a menu bar.
|
||||
We drag-and-drop several instances of the component to \uicontrol Navigator
|
||||
or \uicontrol {Form Editor} and enclose them in a \uicontrol {Row Layout}
|
||||
component instance to lay them out as a menu bar.
|
||||
|
||||
\image sidemenu-menubar.png
|
||||
|
||||
@@ -123,20 +126,23 @@
|
||||
\section1 Creating a Side Menu
|
||||
|
||||
We can now continue to create a side menu that slides open when users
|
||||
click the burger menu. In the \uicontrol {Form Editor}, we use the
|
||||
\l Text and \l {slider-control}{Slider} components to create separate
|
||||
click the burger menu. We drag-and-drop a \l Text component from
|
||||
\uicontrol Library > \uicontrol Components > \uicontrol {Default Components}
|
||||
> \uicontrol Basic and a \l {slider-control}{Slider} component from
|
||||
\uicontrol {Qt Quick Controls} to \uicontrol Navigator to create separate
|
||||
submenus for each set of effects we want to apply to the images. We use
|
||||
a background image for the menu background and a BurgerMenu custom
|
||||
component for the burger menu icon.
|
||||
|
||||
\image sidemenu-ui.png "SliderMenu component"
|
||||
|
||||
We add states to the \e {SideMenu.qml} file in the \uicontrol {Form Editor}.
|
||||
We add states to the \e {SideMenu.qml} file in the \uicontrol States view.
|
||||
When the application starts, the side menu is in the \e closed state, which
|
||||
means that it is hidden. When users click the burger menu, the \c onClicked
|
||||
signal handler triggers the transition to the \e opening state and runs an
|
||||
animation. When the animation finishes, the side menu state changes to
|
||||
\e open and the side menu is fully visible.
|
||||
\l{glossary-signal}{signal handler} triggers the \l{glossary-transition}
|
||||
{transition} to the \e opening state and runs an animation. When the
|
||||
animation finishes, the side menu state changes to \e open and the side
|
||||
menu is fully visible.
|
||||
|
||||
When users click the burger menu again, the state changes to \e closing and
|
||||
another animation is run that closes the side menu. When the animation
|
||||
@@ -165,7 +171,7 @@
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
At frame 0, we set the X coordinate to -423 in \uicontrol Properties >
|
||||
\uicontrol Geometry > \uicontrol Position. We then move the playhead
|
||||
\uicontrol {Geometry - 2D} > \uicontrol Position. We then move the playhead
|
||||
to frame 1000 and set the X coordinate to 0.
|
||||
|
||||
When we deselect the record button to stop recording the timeline, the
|
||||
@@ -175,9 +181,11 @@
|
||||
|
||||
We then record the transition of the \e imageBackground image. At frame
|
||||
0, we set the X coordinate to -424 again. We then move the playhead to
|
||||
frame 400 and select \uicontrol {Insert Keyframe} in the \uicontrol Settings
|
||||
menu of the X coordinate. We keep the value of the X coordinate -424. We
|
||||
then move the playhead to frame 1000 and set the X coordinate to 0.
|
||||
frame 400 and select \uicontrol {Insert Keyframe} in the
|
||||
\inlineimage icons/action-icon.png
|
||||
(\uicontrol Actions) menu of the X coordinate. We keep the value of the
|
||||
X coordinate -424. We then move the playhead to frame 1000 and set the X
|
||||
coordinate to 0.
|
||||
|
||||
We select \inlineimage animation.png "Timeline Settings button"
|
||||
to open the \uicontrol {Timeline Settings} dialog. In the
|
||||
@@ -219,20 +227,21 @@
|
||||
We use property bindings to connect the controls in the slider menu to
|
||||
\l {2D Effects}{graphical effects}. To have access to the
|
||||
properties from all the slider component instances, we export them as
|
||||
|
||||
in \e SliderMenu.ui.qml. We select \uicontrol {Export Property as Alias}
|
||||
aliases in \e SliderMenu.ui.qml. We select \uicontrol {Export Property as Alias}
|
||||
in the \uicontrol Settings menu of the \uicontrol Value property in
|
||||
\uicontrol Properties > \uicontrol Slider.
|
||||
|
||||
We use the \uicontrol {Form Editor} to create the effect stack in the
|
||||
\e {EffectStack.qml} file:
|
||||
We open the \e {EffectStack.qml} file, and drag-and-drop components from
|
||||
\uicontrol Library > \uicontrol Components >
|
||||
\uicontrol {Qt Quick Studio Effects} to \uicontrol Navigator to create the
|
||||
effect stack.
|
||||
|
||||
\image sidemenu-effects-stack.png "Effects stack in the Navigator"
|
||||
|
||||
We use the \l {Images}{Image} component as the last item in the stack to
|
||||
display images that we apply the effects to. We export the image source
|
||||
property as an \l{Adding Property Aliases}{alias} to be able to switch
|
||||
the image inside the stack.
|
||||
We use an instance of the \l {Images}{Image} component as the last item in
|
||||
the stack to display images that we apply the effects to. We export the
|
||||
image source property as an \l{Adding Property Aliases}{alias} to be able
|
||||
to switch the image inside the stack.
|
||||
|
||||
For more information about the available graphical effects, see
|
||||
\l {2D Effects}.
|
||||
|
@@ -46,8 +46,8 @@
|
||||
\endlist
|
||||
|
||||
Users select buttons to navigate between the screens.
|
||||
We use \l{Connecting Components to Signals}{connections} to determine which
|
||||
screen to open when users select a particular button and \l{Adding States}
|
||||
We use \l{glossary-connection}{connections} to determine which
|
||||
screen to open when users select a particular button and \l{glossary-state}
|
||||
{states} to show the screens. We use the \l{Creating Timeline Animations}
|
||||
{timeline} to create progress indicators for buttons and the \e Running
|
||||
screen.
|
||||
@@ -76,9 +76,9 @@
|
||||
that we can use to configure and build our example application for running
|
||||
it on MCUs.
|
||||
|
||||
\note This example was developed using Qt for MCUs version 1.6. You
|
||||
cannot run it on older versions, and we cannot make any promises about
|
||||
newer versions.
|
||||
\note This example has been tested to run using Qt for MCUs versions since
|
||||
1.6. You cannot run it on older versions. Also, at the time of writing,
|
||||
Qt for MCUs only supports Qt 5.
|
||||
|
||||
\section1 Creating Screens
|
||||
|
||||
@@ -142,10 +142,10 @@
|
||||
|
||||
First, we select the initial arc segment, \e arcSegment1, in
|
||||
\l Navigator to display its properties in \uicontrol Properties.
|
||||
In the \uicontrol Layout tab, \uicontrol Rotation field, we select
|
||||
In \uicontrol {Geometry - 2D} > \uicontrol Rotation, we select
|
||||
\inlineimage icons/action-icon.png
|
||||
, and then select \uicontrol {Insert Keyframe} to insert a keyframe
|
||||
that we can animate in the \uicontrol Timeline view.
|
||||
(\uicontrol Actions), and then select \uicontrol {Insert Keyframe} to
|
||||
insert a keyframe that we can animate in the \uicontrol Timeline view.
|
||||
|
||||
\image washingmachineui-insert-keyframe.png "Inserting keyframe for Rotation property"
|
||||
|
||||
@@ -154,8 +154,8 @@
|
||||
(\uicontrol {Auto Key (K)}) button (or press \key k).
|
||||
|
||||
First, we set the rotation at frame 0 to -90 in \uicontrol Properties >
|
||||
\uicontrol Layout > \uicontrol Rotation. Next, we move the playhead to
|
||||
frame 250 and set the rotation to 0.
|
||||
\uicontrol {Geometry - 2D} > \uicontrol Rotation. Next, we move the playhead
|
||||
to frame 250 and set the rotation to 0.
|
||||
|
||||
When we deselect the record button to stop recording the timeline, the
|
||||
new timeline appears in the view.
|
||||
|
@@ -50,15 +50,15 @@
|
||||
We organize our design in Photoshop using artboards as instructed in
|
||||
\l{Organizing Assets}.
|
||||
|
||||
\QB automatically proposes identifiers for all groups and layers. The ids
|
||||
\QB automatically proposes identifiers for all groups and layers. The IDs
|
||||
will be used as filenames in \QDS. We want to change some of them in the
|
||||
\uicontrol {QML ID} field, so that we can easily find them in \QDS. We
|
||||
must keep in mind that the ids must be unique, that they must begin with
|
||||
\uicontrol ID field, so that we can easily find them in \QDS. We
|
||||
must keep in mind that the IDs must be unique, that they must begin with
|
||||
a lower-case letter or an underscore character, and that only letters,
|
||||
numbers, and underscore characters are allowed.
|
||||
|
||||
Each artboard is exported automatically as a component. That is, a separate
|
||||
QML file that contains all the artwork on the artboard. We determine whether
|
||||
file that contains all the artwork on the artboard. We determine whether
|
||||
each group or layer is exported as a component or a child item. Child items
|
||||
will be exported as PNG files, with references to them in the component file
|
||||
that contains them.
|
||||
@@ -94,23 +94,27 @@
|
||||
|
||||
\image webinardemo-qb-stacklayout.png "Settings for exporting stackLayout artboard"
|
||||
|
||||
For the stackLayoutFrame layer, we want to use a \l StackLayout component,
|
||||
For the \e stackLayoutFrame layer, we want to use a \l StackLayout component,
|
||||
which provides a stack of items where only one item is visible at a time.
|
||||
In the \uicontrol {QML Type} field, we enter \e StackLayout.
|
||||
In the \uicontrol Component field, we enter \e StackLayout.
|
||||
|
||||
To be able to use the component, we enter the statement that imports the
|
||||
Qt Quick Layouts module, which contains the component, in the
|
||||
\uicontrol {Add Imports} field: \c {QtQuick.Layouts 1.3}.
|
||||
\uicontrol Imports field: \c {QtQuick.Layouts 1.3}.
|
||||
|
||||
We will add content to the stack layout in \QDS.
|
||||
|
||||
\section2 Using Qt Studio Effects
|
||||
|
||||
\note The availability of effects depends on whether you select
|
||||
\uicontrol {Qt 5} or \uicontrol {Qt 6} when creating your project
|
||||
in \QDS.
|
||||
|
||||
\image webinardemo-qb-fastblur.png "Settings for exporting blurEffect layer"
|
||||
|
||||
We want to apply the \l {FastBlur} effect to the smallPopup UI control.
|
||||
In the artboard, we have a blurEffect layer that we want to export as a
|
||||
FastBlurItem component. In the \uicontrol {QML Type} field, we enter
|
||||
We want to apply the \l {FastBlur} effect to the \e smallPopup UI control.
|
||||
In the artboard, we have a \e blurEffect layer that we want to export as a
|
||||
\e FastBlurItem component. In the \uicontrol Component field, we enter
|
||||
\e FastBlurItem.
|
||||
|
||||
To be able to use the component, we added the statement that imports the
|
||||
@@ -118,8 +122,11 @@
|
||||
|
||||
We specify that the component to which we want to apply the effect is a
|
||||
child of the effect. We then specify the radius property for the effect,
|
||||
in the \uicontrol {QML Properties} field. We can modify the property in
|
||||
the \uicontrol Radius field in the \uicontrol Properties view in \QDS.
|
||||
in the \uicontrol Properties field. We can modify the property in \QDS by
|
||||
opening the \e {SmallPopup.ui.qml} file and selecting the instance of the
|
||||
\uicontrol {Fast Blur Item} component in \uicontrol Navigator. We can find
|
||||
the property in \l Properties > \uicontrol {Geometry- 2D} >
|
||||
\uicontrol Radius.
|
||||
|
||||
\image webinardemo-blureffect.png "FastBlurItem component in Design mode"
|
||||
|
||||
@@ -162,8 +169,8 @@
|
||||
The \e {LayoutReference.ui.qml} file contains a reference image of
|
||||
the UI we will create. We use the imported components to create the
|
||||
UI in the \e {MainApp.ui.qml} file. The imported components are
|
||||
listed in \uicontrol Library > \uicontrol Components >
|
||||
\uicontrol {My Components}, and we can drag-and-drop them to \l {Form Editor}.
|
||||
listed in \l Library > \uicontrol Components > \uicontrol {My Components},
|
||||
and we can drag-and-drop them to \l {Form Editor}.
|
||||
|
||||
\image webinardemo-mainappui.png "Main app UI in Design mode"
|
||||
|
||||
@@ -172,21 +179,21 @@
|
||||
context menu. Any changes we make to a component are immediately visible in
|
||||
all the other components where it appears.
|
||||
|
||||
We can view the QML code for each component in \l{Text Editor}.
|
||||
We can view the code for each component in \l{Text Editor}.
|
||||
|
||||
We can now use states and the timeline to animate the components in the UI.
|
||||
|
||||
\section2 Animating Components
|
||||
|
||||
We open the \e {Largepopup.ui.qml} file in the Design mode to add animation
|
||||
to it. In the \uicontrol States view, we add the \e opening, \e open,
|
||||
We open the \e {Largepopup.ui.qml} file in the \uicontrol Design mode to add
|
||||
animation to it. In the \l States view, we add the \e opening, \e open,
|
||||
\e closing, and \e closed states for the popup.
|
||||
|
||||
\image webinardemo-states.png "Popup states in the States view"
|
||||
|
||||
For more information about using states, see \l {Creating States}.
|
||||
|
||||
We then use the \uicontrol Timeline view to add animations that are run
|
||||
We then use the \l Timeline view to add animations that are run
|
||||
when moving from one state to another.
|
||||
|
||||
\image webinardemo-timeline.png "Popup animations in the Timeline view"
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 27 KiB |
BIN
doc/qtdesignstudio/images/studio-3d-instancing-instance-list.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
doc/qtdesignstudio/images/studio-3d-instancing-model.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
doc/qtdesignstudio/images/studio-3d-instancing-properties.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 47 KiB |
BIN
doc/qtdesignstudio/images/studio-project-custom-screen-size.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
doc/qtdesignstudio/images/studio-project-location.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
@@ -44,9 +44,9 @@
|
||||
\endlist
|
||||
|
||||
Setting up a new project in \QDS is aided by a wizard that guides you
|
||||
step-by-step through the project creation process. The wizards prompt you
|
||||
to enter the settings needed for that particular type of project and create
|
||||
the necessary files for you.
|
||||
step-by-step through the project creation process. The wizard templates
|
||||
prompt you to enter the settings needed for a particular type of project
|
||||
and create the necessary files for you.
|
||||
|
||||
\QDS projects are useful for creating UIs. You cannot use them for
|
||||
application development, because they do not contain:
|
||||
@@ -65,25 +65,43 @@
|
||||
\image studio-project-wizards.png "A list of project wizards"
|
||||
|
||||
You can export designs from other design tools and import them to projects
|
||||
or create them from scratch using the following wizards:
|
||||
or create them from scratch using the following wizard templates:
|
||||
|
||||
\list
|
||||
\li \uicontrol {Qt for MCUs Application} creates an application that
|
||||
uses a subset of preset components (as supported by Qt for MCUs)
|
||||
that you can deploy, run, and debug on MCU boards.
|
||||
\li \uicontrol {Qt Quick Application - Empty} creates a project that
|
||||
uses default components and preset UI controls and can be run on
|
||||
all target platforms.
|
||||
\li \uicontrol {Qt Quick 3D Application} creates a project that uses
|
||||
default components, UI controls, and 3D components.
|
||||
\li \uicontrol {Qt Quick Application - Scroll} and
|
||||
\uicontrol {Qt Quick Application - Stack} create an application
|
||||
that uses UI controls to implement a scrollable list or a set of
|
||||
pages with a stack-based navigation model.
|
||||
\li \uicontrol {Qt Quick Application - Launcher} creates a
|
||||
project that uses default components and UI controls and
|
||||
\table
|
||||
\header
|
||||
\li Category
|
||||
\li Wizard Template
|
||||
\li Purpose
|
||||
\row
|
||||
\li {1,2} General
|
||||
\li Qt Quick Application - Empty
|
||||
\li Creates a project that uses default components and preset UI
|
||||
controls and can be run on all target platforms.
|
||||
\row
|
||||
\li Qt Quick 3D Application
|
||||
\li Creates a project that uses default components, UI controls, and
|
||||
3D components.
|
||||
\row
|
||||
\li Qt for MCUs
|
||||
\li Qt for MCUs Application
|
||||
\li Creates an application that uses a subset of preset components
|
||||
(as supported by Qt for MCUs) that you can deploy, run, and debug
|
||||
on MCU boards.
|
||||
\row
|
||||
\li {1,2} Mobile
|
||||
\li Qt Quick Application - Scroll
|
||||
\li Creates an application that uses UI controls to implement a
|
||||
scrollable list.
|
||||
\row
|
||||
\li Qt Quick Application - Stack
|
||||
\li Creates an application that uses UI controls to implement a
|
||||
set of pages with a stack-based navigation model.
|
||||
\row
|
||||
\li Desktop
|
||||
\li Qt Quick Application - Launcher
|
||||
\li Creates a project that uses default components and UI controls and
|
||||
defines a launcher application.
|
||||
\endlist
|
||||
\endtable
|
||||
|
||||
For an example of creating a \uicontrol {Qt Quick 3D Application} project,
|
||||
watch the following video:
|
||||
@@ -94,19 +112,31 @@
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol File > \uicontrol {New File or Project}.
|
||||
\li Select the type of your project, and then select \uicontrol Choose.
|
||||
\li Select a wizard template, and then select \uicontrol Choose.
|
||||
\li In the \uicontrol Name field, enter a name for the project.
|
||||
When naming your own projects, keep in mind that they cannot be
|
||||
easily renamed later.
|
||||
Keep in mind that projects cannot be easily renamed later.
|
||||
\image studio-project-location.png "Project Location dialog"
|
||||
\li In the \uicontrol {Create in} field, enter the path for the project
|
||||
files, and then select \uicontrol Next (or \uicontrol Continue on
|
||||
\macos). You can move project folders later without problems.
|
||||
files. You can move project folders later without problems.
|
||||
\li Select \uicontrol Next (or \uicontrol Continue on \macos).
|
||||
\li In the \uicontrol {Screen resolution} field, select the screen
|
||||
resolution for previewing the UI on the desktop or on a device.
|
||||
This determines the screen size.
|
||||
\image studio-project-custom-screen-size.png "Define Project Details dialog"
|
||||
\li To use a custom screen size, specify the width and height of the
|
||||
screen in the \uicontrol {Custom screen width} and
|
||||
\uicontrol {Custom screen height} fields.
|
||||
You can easily change the screen size later in \l Properties.
|
||||
\li In the \uicontrol {Qt Quick Controls Style} field, select one of
|
||||
the predefined \l{Styling Qt Quick Controls}{UI styles} to use,
|
||||
and then select \uicontrol Finish (or \uicontrol Done on \macos).
|
||||
the predefined \l{Styling Qt Quick Controls}{UI styles} to use.
|
||||
\li Select the \uicontrol {Use Qt Virtual Keyboard} check box to enable
|
||||
users to enter text using a virtual keyboard.
|
||||
\li In the \uicontrol {Target Qt Version} field, select the Qt version
|
||||
to use for developing the application. While you can change the
|
||||
Qt version later in the \uicontrol {Run Settings} of the project,
|
||||
keep in mind that the two versions are not fully compatible.
|
||||
\li Select \uicontrol Finish (or \uicontrol Done on \macos) to create
|
||||
the project.
|
||||
\endlist
|
||||
|
||||
\QDS creates the following files and folders:
|
||||
@@ -144,51 +174,77 @@
|
||||
|
||||
\section1 Adding Files to Projects
|
||||
|
||||
You can use wizards also to add individual files to your projects.
|
||||
You can use wizard templates also to add individual files to projects.
|
||||
|
||||
The wizard templates in the \uicontrol {Qt Quick Controls} category create
|
||||
stylable versions of the components in the \uicontrol {Qt Quick Controls}
|
||||
module. For more information, see \l{Creating Custom Controls}.
|
||||
|
||||
You can create the following types of files:
|
||||
|
||||
\list
|
||||
\li \uicontrol {Qt Quick Files}
|
||||
\list
|
||||
\li \uicontrol {Flow Item} and \uicontrol {Flow View}
|
||||
generate components that you can use to design the
|
||||
\table
|
||||
\header
|
||||
\li Category
|
||||
\li Wizard Template
|
||||
\li Purpose
|
||||
\row
|
||||
\li {1,4} Qt Quick Files
|
||||
\li Flow Item and Flow View
|
||||
\li Generate components that you can use to design the
|
||||
\l{Designing Application Flows}{application flow}.
|
||||
\li \uicontrol {Qt Quick File} generates a component with one
|
||||
of the following default components or \l{Using Positioners}
|
||||
{positioners} as the root component: \l {basic-item}{Item},
|
||||
\l {basic-rectangle}{Rectangle}, \l {Images}{Image},
|
||||
\l {Border Image}, \l Flickable, Row, Column, Flow, or Grid.
|
||||
\li \uicontrol {Qt Quick UI File} generates a component file
|
||||
with one of the above components as the root component.
|
||||
\li \uicontrol {Qt Quick Views} generates a Grid View or a
|
||||
List View. For more information, see \l{List and Grid Views}.
|
||||
|
||||
\endlist
|
||||
\li \uicontrol {Qt Quick Controls} create stylable versions of the
|
||||
components in the Qt Quick Controls module:
|
||||
\list
|
||||
\li \l {Button}{Custom Button} creates a push button with a text
|
||||
label.
|
||||
\li \l {Check Box}{Custom CheckBox} creates a check box.
|
||||
\li \l {Slider and Dial}{Custom Dial} creates a dial.
|
||||
\li \l {Slider and Dial}{Custom Slider} creates a slider.
|
||||
\li \l {Spin Box}{Custom SpinBox} creates a spin box.
|
||||
\li \l {Switch}{Custom Switch} creates a switch with on and off
|
||||
states.
|
||||
\li \l [Qt Quick Controls 2] {Pane} provides a background that
|
||||
matches the UI style and theme.
|
||||
\li \l [Qt Quick Controls 2] {StackView} provides a stack-based
|
||||
navigation model.
|
||||
\li \l [Qt Quick Controls 2] {SwipeView} enables users to
|
||||
navigate pages by swiping sideways.
|
||||
\endlist
|
||||
For more information, see \l{Creating Custom Controls}.
|
||||
\li \uicontrol ListModel adds a \l{Editing List Models}{list model} to
|
||||
the project.
|
||||
\li \uicontrol {JavaScript File} generates files that you can use to
|
||||
write the application logic. This is useful for testing the
|
||||
application before the developers implement the application logic
|
||||
in C++, for example. For more information, see
|
||||
\l {Simulating Application Logic}.
|
||||
\endlist
|
||||
\row
|
||||
\li Qt Quick File
|
||||
\li Generates a component with one of the following default components
|
||||
or \l{Using Positioners}{positioners} as the root component:
|
||||
\l {basic-item}{Item}, \l {basic-rectangle}{Rectangle}, \l {Images}
|
||||
{Image}, \l {Border Image}, \l Flickable, Row, Column, Flow, or
|
||||
Grid.
|
||||
\row
|
||||
\li Qt Quick UI File
|
||||
\li Generates a UI file with one of the above components as the root
|
||||
component.
|
||||
\row
|
||||
\li Qt Quick Views
|
||||
\li Generates a Grid View or a List View. For more information, see
|
||||
\l{List and Grid Views}.
|
||||
\row
|
||||
\li {1,9} Qt Quick Controls
|
||||
\li Custom Button
|
||||
\li Creates a \l {Button}{push button} with a text label.
|
||||
\row
|
||||
\li Custom \CheckBox
|
||||
\li Creates a \l {Check Box}{check box}.
|
||||
\row
|
||||
\li Custom Dial
|
||||
\li Creates a \l {Slider and Dial}{dial}.
|
||||
\row
|
||||
\li Custom Slider
|
||||
\li Creates a \l {Slider and Dial}{slider}.
|
||||
\row
|
||||
\li Custom \SpinBox
|
||||
\li Creates a \l {Spin Box}{spin box}.
|
||||
\row
|
||||
\li Custom Switch
|
||||
\li Creates a \l {Switch}{switch} with on and off states.
|
||||
\row
|
||||
\li \l Pane
|
||||
\li Provides a background that matches the UI style and theme.
|
||||
\row
|
||||
\li StackView
|
||||
\li Provides a stack-based navigation model.
|
||||
\row
|
||||
\li SwipeView
|
||||
\li Enables users to navigate pages by swiping sideways.
|
||||
\row
|
||||
\li QML Files
|
||||
\li ListModel
|
||||
\li Adds a \l{Editing List Models}{list model} to the project.
|
||||
\row
|
||||
\li JavaScript
|
||||
\li JavaScript File
|
||||
\li Generates files that you can use to write the application logic.
|
||||
This is useful for testing the application before the developers
|
||||
implement the application logic in C++, for example. For more
|
||||
information, see \l {Simulating Application Logic}.
|
||||
\endtable
|
||||
*/
|
||||
|
@@ -89,6 +89,7 @@
|
||||
\li \l Animations
|
||||
\li \l{3D Views}
|
||||
\li \l{Group}
|
||||
\li \l{Instanced Rendering}
|
||||
\li \l{Skeletal Animation}
|
||||
\li \l{3D Models}
|
||||
\li \l{Materials and Shaders}
|
||||
|
@@ -0,0 +1,153 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 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 studio-3d-instancing.html
|
||||
\previouspage studio-3d-node.html
|
||||
\nextpage studio-skeletal-components.html
|
||||
|
||||
\title Instanced Rendering
|
||||
|
||||
Instancing allows duplicating a model with variations. In contrast to using
|
||||
the \uicontrol Repeater3D component, the model and its graphics resources are
|
||||
only allocated once. The rendering of the duplicated instances is done at a
|
||||
low level by the GPU. Depending on the complexity of the model, this can
|
||||
give a performance improvement of several orders of magnitude.
|
||||
|
||||
In practice, instancing is done by defining a table that specifies how each
|
||||
instance is modified relative to the base model.
|
||||
|
||||
You can add instancing to your scenes by using the instancing components
|
||||
available in \uicontrol Library > \uicontrol Components >
|
||||
\uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D}:
|
||||
\list
|
||||
\li \uicontrol {Instancing}
|
||||
\li \uicontrol {Instance List}
|
||||
\li \uicontrol {Instance List Entry}.
|
||||
\endlist
|
||||
|
||||
\section1 Reading Instance Tables from Files
|
||||
|
||||
The \uicontrol Instancing component makes it possible to read instance tables
|
||||
from files in XML or binary format. The binary file format uses the same
|
||||
layout as the table that is uploaded to the GPU, so it can be directly mapped
|
||||
to memory.
|
||||
|
||||
In order to be valid, the XML file must have a top-level instance table
|
||||
element. Each instance is represented by an Instance element inside the
|
||||
InstanceTable. Unknown elements are silently ignored.
|
||||
|
||||
An Instance element can have a number of attributes. Color attributes are
|
||||
specified by using SVG color names, such as "red", "green", or
|
||||
"lightsteelblue", or by using a hexadecimal notation. \c Vector3d and
|
||||
\c vector4d attributes are specified by a string of space-separated numbers,
|
||||
where missing trailing numbers indicate zeroes. The following attributes are
|
||||
supported: position, scale, eulerRotation, quaternion, custom, and color.
|
||||
For more information about instance tables, see the documentation for the
|
||||
\l[Instancing]{FileInstancing} QML type.
|
||||
|
||||
To use the \uicontrol Instancing component, drag-and-drop it from
|
||||
\uicontrol Library to \uicontrol Scene in \uicontrol Navigator.
|
||||
|
||||
\section2 Instancing Properties
|
||||
|
||||
Define the location of an XML or a binary file containing the instance data
|
||||
in \uicontrol Properties > \uicontrol {File Instancing} > \uicontrol Source.
|
||||
|
||||
\image studio-3d-instancing-properties.png "File Instancing in the Properties View"
|
||||
|
||||
If the file name has a \c .bin extension, it is assumed to refer to a binary
|
||||
file. Otherwise it is assumed to refer to an XML file. If an XML file
|
||||
\c foo.xml is specified, and the file \c foo.xml.bin exists, the binary file
|
||||
\c foo.xml.bin will be loaded instead.
|
||||
|
||||
After defining the \uicontrol Source property for the \uicontrol Instancing
|
||||
component, select a model in \uicontrol Navigator, and in
|
||||
\uicontrol Properties > \uicontrol Model > \uicontrol Instancing, select the
|
||||
name of the \uicontrol Instancing component.
|
||||
|
||||
\image studio-3d-instancing-model.png "The Instancing property"
|
||||
|
||||
\section1 Using Instance Lists to Build Instance Tables
|
||||
|
||||
Use the \uicontrol {Instance List} component to define an instance table in
|
||||
\QDS. An instance table consists of instances defined as
|
||||
\uicontrol {Instance List Entry} components, which can have property bindings
|
||||
and animation. This gives great flexibility but also causes memory overhead.
|
||||
Therefore, it is not recommended to use \uicontrol {Instance List}
|
||||
for procedurally generated tables containing a large number of instances.
|
||||
Also, any property change to an entry will cause the entire instance table
|
||||
to be recalculated and uploaded to the GPU.
|
||||
|
||||
\image studio-3d-instancing-instance-list.png "Instance List and Instance Entries in Navigator"
|
||||
|
||||
To build an instance table:
|
||||
\list 1
|
||||
\li Drag-and-drop an \uicontrol {Instance List} component from
|
||||
\uicontrol Library > \uicontrol Components > \uicontrol {Qt Quick 3D}
|
||||
> \uicontrol {Qt Quick 3D} to \uicontrol Scene in
|
||||
\uicontrol Navigator.
|
||||
\li Drag-and-drop \uicontrol {Instance List Entry} components to the
|
||||
\uicontrol {Instance List} component to create list items.
|
||||
\image studio-3d-instancing-instance-list.png "Instance List and Instance Entries in Navigator"
|
||||
|
||||
\li Select the \uicontrol {Instance List} in \uicontrol Navigator, and in
|
||||
\uicontrol Properties > \uicontrol {Instance List} >
|
||||
\uicontrol Instances, select each \uicontrol {Instance List Entry}
|
||||
you wish to include in the \uicontrol {Instance List} by using
|
||||
the dropdown menu. You can add more fields for the property by
|
||||
clicking the \inlineimage plus.png
|
||||
icon.
|
||||
\li To define an \uicontrol {Instance List Entry}, select it in
|
||||
\uicontrol Navigator, and specify its properties in
|
||||
\uicontrol Properties > \uicontrol {Instance List Entry}.
|
||||
\li Select a model component in \uicontrol Navigator, and in
|
||||
\uicontrol Properties > \uicontrol Instancing, select the name
|
||||
of the \uicontrol {Instance List} component.
|
||||
\endlist
|
||||
|
||||
\section2 Defining Instance List Entries
|
||||
|
||||
Use the \uicontrol {Instance List Entry} component to specify each instance
|
||||
in an \uicontrol {Instance List}.
|
||||
|
||||
Each of the \uicontrol {Instance List Entry} properties can have
|
||||
\l {Adding Bindings Between Properties}{bindings} and animation. Select an
|
||||
\uicontrol {Instance List Entry} in \uicontrol Navigator to specify the
|
||||
properties in \uicontrol Properties > \uicontrol {Instance List Entry}.
|
||||
|
||||
\image studio-3d-instancing-instance-list-entry-properties.png "Instance List Entry Properties"
|
||||
|
||||
Use the \uicontrol Color property to \l{Picking Colors}{specify the color}
|
||||
for the instance.
|
||||
|
||||
Specify the position for the instance using the \uicontrol Position property,
|
||||
and the scale by defining the scale factors of the \uicontrol Scale property
|
||||
along the x, y, and z axes.
|
||||
|
||||
Set the rotation for the instance using the \uicontrol Rotation
|
||||
property, which specifies the rotation for the instance as an Euler vector
|
||||
containing the rotation in degrees around the x, y, and z axes.
|
||||
*/
|
@@ -77,7 +77,10 @@
|
||||
The \uicontrol Source field must be empty when custom geometry is used.
|
||||
|
||||
Set the \uicontrol Instancing property to render a number of instances of
|
||||
the model as defined by the instance table.
|
||||
the model as defined by an instancing table. The instancing tables can be
|
||||
defined by using one of the \l{Instanced Rendering}{instancing components}
|
||||
available in \uicontrol Library > \uicontrol Components >
|
||||
\uicontrol {Qt Quick 3D} > {Qt Quick 3D}.
|
||||
|
||||
Set the \uicontrol {Instance root} property to define the origin of the
|
||||
instance's coordinate system.
|
||||
|
@@ -26,7 +26,7 @@
|
||||
/*!
|
||||
\page studio-3d-node.html
|
||||
\previouspage quick-animations.html
|
||||
\nextpage studio-skeletal-components.html
|
||||
\nextpage studio-3d-instancing.html
|
||||
|
||||
\title Group
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
/*!
|
||||
\page studio-skeletal-components.html
|
||||
\previouspage studio-3d-node.html
|
||||
\previouspage studio-3d-instancing.html
|
||||
\nextpage studio-3d-model.html
|
||||
|
||||
\title Skeletal Animation
|
||||
|
@@ -36,6 +36,10 @@
|
||||
|
||||
\image studio-2d-effects.png "Effects tab in Library"
|
||||
|
||||
\note The availability of effects depends on whether you selected
|
||||
\uicontrol {Qt 5} or \uicontrol {Qt 6} when \l{Creating Projects}
|
||||
{creating your project}.
|
||||
|
||||
Effects have one or more source properties for specifying the visual input
|
||||
for which the effect is applied to a component. The altered visual output is
|
||||
then presented in the effect component itself. The source can be another,
|
||||
@@ -55,6 +59,11 @@
|
||||
|
||||
\section1 Caching and Borders
|
||||
|
||||
Specify common properties for 2D effects in the \uicontrol Caching or
|
||||
\uicontrol {Caching and Border} section.
|
||||
|
||||
\image studio-2d-effects-caching-and-border.png "Studio Effects Caching and Border properties"
|
||||
|
||||
The \uicontrol Cached property allows the effect output pixels to be cached
|
||||
in order to improve the rendering performance. Every time the source or
|
||||
effect properties are changed, the pixels in the cache must be updated.
|
||||
@@ -78,7 +87,8 @@
|
||||
\section1 Summary of 2D Effects
|
||||
|
||||
The following table summarizes the available effects and contains links to
|
||||
the developer documentation of the inherited component.
|
||||
the developer documentation of the inherited component. The Qt 6 column
|
||||
indicates which effects are available for Qt 6 projects.
|
||||
|
||||
\note The effects are available when running with OpenGL.
|
||||
|
||||
@@ -86,10 +96,12 @@
|
||||
\header
|
||||
\li Icon
|
||||
\li Effect
|
||||
\li Qt 6
|
||||
\li Description
|
||||
\row
|
||||
\li \inlineimage icons/blend-mode-16px.png
|
||||
\li \l [QML] {Blend}
|
||||
\li
|
||||
\li Merges two source components by using a blend mode.
|
||||
|
||||
The default \uicontrol Mode is \c subtract, where the pixel value
|
||||
@@ -102,21 +114,25 @@
|
||||
\row
|
||||
\li \inlineimage icons/brightness-contrast-16px.png
|
||||
\li \l {BrightnessContrast}{Brightness Contrast}
|
||||
\li \inlineimage ok.png
|
||||
\li Adjusts \uicontrol Brightness and \uicontrol Contrast.
|
||||
\row
|
||||
\li \inlineimage icons/colourize-16px.png
|
||||
\li \l {ColorOverlay}{Color Overlay}
|
||||
\li \inlineimage ok.png
|
||||
\li Alters the colors of the source component by applying an
|
||||
\uicontrol {Overlay Color}. You can use the color picker
|
||||
\uicontrol {Overlay color}. You can use the color picker
|
||||
to \l{Picking Colors}{select the color}.
|
||||
\row
|
||||
\li \inlineimage icons/colourize-16px.png
|
||||
\li \l Colorize
|
||||
\li \inlineimage ok.png
|
||||
\li Sets the color in the HSL color space by specifying \uicontrol Hue,
|
||||
\uicontrol Lightness, and \uicontrol Saturation values.
|
||||
\row
|
||||
\li \inlineimage icons/desaturation-16px.png
|
||||
\li \l {Desaturate}{Desaturation}
|
||||
\li \inlineimage ok.png
|
||||
\li Reduces the saturation of the colors by the value set in the
|
||||
\uicontrol Desaturation field. The value ranges from \c 0.0
|
||||
(no change) to \c 1.0 (desaturated). Desaturated pixel values are
|
||||
@@ -125,8 +141,9 @@
|
||||
\row
|
||||
\li \inlineimage icons/directional-blur-16px.png
|
||||
\li \l {DirectionalBlur}{Directional Blur}
|
||||
\li \inlineimage ok.png
|
||||
\li Applies a blur effect to the specified direction. The value of the
|
||||
\uicontrol Angle field, defines the direction of the blur. This
|
||||
\uicontrol Angle field defines the direction of the blur. This
|
||||
effect makes the source component appear to be moving in the direction of
|
||||
the blur. Blur is applied to both sides of each pixel, and therefore
|
||||
setting the direction to \c 0 and \c 180 provides the same result.
|
||||
@@ -141,6 +158,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/displace-16px.png
|
||||
\li \l Displace
|
||||
\li \inlineimage ok.png
|
||||
\li Moves the pixels of the source component according to the displacement
|
||||
map specified in the \uicontrol {Displacement source} field.
|
||||
|
||||
@@ -153,13 +171,14 @@
|
||||
\row
|
||||
\li \inlineimage icons/drop-shadow-16px.png
|
||||
\li \l {DropShadow}{Drop Shadow}
|
||||
\li \inlineimage ok.png
|
||||
\li Generates a soft shadow behind the source component using a
|
||||
gaussian blur. This effect blurs the alpha channel of the input and
|
||||
colorizes the result, which it then places behind the source component
|
||||
to create a soft shadow. You can set the shadow's color in the
|
||||
\uicontrol {Drop Shadow Color} field and change its location in the
|
||||
\uicontrol {Horizontal offset} and \uicontrol {Vertical offset}
|
||||
fields.
|
||||
\uicontrol {Drop shadow color} field and change its location in the
|
||||
horizontal (\uicontrol H) and vertical (\uicontrol V)
|
||||
\uicontrol Offset fields.
|
||||
|
||||
The value of the \uicontrol Radius field specifies the softness of
|
||||
the shadow. A larger radius causes the edges of the shadow to appear
|
||||
@@ -174,6 +193,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/fast-blur-16px.png
|
||||
\li \l {FastBlur}{Fast Blur}
|
||||
\li \inlineimage ok.png
|
||||
\li Applies a fast blur effect to one or more source components.
|
||||
\uicontrol {Fast Blur} offers lower blur quality than
|
||||
\uicontrol {Gaussian Blur}, but it is faster to render.
|
||||
@@ -191,6 +211,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/gamma-adjust-16px.png
|
||||
\li \l [QML] {GammaAdjust}{Gamma Adjust}
|
||||
\li \inlineimage ok.png
|
||||
\li Alters the luminance of the source component. This effect is applied
|
||||
to each pixel according to the curve that is pre-defined as a
|
||||
power-law expression, where the value of the \uicontrol Gamma
|
||||
@@ -198,6 +219,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/gaussian-blur-16px.png
|
||||
\li \l [QML] {GaussianBlur}{Gaussian Blur}
|
||||
\li
|
||||
\li Applies a gaussian blur effect to one or more source components.
|
||||
The effect softens the image by blurring it with an algorithm that
|
||||
uses the gaussian function to calculate the effect. The effect
|
||||
@@ -219,6 +241,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/glow-16px.png
|
||||
\li \l [QML] {Glow}
|
||||
\li \inlineimage ok.png
|
||||
\li Generates a halo-like glow around the source component. This effect
|
||||
blurs the alpha channel of the source and colorizes it with
|
||||
\uicontrol {Glow color}. It then places the alpha channel behind the
|
||||
@@ -229,6 +252,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/hue-saturation-16px.png
|
||||
\li \l {HueSaturation}{Hue Saturation}
|
||||
\li \inlineimage ok.png
|
||||
\li Alters the source component colors in the HSL color space.
|
||||
This effect is similar to the \uicontrol Colorize effect, but
|
||||
the \uicontrol Hue and \uicontrol Saturation values are handled
|
||||
@@ -238,8 +262,9 @@
|
||||
\row
|
||||
\li \inlineimage icons/inner-shadow-16px.png
|
||||
\li \l {InnerShadow}{Inner Shadow}
|
||||
\li
|
||||
\li Generates a colorized and blurred shadow inside the source using
|
||||
the color that you specify in the \uicontrol {Inner Shadow Color}
|
||||
the color that you specify in the \uicontrol {Inner shadow color}
|
||||
field.
|
||||
|
||||
The quality of the shadow can be controlled by the values of the
|
||||
@@ -259,6 +284,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/levels-16px.png
|
||||
\li \l {LevelAdjust}{Level Adjust}
|
||||
\li \inlineimage ok.png
|
||||
\li Adjusts color levels in the RGBA color space. This effect adjusts
|
||||
the source component colors separately for each color channel. Source
|
||||
component contrast can be adjusted and color balance altered.
|
||||
@@ -271,22 +297,24 @@
|
||||
ranges from \c QtVector3d(0.0, 0.0, 0.0) (darkest) to \c inf
|
||||
(lightest).
|
||||
|
||||
You can specify the maximum and minimum input and output levels for
|
||||
each color channel. \uicontrol {Maximum input} sets the white-point,
|
||||
which means that all pixels with a higher value are rendered as
|
||||
white (per color channel). Decreasing this value lightens the light
|
||||
areas. To darken the light areas and to increase the contrast,
|
||||
decrease the value of the \uicontrol {Maximum output} field.
|
||||
You can specify the maximum and minimum \uicontrol Input and
|
||||
\uicontrol Output levels for each color channel. \uicontrol Maximum
|
||||
input sets the white-point, which means that all pixels with a
|
||||
higher value are rendered as white (per color channel). Decreasing
|
||||
this value lightens the light areas. To darken the light areas and
|
||||
to increase the contrast, decrease the value of the
|
||||
\uicontrol Maximum output field.
|
||||
|
||||
The value of the \uicontrol {Minimum input} field sets the minimum
|
||||
The value of the \uicontrol Minimum input field sets the minimum
|
||||
input level for each color channel. It sets the black-point, which
|
||||
means that all pixels with a lower value are rendered as black
|
||||
(per color channel). Increasing this value darkens the dark areas.
|
||||
To lighten the dark areas and to reduce the contrast, increase the
|
||||
value of the \uicontrol {Minimum output} field.
|
||||
value of the \uicontrol Minimum output field.
|
||||
\row
|
||||
\li \inlineimage icons/mask-blur-16px.png
|
||||
\li \l {MaskedBlur}{Masked Blur}
|
||||
\li
|
||||
\li Softens the image by blurring it. The intensity of the blur can be
|
||||
controlled for each pixel by specifying a \uicontrol {Mask source},
|
||||
so that some parts of the source are blurred more than others.
|
||||
@@ -301,6 +329,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/opacity-mask-16px.png
|
||||
\li \l {OpacityMask}{Opacity Mask}
|
||||
\li \inlineimage ok.png
|
||||
\li Masks the source component with another component specified in the
|
||||
\uicontrol {Mask source} field. The mask component gets rendered into an
|
||||
intermediate pixel buffer and the alpha values from the result are
|
||||
@@ -315,6 +344,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/radial-blur-16px.png
|
||||
\li \l {RadialBlur}{Radial Blur}
|
||||
\li
|
||||
\li Applies a directional blur effect in a circular direction around the
|
||||
component's center point. This effect makes the source component appear
|
||||
to be rotating into the direction of the blur. Other available
|
||||
@@ -329,6 +359,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/recursive-blur-16px.png
|
||||
\li \l {RecursiveBlur}{Recursive Blur}
|
||||
\li
|
||||
\li Blurs repeatedly, providing a strong blur effect. This effect
|
||||
softens the image by blurring it with an algorithm that uses a
|
||||
recursive feedback loop to blur the source as many times as
|
||||
@@ -344,6 +375,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/threshold-16px.png
|
||||
\li \l {ThresholdMask}{Threshold Mask}
|
||||
\li \inlineimage ok.png
|
||||
\li Masks the source component with another component specified by
|
||||
\uicontrol {Mask source}. The value of the \uicontrol Spread
|
||||
field determines the smoothness of the mask edges near the
|
||||
@@ -354,6 +386,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/zoom-blur-16px.png
|
||||
\li \l {ZoomBlur}{Zoom Blur}
|
||||
\li
|
||||
\li Applies a directional blur effect towards source component's
|
||||
center point. This effect makes the source component appear to be
|
||||
moving towards the center point in Z-direction or the camera
|
||||
@@ -361,9 +394,9 @@
|
||||
|
||||
The value of the \uicontrol Length field specifies the maximum
|
||||
perceived amount of movement for each pixel. The amount is smaller
|
||||
near the center specified by the \uicontrol {Horizontal offset} and
|
||||
\uicontrol {Vertical offset} fields and reaches the specified value
|
||||
at the edges.
|
||||
near the center specified by the horizontal (\uicontrol H) and
|
||||
vertical (\uicontrol V) \uicontrol Offset fields and reaches the
|
||||
specified value at the edges.
|
||||
|
||||
The quality of the blur depends on the value of the
|
||||
\uicontrol Samples field. If the length value is large,
|
||||
|
@@ -187,7 +187,6 @@ if [ ! -d "$app_path/Contents/Frameworks/QtCore.framework" ]; then
|
||||
qbsArguments=("-executable=$qbsapp" \
|
||||
"-executable=$qbsapp-config" \
|
||||
"-executable=$qbsapp-config-ui" \
|
||||
"-executable=$qbsapp-qmltypes" \
|
||||
"-executable=$qbsapp-setup-android" \
|
||||
"-executable=$qbsapp-setup-qt" \
|
||||
"-executable=$qbsapp-setup-toolchains" \
|
||||
|
@@ -54,7 +54,7 @@ def main():
|
||||
os.symlink('/Applications', os.path.join(tempdir, 'Applications'))
|
||||
shutil.copy(os.path.join(arguments.source_directory, 'LICENSE.GPL3-EXCEPT'), tempdir)
|
||||
dmg_cmd = ['hdiutil', 'create', '-srcfolder', tempdir, '-volname', arguments.dmg_volumename,
|
||||
'-format', 'UDBZ', arguments.target_diskimage, '-ov', '-scrub', '-size', '1g', '-verbose']
|
||||
'-format', 'UDBZ', arguments.target_diskimage, '-ov', '-scrub', '-size', '1500m', '-verbose']
|
||||
subprocess.check_call(dmg_cmd)
|
||||
# sleep a few seconds to make sure disk image is fully unmounted etc
|
||||
time.sleep(5)
|
||||
|
@@ -189,8 +189,20 @@ SecondColumnLayout {
|
||||
colorEditor.originalColor = colorEditor.color
|
||||
}
|
||||
|
||||
onValueChanged: colorEditor.color = colorEditor.value
|
||||
onBackendValueChanged: colorEditor.color = colorEditor.value
|
||||
Connections {
|
||||
id: backendConnection
|
||||
target: colorEditor
|
||||
|
||||
function onValueChanged() {
|
||||
if (isNotInGradientMode())
|
||||
colorEditor.color = colorEditor.value
|
||||
}
|
||||
|
||||
function onBackendValueChanged() {
|
||||
if (isNotInGradientMode())
|
||||
colorEditor.color = colorEditor.value
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: colorEditorTimer
|
||||
@@ -198,15 +210,18 @@ SecondColumnLayout {
|
||||
interval: 100
|
||||
running: false
|
||||
onTriggered: {
|
||||
backendConnection.enabled = false
|
||||
|
||||
if (colorEditor.backendValue !== undefined) {
|
||||
if (isVector3D) {
|
||||
if (colorEditor.isVector3D)
|
||||
colorEditor.backendValue.value = Qt.vector3d(colorEditor.color.r,
|
||||
colorEditor.color.g,
|
||||
colorEditor.color.b)
|
||||
} else {
|
||||
else
|
||||
colorEditor.backendValue.value = colorEditor.color
|
||||
}
|
||||
}
|
||||
|
||||
backendConnection.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +238,6 @@ SecondColumnLayout {
|
||||
|
||||
if (isNotInGradientMode())
|
||||
colorEditorTimer.restart() // Delay setting the color to keep ui responsive
|
||||
|
||||
colorPalette.selectedColor = colorEditor.color
|
||||
}
|
||||
|
||||
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
|
||||
@@ -419,6 +432,7 @@ SecondColumnLayout {
|
||||
tooltip: qsTr("Transparent")
|
||||
onClicked: {
|
||||
colorPicker.alpha = 0
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
@@ -503,8 +517,10 @@ SecondColumnLayout {
|
||||
visible: !isNotInGradientMode()
|
||||
|
||||
onCurrentColorChanged: {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient)
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient) {
|
||||
colorEditor.color = gradientLine.currentColor
|
||||
colorPicker.color = colorEditor.color
|
||||
}
|
||||
}
|
||||
|
||||
onHasGradientChanged: {
|
||||
@@ -515,10 +531,9 @@ SecondColumnLayout {
|
||||
}
|
||||
|
||||
onSelectedNodeChanged: {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient) {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient)
|
||||
colorEditor.originalColor = gradientLine.currentColor
|
||||
}
|
||||
}
|
||||
|
||||
onInvalidated: colorEditor.updateThumbnail()
|
||||
|
||||
@@ -546,13 +561,15 @@ SecondColumnLayout {
|
||||
function onSelectionChanged() {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient) {
|
||||
colorEditor.color = gradientLine.currentColor
|
||||
gradientLine.currentColor = color
|
||||
gradientLine.currentColor = colorEditor.color
|
||||
hexTextField.text = colorEditor.color
|
||||
popupHexTextField.text = colorEditor.color
|
||||
}
|
||||
|
||||
gradientLine.isInValidState = true
|
||||
colorEditor.originalColor = colorEditor.color
|
||||
colorPalette.selectedColor = colorEditor.color
|
||||
colorPicker.color = colorEditor.color
|
||||
|
||||
colorEditor.createModel()
|
||||
colorEditor.determineActiveColorMode()
|
||||
@@ -563,44 +580,32 @@ SecondColumnLayout {
|
||||
ColorPicker {
|
||||
id: colorPicker
|
||||
|
||||
property color boundColor: colorEditor.color
|
||||
|
||||
width: parent.width
|
||||
sliderMargins: 4
|
||||
|
||||
// Prevent the binding to be deleted by assignment
|
||||
onBoundColorChanged: colorPicker.color = colorPicker.boundColor
|
||||
onUpdateColor: {
|
||||
colorEditor.color = colorPicker.color
|
||||
|
||||
if (contextMenu.opened)
|
||||
contextMenu.close()
|
||||
}
|
||||
onRightMouseButtonClicked: contextMenu.popup(colorPicker)
|
||||
|
||||
onColorInvalidated: {
|
||||
switch (colorPicker.mode) {
|
||||
case ColorPicker.Mode.HSLA:
|
||||
hslHueSpinBox.value = colorPicker.hue
|
||||
hslSaturationSpinBox.value = colorPicker.saturationHSL
|
||||
hslLightnessSpinBox.value = colorPicker.lightness
|
||||
hslAlphaSpinBox.value = colorPicker.alpha
|
||||
break
|
||||
|
||||
case ColorPicker.Mode.RGBA:
|
||||
redSpinBox.value = (colorPicker.color.r * 255)
|
||||
greenSpinBox.value = (colorPicker.color.g * 255)
|
||||
blueSpinBox.value = (colorPicker.color.b * 255)
|
||||
redSpinBox.value = (colorPicker.red * 255)
|
||||
greenSpinBox.value = (colorPicker.green * 255)
|
||||
blueSpinBox.value = (colorPicker.blue * 255)
|
||||
rgbAlphaSpinBox.value = (colorPicker.alpha * 255)
|
||||
break
|
||||
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
hsvHueSpinBox.value = colorPicker.hue
|
||||
hsvSaturationSpinBox.value = colorPicker.saturationHSV
|
||||
hsvValueSpinBox.value = colorPicker.value
|
||||
hsvAlphaSpinBox.value = colorPicker.alpha
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +795,6 @@ SecondColumnLayout {
|
||||
|
||||
RowLayout {
|
||||
id: rgbaRow
|
||||
|
||||
visible: colorPicker.mode === ColorPicker.Mode.RGBA
|
||||
Layout.fillWidth: true
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
@@ -798,7 +802,6 @@ SecondColumnLayout {
|
||||
DoubleSpinBox {
|
||||
id: redSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -806,17 +809,19 @@ SecondColumnLayout {
|
||||
|
||||
onValueModified: {
|
||||
var tmp = redSpinBox.value / 255.0
|
||||
if (colorPicker.color.r !== tmp && !colorPicker.block) {
|
||||
colorPicker.color.r = tmp
|
||||
if (colorPicker.red !== tmp && !colorPicker.block) {
|
||||
colorPicker.red = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: greenSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -824,17 +829,19 @@ SecondColumnLayout {
|
||||
|
||||
onValueModified: {
|
||||
var tmp = greenSpinBox.value / 255.0
|
||||
if (colorPicker.color.g !== tmp && !colorPicker.block) {
|
||||
colorPicker.color.g = tmp
|
||||
if (colorPicker.green !== tmp && !colorPicker.block) {
|
||||
colorPicker.green = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: blueSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -842,17 +849,19 @@ SecondColumnLayout {
|
||||
|
||||
onValueModified: {
|
||||
var tmp = blueSpinBox.value / 255.0
|
||||
if (colorPicker.color.b !== tmp && !colorPicker.block) {
|
||||
colorPicker.color.b = tmp
|
||||
if (colorPicker.blue !== tmp && !colorPicker.block) {
|
||||
colorPicker.blue = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: rgbAlphaSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -862,15 +871,17 @@ SecondColumnLayout {
|
||||
var tmp = rgbAlphaSpinBox.value / 255.0
|
||||
if (colorPicker.alpha !== tmp && !colorPicker.block) {
|
||||
colorPicker.alpha = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: hslaRow
|
||||
|
||||
visible: colorPicker.mode === ColorPicker.Mode.HSLA
|
||||
Layout.fillWidth: true
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
@@ -882,9 +893,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.hue !== hslHueSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.hue = hslHueSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -894,9 +908,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.saturationHSL !== hslSaturationSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.saturationHSL = hslSaturationSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -906,6 +923,7 @@ SecondColumnLayout {
|
||||
if (colorPicker.lightness !== hslLightnessSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.lightness = hslLightnessSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
@@ -918,15 +936,17 @@ SecondColumnLayout {
|
||||
if (colorPicker.alpha !== hslAlphaSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.alpha = hslAlphaSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: hsvaRow
|
||||
|
||||
visible: colorPicker.mode === ColorPicker.Mode.HSVA
|
||||
Layout.fillWidth: true
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
@@ -938,9 +958,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.hue !== hsvHueSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.hue = hsvHueSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -950,9 +973,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.saturationHSV !== hsvSaturationSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.saturationHSV = hsvSaturationSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -962,9 +988,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.value !== hsvValueSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.value = hsvValueSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -974,9 +1003,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.alpha !== hsvAlphaSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.alpha = hsvAlphaSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,7 +1018,6 @@ SecondColumnLayout {
|
||||
caption: qsTr("Palette")
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
bottomPadding: 5
|
||||
@@ -994,8 +1025,14 @@ SecondColumnLayout {
|
||||
ColorPalette {
|
||||
id: colorPalette
|
||||
enableSingletonConnection: cePopup.opened
|
||||
onSelectedColorChanged: colorEditor.color = colorPalette.selectedColor
|
||||
onDialogColorChanged: colorEditor.color = colorPalette.selectedColor
|
||||
onSelectedColorChanged: {
|
||||
colorPicker.color = colorPalette.selectedColor
|
||||
colorEditor.color = colorPalette.selectedColor
|
||||
}
|
||||
onDialogColorChanged: {
|
||||
colorPicker.color = colorPalette.selectedColor
|
||||
colorEditor.color = colorPalette.selectedColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1005,7 +1042,6 @@ SecondColumnLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: !colorEditor.isNotInGradientMode()
|
||||
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
|
||||
@@ -1039,12 +1075,10 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: defaultGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasLinearGradient() && !colorEditor.shapeGradients
|
||||
|
||||
RowLayout {
|
||||
id: defaultGradientOrientation
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
@@ -1055,9 +1089,9 @@ SecondColumnLayout {
|
||||
width: implicitWidth
|
||||
model: [{ value: Gradient.Vertical, text: qsTr("Vertical") },
|
||||
{ value: Gradient.Horizontal, text: qsTr("Horizontal") }]
|
||||
|
||||
textRole: "text"
|
||||
valueRole: "value"
|
||||
|
||||
onActivated: {
|
||||
gradientLine.model.setGradientOrientation(gradientOrientation.currentValue)
|
||||
colorEditor.updateThumbnail()
|
||||
@@ -1090,7 +1124,6 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: linearGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasLinearGradient() && colorEditor.shapeGradients
|
||||
|
||||
ControlsRow {
|
||||
@@ -1126,7 +1159,6 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: radialGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasRadialGradient()
|
||||
|
||||
ControlsRow {
|
||||
@@ -1170,7 +1202,6 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: concialGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasConicalGradient()
|
||||
|
||||
ControlsRow {
|
||||
|
@@ -36,18 +36,20 @@ Column {
|
||||
}
|
||||
|
||||
property int mode: ColorPicker.Mode.HSVA
|
||||
property color color
|
||||
property color color: "#303091"
|
||||
|
||||
property real red: 0
|
||||
property real green: 0
|
||||
property real blue: 0
|
||||
|
||||
property real hue: 0
|
||||
property real saturationHSL: 0
|
||||
property real saturationHSV: 0
|
||||
property real lightness: 0
|
||||
property real value: 0
|
||||
property real saturationHSL: 0.5
|
||||
property real saturationHSV: 0.5
|
||||
property real lightness: 0.5
|
||||
property real value: 0.5
|
||||
|
||||
property real alpha: 1
|
||||
|
||||
property bool achromatic: false
|
||||
|
||||
property int sliderMargins: 6
|
||||
property bool block: false
|
||||
|
||||
@@ -57,81 +59,90 @@ Column {
|
||||
|
||||
spacing: 10
|
||||
|
||||
onModeChanged: {
|
||||
onColorChanged: {
|
||||
if (root.block)
|
||||
return
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.color = Qt.rgba(root.color.r, root.color.g, root.color.b, root.alpha)
|
||||
root.red = root.color.r
|
||||
root.green = root.color.g
|
||||
root.blue = root.color.b
|
||||
root.alpha = root.color.a
|
||||
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.color = Qt.hsla(root.hue, root.saturationHSL, root.lightness, root.alpha)
|
||||
if (root.color.hslHue !== -1)
|
||||
root.hue = root.color.hslHue
|
||||
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
root.lightness = root.color.hslLightness
|
||||
root.alpha = root.color.a
|
||||
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.color = Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
|
||||
if (root.color.hsvHue !== -1)
|
||||
root.hue = root.color.hsvHue
|
||||
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
root.value = root.color.hsvValue
|
||||
root.alpha = root.color.a
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
gradientOverlay.requestPaint()
|
||||
root.invalidateColor()
|
||||
}
|
||||
|
||||
onHueChanged: {
|
||||
if (root.mode === ColorPicker.Mode.HSLA)
|
||||
root.color.hslHue = root.hue
|
||||
else
|
||||
root.color.hsvHue = root.hue
|
||||
}
|
||||
onSaturationHSLChanged: {
|
||||
root.color.hslSaturation = root.saturationHSL
|
||||
invalidateColor()
|
||||
}
|
||||
onSaturationHSVChanged: {
|
||||
root.color.hsvSaturation = root.saturationHSV
|
||||
}
|
||||
onLightnessChanged: {
|
||||
root.color.hslLightness = root.lightness
|
||||
}
|
||||
onValueChanged: {
|
||||
root.color.hsvValue = root.value
|
||||
}
|
||||
onAlphaChanged: invalidateColor()
|
||||
onColorChanged: invalidateColor()
|
||||
|
||||
function invalidateColor() {
|
||||
if (root.block)
|
||||
return
|
||||
|
||||
root.block = true
|
||||
|
||||
if (root.color.hsvSaturation > 0.0
|
||||
&& root.color.hsvValue > 0.0
|
||||
&& root.color.hsvHue !== -1.0)
|
||||
root.hue = root.color.hsvHue
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.color = Qt.rgba(root.red, root.green, root.blue, root.alpha)
|
||||
// Set HSVA and HSLA
|
||||
if (root.color.hsvHue !== -1)
|
||||
root.hue = root.color.hsvHue // doesn't matter if hsvHue or hslHue
|
||||
|
||||
if (root.color.hslSaturation > 0.0
|
||||
&& root.color.hslLightness > 0.0
|
||||
&& root.color.hslHue !== -1.0)
|
||||
root.hue = root.color.hslHue
|
||||
|
||||
if (root.color.hslLightness !== 0.0 && root.color.hslLightness !== 1.0 && !root.achromatic)
|
||||
if (root.color.hslLightness !== 0.0 && root.color.hslLightness !== 1.0)
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
|
||||
if (root.color.hsvValue !== 0.0 && root.color.hsvValue !== 1.0 && !root.achromatic)
|
||||
if (root.color.hsvValue !== 0.0)
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
|
||||
root.lightness = root.color.hslLightness
|
||||
root.value = root.color.hsvValue
|
||||
|
||||
if (root.color.hslLightness === 0.0 || root.color.hslLightness === 1.0
|
||||
|| root.color.hsvValue === 0.0 || root.color.hsvValue === 1.0
|
||||
|| root.color.hsvHue === -1.0 || root.color.hslHue === -1.0)
|
||||
root.achromatic = true
|
||||
else
|
||||
root.achromatic = false
|
||||
|
||||
if (root.mode === ColorPicker.Mode.HSLA)
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.color = Qt.hsla(root.hue, root.saturationHSL, root.lightness, root.alpha)
|
||||
else
|
||||
// Set RGBA and HSVA
|
||||
root.red = root.color.r
|
||||
root.green = root.color.g
|
||||
root.blue = root.color.b
|
||||
|
||||
if (root.color.hsvValue !== 0.0)
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
|
||||
root.value = root.color.hsvValue
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.color = Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
|
||||
// Set RGBA and HSLA
|
||||
root.red = root.color.r
|
||||
root.green = root.color.g
|
||||
root.blue = root.color.b
|
||||
|
||||
if (root.color.hslLightness !== 0.0 && root.color.hslLightness !== 1.0)
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
|
||||
root.lightness = root.color.hslLightness
|
||||
break
|
||||
}
|
||||
|
||||
luminanceSlider.value = (1.0 - root.value)
|
||||
hueSlider.value = root.hue
|
||||
@@ -142,21 +153,21 @@ Column {
|
||||
root.block = false
|
||||
}
|
||||
|
||||
function drawHSVA(ctx) {
|
||||
for (var row = 0; row < gradientOverlay.height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
|
||||
var v = Math.abs(row - gradientOverlay.height) / gradientOverlay.height
|
||||
function drawHSVA(ctx, width, height, hue) {
|
||||
for (var row = 0; row < height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, width, 0)
|
||||
var v = Math.abs(row - height) / height
|
||||
|
||||
gradient.addColorStop(0, Qt.hsva(root.hue, 0, v, 1))
|
||||
gradient.addColorStop(1, Qt.hsva(root.hue, 1, v, 1))
|
||||
gradient.addColorStop(0, Qt.hsva(hue, 0, v, 1))
|
||||
gradient.addColorStop(1, Qt.hsva(hue, 1, v, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, row, gradientOverlay.width, 1)
|
||||
ctx.fillRect(0, row, width, 1)
|
||||
}
|
||||
}
|
||||
|
||||
function drawRGBA(ctx) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
|
||||
function drawRGBA(ctx, width, height) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, width, 0)
|
||||
gradient.addColorStop(0.000, Qt.rgba(1, 0, 0, 1))
|
||||
gradient.addColorStop(0.167, Qt.rgba(1, 1, 0, 1))
|
||||
gradient.addColorStop(0.333, Qt.rgba(0, 1, 0, 1))
|
||||
@@ -166,26 +177,26 @@ Column {
|
||||
gradient.addColorStop(1.000, Qt.rgba(1, 0, 0, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, 0, gradientOverlay.width, gradientOverlay.height)
|
||||
ctx.fillRect(0, 0, width, height)
|
||||
|
||||
gradient = ctx.createLinearGradient(0, 0, 0, gradientOverlay.height)
|
||||
gradient = ctx.createLinearGradient(0, 0, 0, height)
|
||||
gradient.addColorStop(0.000, Qt.rgba(0, 0, 0, 0))
|
||||
gradient.addColorStop(1.000, Qt.rgba(1, 1, 1, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, 0, gradientOverlay.width, gradientOverlay.height)
|
||||
ctx.fillRect(0, 0, width, height)
|
||||
}
|
||||
|
||||
function drawHSLA(ctx) {
|
||||
for (var row = 0; row < gradientOverlay.height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
|
||||
var l = Math.abs(row - gradientOverlay.height) / gradientOverlay.height
|
||||
function drawHSLA(ctx, width, height, hue) {
|
||||
for (var row = 0; row < height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, width, 0)
|
||||
var l = Math.abs(row - height) / height
|
||||
|
||||
gradient.addColorStop(0, Qt.hsla(root.hue, 0, l, 1))
|
||||
gradient.addColorStop(1, Qt.hsla(root.hue, 1, l, 1))
|
||||
gradient.addColorStop(0, Qt.hsla(hue, 0, l, 1))
|
||||
gradient.addColorStop(1, Qt.hsla(hue, 1, l, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, row, gradientOverlay.width, 1)
|
||||
ctx.fillRect(0, row, width, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,11 +222,12 @@ Column {
|
||||
id: gradientOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
opacity: root.color.a
|
||||
opacity: root.alpha
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onHueChanged() { gradientOverlay.requestPaint() }
|
||||
function onModeChanged() { gradientOverlay.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
@@ -225,14 +237,14 @@ Column {
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.drawRGBA(ctx)
|
||||
root.drawRGBA(ctx, gradientOverlay.width, gradientOverlay.height)
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.drawHSLA(ctx)
|
||||
root.drawHSLA(ctx, gradientOverlay.width, gradientOverlay.height, root.hue)
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.drawHSVA(ctx)
|
||||
root.drawHSVA(ctx, gradientOverlay.width, gradientOverlay.height, root.hue)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -244,9 +256,14 @@ Column {
|
||||
id: pickerCross
|
||||
|
||||
property color strokeStyle: "lightGray"
|
||||
property string loadImageUrl: "images/checkers.png"
|
||||
property int radius: 10
|
||||
|
||||
Component.onCompleted: pickerCross.loadImage(pickerCross.loadImageUrl)
|
||||
onImageLoaded: pickerCross.requestPaint()
|
||||
|
||||
opacity: 0.8
|
||||
anchors.fill: parent
|
||||
anchors.margins: -pickerCross.radius
|
||||
antialiasing: true
|
||||
|
||||
Connections {
|
||||
@@ -261,35 +278,63 @@ Column {
|
||||
ctx.save()
|
||||
ctx.clearRect(0, 0, pickerCross.width, pickerCross.height)
|
||||
|
||||
var yy, xx = 0
|
||||
var normX, normY = 0
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
yy = pickerCross.height - root.saturationHSV * pickerCross.height
|
||||
xx = root.hue * pickerCross.width
|
||||
normX = root.hue
|
||||
normY = 1.0 - root.saturationHSV
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
yy = pickerCross.height - root.lightness * pickerCross.height
|
||||
xx = root.saturationHSL * pickerCross.width
|
||||
normX = root.saturationHSL
|
||||
normY = 1.0 - root.lightness
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
yy = pickerCross.height - root.value * pickerCross.height
|
||||
xx = root.saturationHSV * pickerCross.width
|
||||
normX = root.saturationHSV
|
||||
normY = 1.0 - root.value
|
||||
break
|
||||
}
|
||||
|
||||
ctx.strokeStyle = pickerCross.strokeStyle
|
||||
ctx.lineWidth = 1
|
||||
var width = pickerCross.width - pickerCross.radius * 2
|
||||
var height = pickerCross.height - pickerCross.radius * 2
|
||||
|
||||
var x = normX * width
|
||||
var y = normY * height
|
||||
|
||||
var centerX = pickerCross.radius + x
|
||||
var centerY = pickerCross.radius + y
|
||||
|
||||
// Draw checkerboard
|
||||
if (isImageLoaded(pickerCross.loadImageUrl)) {
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, yy)
|
||||
ctx.lineTo(pickerCross.width, yy)
|
||||
ctx.arc(centerX, centerY, pickerCross.radius, 0, 2 * Math.PI)
|
||||
ctx.clip()
|
||||
|
||||
var pattern = context.createPattern(pickerCross.loadImageUrl, 'repeat')
|
||||
context.fillStyle = pattern
|
||||
|
||||
ctx.fillRect(x, y, pickerCross.radius * 2, pickerCross.radius * 2)
|
||||
}
|
||||
|
||||
// Draw current color
|
||||
if (root.mode === ColorPicker.Mode.RGBA)
|
||||
ctx.fillStyle = Qt.hsva(root.hue, root.saturationHSV, 1, root.alpha)
|
||||
else
|
||||
ctx.fillStyle = root.color
|
||||
|
||||
ctx.fillRect(x, y, pickerCross.radius * 2, pickerCross.radius * 2)
|
||||
|
||||
// Draw black and white circle
|
||||
ctx.lineWidth = 2
|
||||
ctx.strokeStyle = "black"
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, pickerCross.radius, 0, 2 * Math.PI)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.strokeStyle = "white"
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(xx, 0)
|
||||
ctx.lineTo(xx, pickerCross.height)
|
||||
ctx.arc(centerX, centerY, pickerCross.radius - 2, 0, 2 * Math.PI)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.restore()
|
||||
@@ -298,31 +343,48 @@ Column {
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: -pickerCross.radius
|
||||
preventStealing: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
onPositionChanged: function(mouse) {
|
||||
if (mouseArea.pressed && mouse.buttons === Qt.LeftButton) {
|
||||
var xx = Math.max(0, Math.min(mouse.x, parent.width))
|
||||
var yy = Math.max(0, Math.min(mouse.y, parent.height))
|
||||
// Generate color values from mouse position
|
||||
|
||||
// Clip/limit to margin
|
||||
var x = Math.max(0, Math.min(mouse.x - pickerCross.radius, parent.width))
|
||||
var y = Math.max(0, Math.min(mouse.y - pickerCross.radius, parent.height))
|
||||
|
||||
var normX = x / parent.width
|
||||
var normY = y / parent.height
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.saturationHSV = 1.0 - yy / parent.height
|
||||
root.hue = xx / parent.width
|
||||
var tmpColor = Qt.hsva(normX, // hue
|
||||
1.0 - normY, // saturation
|
||||
root.value,
|
||||
root.alpha)
|
||||
|
||||
root.hue = normX
|
||||
root.saturationHSV = 1.0 - normY
|
||||
|
||||
root.red = tmpColor.r
|
||||
root.green = tmpColor.g
|
||||
root.blue = tmpColor.b
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.saturationHSL = xx / parent.width
|
||||
root.lightness = 1.0 - yy / parent.height
|
||||
root.saturationHSL = normX
|
||||
root.lightness = 1.0 - normY
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.saturationHSV = xx / parent.width
|
||||
root.value = 1.0 - yy / parent.height
|
||||
root.saturationHSV = normX
|
||||
root.value = 1.0 - normY
|
||||
break
|
||||
}
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
}
|
||||
onPressed: function(mouse) {
|
||||
@@ -345,9 +407,11 @@ Column {
|
||||
id: hueSlider
|
||||
visible: root.mode !== ColorPicker.Mode.RGBA
|
||||
width: parent.width
|
||||
onValueChanged: {
|
||||
onMoved: {
|
||||
if (root.hue !== hueSlider.value)
|
||||
root.hue = hueSlider.value
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
onClicked: root.updateColor()
|
||||
}
|
||||
@@ -356,10 +420,21 @@ Column {
|
||||
id: luminanceSlider
|
||||
visible: root.mode === ColorPicker.Mode.RGBA
|
||||
width: parent.width
|
||||
color: Qt.hsva(root.hue, root.color.hsvSaturation, 1, 1)
|
||||
onValueChanged: {
|
||||
if (root.value !== luminanceSlider.value)
|
||||
color: Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
|
||||
onMoved: {
|
||||
if (root.value !== (1.0 - luminanceSlider.value))
|
||||
root.value = (1.0 - luminanceSlider.value)
|
||||
|
||||
var tmpColor = Qt.hsva(root.hue,
|
||||
root.saturationHSV,
|
||||
root.value,
|
||||
root.alpha)
|
||||
|
||||
root.red = tmpColor.r
|
||||
root.green = tmpColor.g
|
||||
root.blue = tmpColor.b
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
onClicked: root.updateColor()
|
||||
}
|
||||
@@ -367,10 +442,12 @@ Column {
|
||||
OpacitySlider {
|
||||
id: opacitySlider
|
||||
width: parent.width
|
||||
color: Qt.rgba(root.color.r, root.color.g, root.color.b, 1)
|
||||
onValueChanged: {
|
||||
if (root.alpha !== opacitySlider.value)
|
||||
color: root.color
|
||||
onMoved: {
|
||||
if (root.alpha !== (1.0 - opacitySlider.value))
|
||||
root.alpha = (1.0 - opacitySlider.value)
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
onClicked: root.updateColor()
|
||||
}
|
||||
|
@@ -39,6 +39,8 @@ Item {
|
||||
property alias hover: spinBox.hover
|
||||
|
||||
signal valueModified
|
||||
signal dragStarted
|
||||
signal indicatorPressed
|
||||
|
||||
width: 90
|
||||
implicitHeight: spinBox.height
|
||||
@@ -48,9 +50,13 @@ Item {
|
||||
StudioControls.RealSpinBox {
|
||||
id: spinBox
|
||||
|
||||
onDragStarted: hideCursor()
|
||||
onDragStarted: {
|
||||
hideCursor()
|
||||
wrapper.dragStarted()
|
||||
}
|
||||
onDragEnded: restoreCursor()
|
||||
onDragging: holdCursorInPlace()
|
||||
onIndicatorPressed: wrapper.indicatorPressed()
|
||||
|
||||
property bool hasSlider: spinBox.sliderIndicatorVisible
|
||||
|
||||
|
@@ -96,13 +96,12 @@ Item {
|
||||
height: 80
|
||||
width: parent.width
|
||||
|
||||
property int effectiveWidth: width - 10
|
||||
property int effectiveWidth: colorLine.width - 10
|
||||
property int selectedIndex: 0
|
||||
|
||||
function select(index) {
|
||||
for (var i = 0; i < repeater.model.count; i++) {
|
||||
for (var i = 0; i < repeater.model.count; i++)
|
||||
repeater.itemAt(i).item.highlighted = false
|
||||
}
|
||||
|
||||
if (repeater.model.count < index + 1)
|
||||
return
|
||||
@@ -113,11 +112,12 @@ Item {
|
||||
gradientModel.lock()
|
||||
root.currentColor = repeater.itemAt(index).item.color
|
||||
gradientModel.unlock()
|
||||
|
||||
root.selectedNodeChanged()
|
||||
}
|
||||
|
||||
function invalidate() {
|
||||
var gradientString = "import QtQuick 2.15; Gradient {"
|
||||
var gradientString = "import QtQuick 2.15; Gradient { orientation: Gradient.Horizontal;"
|
||||
|
||||
for (var i = 0; i < gradientModel.count; i++) {
|
||||
gradientString += "GradientStop {}"
|
||||
@@ -209,21 +209,21 @@ Item {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Image {
|
||||
id: checkerboard
|
||||
anchors.fill: parent
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: gradientRectangle
|
||||
smooth: true
|
||||
x: 0
|
||||
y: 16
|
||||
radius: 1
|
||||
border.color: "#555555"
|
||||
border.width: 1
|
||||
width: parent.height
|
||||
height: parent.width
|
||||
anchors.fill: parent
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
gradient: Gradient {
|
||||
id: gradient
|
||||
}
|
||||
transformOrigin: Item.TopLeft
|
||||
rotation: 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,6 +270,13 @@ Item {
|
||||
|
||||
onXChanged: gradientStopHandle.refreshToolTip(gradientStopHandle.toolTipVisible)
|
||||
|
||||
Image {
|
||||
width: 10
|
||||
height: 10
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangle
|
||||
width: 10
|
||||
@@ -277,7 +284,6 @@ Item {
|
||||
color: "red"
|
||||
border.color: "gray"
|
||||
border.width: 1
|
||||
radius: 1
|
||||
}
|
||||
|
||||
Canvas {
|
||||
|
@@ -1,50 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Image {
|
||||
id: root
|
||||
signal clicked
|
||||
visible: colorEditor.shapeGradients && parent.checked
|
||||
width: 8
|
||||
height: 4
|
||||
source: "image://icons/down-arrow"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.bottom
|
||||
anchors.topMargin: 2
|
||||
opacity: popupRegion.containsMouse ? 1 : 0.8
|
||||
|
||||
ToolTipArea {
|
||||
id: popupRegion
|
||||
|
||||
onClicked: root.clicked()
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: -2
|
||||
tooltip: qsTr("Edit Gradient Properties")
|
||||
}
|
||||
}
|
@@ -36,13 +36,14 @@ Item {
|
||||
property bool integer: false
|
||||
|
||||
signal clicked
|
||||
signal moved
|
||||
|
||||
height: StudioTheme.Values.hueSliderHeight
|
||||
|
||||
function updatePos() {
|
||||
if (root.maximum > root.minimum) {
|
||||
var pos = (track.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width - handle.width)
|
||||
var pos = track.width * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
@@ -50,7 +51,6 @@ Item {
|
||||
|
||||
Item {
|
||||
id: track
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
@@ -74,21 +74,20 @@ Item {
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: StudioTheme.Values.hueSliderHandleWidth
|
||||
height: track.height - 4
|
||||
height: track.height + 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
color: "transparent"
|
||||
radius: 2
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
x: root.updatePos()
|
||||
x: root.updatePos() - handle.width * 0.5
|
||||
y: 2
|
||||
z: 1
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
color: Qt.hsva(value, 1, 1, 1)
|
||||
radius: 1
|
||||
border.color: "white"
|
||||
border.width: 1
|
||||
@@ -98,21 +97,23 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
preventStealing: true
|
||||
|
||||
function calculateValue() {
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX, mouseArea.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / mouseArea.width + root.minimum
|
||||
var halfHandle = StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX - halfHandle, parent.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / parent.width + root.minimum
|
||||
root.value = root.integer ? Math.round(realValue) : realValue
|
||||
root.moved()
|
||||
}
|
||||
|
||||
onPressed: calculateValue()
|
||||
onPressed: mouseArea.calculateValue()
|
||||
onReleased: root.clicked()
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
calculateValue()
|
||||
if (mouseArea.pressed)
|
||||
mouseArea.calculateValue()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -37,13 +37,14 @@ Item {
|
||||
property color color
|
||||
|
||||
signal clicked
|
||||
signal moved
|
||||
|
||||
height: StudioTheme.Values.hueSliderHeight
|
||||
|
||||
function updatePos() {
|
||||
if (root.maximum > root.minimum) {
|
||||
var pos = (track.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width - handle.width)
|
||||
var pos = track.width * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
@@ -51,17 +52,9 @@ Item {
|
||||
|
||||
Item {
|
||||
id: track
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Image {
|
||||
id: checkerboard
|
||||
anchors.fill: parent
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
@@ -69,7 +62,7 @@ Item {
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.000; color: root.color }
|
||||
GradientStop { position: 0.000; color: Qt.hsva(root.color.hsvHue, root.color.hsvSaturation, 1, 1) }
|
||||
GradientStop { position: 1.000; color: "black" }
|
||||
}
|
||||
}
|
||||
@@ -77,21 +70,20 @@ Item {
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: StudioTheme.Values.hueSliderHandleWidth
|
||||
height: track.height - 4
|
||||
height: track.height + 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
color: "transparent"
|
||||
radius: 2
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
x: root.updatePos()
|
||||
x: root.updatePos() - handle.width * 0.5
|
||||
y: 2
|
||||
z: 1
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
color: Qt.hsva(root.color.hsvHue, root.color.hsvSaturation, root.color.hsvValue, 1)
|
||||
radius: 1
|
||||
border.color: "white"
|
||||
border.width: 1
|
||||
@@ -101,19 +93,22 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
preventStealing: true
|
||||
|
||||
function calculateValue() {
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX, mouseArea.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / mouseArea.width + root.minimum
|
||||
var halfHandle = StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX - halfHandle, parent.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / parent.width + root.minimum
|
||||
root.value = root.integer ? Math.round(realValue) : realValue
|
||||
root.moved()
|
||||
}
|
||||
|
||||
onPressed: calculateValue()
|
||||
onPressed: mouseArea.calculateValue()
|
||||
onReleased: root.clicked()
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
calculateValue()
|
||||
if (mouseArea.pressed)
|
||||
mouseArea.calculateValue()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,13 +37,14 @@ Item {
|
||||
property color color
|
||||
|
||||
signal clicked
|
||||
signal moved
|
||||
|
||||
height: StudioTheme.Values.hueSliderHeight
|
||||
|
||||
function updatePos() {
|
||||
if (root.maximum > root.minimum) {
|
||||
var pos = (track.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width - handle.width)
|
||||
var pos = track.width * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
@@ -51,12 +52,10 @@ Item {
|
||||
|
||||
Item {
|
||||
id: track
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Image {
|
||||
id: checkerboard
|
||||
anchors.fill: parent
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
@@ -69,7 +68,7 @@ Item {
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.000; color: root.color }
|
||||
GradientStop { position: 0.000; color: Qt.rgba(root.color.r, root.color.g, root.color.b, 1) }
|
||||
GradientStop { position: 1.000; color: "transparent" }
|
||||
}
|
||||
}
|
||||
@@ -77,21 +76,27 @@ Item {
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: StudioTheme.Values.hueSliderHandleWidth
|
||||
height: track.height - 4
|
||||
height: track.height + 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
color: "transparent"
|
||||
radius: 2
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
x: root.updatePos()
|
||||
x: root.updatePos() - handle.width * 0.5
|
||||
y: 2
|
||||
z: 1
|
||||
|
||||
Image {
|
||||
anchors.fill: handleInside
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: handleInside
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
color: root.color
|
||||
radius: 1
|
||||
border.color: "white"
|
||||
border.width: 1
|
||||
@@ -101,19 +106,22 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
preventStealing: true
|
||||
|
||||
function calculateValue() {
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX, mouseArea.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / mouseArea.width + root.minimum
|
||||
var halfHandle = StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX - halfHandle, parent.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / parent.width + root.minimum
|
||||
root.value = root.integer ? Math.round(realValue) : realValue
|
||||
root.moved()
|
||||
}
|
||||
|
||||
onPressed: calculateValue()
|
||||
onPressed: mouseArea.calculateValue()
|
||||
onReleased: root.clicked()
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
calculateValue()
|
||||
if (mouseArea.pressed)
|
||||
mouseArea.calculateValue()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -71,7 +71,7 @@ Row {
|
||||
border.color: StudioTheme.Values.themeToolTipOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
}
|
||||
contentItem: Label {
|
||||
contentItem: Text {
|
||||
color: StudioTheme.Values.themeToolTipText
|
||||
text: toolTip.text
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
@@ -135,7 +135,7 @@ Row {
|
||||
border.color: StudioTheme.Values.themeToolTipOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
}
|
||||
contentItem: Label {
|
||||
contentItem: Text {
|
||||
color: StudioTheme.Values.themeToolTipText
|
||||
text: itemToolTip.text
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
@@ -31,7 +31,6 @@ FontExtrasSection 2.0 FontExtrasSection.qml
|
||||
FontSection 2.0 FontSection.qml
|
||||
FontStyleButtons 2.0 FontStyleButtons.qml
|
||||
GradientLine 2.0 GradientLine.qml
|
||||
GradientPopupIndicator 2.0 GradientPopupIndicator.qml
|
||||
GradientPresetList 2.0 GradientPresetList.qml
|
||||
GradientPresetTabContent 2.0 GradientPresetTabContent.qml
|
||||
GradientPropertySpinBox 2.0 GradientPropertySpinBox.qml
|
||||
|
@@ -131,7 +131,7 @@ T.CheckBox {
|
||||
},
|
||||
State {
|
||||
name: "globalHover"
|
||||
when: actionIndicator.hover && myCheckBox.hover && !myCheckBox.pressed
|
||||
when: actionIndicator.hover && !myCheckBox.pressed && myCheckBox.enabled
|
||||
PropertyChanges {
|
||||
target: checkBoxBackground
|
||||
color: StudioTheme.Values.themeControlBackgroundGlobalHover
|
||||
|
@@ -121,7 +121,7 @@ T.ComboBox {
|
||||
ComboBox.ActivatedReason.Other)
|
||||
}
|
||||
|
||||
onActivated: {
|
||||
onActivated: function(index) {
|
||||
myTimer.activatedIndex = index
|
||||
myTimer.restart()
|
||||
}
|
||||
|
@@ -81,6 +81,7 @@ T.SpinBox {
|
||||
signal dragStarted
|
||||
signal dragEnded
|
||||
signal dragging
|
||||
signal indicatorPressed
|
||||
|
||||
// Use custom wheel handling due to bugs
|
||||
property bool __wheelEnabled: false
|
||||
@@ -124,6 +125,7 @@ T.SpinBox {
|
||||
myControl: mySpinBox
|
||||
iconFlip: -1
|
||||
visible: mySpinBox.spinBoxIndicatorVisible
|
||||
onRealPressed: mySpinBox.indicatorPressed()
|
||||
onRealReleased: mySpinBox.realIncrease()
|
||||
onRealPressAndHold: mySpinBox.realIncrease()
|
||||
x: actionIndicator.width + StudioTheme.Values.border
|
||||
@@ -139,6 +141,7 @@ T.SpinBox {
|
||||
id: spinBoxIndicatorDown
|
||||
myControl: mySpinBox
|
||||
visible: mySpinBox.spinBoxIndicatorVisible
|
||||
onRealPressed: mySpinBox.indicatorPressed()
|
||||
onRealReleased: mySpinBox.realDecrease()
|
||||
onRealPressAndHold: mySpinBox.realDecrease()
|
||||
x: actionIndicator.width + StudioTheme.Values.border
|
||||
|
@@ -157,7 +157,6 @@ void ProcessReaper::reap(QProcess *process, int timeoutMs)
|
||||
QTC_ASSERT(QThread::currentThread() == process->thread(), return);
|
||||
|
||||
process->disconnect();
|
||||
process->setParent(nullptr);
|
||||
if (process->state() == QProcess::NotRunning) {
|
||||
process->deleteLater();
|
||||
return;
|
||||
|
@@ -473,7 +473,13 @@ FilePath AndroidConfig::avdManagerToolPath() const
|
||||
|
||||
FilePath AndroidConfig::toolchainPathFromNdk(const FilePath &ndkLocation) const
|
||||
{
|
||||
const FilePath toolchainPath = ndkLocation / "toolchains/llvm/prebuilt/";
|
||||
const FilePath tcPath = ndkLocation / "toolchains/";
|
||||
FilePath toolchainPath;
|
||||
QDirIterator llvmIter(tcPath.toString(), {"llvm*"}, QDir::Dirs);
|
||||
if (llvmIter.hasNext()) {
|
||||
llvmIter.next();
|
||||
toolchainPath = tcPath / llvmIter.fileName() / "prebuilt/";
|
||||
}
|
||||
|
||||
// detect toolchain host
|
||||
QStringList hostPatterns;
|
||||
|
@@ -544,11 +544,13 @@ void AndroidDeployQtStep::stdError(const QString &line)
|
||||
return;
|
||||
|
||||
if (newOutput.startsWith("warning", Qt::CaseInsensitive)
|
||||
|| newOutput.startsWith("note", Qt::CaseInsensitive))
|
||||
|| newOutput.startsWith("note", Qt::CaseInsensitive)
|
||||
|| newOutput.startsWith(QLatin1String("All files should be loaded."))) {
|
||||
TaskHub::addTask(DeploymentTask(Task::Warning, newOutput));
|
||||
else if (newOutput != QLatin1String("All files should be loaded. Notifying the device."))
|
||||
} else {
|
||||
TaskHub::addTask(DeploymentTask(Task::Error, newOutput));
|
||||
}
|
||||
}
|
||||
|
||||
AndroidDeployQtStep::DeployErrorCode AndroidDeployQtStep::parseDeployErrors(
|
||||
const QString &deployOutputLine) const
|
||||
|
@@ -117,12 +117,16 @@ QList<ITestConfiguration *> CTestTreeItem::testConfigurationsFor(const QStringLi
|
||||
config->setProject(project);
|
||||
config->setCommandLine(command);
|
||||
const ProjectExplorer::RunConfiguration *runConfig = target->activeRunConfiguration();
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
if (QTC_GUARD(runConfig)) {
|
||||
if (auto envAspect = runConfig->aspect<ProjectExplorer::EnvironmentAspect>())
|
||||
config->setEnvironment(envAspect->environment());
|
||||
else
|
||||
config->setEnvironment(Utils::Environment::systemEnvironment());
|
||||
env = envAspect->environment();
|
||||
}
|
||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||
env.set("QT_FORCE_STDERR_LOGGING", "1");
|
||||
env.set("QT_LOGGING_TO_CONSOLE", "1");
|
||||
}
|
||||
config->setEnvironment(env);
|
||||
const ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
|
||||
if (QTC_GUARD(buildConfig))
|
||||
config->setWorkingDirectory(buildConfig->buildDirectory());
|
||||
|
@@ -153,8 +153,10 @@ QStringList filterInterfering(const QStringList &provided, QStringList *omitted,
|
||||
Utils::Environment prepareBasicEnvironment(const Utils::Environment &env)
|
||||
{
|
||||
Utils::Environment result(env);
|
||||
if (Utils::HostOsInfo::isWindowsHost())
|
||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||
result.set("QT_FORCE_STDERR_LOGGING", "1");
|
||||
result.set("QT_LOGGING_TO_CONSOLE", "1");
|
||||
}
|
||||
const int timeout = AutotestPlugin::settings()->timeout;
|
||||
if (timeout > 5 * 60 * 1000) // Qt5.5 introduced hard limit, Qt5.6.1 added env var to raise this
|
||||
result.set("QTEST_FUNCTION_TIMEOUT", QString::number(timeout));
|
||||
|
@@ -312,6 +312,7 @@ void QuickTestParser::handleDirectoryChanged(const QString &directory)
|
||||
return filesAndDates.value(file) != watched.value(file);
|
||||
});
|
||||
if (timestampChanged) {
|
||||
m_watchedFiles[directory] = filesAndDates;
|
||||
PathsAndLanguages paths;
|
||||
paths.maybeInsert(Utils::FilePath::fromString(directory), Dialect::Qml);
|
||||
QFutureInterface<void> future;
|
||||
|
@@ -391,12 +391,10 @@ void TestTreeModel::synchronizeTestTools()
|
||||
|
||||
for (ITestTool *testTool : qAsConst(tools)) {
|
||||
ITestTreeItem *testToolRootNode = testTool->rootNode();
|
||||
if (testTool->active()) {
|
||||
invisibleRoot->appendChild(testToolRootNode);
|
||||
if (!oldFrameworkRoots.removeOne(testToolRootNode))
|
||||
newlyAdded.insert(testTool);
|
||||
}
|
||||
}
|
||||
|
||||
if (project) {
|
||||
const QList<Target *> &allTargets = project->targets();
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include <QMenu>
|
||||
#include <QTextBlock>
|
||||
#include <QTimer>
|
||||
#include <QtDebug>
|
||||
|
||||
using namespace CppEditor;
|
||||
using namespace LanguageClient;
|
||||
@@ -381,7 +382,7 @@ ClangdClient *ClangModelManagerSupport::clientForProject(
|
||||
&& c->state() != Client::ShutdownRequested
|
||||
&& c->state() != Client::Shutdown;
|
||||
});
|
||||
QTC_CHECK(clients.size() <= 1);
|
||||
QTC_ASSERT(clients.size() <= 1, qDebug() << project << clients.size());
|
||||
return clients.empty() ? nullptr : qobject_cast<ClangdClient *>(clients.first());
|
||||
}
|
||||
|
||||
|
@@ -53,7 +53,7 @@ using namespace CMakeProjectManager::Internal::FileApiDetails;
|
||||
class CMakeFileResult
|
||||
{
|
||||
public:
|
||||
QSet<FilePath> cmakeFiles;
|
||||
QSet<CMakeFileInfo> cmakeFiles;
|
||||
|
||||
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesSource;
|
||||
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesBuild;
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeListNodes;
|
||||
};
|
||||
|
||||
CMakeFileResult extractCMakeFilesData(const std::vector<FileApiDetails::CMakeFileInfo> &cmakefiles,
|
||||
CMakeFileResult extractCMakeFilesData(const std::vector<CMakeFileInfo> &cmakefiles,
|
||||
const FilePath &sourceDirectory,
|
||||
const FilePath &buildDirectory)
|
||||
{
|
||||
@@ -72,9 +72,11 @@ CMakeFileResult extractCMakeFilesData(const std::vector<FileApiDetails::CMakeFil
|
||||
|
||||
for (const CMakeFileInfo &info : cmakefiles) {
|
||||
const FilePath sfn = FilePath::fromString(
|
||||
QDir::cleanPath(sourceDir.absoluteFilePath(info.path)));
|
||||
QDir::cleanPath(sourceDir.absoluteFilePath(info.path.toString())));
|
||||
const int oldCount = result.cmakeFiles.count();
|
||||
result.cmakeFiles.insert(sfn);
|
||||
CMakeFileInfo absolute(info);
|
||||
absolute.path = sfn;
|
||||
result.cmakeFiles.insert(absolute);
|
||||
if (oldCount < result.cmakeFiles.count()) {
|
||||
if (info.isCMake && !info.isCMakeListsDotTxt) {
|
||||
// Skip files that cmake considers to be part of the installation -- but include
|
||||
@@ -109,7 +111,7 @@ class PreprocessedData
|
||||
public:
|
||||
CMakeProjectManager::CMakeConfig cache;
|
||||
|
||||
QSet<FilePath> cmakeFiles;
|
||||
QSet<CMakeFileInfo> cmakeFiles;
|
||||
|
||||
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesSource;
|
||||
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> cmakeNodesBuild;
|
||||
|
@@ -44,12 +44,26 @@ namespace Internal {
|
||||
|
||||
class FileApiData;
|
||||
|
||||
class CMakeFileInfo
|
||||
{
|
||||
public:
|
||||
bool operator==(const CMakeFileInfo& other) const { return path == other.path; }
|
||||
|
||||
Utils::FilePath path;
|
||||
bool isCMake = false;
|
||||
bool isCMakeListsDotTxt = false;
|
||||
bool isExternal = false;
|
||||
bool isGenerated = false;
|
||||
};
|
||||
|
||||
inline uint qHash(const CMakeFileInfo &info, uint seed = 0) { return info.path.hash(seed); }
|
||||
|
||||
class FileApiQtcData
|
||||
{
|
||||
public:
|
||||
QString errorMessage;
|
||||
CMakeConfig cache;
|
||||
QSet<Utils::FilePath> cmakeFiles;
|
||||
QSet<CMakeFileInfo> cmakeFiles;
|
||||
QList<CMakeBuildTarget> buildTargets;
|
||||
ProjectExplorer::RawProjectParts projectParts;
|
||||
std::unique_ptr<CMakeProjectNode> rootProjectNode;
|
||||
|
@@ -249,10 +249,10 @@ static std::vector<CMakeFileInfo> readCMakeFilesFile(const FilePath &cmakeFilesF
|
||||
for (const QJsonValue &v : inputs) {
|
||||
CMakeFileInfo info;
|
||||
const QJsonObject input = v.toObject();
|
||||
info.path = input.value("path").toString();
|
||||
info.path = FilePath::fromString(input.value("path").toString());
|
||||
|
||||
info.isCMake = input.value("isCMake").toBool();
|
||||
const QString filename = FilePath::fromString(info.path).fileName();
|
||||
const QString filename = info.path.fileName();
|
||||
info.isCMakeListsDotTxt = (filename.compare("CMakeLists.txt",
|
||||
HostOsInfo::fileNameCaseSensitivity())
|
||||
== 0);
|
||||
|
@@ -71,16 +71,6 @@ public:
|
||||
Utils::FilePath jsonFile(const QString &kind, const Utils::FilePath &replyDir) const;
|
||||
};
|
||||
|
||||
class CMakeFileInfo
|
||||
{
|
||||
public:
|
||||
QString path;
|
||||
bool isCMake = false;
|
||||
bool isCMakeListsDotTxt = false;
|
||||
bool isExternal = false;
|
||||
bool isGenerated = false;
|
||||
};
|
||||
|
||||
class Directory
|
||||
{
|
||||
public:
|
||||
@@ -243,7 +233,7 @@ class FileApiData
|
||||
public:
|
||||
FileApiDetails::ReplyFileContents replyFile;
|
||||
CMakeConfig cache;
|
||||
std::vector<FileApiDetails::CMakeFileInfo> cmakeFiles;
|
||||
std::vector<CMakeFileInfo> cmakeFiles;
|
||||
FileApiDetails::Configuration codemodel;
|
||||
std::vector<FileApiDetails::TargetDetails> targetDetails;
|
||||
};
|
||||
|
@@ -88,8 +88,12 @@ void FileApiReader::setParameters(const BuildDirParameters &p)
|
||||
void FileApiReader::resetData()
|
||||
{
|
||||
m_cmakeFiles.clear();
|
||||
if (!m_parameters.sourceDirectory.isEmpty())
|
||||
m_cmakeFiles.insert(m_parameters.sourceDirectory.pathAppended("CMakeLists.txt"));
|
||||
if (!m_parameters.sourceDirectory.isEmpty()) {
|
||||
CMakeFileInfo cmakeListsTxt;
|
||||
cmakeListsTxt.path = m_parameters.sourceDirectory.pathAppended("CMakeLists.txt");
|
||||
cmakeListsTxt.isCMakeListsDotTxt = true;
|
||||
m_cmakeFiles.insert(cmakeListsTxt);
|
||||
}
|
||||
|
||||
m_cache.clear();
|
||||
m_buildTargets.clear();
|
||||
@@ -124,8 +128,9 @@ void FileApiReader::parse(bool forceCMakeRun,
|
||||
const bool hasArguments = !args.isEmpty();
|
||||
const bool replyFileMissing = !replyFile.exists();
|
||||
const bool cmakeFilesChanged = m_parameters.cmakeTool() && m_parameters.cmakeTool()->isAutoRun()
|
||||
&& anyOf(m_cmakeFiles, [&replyFile](const FilePath &f) {
|
||||
return f.lastModified() > replyFile.lastModified();
|
||||
&& anyOf(m_cmakeFiles, [&replyFile](const CMakeFileInfo &info) {
|
||||
return !info.isGenerated
|
||||
&& info.path.lastModified() > replyFile.lastModified();
|
||||
});
|
||||
const bool queryFileChanged = anyOf(FileApiParser::cmakeQueryFilePaths(m_parameters.buildDirectory),
|
||||
[&replyFile](const FilePath &qf) {
|
||||
@@ -175,7 +180,10 @@ bool FileApiReader::isParsing() const
|
||||
|
||||
QSet<FilePath> FileApiReader::projectFilesToWatch() const
|
||||
{
|
||||
return m_cmakeFiles;
|
||||
return Utils::transform(
|
||||
Utils::filtered(m_cmakeFiles,
|
||||
[](const CMakeFileInfo &info) { return !info.isGenerated; }),
|
||||
[](const CMakeFileInfo &info) { return info.path;});
|
||||
}
|
||||
|
||||
QList<CMakeBuildTarget> FileApiReader::takeBuildTargets(QString &errorMessage){
|
||||
@@ -249,7 +257,7 @@ void FileApiReader::endState(const FilePath &replyFilePath)
|
||||
|
||||
const FilePath sourceDirectory = m_parameters.sourceDirectory;
|
||||
const FilePath buildDirectory = m_parameters.buildDirectory;
|
||||
const FilePath topCmakeFile = m_cmakeFiles.size() == 1 ? *m_cmakeFiles.begin() : FilePath{};
|
||||
const FilePath topCmakeFile = m_cmakeFiles.size() == 1 ? (*m_cmakeFiles.begin()).path : FilePath{};
|
||||
const QString cmakeBuildType = m_parameters.cmakeBuildType == "Build" ? "" : m_parameters.cmakeBuildType;
|
||||
|
||||
QTC_CHECK(!replyFilePath.needsDevice());
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "cmakebuildtarget.h"
|
||||
#include "cmakeprocess.h"
|
||||
#include "cmakeprojectnodes.h"
|
||||
#include "fileapidataextractor.h"
|
||||
|
||||
#include <projectexplorer/rawprojectpart.h>
|
||||
#include <projectexplorer/treescanner.h>
|
||||
@@ -100,7 +101,7 @@ private:
|
||||
|
||||
// cmake data:
|
||||
CMakeConfig m_cache;
|
||||
QSet<Utils::FilePath> m_cmakeFiles;
|
||||
QSet<CMakeFileInfo> m_cmakeFiles;
|
||||
QList<CMakeBuildTarget> m_buildTargets;
|
||||
ProjectExplorer::RawProjectParts m_projectParts;
|
||||
std::unique_ptr<CMakeProjectNode> m_rootProjectNode;
|
||||
|
@@ -440,8 +440,13 @@ Utils::FilePath CompilationDatabaseProject::rootPathFromSettings() const
|
||||
#ifdef WITH_TESTS
|
||||
return Utils::FilePath::fromString(projectDirectory().fileName());
|
||||
#else
|
||||
return Utils::FilePath::fromString(
|
||||
auto rootPath = Utils::FilePath::fromString(
|
||||
namedSettings(ProjectExplorer::Constants::PROJECT_ROOT_PATH_KEY).toString());
|
||||
|
||||
if (rootPath.isEmpty())
|
||||
rootPath = Utils::FilePath::fromString(projectDirectory().fileName());
|
||||
|
||||
return rootPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,7 @@ public:
|
||||
virtual QString currentFindString() const = 0;
|
||||
virtual QString completedFindString() const = 0;
|
||||
|
||||
virtual void highlightAll(const QString &txt, FindFlags findFlags);
|
||||
virtual void highlightAll(const QString &txt, FindFlags findFlags) {}
|
||||
virtual Result findIncremental(const QString &txt, FindFlags findFlags) = 0;
|
||||
virtual Result findStep(const QString &txt, FindFlags findFlags) = 0;
|
||||
virtual void replace(const QString &before, const QString &after,
|
||||
@@ -68,6 +68,4 @@ signals:
|
||||
void changed();
|
||||
};
|
||||
|
||||
inline void IFindSupport::highlightAll(const QString &, FindFlags) {}
|
||||
|
||||
} // namespace Core
|
||||
|
@@ -2816,7 +2816,7 @@ public:
|
||||
N2::test *getBar() const;
|
||||
void setBar(const custom<N2::test> &newBar);
|
||||
signals:
|
||||
void barChanged(N2::test*);
|
||||
void barChanged(N2::test *bar);
|
||||
private:
|
||||
Q_PROPERTY(N2::test *bar READ getBar NOTIFY barChanged)
|
||||
};
|
||||
@@ -3613,7 +3613,7 @@ void QuickfixTest::testInsertQtPropertyMembers_data()
|
||||
" }\n"
|
||||
"\n"
|
||||
"signals:\n"
|
||||
" void itChanged(int);\n"
|
||||
" void itChanged(int it);\n"
|
||||
"\n"
|
||||
"private:\n"
|
||||
" int m_it;\n"
|
||||
@@ -3646,7 +3646,7 @@ void QuickfixTest::testInsertQtPropertyMembers_data()
|
||||
" }\n"
|
||||
"\n"
|
||||
"signals:\n"
|
||||
" void itChanged(int);\n"
|
||||
" void itChanged(int it);\n"
|
||||
"\n"
|
||||
"private:\n"
|
||||
" int m_it;\n"
|
||||
@@ -3708,7 +3708,7 @@ void QuickfixTest::testInsertQtPropertyMembers_data()
|
||||
" emit itChanged(m_it);\n"
|
||||
" }\n"
|
||||
"signals:\n"
|
||||
" void itChanged(int);\n"
|
||||
" void itChanged(int it);\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"int XmarksTheSpot::getIt() const\n"
|
||||
|
@@ -4117,8 +4117,8 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
|
||||
|
||||
// signal declaration
|
||||
if (generateFlags & Flag::GenerateSignal) {
|
||||
const auto ¶mType = overview.prettyType(returnTypeHeader);
|
||||
const QString newValue = m_settings->signalWithNewValue ? paramType : QString();
|
||||
const auto ¶meter = overview.prettyType(returnTypeHeader, data.qPropertyName);
|
||||
const QString newValue = m_settings->signalWithNewValue ? parameter : QString();
|
||||
const QString declaration = QString("void %1(%2);\n").arg(data.signalName, newValue);
|
||||
addHeaderCode(InsertionPointLocator::Signals, declaration);
|
||||
}
|
||||
@@ -4140,8 +4140,9 @@ void GetterSetterRefactoringHelper::performGeneration(ExistingGetterSetterData d
|
||||
type = ref->elementType();
|
||||
type.setConst(false);
|
||||
|
||||
QString propertyDeclaration = QLatin1String("Q_PROPERTY(") + overview.prettyType(type)
|
||||
+ QLatin1Char(' ') + memberBaseName(data.memberVariableName);
|
||||
QString propertyDeclaration = QLatin1String("Q_PROPERTY(")
|
||||
+ overview.prettyType(type,
|
||||
memberBaseName(data.memberVariableName));
|
||||
bool needMember = false;
|
||||
if (data.getterName.isEmpty())
|
||||
needMember = true;
|
||||
|
@@ -158,26 +158,6 @@ QList<QMakeAssignment> MakeFileParse::parseAssignments(const QList<QMakeAssignme
|
||||
m_qmakeBuildConfig.explicitBuildAll = false;
|
||||
m_qmakeBuildConfig.explicitNoBuildAll = true;
|
||||
}
|
||||
} else if (value == QLatin1String("x86")) {
|
||||
if (qa.op == QLatin1String("+="))
|
||||
m_config.archConfig = QMakeStepConfig::X86;
|
||||
else
|
||||
m_config.archConfig = QMakeStepConfig::NoArch;
|
||||
} else if (value == QLatin1String("x86_64")) {
|
||||
if (qa.op == QLatin1String("+="))
|
||||
m_config.archConfig = QMakeStepConfig::X86_64;
|
||||
else
|
||||
m_config.archConfig = QMakeStepConfig::NoArch;
|
||||
} else if (value == QLatin1String("ppc")) {
|
||||
if (qa.op == QLatin1String("+="))
|
||||
m_config.archConfig = QMakeStepConfig::PowerPC;
|
||||
else
|
||||
m_config.archConfig = QMakeStepConfig::NoArch;
|
||||
} else if (value == QLatin1String("ppc64")) {
|
||||
if (qa.op == QLatin1String("+="))
|
||||
m_config.archConfig = QMakeStepConfig::PowerPC64;
|
||||
else
|
||||
m_config.archConfig = QMakeStepConfig::NoArch;
|
||||
} else if (value == QLatin1String("iphonesimulator")) {
|
||||
if (qa.op == QLatin1String("+="))
|
||||
m_config.osType = QMakeStepConfig::IphoneSimulator;
|
||||
@@ -376,7 +356,6 @@ void MakeFileParse::parseCommandLine(const QString &command, const QString &proj
|
||||
qCDebug(logging()) << " Explicit Release" << m_qmakeBuildConfig.explicitRelease;
|
||||
qCDebug(logging()) << " Explicit BuildAll" << m_qmakeBuildConfig.explicitBuildAll;
|
||||
qCDebug(logging()) << " Explicit NoBuildAll" << m_qmakeBuildConfig.explicitNoBuildAll;
|
||||
qCDebug(logging()) << " TargetArch" << m_config.archConfig;
|
||||
qCDebug(logging()) << " OsType" << m_config.osType;
|
||||
qCDebug(logging()) << " LinkQmlDebuggingQQ2"
|
||||
<< (m_config.linkQmlDebuggingQQ2 == TriState::Enabled);
|
||||
@@ -530,7 +509,6 @@ void QmakeProjectManagerPlugin::testMakefileParser()
|
||||
QCOMPARE(parser.effectiveBuildConfig({}), effectiveBuildConfig);
|
||||
|
||||
const QMakeStepConfig qmsc = parser.config();
|
||||
QCOMPARE(qmsc.archConfig, static_cast<QMakeStepConfig::TargetArchConfig>(archConfig));
|
||||
QCOMPARE(qmsc.osType, static_cast<QMakeStepConfig::OsType>(osType));
|
||||
QCOMPARE(qmsc.linkQmlDebuggingQQ2 == TriState::Enabled, linkQmlDebuggingQQ2);
|
||||
QCOMPARE(qmsc.useQtQuickCompiler == TriState::Enabled, useQtQuickCompiler);
|
||||
|
@@ -71,7 +71,6 @@ struct DirectoryData
|
||||
BaseQtVersion::QmakeBuildConfigs buildConfig;
|
||||
QString additionalArguments;
|
||||
QMakeStepConfig config;
|
||||
QMakeStepConfig::TargetArchConfig archConfig;
|
||||
QMakeStepConfig::OsType osType;
|
||||
};
|
||||
|
||||
@@ -154,10 +153,8 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
|
||||
qCDebug(logs) << " qt version:" << version->displayName() << " temporary:" << isTemporaryVersion;
|
||||
|
||||
data->archConfig = parse.config().archConfig;
|
||||
data->osType = parse.config().osType;
|
||||
|
||||
qCDebug(logs) << " archConfig:" << data->archConfig;
|
||||
qCDebug(logs) << " osType: " << data->osType;
|
||||
if (version->type() == QLatin1String(IOSQT)
|
||||
&& data->osType == QMakeStepConfig::NoOsType) {
|
||||
@@ -165,20 +162,6 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath,
|
||||
qCDebug(logs) << " IOS found without osType, adjusting osType" << data->osType;
|
||||
}
|
||||
|
||||
if (version->type() == QtSupport::Constants::DESKTOPQT) {
|
||||
const ProjectExplorer::Abis abis = version->qtAbis();
|
||||
if (!abis.isEmpty()) {
|
||||
ProjectExplorer::Abi abi = abis.first();
|
||||
if (abi.os() == ProjectExplorer::Abi::DarwinOS) {
|
||||
if (abi.wordWidth() == 64)
|
||||
data->archConfig = QMakeStepConfig::X86_64;
|
||||
else
|
||||
data->archConfig = QMakeStepConfig::X86;
|
||||
qCDebug(logs) << " OS X found without targetarch, adjusting archType" << data->archConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find qmake arguments and mkspec
|
||||
data->additionalArguments = parse.unparsedArguments();
|
||||
qCDebug(logs) << " Unparsed arguments:" << data->additionalArguments;
|
||||
@@ -210,27 +193,23 @@ bool QmakeProjectImporter::matchKit(void *directoryData, const Kit *k) const
|
||||
ToolChain *tc = ToolChainKitAspect::cxxToolChain(k);
|
||||
if (kitSpec.isEmpty() && kitVersion)
|
||||
kitSpec = kitVersion->mkspecFor(tc);
|
||||
QMakeStepConfig::TargetArchConfig kitTargetArch = QMakeStepConfig::NoArch;
|
||||
QMakeStepConfig::OsType kitOsType = QMakeStepConfig::NoOsType;
|
||||
if (tc) {
|
||||
kitTargetArch = QMakeStepConfig::targetArchFor(tc->targetAbi(), kitVersion);
|
||||
kitOsType = QMakeStepConfig::osTypeFor(tc->targetAbi(), kitVersion);
|
||||
}
|
||||
qCDebug(logs) << k->displayName()
|
||||
<< "version:" << (kitVersion == data->qtVersionData.qt)
|
||||
<< "spec:" << (kitSpec == data->parsedSpec)
|
||||
<< "targetarch:" << (kitTargetArch == data->archConfig)
|
||||
<< "ostype:" << (kitOsType == data->osType);
|
||||
return kitVersion == data->qtVersionData.qt
|
||||
&& kitSpec == data->parsedSpec
|
||||
&& kitTargetArch == data->archConfig
|
||||
&& kitOsType == data->osType;
|
||||
}
|
||||
|
||||
Kit *QmakeProjectImporter::createKit(void *directoryData) const
|
||||
{
|
||||
auto *data = static_cast<DirectoryData *>(directoryData);
|
||||
return createTemporaryKit(data->qtVersionData, data->parsedSpec, data->archConfig, data->osType);
|
||||
return createTemporaryKit(data->qtVersionData, data->parsedSpec, data->osType);
|
||||
}
|
||||
|
||||
const QList<BuildInfo> QmakeProjectImporter::buildInfoList(void *directoryData) const
|
||||
@@ -262,17 +241,14 @@ void QmakeProjectImporter::deleteDirectoryData(void *directoryData) const
|
||||
delete static_cast<DirectoryData *>(directoryData);
|
||||
}
|
||||
|
||||
static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, const QString &ms,
|
||||
const QMakeStepConfig::TargetArchConfig &archConfig)
|
||||
static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, const QString &ms)
|
||||
{
|
||||
const QString spec = ms.isEmpty() ? qtVersion->mkspec() : ms;
|
||||
|
||||
const QList<ToolChain *> toolchains = ToolChainManager::toolChains();
|
||||
const Abis qtAbis = qtVersion->qtAbis();
|
||||
const auto matcher = [&](const ToolChain *tc) {
|
||||
return qtAbis.contains(tc->targetAbi())
|
||||
&& tc->suggestedMkspecList().contains(spec)
|
||||
&& QMakeStepConfig::targetArchFor(tc->targetAbi(), qtVersion) == archConfig;
|
||||
return qtAbis.contains(tc->targetAbi()) && tc->suggestedMkspecList().contains(spec);
|
||||
};
|
||||
ToolChain * const cxxToolchain = findOrDefault(toolchains, [matcher](const ToolChain *tc) {
|
||||
return tc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID && matcher(tc);
|
||||
@@ -290,13 +266,11 @@ static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, co
|
||||
|
||||
Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersionData &data,
|
||||
const QString &parsedSpec,
|
||||
const QMakeStepConfig::TargetArchConfig &archConfig,
|
||||
const QMakeStepConfig::OsType &osType) const
|
||||
{
|
||||
Q_UNUSED(osType) // TODO use this to select the right toolchain?
|
||||
return QtProjectImporter::createTemporaryKit(data,
|
||||
[&data, parsedSpec, archConfig](Kit *k) -> void {
|
||||
for (ToolChain * const tc : preferredToolChains(data.qt, parsedSpec, archConfig))
|
||||
return QtProjectImporter::createTemporaryKit(data, [&data, parsedSpec](Kit *k) -> void {
|
||||
for (ToolChain *const tc : preferredToolChains(data.qt, parsedSpec))
|
||||
ToolChainKitAspect::setToolChain(k, tc);
|
||||
if (parsedSpec != data.qt->mkspec())
|
||||
QmakeKitAspect::setMkspec(k, parsedSpec, QmakeKitAspect::MkspecSource::Code);
|
||||
|
@@ -50,7 +50,6 @@ private:
|
||||
|
||||
ProjectExplorer::Kit *createTemporaryKit(const QtProjectImporter::QtVersionData &data,
|
||||
const QString &parsedSpec,
|
||||
const QmakeProjectManager::QMakeStepConfig::TargetArchConfig &archConfig,
|
||||
const QMakeStepConfig::OsType &osType) const;
|
||||
};
|
||||
|
||||
|
@@ -185,7 +185,6 @@ QMakeStepConfig QMakeStep::deducedArguments() const
|
||||
|
||||
BaseQtVersion *version = QtKitAspect::qtVersion(kit);
|
||||
|
||||
config.archConfig = QMakeStepConfig::targetArchFor(targetAbi, version);
|
||||
config.osType = QMakeStepConfig::osTypeFor(targetAbi, version);
|
||||
config.separateDebugInfo = qmakeBuildConfiguration()->separateDebugInfo();
|
||||
config.linkQmlDebuggingQQ2 = qmakeBuildConfiguration()->qmlDebugging();
|
||||
@@ -780,25 +779,9 @@ QMakeStepFactory::QMakeStepFactory()
|
||||
setFlags(BuildStepInfo::UniqueStep);
|
||||
}
|
||||
|
||||
QMakeStepConfig::TargetArchConfig QMakeStepConfig::targetArchFor(const Abi &targetAbi, const BaseQtVersion *version)
|
||||
QMakeStepConfig::TargetArchConfig QMakeStepConfig::targetArchFor(const Abi &, const BaseQtVersion *)
|
||||
{
|
||||
TargetArchConfig arch = NoArch;
|
||||
if (!version || version->type() != QtSupport::Constants::DESKTOPQT)
|
||||
return arch;
|
||||
if (targetAbi.os() == Abi::DarwinOS && targetAbi.binaryFormat() == Abi::MachOFormat) {
|
||||
if (targetAbi.architecture() == Abi::X86Architecture) {
|
||||
if (targetAbi.wordWidth() == 32)
|
||||
arch = X86;
|
||||
else if (targetAbi.wordWidth() == 64)
|
||||
arch = X86_64;
|
||||
} else if (targetAbi.architecture() == Abi::PowerPCArchitecture) {
|
||||
if (targetAbi.wordWidth() == 32)
|
||||
arch = PowerPC;
|
||||
else if (targetAbi.wordWidth() == 64)
|
||||
arch = PowerPC64;
|
||||
}
|
||||
}
|
||||
return arch;
|
||||
return NoArch;
|
||||
}
|
||||
|
||||
QMakeStepConfig::OsType QMakeStepConfig::osTypeFor(const Abi &targetAbi, const BaseQtVersion *version)
|
||||
|
@@ -66,15 +66,14 @@ public:
|
||||
class QMAKEPROJECTMANAGER_EXPORT QMakeStepConfig
|
||||
{
|
||||
public:
|
||||
enum TargetArchConfig {
|
||||
NoArch, X86, X86_64, PowerPC, PowerPC64
|
||||
};
|
||||
// TODO remove, does nothing
|
||||
enum TargetArchConfig { NoArch, X86, X86_64, PowerPC, PowerPC64 };
|
||||
|
||||
enum OsType {
|
||||
NoOsType, IphoneSimulator, IphoneOS
|
||||
};
|
||||
enum OsType { NoOsType, IphoneSimulator, IphoneOS };
|
||||
|
||||
static TargetArchConfig targetArchFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version);
|
||||
// TODO remove, does nothing
|
||||
static TargetArchConfig targetArchFor(const ProjectExplorer::Abi &targetAbi,
|
||||
const QtSupport::BaseQtVersion *version);
|
||||
static OsType osTypeFor(const ProjectExplorer::Abi &targetAbi, const QtSupport::BaseQtVersion *version);
|
||||
|
||||
QStringList toArguments() const;
|
||||
@@ -82,6 +81,7 @@ public:
|
||||
// Actual data
|
||||
QString sysRoot;
|
||||
QString targetTriple;
|
||||
// TODO remove, does nothing
|
||||
TargetArchConfig archConfig = NoArch;
|
||||
OsType osType = NoOsType;
|
||||
Utils::TriState separateDebugInfo;
|
||||
|
@@ -35,6 +35,7 @@
|
||||
|
||||
#include "nodemetainfo.h"
|
||||
#include "qmlitemnode.h"
|
||||
#include "bindingproperty.h"
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <abstractaction.h>
|
||||
#include <designeractionmanager.h>
|
||||
@@ -162,13 +163,16 @@ void ColorTool::itemsAboutToRemoved(const QList<FormEditorItem*> &removedItemLis
|
||||
|
||||
void ColorTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
||||
{
|
||||
if (m_colorDialog.data()
|
||||
&& m_oldColor.isValid())
|
||||
if (m_colorDialog.data() && m_oldColor.isValid())
|
||||
m_formEditorItem->qmlItemNode().setVariantProperty("color", m_oldColor);
|
||||
|
||||
if (!itemList.isEmpty()
|
||||
&& itemList.constFirst()->qmlItemNode().modelNode().metaInfo().hasProperty("color")) {
|
||||
m_formEditorItem = itemList.constFirst();
|
||||
|
||||
if (m_formEditorItem->qmlItemNode().hasBindingProperty("color"))
|
||||
m_oldExpression = m_formEditorItem->qmlItemNode().modelNode().bindingProperty("color").expression();
|
||||
else
|
||||
m_oldColor = m_formEditorItem->qmlItemNode().modelValue("color").value<QColor>();
|
||||
|
||||
if (m_colorDialog.isNull()) {
|
||||
@@ -217,27 +221,31 @@ QString ColorTool::name() const
|
||||
|
||||
void ColorTool::colorDialogAccepted()
|
||||
{
|
||||
m_oldExpression.clear();
|
||||
view()->changeToSelectionTool();
|
||||
}
|
||||
|
||||
void ColorTool::colorDialogRejected()
|
||||
{
|
||||
if (m_formEditorItem) {
|
||||
if (!m_oldExpression.isEmpty())
|
||||
m_formEditorItem->qmlItemNode().setBindingProperty("color", m_oldExpression);
|
||||
else {
|
||||
if (m_oldColor.isValid())
|
||||
m_formEditorItem->qmlItemNode().setVariantProperty("color", m_oldColor);
|
||||
else
|
||||
m_formEditorItem->qmlItemNode().removeProperty("color");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_oldExpression.clear();
|
||||
view()->changeToSelectionTool();
|
||||
}
|
||||
|
||||
void ColorTool::currentColorChanged(const QColor &color)
|
||||
{
|
||||
if (m_formEditorItem) {
|
||||
if (m_formEditorItem)
|
||||
m_formEditorItem->qmlItemNode().setVariantProperty("color", color);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -84,6 +84,7 @@ private:
|
||||
QPointer<QColorDialog> m_colorDialog;
|
||||
FormEditorItem *m_formEditorItem = nullptr;
|
||||
QColor m_oldColor;
|
||||
QString m_oldExpression;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -161,6 +161,8 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
{
|
||||
m_compressionTimer.setInterval(200);
|
||||
m_compressionTimer.setSingleShot(true);
|
||||
m_assetCompressionTimer.setInterval(200);
|
||||
m_assetCompressionTimer.setSingleShot(true);
|
||||
ItemLibraryModel::registerQmlTypes();
|
||||
|
||||
setWindowTitle(tr("Library", "Title of library view"));
|
||||
@@ -234,17 +236,7 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
// reconstruct the model to update the icons
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, [this](const QString & changedDirPath) {
|
||||
Q_UNUSED(changedDirPath)
|
||||
// TODO: find a clever way to only refresh the changed directory part of the model
|
||||
|
||||
m_assetsModel->refresh();
|
||||
if (!QApplication::activeModalWidget()) {
|
||||
// reload assets qml so that an overridden file's image shows the new image
|
||||
QTimer::singleShot(100, this, [this] {
|
||||
const QString assetsQmlPath = qmlSourcesPath() + "/Assets.qml";
|
||||
m_assetsWidget->engine()->clearComponentCache();
|
||||
m_assetsWidget->setSource(QUrl::fromLocalFile(assetsQmlPath));
|
||||
});
|
||||
}
|
||||
m_assetCompressionTimer.start();
|
||||
});
|
||||
|
||||
m_stackedWidget = new QStackedWidget(this);
|
||||
@@ -270,6 +262,26 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
connect(m_qmlSourceUpdateShortcut, &QShortcut::activated, this, &ItemLibraryWidget::reloadQmlSource);
|
||||
|
||||
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
|
||||
connect(&m_assetCompressionTimer, &QTimer::timeout, this, [this]() {
|
||||
// TODO: find a clever way to only refresh the changed directory part of the model
|
||||
|
||||
// Don't bother with asset updates after model has detached, project is probably closing
|
||||
if (!m_model.isNull()) {
|
||||
if (QApplication::activeModalWidget()) {
|
||||
// Retry later, as updating file system watchers can crash when there is an active
|
||||
// modal widget
|
||||
m_assetCompressionTimer.start();
|
||||
} else {
|
||||
m_assetsModel->refresh();
|
||||
// reload assets qml so that an overridden file's image shows the new image
|
||||
QTimer::singleShot(100, this, [this] {
|
||||
const QString assetsQmlPath = qmlSourcesPath() + "/Assets.qml";
|
||||
m_assetsWidget->engine()->clearComponentCache();
|
||||
m_assetsWidget->setSource(QUrl::fromLocalFile(assetsQmlPath));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
m_itemViewQuickWidget->engine()->addImageProvider("itemlibrary_preview",
|
||||
new ItemLibraryIconImageProvider{m_imageCache});
|
||||
|
@@ -119,6 +119,7 @@ private:
|
||||
void handlePriorityImportsChanged();
|
||||
|
||||
QTimer m_compressionTimer;
|
||||
QTimer m_assetCompressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
|
@@ -155,15 +155,17 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
|
||||
|
||||
void PropertyEditorValue::setValue(const QVariant &value)
|
||||
{
|
||||
const bool colorsEqual = cleverColorCompare(value, m_value);
|
||||
|
||||
if (!compareVariants(m_value, value) &&
|
||||
!cleverDoubleCompare(value, m_value) &&
|
||||
!cleverColorCompare(value, m_value))
|
||||
!colorsEqual)
|
||||
m_value = value;
|
||||
|
||||
fixAmbigousColorNames(modelNode(), name(), &m_value);
|
||||
fixUrl(modelNode(), name(), &m_value);
|
||||
|
||||
if (m_value.isValid())
|
||||
if (m_value.isValid() && !colorsEqual)
|
||||
emit valueChangedQml();
|
||||
|
||||
emit isExplicitChanged();
|
||||
|
@@ -45,6 +45,8 @@
|
||||
#include <qmldesignerplugin.h>
|
||||
#endif
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -356,6 +358,16 @@ static void removeAliasExports(const QmlObjectNode &node)
|
||||
|
||||
}
|
||||
|
||||
static void removeLayerEnabled(const ModelNode &node)
|
||||
{
|
||||
QTC_ASSERT(node.isValid(), return );
|
||||
if (node.parentProperty().isValid() && node.parentProperty().name() == "layer.effect") {
|
||||
ModelNode parent = node.parentProperty().parentModelNode();
|
||||
if (parent.isValid() && parent.hasProperty("layer.enabled"))
|
||||
parent.removeProperty("layer.enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Deletes this object's node and its dependencies from the model.
|
||||
Everything that belongs to this Object, the ModelNode, and ChangeOperations
|
||||
@@ -366,6 +378,7 @@ void QmlObjectNode::destroy()
|
||||
if (!isValid())
|
||||
throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
removeLayerEnabled(modelNode());
|
||||
removeAliasExports(modelNode());
|
||||
|
||||
for (QmlModelStateOperation stateOperation : allAffectingStatesOperations()) {
|
||||
|
@@ -1099,7 +1099,6 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
|
||||
m_rewriterView->setWarnings(warnings);
|
||||
qCInfo(rewriterBenchmark) << "checked semantic errors:" << time.elapsed();
|
||||
}
|
||||
setupUsedImports();
|
||||
|
||||
AST::UiObjectMember *astRootNode = nullptr;
|
||||
if (AST::UiProgram *program = m_document->qmlProgram())
|
||||
@@ -1111,6 +1110,8 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
|
||||
|
||||
qCInfo(rewriterBenchmark) << "synced nodes:" << time.elapsed();
|
||||
|
||||
setupUsedImports();
|
||||
|
||||
setActive(false);
|
||||
|
||||
return true;
|
||||
|
@@ -154,7 +154,7 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex
|
||||
m_deleteAction.setIcon(QIcon::fromTheme(QLatin1String("edit-cut"), Utils::Icons::EDIT_CLEAR_TOOLBAR.icon()));
|
||||
|
||||
command = Core::ActionManager::registerAction(&m_deleteAction, QmlDesigner::Constants::C_DELETE, qmlDesignerMainContext);
|
||||
command->setDefaultKeySequences({QKeySequence::Delete, QKeySequence::Backspace});
|
||||
command->setDefaultKeySequences({Qt::Key_Backspace, Qt::Key_Delete});
|
||||
|
||||
command->setAttribute(Core::Command::CA_Hide); // don't show delete in other modes
|
||||
if (!Utils::HostOsInfo::isMacHost())
|
||||
|
@@ -73,6 +73,7 @@ public:
|
||||
if (!m_idName.isEmpty()) {
|
||||
m_componentName = m_idName;
|
||||
m_componentName[0] = m_componentName.at(0).toUpper();
|
||||
m_componentName.prepend("My");
|
||||
}
|
||||
|
||||
setDescription(QCoreApplication::translate("QmlJSEditor::ComponentFromObjectDef",
|
||||
|
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/documentmodel.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -144,6 +145,18 @@ QmlProject::QmlProject(const Utils::FilePath &fileName)
|
||||
|
||||
QTimer::singleShot(0, this, lambda);
|
||||
}
|
||||
} else {
|
||||
connect(this, &QmlProject::anyParsingFinished, this, [this](Target *target, bool success) {
|
||||
if (target && success) {
|
||||
const Utils::FilePath &folder = projectDirectory();
|
||||
const Utils::FilePaths &uiFiles = files([&](const ProjectExplorer::Node *node) {
|
||||
return node->filePath().completeSuffix() == "ui.qml"
|
||||
&& node->filePath().parentDir() == folder;
|
||||
});
|
||||
if (!uiFiles.isEmpty())
|
||||
Core::EditorManager::openEditor(uiFiles.first(), Utils::Id());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|