Merge remote-tracking branch 'origin/6.0'
Change-Id: I405e3f95b0cdcd7b2686f31baae16c03c787f007
@@ -7,26 +7,26 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Qt6 6.2 COMPONENTS Quick Sensors Svg Xml REQUIRED)
|
||||
|
||||
qt_add_executable(accelbubbleexample
|
||||
qt_add_executable(appaccelbubble
|
||||
main.cpp
|
||||
MANUAL_FINALIZATION
|
||||
)
|
||||
set_target_properties(accelbubbleexample PROPERTIES
|
||||
set_target_properties(appaccelbubble PROPERTIES
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist"
|
||||
)
|
||||
set_property(TARGET accelbubbleexample APPEND PROPERTY
|
||||
set_property(TARGET appaccelbubble APPEND PROPERTY
|
||||
QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android
|
||||
)
|
||||
qt_add_qml_module(accelbubbleexample
|
||||
qt_add_qml_module(appaccelbubble
|
||||
URI accelbubble
|
||||
VERSION 1.0
|
||||
QML_FILES main.qml
|
||||
RESOURCES Bluebubble.svg
|
||||
)
|
||||
|
||||
target_compile_definitions(accelbubbleexample
|
||||
target_compile_definitions(appaccelbubble
|
||||
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
|
||||
target_link_libraries(accelbubbleexample
|
||||
target_link_libraries(appaccelbubble
|
||||
PRIVATE Qt6::Quick Qt6::Sensors Qt6::Svg Qt6::Xml)
|
||||
|
||||
qt_finalize_executable(accelbubbleexample)
|
||||
qt_finalize_executable(appaccelbubble)
|
||||
|
||||
@@ -7,18 +7,18 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Qt6 6.2 COMPONENTS Quick REQUIRED)
|
||||
|
||||
qt_add_executable(transitionsexample
|
||||
qt_add_executable(apptransitions
|
||||
main.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(transitionsexample
|
||||
qt_add_qml_module(apptransitions
|
||||
URI transitions
|
||||
VERSION 1.0
|
||||
QML_FILES main.qml Page.qml
|
||||
RESOURCES qt-logo.png
|
||||
)
|
||||
|
||||
target_compile_definitions(transitionsexample
|
||||
target_compile_definitions(apptransitions
|
||||
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
|
||||
target_link_libraries(transitionsexample
|
||||
target_link_libraries(apptransitions
|
||||
PRIVATE Qt6::Quick)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -200,7 +200,7 @@
|
||||
arguments to the linker and makes sure that the appropriate include
|
||||
directories and compiler definitions are passed to the C++ compiler.
|
||||
|
||||
\skipto target_link_libraries(accelbubble
|
||||
\skipto target_link_libraries(appaccelbubble
|
||||
\printuntil Qt6
|
||||
|
||||
After adding the dependencies, select \uicontrol Build >
|
||||
|
||||
@@ -24,11 +24,7 @@ imagedirs = ../images \
|
||||
../../../src/libs/qmleditorwidgets/images \
|
||||
../../../src/plugins/qmldesigner/components/componentcore/images \
|
||||
../../../src/plugins/qmldesigner/components/edit3d/images \
|
||||
../../../src/plugins/qmldesigner/components/formeditor \
|
||||
../../../src/plugins/qmldesigner/components/navigator \
|
||||
../../../src/plugins/qmldesigner/components/timelineeditor/images \
|
||||
../../../src/plugins/qmldesigner/componentsplugin/images \
|
||||
../../../src/plugins/qmldesigner/qmlpreviewplugin/images \
|
||||
../../../src/plugins/qmldesigner/qtquickplugin/images \
|
||||
|
||||
include(../../qtcreator/images/extraimages/qtdesignstudio-extraimages.qdocconf)
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
\c {"settings"} and \c {"selection"} states.
|
||||
|
||||
We then return to the \uicontrol Timeline view and select
|
||||
\inlineimage animation.png "Timeline Settings button"
|
||||
\inlineimage icons/animation.png "Timeline Settings button"
|
||||
to open the \uicontrol {Timeline Settings} dialog. We select
|
||||
the \uicontrol Add button to create animations for each part
|
||||
of the timeline. Therefore, the start and end frame of each
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
ToBig, and FromBig.
|
||||
|
||||
We then return to the \uicontrol Timeline view and select
|
||||
\inlineimage animation.png "Timeline Settings button"
|
||||
\inlineimage icons/animation.png "Timeline Settings button"
|
||||
to open the \uicontrol {Timeline Settings} dialog. We select
|
||||
the \uicontrol Add button to create animations for each part
|
||||
of the timeline. Therefore, the start and end frame of each
|
||||
|
||||
@@ -169,7 +169,7 @@
|
||||
\endlist
|
||||
|
||||
To preview the changes that you make to the UI while you make
|
||||
them, select the \inlineimage live_preview.png
|
||||
them, select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the \uicontrol {Form Editor}
|
||||
view toolbar or press \key {Alt+P}.
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
adjust the margins to align it with \e qt_logo_green_128x128px on the page.
|
||||
|
||||
To preview the changes that you make to the UI while you make
|
||||
them, select the \inlineimage live_preview.png
|
||||
them, select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the \l {Form Editor}
|
||||
toolbar or press \key {Alt+P}.
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
this section from previous parts of the tutorial.
|
||||
|
||||
To preview the changes that you make to the UI while you make
|
||||
them, select the \inlineimage live_preview.png
|
||||
them, select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the \l {Form Editor}
|
||||
toolbar or press \key {Alt+P}.
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
column component and anchor them to the rectangle and to each other instead.
|
||||
|
||||
To preview the changes that you make to the UI while you make
|
||||
them, select the \inlineimage live_preview.png
|
||||
them, select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the \uicontrol Design
|
||||
mode \l {Summary of Main Toolbar Actions}{toolbar} or press \key {Alt+P}.
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
\inlineimage icons/close.png
|
||||
to remove the state. Repeat for the \e createAccount state.
|
||||
\li Select \e username in \l Navigator, and then select
|
||||
\inlineimage arrowleft.png
|
||||
\inlineimage icons/arrowleft.png
|
||||
to move it into the parent rectangle to prepare for
|
||||
deleting the \e fields column component instance.
|
||||
\li Select \inlineimage icons/navigator-arrowup.png
|
||||
@@ -275,7 +275,7 @@
|
||||
for \e login to open the \uicontrol Actions menu, and then
|
||||
select \uicontrol {Set as Default} to determine that the \e login
|
||||
state is applied when the application starts.
|
||||
\li In \uicontrol Timeline, select the \inlineimage animation.png
|
||||
\li In \uicontrol Timeline, select the \inlineimage icons/animation.png
|
||||
(\uicontrol {Timeline Settings (S)}) button on the toolbar (or press
|
||||
\key S) to open the \uicontrol {Timeline Settings} dialog.
|
||||
\image loginui4-timeline-settings-states.png
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
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"
|
||||
We select \inlineimage icons/animation.png "Timeline Settings button"
|
||||
to open the \uicontrol {Timeline Settings} dialog. In the
|
||||
\uicontrol {Transitions to states} field, we select the state to
|
||||
apply when the animation finishes. In the lower part of the
|
||||
|
||||
|
After Width: | Height: | Size: 200 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 149 B |
|
After Width: | Height: | Size: 153 B |
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
|
After Width: | Height: | Size: 190 B |
|
After Width: | Height: | Size: 354 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 162 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 186 B |
|
After Width: | Height: | Size: 133 B |
|
After Width: | Height: | Size: 192 B |
|
After Width: | Height: | Size: 132 B |
|
After Width: | Height: | Size: 168 B |
|
After Width: | Height: | Size: 220 B |
|
After Width: | Height: | Size: 126 B |
|
After Width: | Height: | Size: 148 B |
|
After Width: | Height: | Size: 175 B |
|
After Width: | Height: | Size: 143 B |
|
After Width: | Height: | Size: 135 B |
|
After Width: | Height: | Size: 132 B |
|
After Width: | Height: | Size: 202 B |
|
After Width: | Height: | Size: 191 B |
|
Before Width: | Height: | Size: 521 B |
|
Before Width: | Height: | Size: 472 B |
|
Before Width: | Height: | Size: 379 B |
@@ -151,7 +151,7 @@
|
||||
(\uicontrol Paused) check box.
|
||||
|
||||
To attach an \l{Editing Easing Curves}{easing curve} to
|
||||
the animation, select the \inlineimage curve_editor.png
|
||||
the animation, select the \inlineimage icons/curve_editor.png
|
||||
(\uicontrol {Easing Curve Editor}) button in the
|
||||
\uicontrol {Easing Curve} field.
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
pressed down.
|
||||
\image qmldesigner-borderimage-bindings1.png "Inactive state when condition"
|
||||
\li Press \key {Ctrl+S} to save the button.
|
||||
\li Select the \inlineimage live_preview.png
|
||||
\li Select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button to check how the
|
||||
button behaves when you click it. You can drag the preview
|
||||
window borders to see what happens when you resize the
|
||||
|
||||
@@ -729,12 +729,12 @@
|
||||
\row
|
||||
\li \inlineimage icons/button-icon16.png
|
||||
\li \l [QtQuickControls]{Button}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li A push button that you can associate with an action.
|
||||
\row
|
||||
\li \inlineimage icons/checkbox-icon16.png
|
||||
\li \l [QtQuickControls]{CheckBox}{Check Box}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li An option button that can be toggled on (checked) or off
|
||||
(unchecked).
|
||||
\row
|
||||
@@ -757,7 +757,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/dial-icon16.png
|
||||
\li \l [QtQuickControls]{Dial}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li A circular dial that is rotated to set a value.
|
||||
\row
|
||||
\li \inlineimage icons/pageindicator-icon16.png
|
||||
@@ -768,12 +768,12 @@
|
||||
\row
|
||||
\li \inlineimage icons/progressbar-icon16.png
|
||||
\li \l [QtQuickControls]{ProgressBar}{Progress Bar}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li Indicates the progress of an operation.
|
||||
\row
|
||||
\li \inlineimage icons/radiobutton-icon16.png
|
||||
\li \l [QtQuickControls]{RadioButton}{Radio Button}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li An option button that can be switched on (checked) or off
|
||||
(unchecked).
|
||||
\row
|
||||
@@ -797,7 +797,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/slider-icon16.png
|
||||
\li \l [QtQuickControls]{Slider}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li Enables users to select a value by sliding a handle along a track.
|
||||
\row
|
||||
\li \inlineimage icons/spinbox-icon16.png
|
||||
@@ -809,7 +809,7 @@
|
||||
\row
|
||||
\li \inlineimage icons/switch-icon16.png
|
||||
\li \l [QtQuickControls]{Switch}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li An option button that can be toggled on or off.
|
||||
\row
|
||||
\li \inlineimage icons/switch-icon16.png
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
\li \inlineimage listview-icon16.png
|
||||
\li \l{ListView}{List View}
|
||||
\li Default Components - Views
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li A list vizualization of a model.
|
||||
\row
|
||||
\li \inlineimage pathview-icon16.png
|
||||
@@ -265,7 +265,7 @@
|
||||
\li \inlineimage icons/swipeview-icon16.png
|
||||
\li \l[QtQuickControls] {SwipeView}{Swipe View}
|
||||
\li Qt Quick Controls
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li Enables users to navigate pages by swiping sideways.
|
||||
\endtable
|
||||
*/
|
||||
|
||||
@@ -256,13 +256,13 @@
|
||||
\li \inlineimage border-image-icon16.png
|
||||
\li \l [QtQuick]{BorderImage}{Border Image}
|
||||
\li Default Components - Basic
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li An image that is used as a border or background.
|
||||
\row
|
||||
\li \inlineimage image-icon16.png
|
||||
\li \l [QtQuick]{Image}
|
||||
\li Default Components - Basic
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li An image in one of the supported formats, including bitmap formats
|
||||
such as PNG and JPEG and vector graphics formats such as SVG.
|
||||
\if defined(qtdesignstudio)
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
\l{Completing Code}.
|
||||
|
||||
When a binding is set, the \uicontrol Actions menu icon changes to
|
||||
\inlineimage icons/action-icon-binding
|
||||
\inlineimage icons/action-icon-binding.png
|
||||
. To remove bindings, select \uicontrol Actions > \uicontrol Reset.
|
||||
|
||||
You can set bindings also in \l {Connection View} > \uicontrol Bindings.
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
\li \inlineimage rect-icon16.png
|
||||
\li \l Rectangle
|
||||
\li Default Components - Basic
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li A rectangle that is painted with a solid fill color or linear
|
||||
gradient and an optional border. You can use the radius property
|
||||
to draw circles.
|
||||
|
||||
@@ -442,7 +442,7 @@
|
||||
\li \inlineimage text-icon16.png
|
||||
\li \l [QtQuick]{Text}
|
||||
\li Default Components - Basic
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li Formatted read-only text.
|
||||
\row
|
||||
\li \inlineimage icons/textarea-icon16.png
|
||||
|
||||
@@ -331,7 +331,7 @@
|
||||
\row
|
||||
\li \inlineimage flickable-icon16.png
|
||||
\li \l [QML]{Flickable}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li Enables flicking components horizontally or vertically.
|
||||
\row
|
||||
\li \inlineimage focusscope-icon16.png
|
||||
@@ -342,7 +342,7 @@
|
||||
\row
|
||||
\li \inlineimage mouse-area-icon16.png
|
||||
\li \l [QtQuick]{MouseArea}{Mouse Area}
|
||||
\li \inlineimage ok
|
||||
\li \inlineimage ok.png
|
||||
\li Enables simple mouse handling.
|
||||
\endtable
|
||||
*/
|
||||
|
||||
@@ -304,7 +304,7 @@
|
||||
and transition line.
|
||||
\endlist
|
||||
|
||||
To preview the flow, select the \inlineimage live_preview.png
|
||||
To preview the flow, select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the Design mode
|
||||
\l{Summary of Main Toolbar Actions}{toolbar} or press \key {Alt+P}.
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
\list
|
||||
\li In the \uicontrol Duration field, specify the duration of the
|
||||
effect.
|
||||
\li Select the \inlineimage curve_editor.png
|
||||
\li Select the \inlineimage icons/curve_editor.png
|
||||
button to open \uicontrol {Easing Curve Editor} for attaching an
|
||||
\l{Editing Easing Curves}{easing curve} to the effect.
|
||||
\endlist
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
To run an example project:
|
||||
\list 1
|
||||
\li Select the example.
|
||||
\li Select the \inlineimage live_preview.png
|
||||
\li Select the \inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button to preview the example.
|
||||
\endlist
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
We can now start playing with the particle system component properties to
|
||||
achieve the artistic effect that we want. To see how the changes in property
|
||||
values affect the simulation, we will open the live preview by selecting
|
||||
\inlineimage live_preview.png
|
||||
\inlineimage icons/live_preview.png
|
||||
on the main toolbar (or by pressing \key {Alt+P}).
|
||||
|
||||
First, we will specify property values for the \uicontrol {Particle System}
|
||||
|
||||
@@ -183,7 +183,7 @@
|
||||
\li \key Ctrl+W (\key Cmd+W on \macos)
|
||||
\li
|
||||
\row
|
||||
\li \inlineimage live_preview.png
|
||||
\li \inlineimage icons/live_preview.png
|
||||
\li \uicontrol {Show Live Preview} shows a preview of the current file
|
||||
or the entire UI. The changes you make to the UI are instantly
|
||||
visible to you in the preview.
|
||||
@@ -210,13 +210,13 @@
|
||||
\li
|
||||
\li
|
||||
\row
|
||||
\li \inlineimage qtcreator-reset-position-icon.png
|
||||
\li \inlineimage icons/qtcreator-reset-position-icon.png
|
||||
\li Returns a component to its \e {implicit position} after
|
||||
being moved.
|
||||
\li \key Ctrl+D (\key Cmd+D on \macos)
|
||||
\li \l{Resetting Component Position and Size}
|
||||
\row
|
||||
\li \inlineimage qtcreator-reset-size-icon.png
|
||||
\li \inlineimage icons/qtcreator-reset-size-icon.png
|
||||
\li Returns a component to its implicit size after it was scaled.
|
||||
\li \key Shift+S
|
||||
\li \l{Resetting Component Position and Size}
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
To attach easing curves to transitions:
|
||||
|
||||
\list 1
|
||||
\li In \l{Transition Editor}, select the \inlineimage curve_editor.png
|
||||
\li In \l{Transition Editor}, select the \inlineimage icons/curve_editor.png
|
||||
(\uicontrol {Easing Curve Editor}) button.
|
||||
\li Select an easing curve, as described in \l{Selecting Easing Curves}.
|
||||
\endlist
|
||||
@@ -122,7 +122,7 @@
|
||||
\list 1
|
||||
\li In \l Navigator, select an \l{Animations}{Animation} component
|
||||
instance.
|
||||
\li In \l Properties, select the \inlineimage curve_editor.png
|
||||
\li In \l Properties, select the \inlineimage icons/curve_editor.png
|
||||
(\uicontrol {Easing Curve Editor}) button.
|
||||
\li Select an easing curve, as described in \l{Selecting Easing Curves}.
|
||||
\endlist
|
||||
|
||||
@@ -58,16 +58,16 @@
|
||||
\li Tooltip
|
||||
\li Read More
|
||||
\row
|
||||
\li \inlineimage no_snapping.png
|
||||
\li \inlineimage icons/no_snapping.png
|
||||
\li Disables snapping.
|
||||
\li \l{Snapping to Parent and Sibling Components}
|
||||
\row
|
||||
\li \inlineimage snapping_and_anchoring.png
|
||||
\li \inlineimage icons/snapping_and_anchoring.png
|
||||
\li Anchors the component instance to the component instances that it
|
||||
is snapped to.
|
||||
\li \l{Snapping to Parent and Sibling Components}
|
||||
\row
|
||||
\li \inlineimage snapping.png
|
||||
\li \inlineimage icons/snapping.png
|
||||
\li Snaps component instances to their parent or siblings when you
|
||||
align them.
|
||||
\li \l{Snapping to Parent and Sibling Components}
|
||||
@@ -171,10 +171,10 @@
|
||||
\section1 Snapping to Parent and Sibling Components
|
||||
|
||||
You can use snapping to align component instances in
|
||||
\uicontrol {Form Editor}. Select the \inlineimage snapping.png
|
||||
\uicontrol {Form Editor}. Select the \inlineimage icons/snapping.png
|
||||
button to have the component instances snap to their parent or siblings.
|
||||
Snapping lines automatically appear to help you position the component
|
||||
instances. Click the \inlineimage snapping_and_anchoring.png
|
||||
instances. Click the \inlineimage icons/snapping_and_anchoring.png
|
||||
button to anchor the selected component instance to those that you snap to.
|
||||
Only one snapping button can be selected at the time. Selecting
|
||||
one snapping button automatically deselects the others.
|
||||
|
||||
@@ -68,12 +68,12 @@
|
||||
\li Tooltip
|
||||
\li Read More
|
||||
\row
|
||||
\li \inlineimage arrowleft.png
|
||||
\li \inlineimage icons/arrowleft.png
|
||||
\li Moves the component one level up in the component tree, so that
|
||||
it becomes the last sibling of its current parent.
|
||||
\li \l{Arranging Components}
|
||||
\row
|
||||
\li \inlineimage arrowright.png
|
||||
\li \inlineimage icons/arrowright.png
|
||||
\li Moves the component one level down in the component tree, so that it
|
||||
becomes the child of its last sibling.
|
||||
\li \l{Arranging Components}
|
||||
|
||||
@@ -112,10 +112,10 @@
|
||||
\section2 Resetting Component Position and Size
|
||||
|
||||
To return a component to its default position after moving it,
|
||||
select the \inlineimage qtcreator-reset-position-icon.png
|
||||
select the \inlineimage icons/qtcreator-reset-position-icon.png
|
||||
(\uicontrol {Reset Position}) button on the \l{Design Views}
|
||||
{Design mode toolbar}. To return it to its default size, select
|
||||
\inlineimage qtcreator-reset-size-icon.png
|
||||
\inlineimage icons/qtcreator-reset-size-icon.png
|
||||
(\uicontrol {Reset Size}) button.
|
||||
|
||||
\section2 Managing 2D Transformations
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
\image studio-timeline-with-empty-tracks.png "Timeline view with a property"
|
||||
|
||||
You can now select \inlineimage local_record_keyframes.png
|
||||
You can now select \inlineimage icons/local_record_keyframes.png
|
||||
to \l{Setting Keyframe Values}{record changes} in component properties
|
||||
while you \l{Navigating in Timeline}{navigate the timeline}.
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
\section1 Zooming in Timeline
|
||||
|
||||
Use the slider on the toolbar to set the zooming level in the
|
||||
\uicontrol Timeline view. Select the \inlineimage zoom_small.png
|
||||
and \inlineimage zoom_big.png
|
||||
\uicontrol Timeline view. Select the \inlineimage icons/zoom_small.png
|
||||
and \inlineimage icons/zoom_big.png
|
||||
buttons to zoom out of or into the view.
|
||||
|
||||
\section1 Setting Keyframe Track Color
|
||||
@@ -121,7 +121,7 @@
|
||||
\li Action
|
||||
\li Read More
|
||||
\row
|
||||
\li \inlineimage animation.png
|
||||
\li \inlineimage icons/animation.png
|
||||
\li Opens the \uicontrol {Timeline Settings} dialog for editing
|
||||
timeline settings.
|
||||
\li \l{Creating Timelines}
|
||||
@@ -130,25 +130,25 @@
|
||||
\li Displays the ID of the current timeline.
|
||||
\li \l{Creating Timelines}
|
||||
\row
|
||||
\li \inlineimage to_first_frame.png
|
||||
\li \inlineimage icons/to_first_frame.png
|
||||
\li \uicontrol {To Start (Home)} moves to the first frame on the
|
||||
timeline.
|
||||
\li \l{Navigating in Timeline}
|
||||
\row
|
||||
\li \inlineimage back_one_frame.png
|
||||
\li \inlineimage icons/back_one_frame.png
|
||||
\li \uicontrol {Previous (,)} moves to the previous frame on the
|
||||
timeline.
|
||||
\li \l{Navigating in Timeline}
|
||||
\row
|
||||
\li \inlineimage start_playback.png
|
||||
\li \inlineimage icons/start_playback.png
|
||||
\li \uicontrol {Play (Space)} previews the animation.
|
||||
\li \l{Viewing the Animation}
|
||||
\row
|
||||
\li \inlineimage forward_one_frame.png
|
||||
\li \inlineimage icons/forward_one_frame.png
|
||||
\li \uicontrol {Next (.)} moves to the next frame on the timeline.
|
||||
\li \l{Navigating in Timeline}
|
||||
\row
|
||||
\li \inlineimage to_last_frame.png
|
||||
\li \inlineimage icons/to_last_frame.png
|
||||
\li \uicontrol {To End (End)} moves to the last frame on the timeline.
|
||||
\li \l{Navigating in Timeline}
|
||||
\row
|
||||
@@ -157,11 +157,11 @@
|
||||
number in the field to move the playhead to the respective frame.
|
||||
\li \l{Navigating in Timeline}
|
||||
\row
|
||||
\li \inlineimage global_record_keyframes.png
|
||||
\li \inlineimage icons/global_record_keyframes.png
|
||||
\li Records changes in keyframe values.
|
||||
\li \l {Setting Keyframe Values}
|
||||
\row
|
||||
\li \inlineimage curve_editor.png
|
||||
\li \inlineimage icons/curve_editor.png
|
||||
\li Opens \uicontrol {Easing Curve Editor} for attaching an easing
|
||||
curve to the selected transition.
|
||||
\li \l{Editing Easing Curves}
|
||||
@@ -172,7 +172,7 @@
|
||||
determines the duration of the animation.
|
||||
\li \l{Creating Timelines}
|
||||
\row
|
||||
\li \inlineimage zoom_small.png
|
||||
\li \inlineimage icons/zoom_small.png
|
||||
\li \uicontrol {Zoom Out} (\key Ctrl+-) zooms out of the view.
|
||||
\li \l{Zooming in Timeline}
|
||||
\row
|
||||
@@ -180,7 +180,7 @@
|
||||
\li Sets the zooming level.
|
||||
\li \l{Zooming in Timeline}
|
||||
\row
|
||||
\li \inlineimage zoom_big.png
|
||||
\li \inlineimage icons/zoom_big.png
|
||||
\li \uicontrol {Zoom In} (\key Ctrl++) zooms into the view.
|
||||
\li \l{Zooming in Timeline}
|
||||
\row
|
||||
@@ -206,20 +206,20 @@
|
||||
\li Action
|
||||
\li Read More
|
||||
\row
|
||||
\li \inlineimage previous_keyframe.png
|
||||
\li \inlineimage icons/previous_keyframe.png
|
||||
\li Jumps to the previous frame on the timeline.
|
||||
\li \l{Setting Keyframe Values}
|
||||
\row
|
||||
\li \inlineimage next_keyframe.png
|
||||
\li \inlineimage icons/next_keyframe.png
|
||||
\li Jumps to the next frame on the timeline.
|
||||
\li \l{Setting Keyframe Values}
|
||||
\row
|
||||
\li \inlineimage local_record_keyframes.png
|
||||
\li \inlineimage icons/local_record_keyframes.png
|
||||
\li Records changes in keyframe values for a particular property.
|
||||
\li \l {Setting Keyframe Values}
|
||||
\target keyframe_marker
|
||||
\row
|
||||
\li \inlineimage keyframe.png
|
||||
\li \inlineimage icons/keyframe.png
|
||||
\li Indicates the type of easing curve attached to the keyframe.
|
||||
When a keyframe track is selected, the keyframe markers on it turn
|
||||
gray, and when a keyframe itself is selected, its marker turns
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
frames or for running the animation backwards from the last frame to the
|
||||
first.
|
||||
|
||||
To modify the settings, select the \inlineimage animation.png
|
||||
To modify the settings, select the \inlineimage icons/animation.png
|
||||
(\uicontrol {Timeline Settings (S)}) button on the \l{Timeline Toolbar}
|
||||
{toolbar} (or press \key S) in the \l Timeline view.
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
You can insert keyframes for all the properties of all the components that
|
||||
you want to animate first, and then record the changes in their values by
|
||||
selecting the \inlineimage local_record_keyframes.png
|
||||
selecting the \inlineimage icons/local_record_keyframes.png
|
||||
(\uicontrol {Per Property Recording}) button for one property at a time.
|
||||
For example, you can hide and show components by turning their visibility
|
||||
off and on or by setting their opacity to 0 or 1.
|
||||
@@ -194,7 +194,7 @@
|
||||
|
||||
To preview the animation, select the \uicontrol {Play (Space)}
|
||||
button or press \key Space. To preview the whole UI, select the
|
||||
\inlineimage live_preview.png
|
||||
\inlineimage icons/live_preview.png
|
||||
(\uicontrol {Show Live Preview}) button on the canvas toolbar
|
||||
or press \key {Alt+P}.
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
\section1 Zooming in Transition Editor
|
||||
|
||||
Use the slider on the toolbar to set the zooming level in
|
||||
\uicontrol {Transition Editor}. Select the \inlineimage zoom_small.png
|
||||
and \inlineimage zoom_big.png
|
||||
\uicontrol {Transition Editor}. Select the \inlineimage icons/zoom_small.png
|
||||
and \inlineimage icons/zoom_big.png
|
||||
buttons to zoom out of or into the view.
|
||||
|
||||
\section1 Summary of Transition Editor Toolbar Actions
|
||||
@@ -61,7 +61,7 @@
|
||||
\li Action
|
||||
\li Read More
|
||||
\row
|
||||
\li \inlineimage animation.png
|
||||
\li \inlineimage icons/animation.png
|
||||
\li Opens \uicontrol {Transition Settings} dialog for editing
|
||||
transition settings.
|
||||
\li \l{Specifying Transition Settings}
|
||||
@@ -71,12 +71,12 @@
|
||||
\uicontrol {Transition Editor}.
|
||||
\li \l{Animating Transitions Between States}
|
||||
\row
|
||||
\li \inlineimage curve_editor.png
|
||||
\li \inlineimage icons/curve_editor.png
|
||||
\li Opens \uicontrol {Easing Curve Editor} for attaching an easing
|
||||
curve to the selected transition.
|
||||
\li \l{Editing Easing Curves}
|
||||
\row
|
||||
\li \inlineimage zoom_small.png
|
||||
\li \inlineimage icons/zoom_small.png
|
||||
\li \uicontrol {Zoom Out} (\key Ctrl+-): zooms out of the view.
|
||||
\li \l{Zooming in Transition Editor}
|
||||
\row
|
||||
@@ -84,7 +84,7 @@
|
||||
\li Sets the zooming level.
|
||||
\li \l{Zooming in Transition Editor}
|
||||
\row
|
||||
\li \inlineimage zoom_big.png
|
||||
\li \inlineimage icons/zoom_big.png
|
||||
\li \uicontrol {Zoom In} (\key Ctrl++): zooms into the view.
|
||||
\li \l{Zooming in Transition Editor}
|
||||
\row
|
||||
@@ -110,13 +110,13 @@
|
||||
the start and end frame of the animation of the property. Pull its
|
||||
left and right edges to set the duration of the animation.
|
||||
\li To attach an \l{Editing Easing Curves}{easing curve} to the
|
||||
selected transition, select the \inlineimage curve_editor.png
|
||||
selected transition, select the \inlineimage icons/curve_editor.png
|
||||
(\uicontrol {Easing Curve Editor (C)}) button.
|
||||
\endlist
|
||||
|
||||
\section1 Specifying Transition Settings
|
||||
|
||||
To modify transition settings, select the \inlineimage animation.png
|
||||
To modify transition settings, select the \inlineimage icons/animation.png
|
||||
(\uicontrol {Transition Settings (S)}) button in
|
||||
\uicontrol {Transition Editor}.
|
||||
|
||||
|
||||
@@ -109,6 +109,10 @@ def build(args, paths):
|
||||
# TODO this works around a CMake bug https://gitlab.kitware.com/cmake/cmake/issues/20119
|
||||
cmake_args += ['-DBUILD_WITH_PCH=OFF']
|
||||
|
||||
# work around QTBUG-89754
|
||||
# Qt otherwise adds dependencies on libGLX and libOpenGL
|
||||
cmake_args += ['-DOpenGL_GL_PREFERENCE=LEGACY']
|
||||
|
||||
if args.with_docs:
|
||||
cmake_args += ['-DWITH_DOCS=ON']
|
||||
|
||||
|
||||
@@ -77,33 +77,8 @@ Item {
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
clip: true
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
property bool scrollBarVisible: parent.childrenRect.height > parent.height
|
||||
|
||||
minimumSize: orientation == Qt.Horizontal ? height / width : width / height
|
||||
|
||||
orientation: Qt.Vertical
|
||||
policy: scrollBarVisible ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||
x: parent.width - width
|
||||
y: 0
|
||||
height: parent.availableHeight
|
||||
- (parent.bothVisible ? parent.horizontalThickness : 0)
|
||||
padding: 0
|
||||
|
||||
background: Rectangle {
|
||||
color: StudioTheme.Values.themeScrollBarTrack
|
||||
}
|
||||
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: StudioTheme.Values.scrollBarThickness
|
||||
color: StudioTheme.Values.themeScrollBarHandle
|
||||
}
|
||||
} // ScrollBar
|
||||
ScrollBar.vertical: SC.VerticalScrollBar {
|
||||
}
|
||||
|
||||
Column {
|
||||
id: scrollContent
|
||||
|
||||
@@ -30,6 +30,7 @@ import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
import StudioControls as SC
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Item {
|
||||
width: DialogValues.stylesPaneWidth
|
||||
@@ -55,8 +56,8 @@ Item {
|
||||
radius: 6
|
||||
|
||||
Item {
|
||||
x: DialogValues.stylesPanePadding // left padding
|
||||
width: parent.width - DialogValues.stylesPanePadding * 2 // right padding
|
||||
x: DialogValues.stylesPanePadding
|
||||
width: parent.width - DialogValues.stylesPanePadding * 2 + styleScrollBar.width
|
||||
height: parent.height
|
||||
|
||||
ColumnLayout {
|
||||
@@ -100,6 +101,8 @@ Item {
|
||||
}
|
||||
} // Style Filter ComboBox
|
||||
|
||||
Item { implicitWidth: 1; implicitHeight: 9 }
|
||||
|
||||
ListView {
|
||||
id: stylesList
|
||||
Layout.fillWidth: true
|
||||
@@ -107,11 +110,26 @@ Item {
|
||||
clip: true
|
||||
model: styleModel
|
||||
|
||||
MouseArea {
|
||||
id: listViewMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
}
|
||||
|
||||
focus: true
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
||||
highlightFollowsCurrentItem: false
|
||||
|
||||
ScrollBar.vertical: SC.VerticalScrollBar {
|
||||
id: styleScrollBar
|
||||
property int extraPadding: 0
|
||||
bottomInset: extraPadding
|
||||
bottomPadding: bottomInset + 16
|
||||
viewMouseArea: listViewMouseArea
|
||||
} // ScrollBar
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (styleModel.rowCount() > 0)
|
||||
dialogBox.styleIndex = stylesList.currentIndex;
|
||||
@@ -120,7 +138,11 @@ Item {
|
||||
delegate: ItemDelegate {
|
||||
id: delegateId
|
||||
height: styleImage.height + DialogValues.styleImageBorderWidth + styleText.height + extraPadding.height + 1
|
||||
width: stylesList.width
|
||||
width: stylesList.width - styleScrollBar.width
|
||||
|
||||
Component.onCompleted: {
|
||||
styleScrollBar.extraPadding = styleText.height + extraPadding.height
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -37,7 +37,12 @@ Row {
|
||||
property variant backendValue
|
||||
property color textColor: colorLogic.highlight ? colorLogic.textColor
|
||||
: StudioTheme.Values.themeTextColor
|
||||
property string filter: "*.png *.gif *.jpg *.bmp *.jpeg *.svg *.pbm *.pgm *.ppm *.xbm *.xpm *.hdr *.webp"
|
||||
property string filter: "*.png *.gif *.jpg *.bmp *.jpeg *.svg *.pbm *.pgm *.ppm *.xbm *.xpm *.hdr *.ktx *.webp"
|
||||
|
||||
// This property takes an array of strings which define default items that should be added
|
||||
// to the ComboBox model in addition to the items from the FileResourcesModel. This is used
|
||||
// by QtQuick3D to add built-in primitives to the model.
|
||||
property var defaultItems
|
||||
|
||||
FileResourcesModel {
|
||||
id: fileModel
|
||||
@@ -53,6 +58,8 @@ Row {
|
||||
StudioControls.ComboBox {
|
||||
id: comboBox
|
||||
|
||||
property ListModel items: ListModel {}
|
||||
|
||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
width: implicitWidth
|
||||
@@ -62,7 +69,7 @@ Row {
|
||||
|
||||
ToolTip {
|
||||
id: toolTip
|
||||
visible: comboBox.hovered && toolTip.text !== ""
|
||||
visible: comboBox.hover && toolTip.text !== ""
|
||||
text: urlChooser.backendValue.valueToString
|
||||
delay: StudioTheme.Values.toolTipDelay
|
||||
height: StudioTheme.Values.toolTipHeight
|
||||
@@ -79,6 +86,10 @@ Row {
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
required property string fullPath
|
||||
required property string name
|
||||
required property int index
|
||||
|
||||
id: delegateItem
|
||||
width: parent.width
|
||||
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
|
||||
@@ -107,7 +118,7 @@ Row {
|
||||
|
||||
contentItem: Text {
|
||||
leftPadding: itemDelegateIconArea.width
|
||||
text: modelData
|
||||
text: name
|
||||
color: delegateItem.highlighted ? StudioTheme.Values.themeTextSelectedTextColor
|
||||
: StudioTheme.Values.themeTextColor
|
||||
font: comboBox.font
|
||||
@@ -127,7 +138,7 @@ Row {
|
||||
ToolTip {
|
||||
id: itemToolTip
|
||||
visible: delegateItem.hovered && comboBox.highlightedIndex === index
|
||||
text: fileModel.fullPathModel[index]
|
||||
text: fullPath
|
||||
delay: StudioTheme.Values.toolTipDelay
|
||||
height: StudioTheme.Values.toolTipHeight
|
||||
background: Rectangle {
|
||||
@@ -151,6 +162,7 @@ Row {
|
||||
ExtendedFunctionLogic {
|
||||
id: extFuncLogic
|
||||
backendValue: urlChooser.backendValue
|
||||
onReseted: comboBox.editText = ""
|
||||
}
|
||||
|
||||
property bool isComplete: false
|
||||
@@ -161,26 +173,27 @@ Row {
|
||||
function setCurrentText(text) {
|
||||
var index = comboBox.find(text)
|
||||
if (index === -1)
|
||||
currentIndex = -1
|
||||
comboBox.currentIndex = -1
|
||||
|
||||
comboBox.editText = text
|
||||
comboBox.dirty = false
|
||||
}
|
||||
|
||||
// Takes into account applied bindings
|
||||
property string textValue: {
|
||||
if (urlChooser.backendValue.isBound)
|
||||
return urlChooser.backendValue.expression
|
||||
|
||||
var fullPath = urlChooser.backendValue.valueToString;
|
||||
var fileName = fullPath.substr(fullPath.lastIndexOf('/') + 1);
|
||||
return fileName;
|
||||
var fullPath = urlChooser.backendValue.valueToString
|
||||
return fullPath.substr(fullPath.lastIndexOf('/') + 1)
|
||||
}
|
||||
|
||||
onTextValueChanged: comboBox.setCurrentText(comboBox.textValue)
|
||||
|
||||
editable: true
|
||||
|
||||
model: fileModel.fileNameModel
|
||||
textRole: "name"
|
||||
valueRole: "fullPath"
|
||||
model: comboBox.items
|
||||
|
||||
onModelChanged: {
|
||||
if (!comboBox.isComplete)
|
||||
@@ -193,8 +206,20 @@ Row {
|
||||
if (!comboBox.isComplete)
|
||||
return
|
||||
|
||||
if (comboBox.backendValue.value !== comboBox.editText)
|
||||
comboBox.backendValue.value = comboBox.editText
|
||||
var inputValue = comboBox.editText
|
||||
|
||||
// Check if value set by user matches with a name in the model then pick the full path
|
||||
var index = comboBox.find(inputValue)
|
||||
if (index !== -1)
|
||||
inputValue = comboBox.items.get(index).fullPath
|
||||
|
||||
// Get the currently assigned backend value, extract its file name and compare it to the
|
||||
// input value. If they differ the new value needs to be set.
|
||||
var currentValue = urlChooser.backendValue.value
|
||||
var fileName = currentValue.substr(currentValue.lastIndexOf('/') + 1);
|
||||
|
||||
if (fileName !== inputValue)
|
||||
urlChooser.backendValue.value = inputValue
|
||||
|
||||
comboBox.dirty = false
|
||||
}
|
||||
@@ -204,20 +229,19 @@ Row {
|
||||
comboBox.handleActivate(comboBox.currentIndex)
|
||||
}
|
||||
|
||||
onCompressedActivated: comboBox.handleActivate(index)
|
||||
onCompressedActivated: function (index) {
|
||||
comboBox.handleActivate(index)
|
||||
}
|
||||
|
||||
function handleActivate(index) {
|
||||
if (urlChooser.backendValue === undefined)
|
||||
return
|
||||
|
||||
if (!comboBox.isComplete)
|
||||
if (urlChooser.backendValue === undefined || !comboBox.isComplete)
|
||||
return
|
||||
|
||||
if (index === -1) // select first item if index is invalid
|
||||
index = 0
|
||||
|
||||
if (urlChooser.backendValue.value !== fileModel.fullPathModel[index])
|
||||
urlChooser.backendValue.value = fileModel.fullPathModel[index]
|
||||
if (urlChooser.backendValue.value !== comboBox.items.get(index).fullPath)
|
||||
urlChooser.backendValue.value = comboBox.items.get(index).fullPath
|
||||
|
||||
comboBox.dirty = false
|
||||
}
|
||||
@@ -235,16 +259,60 @@ Row {
|
||||
}
|
||||
}
|
||||
|
||||
function createModel() {
|
||||
// Build the combobox model
|
||||
comboBox.items.clear()
|
||||
|
||||
for (var i = 0; i < urlChooser.defaultItems.length; ++i) {
|
||||
comboBox.items.append({
|
||||
fullPath: urlChooser.defaultItems[i],
|
||||
name: urlChooser.defaultItems[i]
|
||||
})
|
||||
}
|
||||
|
||||
for (var j = 0; j < fileModel.fullPathModel.length; ++j) {
|
||||
comboBox.items.append({
|
||||
fullPath: fileModel.fullPathModel[j],
|
||||
name: fileModel.fileNameModel[j]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: fileModel
|
||||
function onFullPathModelChanged() {
|
||||
urlChooser.createModel()
|
||||
comboBox.setCurrentText(comboBox.textValue)
|
||||
}
|
||||
}
|
||||
|
||||
onDefaultItemsChanged: urlChooser.createModel()
|
||||
|
||||
Component.onCompleted: urlChooser.createModel()
|
||||
|
||||
function indexOf(model, criteria) {
|
||||
for (var i = 0; i < model.count; ++i) {
|
||||
if (criteria(model.get(i)))
|
||||
return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: comboBox
|
||||
function onStateChanged(state) {
|
||||
// update currentIndex when the popup opens to override the default behavior in super classes
|
||||
// that selects currentIndex based on values in the combo box.
|
||||
if (comboBox.popup.opened) {
|
||||
var index = fileModel.fullPathModel.indexOf(urlChooser.backendValue.value)
|
||||
if (comboBox.popup.opened && !urlChooser.backendValue.isBound) {
|
||||
var index = urlChooser.indexOf(comboBox.items,
|
||||
function(item) {
|
||||
return item.fullPath === urlChooser.backendValue.value
|
||||
})
|
||||
|
||||
if (index !== -1) {
|
||||
comboBox.currentIndex = index
|
||||
comboBox.hoverIndex = index
|
||||
comboBox.editText = comboBox.items.get(index).name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,9 @@ T.ComboBox {
|
||||
text: myComboBox.editText
|
||||
|
||||
onEditingFinished: {
|
||||
comboBoxInput.deselect()
|
||||
comboBoxInput.focus = false
|
||||
|
||||
// Only trigger the signal, if the value was modified
|
||||
if (myComboBox.dirty) {
|
||||
myTimer.stop()
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.Controls 2.15
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
ScrollBar {
|
||||
id: scrollBar
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
property bool scrollBarVisible: parent.childrenRect.height > parent.height
|
||||
// viewMouseArea: if set, the scrollbar will be visible only on hover over the view containing
|
||||
// the mouse area item.
|
||||
property MouseArea viewMouseArea: null
|
||||
|
||||
minimumSize: orientation == Qt.Horizontal ? height / width : width / height
|
||||
|
||||
orientation: Qt.Vertical
|
||||
policy: computePolicy()
|
||||
x: parent.width - width
|
||||
y: 0
|
||||
height: parent.availableHeight
|
||||
- (parent.bothVisible ? parent.horizontalThickness : 0)
|
||||
padding: 0
|
||||
|
||||
background: Rectangle {
|
||||
color: StudioTheme.Values.themeScrollBarTrack
|
||||
}
|
||||
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: StudioTheme.Values.scrollBarThickness
|
||||
color: StudioTheme.Values.themeScrollBarHandle
|
||||
}
|
||||
|
||||
function computePolicy() {
|
||||
if (!scrollBar.scrollBarVisible)
|
||||
return ScrollBar.AlwaysOff;
|
||||
|
||||
if (scrollBar.viewMouseArea)
|
||||
return scrollBar.viewMouseArea.containsMouse ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||
else
|
||||
return ScrollBar.AlwaysOn;
|
||||
}
|
||||
}
|
||||
@@ -38,3 +38,4 @@ TabButton 1.0 TabButton.qml
|
||||
TextArea 1.0 TextArea.qml
|
||||
TextField 1.0 TextField.qml
|
||||
TranslationIndicator 1.0 TranslationIndicator.qml
|
||||
VerticalScrollBar 1.0 VerticalScrollBar.qml
|
||||
|
||||
@@ -205,6 +205,8 @@ QtObject {
|
||||
|
||||
// Theme Colors
|
||||
|
||||
property bool isLightTheme: themeControlBackground.hsvValue > themeTextColor.hsvValue
|
||||
|
||||
property string themePanelBackground: Theme.color(Theme.DSpanelBackground)
|
||||
|
||||
property string themeInteraction: Theme.color(Theme.DSinteraction)
|
||||
@@ -215,7 +217,7 @@ QtObject {
|
||||
property string themeAliasIconChecked: Theme.color(Theme.DSnavigatorAliasIconChecked)
|
||||
|
||||
// Control colors
|
||||
property string themeControlBackground: Theme.color(Theme.DScontrolBackground)
|
||||
property color themeControlBackground: Theme.color(Theme.DScontrolBackground)
|
||||
property string themeControlBackgroundInteraction: Theme.color(Theme.DScontrolBackgroundInteraction)
|
||||
property string themeControlBackgroundDisabled: Theme.color(Theme.DScontrolBackgroundDisabled)
|
||||
property string themeControlBackgroundGlobalHover: Theme.color(Theme.DScontrolBackgroundGlobalHover)
|
||||
@@ -230,7 +232,7 @@ QtObject {
|
||||
property string themeBackgroundColorAlternate: Theme.color(Theme.DSBackgroundColorAlternate)
|
||||
|
||||
// Text colors
|
||||
property string themeTextColor: Theme.color(Theme.DStextColor)
|
||||
property color themeTextColor: Theme.color(Theme.DStextColor)
|
||||
property string themeTextColorDisabled: Theme.color(Theme.DStextColorDisabled)
|
||||
property string themeTextSelectionColor: Theme.color(Theme.DStextSelectionColor)
|
||||
property string themeTextSelectedTextColor: Theme.color(Theme.DStextSelectedTextColor)
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
ConnectionClient::ConnectionClient(const QString &connectionName)
|
||||
@@ -161,7 +159,7 @@ void ConnectionClient::restartProcessIfTimerIsNotResettedAndSocketIsEmpty()
|
||||
restartProcessAsynchronously();
|
||||
}
|
||||
|
||||
void ConnectionClient::endProcess(QtcProcess *process)
|
||||
void ConnectionClient::endProcess(QProcess *process)
|
||||
{
|
||||
if (isProcessRunning(process) && isConnected()) {
|
||||
sendEndMessage();
|
||||
@@ -169,15 +167,15 @@ void ConnectionClient::endProcess(QtcProcess *process)
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionClient::terminateProcess(QtcProcess *process)
|
||||
void ConnectionClient::terminateProcess(QProcess *process)
|
||||
{
|
||||
if (!HostOsInfo::isWindowsHost() && isProcessRunning()) {
|
||||
if (!Utils::HostOsInfo::isWindowsHost() && isProcessRunning()) {
|
||||
process->terminate();
|
||||
process->waitForFinished(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionClient::killProcess(QtcProcess *process)
|
||||
void ConnectionClient::killProcess(QProcess *process)
|
||||
{
|
||||
if (isProcessRunning(process)) {
|
||||
process->kill();
|
||||
@@ -215,7 +213,7 @@ void ConnectionClient::resetTemporaryDirectory()
|
||||
m_processCreator.resetTemporaryDirectory();
|
||||
}
|
||||
|
||||
void ConnectionClient::initializeProcess(QtcProcess *process)
|
||||
void ConnectionClient::initializeProcess(QProcess *process)
|
||||
{
|
||||
connectStandardOutputAndError(process);
|
||||
|
||||
@@ -301,7 +299,7 @@ bool ConnectionClient::waitForConnected()
|
||||
}
|
||||
|
||||
|
||||
QtcProcess *ConnectionClient::processForTestOnly()
|
||||
QProcess *ConnectionClient::processForTestOnly()
|
||||
{
|
||||
getProcessFromFuture();
|
||||
|
||||
@@ -313,15 +311,15 @@ QIODevice *ConnectionClient::ioDevice()
|
||||
return m_localSocket;
|
||||
}
|
||||
|
||||
bool ConnectionClient::isProcessRunning(QtcProcess *process)
|
||||
bool ConnectionClient::isProcessRunning(QProcess *process)
|
||||
{
|
||||
return process && process->isRunning();
|
||||
return process && process->state() == QProcess::Running;
|
||||
}
|
||||
|
||||
void ConnectionClient::connectStandardOutputAndError(QtcProcess *process) const
|
||||
void ConnectionClient::connectStandardOutputAndError(QProcess *process) const
|
||||
{
|
||||
connect(process, &QtcProcess::readyReadStandardOutput, this, &ConnectionClient::printStandardOutput);
|
||||
connect(process, &QtcProcess::readyReadStandardError, this, &ConnectionClient::printStandardError);
|
||||
connect(process, &QProcess::readyReadStandardOutput, this, &ConnectionClient::printStandardOutput);
|
||||
connect(process, &QProcess::readyReadStandardError, this, &ConnectionClient::printStandardError);
|
||||
}
|
||||
|
||||
void ConnectionClient::connectLocalSocketError() const
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "clangcodemodelserverproxy.h"
|
||||
#include "lineprefixer.h"
|
||||
#include "processcreator.h"
|
||||
#include "processhandle.h"
|
||||
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
@@ -38,7 +37,9 @@
|
||||
#include <future>
|
||||
#include <memory>
|
||||
|
||||
namespace Utils { class QtcProcess; }
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QProcess;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class Utf8String;
|
||||
class Utf8StringVector;
|
||||
@@ -76,7 +77,7 @@ public:
|
||||
bool waitForEcho();
|
||||
bool waitForConnected();
|
||||
|
||||
Utils::QtcProcess *processForTestOnly();
|
||||
QProcess *processForTestOnly();
|
||||
|
||||
signals:
|
||||
void connectedToLocalSocket();
|
||||
@@ -102,22 +103,22 @@ protected:
|
||||
virtual void newConnectedServer(QLocalSocket *localSocket) = 0;
|
||||
|
||||
private:
|
||||
static bool isProcessRunning(Utils::QtcProcess *process);
|
||||
static bool isProcessRunning(QProcess *process);
|
||||
void finishProcess(QProcessUniquePointer &&process);
|
||||
void endProcess(Utils::QtcProcess *process);
|
||||
void terminateProcess(Utils::QtcProcess *process);
|
||||
void killProcess(Utils::QtcProcess *process);
|
||||
void endProcess(QProcess *process);
|
||||
void terminateProcess(QProcess *process);
|
||||
void killProcess(QProcess *process);
|
||||
void finishConnection();
|
||||
void printLocalSocketError(QLocalSocket::LocalSocketError socketError);
|
||||
void printStandardOutput();
|
||||
void printStandardError();
|
||||
void initializeProcess(Utils::QtcProcess *process);
|
||||
void initializeProcess(QProcess *process);
|
||||
|
||||
void resetTemporaryDirectory();
|
||||
|
||||
void connectLocalSocketDisconnected();
|
||||
void disconnectLocalSocketDisconnected();
|
||||
void connectStandardOutputAndError(Utils::QtcProcess *process) const;
|
||||
void connectStandardOutputAndError(QProcess *process) const;
|
||||
void connectLocalSocketError() const;
|
||||
void connectAliveTimer();
|
||||
void connectNewConnection();
|
||||
|
||||
@@ -28,15 +28,10 @@
|
||||
#include "processexception.h"
|
||||
#include "processstartedevent.h"
|
||||
|
||||
#include <utils/commandline.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
@@ -61,7 +56,7 @@ void ProcessCreator::setArguments(const QStringList &arguments)
|
||||
m_arguments = arguments;
|
||||
}
|
||||
|
||||
void ProcessCreator::setEnvironment(const Environment &environment)
|
||||
void ProcessCreator::setEnvironment(const Utils::Environment &environment)
|
||||
{
|
||||
m_environment = environment;
|
||||
}
|
||||
@@ -70,11 +65,10 @@ std::future<QProcessUniquePointer> ProcessCreator::createProcess() const
|
||||
{
|
||||
return std::async(std::launch::async, [&] {
|
||||
checkIfProcessPathExists();
|
||||
auto process = QProcessUniquePointer(new QtcProcess(ProcessMode::Writer));
|
||||
process->setProcessChannelMode(QProcess::ForwardedChannels);
|
||||
process->setEnvironment(processEnvironment());
|
||||
process->setCommand(CommandLine(FilePath::fromString(m_processPath), m_arguments));
|
||||
process->start();
|
||||
auto process = QProcessUniquePointer(new QProcess);
|
||||
process->setProcessChannelMode(QProcess::QProcess::ForwardedChannels);
|
||||
process->setProcessEnvironment(processEnvironment());
|
||||
process->start(m_processPath, m_arguments);
|
||||
process->waitForStarted(5000);
|
||||
|
||||
checkIfProcessWasStartingSuccessful(process.get());
|
||||
@@ -101,13 +95,13 @@ void ProcessCreator::checkIfProcessPathExists() const
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessCreator::checkIfProcessWasStartingSuccessful(QtcProcess *process) const
|
||||
void ProcessCreator::checkIfProcessWasStartingSuccessful(QProcess *process) const
|
||||
{
|
||||
if (process->exitStatus() == QProcess::CrashExit || process->exitCode() != 0)
|
||||
dispatchProcessError(process);
|
||||
}
|
||||
|
||||
void ProcessCreator::dispatchProcessError(QtcProcess *process) const
|
||||
void ProcessCreator::dispatchProcessError(QProcess *process) const
|
||||
{
|
||||
switch (process->error()) {
|
||||
case QProcess::UnknownError: {
|
||||
@@ -164,24 +158,24 @@ const QTemporaryDir &ProcessCreator::temporaryDirectory() const
|
||||
|
||||
void ProcessCreator::resetTemporaryDirectory()
|
||||
{
|
||||
m_temporaryDirectory = std::make_unique<TemporaryDirectory>(m_temporaryDirectoryPattern);
|
||||
m_temporaryDirectory = std::make_unique<Utils::TemporaryDirectory>(m_temporaryDirectoryPattern);
|
||||
}
|
||||
|
||||
Environment ProcessCreator::processEnvironment() const
|
||||
QProcessEnvironment ProcessCreator::processEnvironment() const
|
||||
{
|
||||
auto processEnvironment = Environment::systemEnvironment();
|
||||
auto processEnvironment = QProcessEnvironment::systemEnvironment();
|
||||
|
||||
if (temporaryDirectory().isValid()) {
|
||||
const QString temporaryDirectoryPath = temporaryDirectory().path();
|
||||
processEnvironment.appendOrSet("TMPDIR", temporaryDirectoryPath);
|
||||
processEnvironment.appendOrSet("TMP", temporaryDirectoryPath);
|
||||
processEnvironment.appendOrSet("TEMP", temporaryDirectoryPath);
|
||||
processEnvironment.insert("TMPDIR", temporaryDirectoryPath);
|
||||
processEnvironment.insert("TMP", temporaryDirectoryPath);
|
||||
processEnvironment.insert("TEMP", temporaryDirectoryPath);
|
||||
}
|
||||
|
||||
const Environment &env = m_environment;
|
||||
const Utils::Environment &env = m_environment;
|
||||
for (auto it = env.constBegin(); it != env.constEnd(); ++it) {
|
||||
if (env.isEnabled(it))
|
||||
processEnvironment.appendOrSet(env.key(it), env.expandedValueForKey(env.key(it)));
|
||||
processEnvironment.insert(env.key(it), env.expandedValueForKey(env.key(it)));
|
||||
}
|
||||
|
||||
return processEnvironment;
|
||||
|
||||
@@ -39,13 +39,9 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTemporaryDir;
|
||||
class QProcessEnvironment;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class Environment;
|
||||
class QtcProcess;
|
||||
}
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class CLANGSUPPORT_EXPORT ProcessCreator
|
||||
@@ -66,12 +62,12 @@ public:
|
||||
|
||||
private:
|
||||
void checkIfProcessPathExists() const;
|
||||
void checkIfProcessWasStartingSuccessful(Utils::QtcProcess *process) const;
|
||||
[[noreturn]] void dispatchProcessError(Utils::QtcProcess *process) const;
|
||||
void checkIfProcessWasStartingSuccessful(QProcess *process) const;
|
||||
[[noreturn]] void dispatchProcessError(QProcess *process) const;
|
||||
void postProcessStartedEvent() const;
|
||||
[[noreturn]] void throwProcessException(const QString &message) const;
|
||||
|
||||
Utils::Environment processEnvironment() const;
|
||||
QProcessEnvironment processEnvironment() const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Utils::TemporaryDirectory> m_temporaryDirectory;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <QProcess>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace ClangBackEnd {
|
||||
class QProcessUniquePointerDeleter
|
||||
{
|
||||
public:
|
||||
void operator()(Utils::QtcProcess* process)
|
||||
void operator()(QProcess* process)
|
||||
{
|
||||
process->kill();
|
||||
process->waitForFinished();
|
||||
@@ -42,6 +42,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
using QProcessUniquePointer = std::unique_ptr<Utils::QtcProcess, QProcessUniquePointerDeleter>;
|
||||
using QProcessUniquePointer = std::unique_ptr<QProcess, QProcessUniquePointerDeleter>;
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -71,16 +71,16 @@ public:
|
||||
signals:
|
||||
void beginResetAllDiagrams();
|
||||
void endResetAllDiagrams();
|
||||
void beginResetDiagram(const MDiagram *diagram);
|
||||
void endResetDiagram(const MDiagram *diagram);
|
||||
void beginUpdateElement(int row, const MDiagram *diagram);
|
||||
void endUpdateElement(int row, const MDiagram *diagram);
|
||||
void beginInsertElement(int row, const MDiagram *diagram);
|
||||
void endInsertElement(int row, const MDiagram *diagram);
|
||||
void beginRemoveElement(int row, const MDiagram *diagram);
|
||||
void endRemoveElement(int row, const MDiagram *diagram);
|
||||
void modified(const MDiagram *diagram);
|
||||
void diagramAboutToBeRemoved(const MDiagram *diagram);
|
||||
void beginResetDiagram(const qmt::MDiagram *diagram);
|
||||
void endResetDiagram(const qmt::MDiagram *diagram);
|
||||
void beginUpdateElement(int row, const qmt::MDiagram *diagram);
|
||||
void endUpdateElement(int row, const qmt::MDiagram *diagram);
|
||||
void beginInsertElement(int row, const qmt::MDiagram *diagram);
|
||||
void endInsertElement(int row, const qmt::MDiagram *diagram);
|
||||
void beginRemoveElement(int row, const qmt::MDiagram *diagram);
|
||||
void endRemoveElement(int row, const qmt::MDiagram *diagram);
|
||||
void modified(const qmt::MDiagram *diagram);
|
||||
void diagramAboutToBeRemoved(const qmt::MDiagram *diagram);
|
||||
|
||||
public:
|
||||
ModelController *modelController() const { return m_modelController; }
|
||||
|
||||
@@ -80,8 +80,8 @@ public:
|
||||
~DiagramSceneModel() override;
|
||||
|
||||
signals:
|
||||
void diagramSceneActivated(const MDiagram *diagram);
|
||||
void selectionHasChanged(const MDiagram *diagram);
|
||||
void diagramSceneActivated(const qmt::MDiagram *diagram);
|
||||
void selectionHasChanged(const qmt::MDiagram *diagram);
|
||||
void sceneRectChanged(const QRectF &sceneRect);
|
||||
|
||||
public:
|
||||
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
|
||||
signals:
|
||||
void someDiagramOpened(bool);
|
||||
void diagramActivated(const MDiagram *diagram);
|
||||
void diagramSelectionChanged(const MDiagram *diagram);
|
||||
void diagramActivated(const qmt::MDiagram *diagram);
|
||||
void diagramSelectionChanged(const qmt::MDiagram *diagram);
|
||||
|
||||
public:
|
||||
void setModel(TreeModel *model);
|
||||
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
~DiagramsView() override;
|
||||
|
||||
signals:
|
||||
void currentDiagramChanged(const MDiagram *diagram);
|
||||
void diagramCloseRequested(const MDiagram *diagram);
|
||||
void currentDiagramChanged(const qmt::MDiagram *diagram);
|
||||
void diagramCloseRequested(const qmt::MDiagram *diagram);
|
||||
void someDiagramOpened(bool);
|
||||
|
||||
public:
|
||||
|
||||
@@ -49,8 +49,8 @@ public:
|
||||
~StackedDiagramsView() override;
|
||||
|
||||
signals:
|
||||
void currentDiagramChanged(const MDiagram *diagram);
|
||||
void diagramCloseRequested(const MDiagram *diagram);
|
||||
void currentDiagramChanged(const qmt::MDiagram *diagram);
|
||||
void diagramCloseRequested(const qmt::MDiagram *diagram);
|
||||
void someDiagramOpened(bool);
|
||||
|
||||
public:
|
||||
|
||||
@@ -72,3 +72,6 @@ private:
|
||||
};
|
||||
|
||||
} // namespace qmt
|
||||
|
||||
Q_DECLARE_METATYPE(qmt::MDiagram *)
|
||||
Q_DECLARE_METATYPE(const qmt::MDiagram *)
|
||||
|
||||
@@ -72,8 +72,8 @@ public:
|
||||
~DiagramSceneController() override;
|
||||
|
||||
signals:
|
||||
void newElementCreated(DElement *element, MDiagram *diagram);
|
||||
void elementAdded(DElement *element, MDiagram *diagram);
|
||||
void newElementCreated(DElement *element, qmt::MDiagram *diagram);
|
||||
void elementAdded(DElement *element, qmt::MDiagram *diagram);
|
||||
|
||||
public:
|
||||
ModelController *modelController() const { return m_modelController; }
|
||||
|
||||
@@ -4,7 +4,6 @@ VPATH += $$PWD
|
||||
SOURCES += \
|
||||
columndefinition.cpp \
|
||||
createtablecommand.cpp \
|
||||
createtablesqlstatementbuilder.cpp \
|
||||
sqlitedatabasebackend.cpp \
|
||||
sqlitedatabaseconnection.cpp \
|
||||
sqlitedatabaseconnectionproxy.cpp \
|
||||
|
||||
@@ -40,6 +40,12 @@ public:
|
||||
return first.value == second.value;
|
||||
}
|
||||
|
||||
friend bool operator!=(TimeStamp first, TimeStamp second) { return !(first == second); }
|
||||
|
||||
bool isValid() const { return value >= 0; }
|
||||
|
||||
long long operator*() { return value; }
|
||||
|
||||
public:
|
||||
long long value = -1;
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace Utils {
|
||||
using std::get;
|
||||
using std::get_if;
|
||||
using std::holds_alternative;
|
||||
using std::monostate;
|
||||
using std::variant;
|
||||
using std::variant_alternative_t;
|
||||
using std::visit;
|
||||
@@ -51,6 +52,7 @@ namespace Utils {
|
||||
using mpark::get;
|
||||
using mpark::get_if;
|
||||
using mpark::holds_alternative;
|
||||
using mpark::monostate;
|
||||
using mpark::variant;
|
||||
using mpark::variant_alternative_t;
|
||||
using mpark::visit;
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
#include "uicontroller.h"
|
||||
#include "actionhandler.h"
|
||||
|
||||
#include "qmt/infrastructure/uid.h"
|
||||
#include <qmt/infrastructure/uid.h>
|
||||
#include <qmt/model/mdiagram.h>
|
||||
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
@@ -70,6 +71,8 @@ ModelEditorPlugin::ModelEditorPlugin()
|
||||
pluginInstance = this;
|
||||
qRegisterMetaType<QItemSelection>("QItemSelection");
|
||||
qRegisterMetaType<qmt::Uid>("qmt::Uid");
|
||||
qRegisterMetaType<qmt::MDiagram *>();
|
||||
qRegisterMetaType<const qmt::MDiagram *>();
|
||||
}
|
||||
|
||||
ModelEditorPlugin::~ModelEditorPlugin()
|
||||
|
||||
@@ -605,9 +605,10 @@ void AppOutputPane::stopRunControl()
|
||||
RunControl *rc = m_runControlTabs.at(index).runControl;
|
||||
QTC_ASSERT(rc, return);
|
||||
|
||||
if (rc->isRunning() && optionallyPromptToStop(rc))
|
||||
rc->initiateStop();
|
||||
else {
|
||||
if (rc->isRunning()) {
|
||||
if (optionallyPromptToStop(rc))
|
||||
rc->initiateStop();
|
||||
} else {
|
||||
QTC_CHECK(false);
|
||||
rc->forceStop();
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ void openPythonRepl(const FilePath &file, ReplType type)
|
||||
return project->projectDirectory();
|
||||
return FilePath::fromString(QDir::currentPath());
|
||||
}
|
||||
return file;
|
||||
return file.absolutePath();
|
||||
};
|
||||
|
||||
const auto args = QStringList{"-i"} + replImportArgs(file, type);
|
||||
|
||||
@@ -36,6 +36,7 @@ add_qtc_plugin(QmlDesigner
|
||||
qmldesignerconstants.h
|
||||
qmldesignericons.h
|
||||
qmldesignerplugin.cpp qmldesignerplugin.h
|
||||
qmldesignerprojectmanager.cpp qmldesignerprojectmanager.h
|
||||
settingspage.cpp settingspage.h settingspage.ui
|
||||
shortcutmanager.cpp shortcutmanager.h
|
||||
designermcumanager.cpp designermcumanager.h
|
||||
@@ -340,6 +341,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
include/propertybinding.h
|
||||
include/qml3dnode.h
|
||||
include/qmlvisualnode.h
|
||||
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
@@ -349,6 +351,14 @@ extend_qtc_plugin(QmlDesigner
|
||||
interactiveconnectionmanager.cpp interactiveconnectionmanager.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX designercore/imagecache
|
||||
SOURCES
|
||||
explicitimagecacheimageprovider.cpp
|
||||
explicitimagecacheimageprovider.h
|
||||
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX designercore
|
||||
PUBLIC_INCLUDES designercore
|
||||
|
||||
@@ -1553,6 +1553,7 @@ void DesignerActionManager::createDefaultAddResourceHandler()
|
||||
auto transformer = [](const QByteArray& format) -> QString { return QString("*.") + format; };
|
||||
auto imageFormats = Utils::transform(QImageReader::supportedImageFormats(), transformer);
|
||||
imageFormats.push_back("*.hdr");
|
||||
imageFormats.push_back("*.ktx");
|
||||
|
||||
// The filters will be displayed in reverse order to these lists in file dialog,
|
||||
// so declare most common types last
|
||||
|
||||
@@ -84,6 +84,12 @@ ConnectionViewWidget::ConnectionViewWidget(QWidget *parent) :
|
||||
ui->tabBar->addTab(tr("Bindings", "Title of connection view"));
|
||||
ui->tabBar->addTab(tr("Properties", "Title of dynamic properties view"));
|
||||
|
||||
const Qt::Alignment headerAlignment = Qt::AlignLeft | Qt::AlignVCenter;
|
||||
ui->connectionView->horizontalHeader()->setDefaultAlignment(headerAlignment);
|
||||
ui->bindingView->horizontalHeader()->setDefaultAlignment(headerAlignment);
|
||||
ui->dynamicPropertiesView->horizontalHeader()->setDefaultAlignment(headerAlignment);
|
||||
ui->backendView->horizontalHeader()->setDefaultAlignment(headerAlignment);
|
||||
|
||||
const QList<QToolButton*> buttons = createToolBarWidgets();
|
||||
|
||||
for (auto toolButton : buttons)
|
||||
|
||||
@@ -28,14 +28,15 @@ QTableView::item:focus {
|
||||
}
|
||||
|
||||
QTableView::item:selected {
|
||||
border: none
|
||||
border: none;
|
||||
}
|
||||
|
||||
QHeaderView::section {
|
||||
background-color: creatorTheme.DSheaderViewBackground;
|
||||
border: 0px;
|
||||
color: creatorTheme.DStextColor;
|
||||
margin-right: 1px
|
||||
margin-right: 1px;
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
QTableView {
|
||||
|
||||
@@ -859,8 +859,10 @@ bool FormEditorView::isMoveToolAvailable() const
|
||||
|
||||
void FormEditorView::resetNodeInstanceView()
|
||||
{
|
||||
ModelNode currentStateNode = currentState().modelNode();
|
||||
setCurrentStateNode(rootModelNode());
|
||||
resetPuppet();
|
||||
setCurrentStateNode(currentStateNode);
|
||||
}
|
||||
|
||||
void FormEditorView::addOrRemoveFormEditorItem(const ModelNode &node)
|
||||
|
||||
@@ -180,7 +180,7 @@ const QStringList &ItemLibraryAssetsModel::supportedVideoSuffixes()
|
||||
const QStringList &ItemLibraryAssetsModel::supportedTexture3DSuffixes()
|
||||
{
|
||||
// These are file types only supported by 3D textures
|
||||
static QStringList retList {"*.hdr"};
|
||||
static QStringList retList {"*.hdr", "*.ktx"};
|
||||
return retList;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,22 @@
|
||||
#include <QDirIterator>
|
||||
#include <qmlmodelnodeproxy.h>
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
static QString s_lastBrowserPath;
|
||||
|
||||
FileResourcesModel::FileResourcesModel(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_filter(QLatin1String("(*.*)"))
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
{
|
||||
connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged,
|
||||
this, &FileResourcesModel::refreshModel);
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(
|
||||
QmlDesigner::DocumentManager::currentFilePath());
|
||||
|
||||
if (project) {
|
||||
connect(project, &ProjectExplorer::Project::fileListChanged,
|
||||
this, &FileResourcesModel::refreshModel);
|
||||
}
|
||||
}
|
||||
|
||||
void FileResourcesModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
||||
@@ -195,12 +202,7 @@ bool filterMetaIcons(const QString &fileName)
|
||||
void FileResourcesModel::setupModel()
|
||||
{
|
||||
m_dirPath = QDir(m_path.toLocalFile());
|
||||
|
||||
refreshModel();
|
||||
|
||||
m_fileSystemWatcher->removeDirectories(m_fileSystemWatcher->directories());
|
||||
m_fileSystemWatcher->addDirectory(m_dirPath.absolutePath(),
|
||||
Utils::FileSystemWatcher::WatchAllChanges);
|
||||
}
|
||||
|
||||
void FileResourcesModel::refreshModel()
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
|
||||
#include <qmlitemnode.h>
|
||||
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
@@ -87,7 +85,6 @@ private:
|
||||
QString m_lastResourcePath;
|
||||
QStringList m_fullPathModel;
|
||||
QStringList m_fileNameModel;
|
||||
Utils::FileSystemWatcher *m_fileSystemWatcher;
|
||||
};
|
||||
|
||||
QML_DECLARE_TYPE(FileResourcesModel)
|
||||
|
||||
@@ -300,6 +300,44 @@ TimelineWidget *TimelineView::widget() const
|
||||
return m_timelineWidget;
|
||||
}
|
||||
|
||||
QList<QmlModelState> getAllStates(TimelineView* view)
|
||||
{
|
||||
QmlVisualNode visNode(view->rootModelNode());
|
||||
if (visNode.isValid()) {
|
||||
return visNode.states().allStates();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QString getStateName(TimelineView* view, bool& enableInBaseState)
|
||||
{
|
||||
QString currentStateName;
|
||||
if (QmlModelState state = view->currentState(); state.isValid()) {
|
||||
if (!state.isBaseState()) {
|
||||
enableInBaseState = false;
|
||||
return state.name();
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void enableInCurrentState(
|
||||
TimelineView* view, const QString& stateName,
|
||||
const ModelNode& node, const PropertyName& propertyName)
|
||||
{
|
||||
if (!stateName.isEmpty()) {
|
||||
for (auto& state : getAllStates(view)) {
|
||||
if (state.isValid()) {
|
||||
QmlPropertyChanges propertyChanges(state.propertyChanges(node));
|
||||
if (state.name() == stateName)
|
||||
propertyChanges.modelNode().variantProperty(propertyName).setValue(true);
|
||||
else
|
||||
propertyChanges.modelNode().variantProperty(propertyName).setValue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QmlTimeline TimelineView::addNewTimeline()
|
||||
{
|
||||
const TypeName timelineType = "QtQuick.Timeline.Timeline";
|
||||
@@ -322,6 +360,7 @@ const QmlTimeline TimelineView::addNewTimeline()
|
||||
|
||||
executeInTransaction("TimelineView::addNewTimeline", [=, &timelineNode]() {
|
||||
bool hasTimelines = getTimelines().isEmpty();
|
||||
QString currentStateName = getStateName(this, hasTimelines);
|
||||
|
||||
timelineNode = createModelNode(timelineType,
|
||||
metaInfo.majorVersion(),
|
||||
@@ -333,6 +372,8 @@ const QmlTimeline TimelineView::addNewTimeline()
|
||||
timelineNode.variantProperty("enabled").setValue(hasTimelines);
|
||||
|
||||
rootModelNode().defaultNodeListProperty().reparentHere(timelineNode);
|
||||
|
||||
enableInCurrentState(this, currentStateName, timelineNode, "enabled");
|
||||
});
|
||||
|
||||
return QmlTimeline(timelineNode);
|
||||
@@ -353,6 +394,9 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline)
|
||||
ModelNode animationNode;
|
||||
|
||||
executeInTransaction("TimelineView::addAnimation", [=, &animationNode]() {
|
||||
bool hasAnimations = getAnimations(timeline).isEmpty();
|
||||
QString currentStateName = getStateName(this, hasAnimations);
|
||||
|
||||
animationNode = createModelNode(animationType,
|
||||
metaInfo.majorVersion(),
|
||||
metaInfo.minorVersion());
|
||||
@@ -364,12 +408,14 @@ ModelNode TimelineView::addAnimation(QmlTimeline timeline)
|
||||
|
||||
animationNode.variantProperty("loops").setValue(1);
|
||||
|
||||
animationNode.variantProperty("running").setValue(getAnimations(timeline).isEmpty());
|
||||
animationNode.variantProperty("running").setValue(hasAnimations);
|
||||
|
||||
timeline.modelNode().nodeListProperty("animations").reparentHere(animationNode);
|
||||
|
||||
if (timeline.modelNode().hasProperty("currentFrame"))
|
||||
timeline.modelNode().removeProperty("currentFrame");
|
||||
|
||||
enableInCurrentState(this, currentStateName, animationNode, "running");
|
||||
});
|
||||
|
||||
return animationNode;
|
||||
|
||||
@@ -568,11 +568,20 @@ void TimelineWidget::setupScrollbar(int min, int max, int current)
|
||||
|
||||
void TimelineWidget::setTimelineId(const QString &id)
|
||||
{
|
||||
auto currentState = m_timelineView->currentState();
|
||||
auto timelineOfState = m_timelineView->timelineForState(currentState.modelNode());
|
||||
|
||||
bool active = false;
|
||||
if (auto node = timelineOfState.modelNode(); node.isValid())
|
||||
active = node.id() == id;
|
||||
|
||||
const bool empty = m_timelineView->getTimelines().isEmpty();
|
||||
setTimelineActive(!empty);
|
||||
if (m_timelineView->isAttached() && !empty) {
|
||||
m_toolbar->setCurrentTimeline(m_timelineView->modelNodeForId(id));
|
||||
m_toolbar->setCurrentState(m_timelineView->currentState().name());
|
||||
const bool valid = active && !empty;
|
||||
|
||||
setTimelineActive(valid);
|
||||
if (m_timelineView->isAttached() && valid) {
|
||||
m_toolbar->setCurrentTimeline(timelineOfState);
|
||||
m_toolbar->setCurrentState(currentState.name());
|
||||
} else {
|
||||
m_toolbar->setCurrentTimeline({});
|
||||
m_toolbar->setCurrentState({});
|
||||
|
||||
@@ -92,7 +92,10 @@ SOURCES += $$PWD/model/abstractview.cpp \
|
||||
$$PWD/imagecache/synchronousimagecache.cpp \
|
||||
$$PWD/imagecache/imagecacheconnectionmanager.cpp \
|
||||
$$PWD/imagecache/imagecachegenerator.cpp \
|
||||
$$PWD/imagecache/timestampprovider.cpp
|
||||
$$PWD/imagecache/timestampprovider.cpp \
|
||||
$$PWD/imagecache/explicitimagecacheimageprovider.cpp \
|
||||
$$PWD/imagecache/asynchronousimagefactory.cpp \
|
||||
$$PWD/imagecache/asynchronousexplicitimagecache.cpp
|
||||
|
||||
|
||||
HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
||||
@@ -185,7 +188,10 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \
|
||||
$$PWD/imagecache/imagecachegenerator.h \
|
||||
$$PWD/imagecache/imagecachestorage.h \
|
||||
$$PWD/imagecache/timestampprovider.h \
|
||||
$$PWD/imagecache/timestampproviderinterface.h
|
||||
$$PWD/imagecache/timestampproviderinterface.h \
|
||||
$$PWD/imagecache/explicitimagecacheimageprovider.h \
|
||||
$$PWD/imagecache/asynchronousimagefactory.h \
|
||||
$$PWD/include/asynchronousexplicitimagecache.h
|
||||
|
||||
|
||||
FORMS += \
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "asynchronousexplicitimagecache.h"
|
||||
|
||||
#include "imagecachestorage.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
AsynchronousExplicitImageCache::AsynchronousExplicitImageCache(ImageCacheStorageInterface &storage)
|
||||
: m_storage(storage)
|
||||
{
|
||||
m_backgroundThread = std::thread{[this] {
|
||||
while (isRunning()) {
|
||||
if (auto entry = getEntry(); entry) {
|
||||
request(entry->name,
|
||||
entry->extraId,
|
||||
entry->requestType,
|
||||
std::move(entry->captureCallback),
|
||||
std::move(entry->abortCallback),
|
||||
m_storage);
|
||||
}
|
||||
|
||||
waitForEntries();
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
AsynchronousExplicitImageCache::~AsynchronousExplicitImageCache()
|
||||
{
|
||||
clean();
|
||||
wait();
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::request(Utils::SmallStringView name,
|
||||
Utils::SmallStringView extraId,
|
||||
AsynchronousExplicitImageCache::RequestType requestType,
|
||||
ImageCache::CaptureImageCallback captureCallback,
|
||||
ImageCache::AbortCallback abortCallback,
|
||||
ImageCacheStorageInterface &storage)
|
||||
{
|
||||
const auto id = extraId.empty() ? Utils::PathString{name}
|
||||
: Utils::PathString::join({name, "+", extraId});
|
||||
|
||||
const auto entry = requestType == RequestType::Image
|
||||
? storage.fetchImage(id, Sqlite::TimeStamp{})
|
||||
: storage.fetchSmallImage(id, Sqlite::TimeStamp{});
|
||||
|
||||
if (entry && !entry->isNull())
|
||||
captureCallback(*entry);
|
||||
else
|
||||
abortCallback(ImageCache::AbortReason::Failed);
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::wait()
|
||||
{
|
||||
stopThread();
|
||||
m_condition.notify_all();
|
||||
if (m_backgroundThread.joinable())
|
||||
m_backgroundThread.join();
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::requestImage(Utils::PathString name,
|
||||
ImageCache::CaptureImageCallback captureCallback,
|
||||
ImageCache::AbortCallback abortCallback,
|
||||
Utils::SmallString extraId)
|
||||
{
|
||||
addEntry(std::move(name),
|
||||
std::move(extraId),
|
||||
std::move(captureCallback),
|
||||
std::move(abortCallback),
|
||||
RequestType::Image);
|
||||
m_condition.notify_all();
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::requestSmallImage(Utils::PathString name,
|
||||
ImageCache::CaptureImageCallback captureCallback,
|
||||
ImageCache::AbortCallback abortCallback,
|
||||
Utils::SmallString extraId)
|
||||
{
|
||||
addEntry(std::move(name),
|
||||
std::move(extraId),
|
||||
std::move(captureCallback),
|
||||
std::move(abortCallback),
|
||||
RequestType::SmallImage);
|
||||
m_condition.notify_all();
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::clean()
|
||||
{
|
||||
clearEntries();
|
||||
}
|
||||
|
||||
std::optional<AsynchronousExplicitImageCache::RequestEntry> AsynchronousExplicitImageCache::getEntry()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
if (m_requestEntries.empty())
|
||||
return {};
|
||||
|
||||
RequestEntry entry = m_requestEntries.front();
|
||||
m_requestEntries.pop_front();
|
||||
|
||||
return {entry};
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::addEntry(Utils::PathString &&name,
|
||||
Utils::SmallString &&extraId,
|
||||
ImageCache::CaptureImageCallback &&captureCallback,
|
||||
ImageCache::AbortCallback &&abortCallback,
|
||||
RequestType requestType)
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
m_requestEntries.emplace_back(std::move(name),
|
||||
std::move(extraId),
|
||||
std::move(captureCallback),
|
||||
std::move(abortCallback),
|
||||
requestType);
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::clearEntries()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
for (RequestEntry &entry : m_requestEntries)
|
||||
entry.abortCallback(ImageCache::AbortReason::Abort);
|
||||
m_requestEntries.clear();
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::waitForEntries()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
if (m_requestEntries.empty())
|
||||
m_condition.wait(lock, [&] { return m_requestEntries.size() || m_finishing; });
|
||||
}
|
||||
|
||||
void AsynchronousExplicitImageCache::stopThread()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
m_finishing = true;
|
||||
}
|
||||
|
||||
bool AsynchronousExplicitImageCache::isRunning()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
return !m_finishing || m_requestEntries.size();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -42,13 +42,13 @@ AsynchronousImageCache::AsynchronousImageCache(ImageCacheStorageInterface &stora
|
||||
{
|
||||
m_backgroundThread = std::thread{[this] {
|
||||
while (isRunning()) {
|
||||
if (auto [hasEntry, entry] = getEntry(); hasEntry) {
|
||||
request(entry.name,
|
||||
entry.extraId,
|
||||
entry.requestType,
|
||||
std::move(entry.captureCallback),
|
||||
std::move(entry.abortCallback),
|
||||
std::move(entry.auxiliaryData),
|
||||
if (auto entry = getEntry(); entry) {
|
||||
request(entry->name,
|
||||
entry->extraId,
|
||||
entry->requestType,
|
||||
std::move(entry->captureCallback),
|
||||
std::move(entry->abortCallback),
|
||||
std::move(entry->auxiliaryData),
|
||||
m_storage,
|
||||
m_generator,
|
||||
m_timeStampProvider);
|
||||
@@ -82,11 +82,11 @@ void AsynchronousImageCache::request(Utils::SmallStringView name,
|
||||
const auto entry = requestType == RequestType::Image ? storage.fetchImage(id, timeStamp)
|
||||
: storage.fetchSmallImage(id, timeStamp);
|
||||
|
||||
if (entry.hasEntry) {
|
||||
if (entry.image.isNull())
|
||||
if (entry) {
|
||||
if (entry->isNull())
|
||||
abortCallback(ImageCache::AbortReason::Failed);
|
||||
else
|
||||
captureCallback(entry.image);
|
||||
captureCallback(*entry);
|
||||
} else {
|
||||
auto callback = [captureCallback = std::move(captureCallback),
|
||||
requestType](const QImage &image, const QImage &smallImage) {
|
||||
@@ -145,17 +145,17 @@ void AsynchronousImageCache::clean()
|
||||
m_generator.clean();
|
||||
}
|
||||
|
||||
std::tuple<bool, AsynchronousImageCache::Entry> AsynchronousImageCache::getEntry()
|
||||
std::optional<AsynchronousImageCache::Entry> AsynchronousImageCache::getEntry()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
if (m_entries.empty())
|
||||
return {false, Entry{}};
|
||||
return {};
|
||||
|
||||
Entry entry = m_entries.front();
|
||||
m_entries.pop_front();
|
||||
|
||||
return {true, entry};
|
||||
return {entry};
|
||||
}
|
||||
|
||||
void AsynchronousImageCache::addEntry(Utils::PathString &&name,
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "asynchronousimagefactory.h"
|
||||
|
||||
#include "imagecachegenerator.h"
|
||||
#include "imagecachestorage.h"
|
||||
#include "timestampprovider.h"
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
AsynchronousImageFactory::AsynchronousImageFactory(ImageCacheStorageInterface &storage,
|
||||
ImageCacheGeneratorInterface &generator,
|
||||
TimeStampProviderInterface &timeStampProvider)
|
||||
: m_storage(storage)
|
||||
, m_generator(generator)
|
||||
, m_timeStampProvider(timeStampProvider)
|
||||
{
|
||||
m_backgroundThread = std::thread{[this] {
|
||||
while (isRunning()) {
|
||||
if (auto entry = getEntry(); entry) {
|
||||
request(entry->name,
|
||||
entry->extraId,
|
||||
std::move(entry->auxiliaryData),
|
||||
m_storage,
|
||||
m_generator,
|
||||
m_timeStampProvider);
|
||||
}
|
||||
|
||||
waitForEntries();
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
AsynchronousImageFactory::~AsynchronousImageFactory()
|
||||
{
|
||||
clean();
|
||||
wait();
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::generate(Utils::PathString name,
|
||||
Utils::SmallString extraId,
|
||||
ImageCache::AuxiliaryData auxiliaryData)
|
||||
{
|
||||
addEntry(std::move(name), std::move(extraId), std::move(auxiliaryData));
|
||||
m_condition.notify_all();
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::addEntry(Utils::PathString &&name,
|
||||
Utils::SmallString &&extraId,
|
||||
ImageCache::AuxiliaryData &&auxiliaryData)
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
m_entries.emplace_back(std::move(name), std::move(extraId), std::move(auxiliaryData));
|
||||
}
|
||||
|
||||
bool AsynchronousImageFactory::isRunning()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
return !m_finishing || m_entries.size();
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::waitForEntries()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
if (m_entries.empty())
|
||||
m_condition.wait(lock, [&] { return m_entries.size() || m_finishing; });
|
||||
}
|
||||
|
||||
std::optional<AsynchronousImageFactory::Entry> AsynchronousImageFactory::getEntry()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
|
||||
if (m_entries.empty())
|
||||
return {};
|
||||
|
||||
Entry entry = m_entries.front();
|
||||
m_entries.pop_front();
|
||||
|
||||
return {entry};
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::request(Utils::SmallStringView name,
|
||||
Utils::SmallStringView extraId,
|
||||
ImageCache::AuxiliaryData auxiliaryData,
|
||||
ImageCacheStorageInterface &storage,
|
||||
ImageCacheGeneratorInterface &generator,
|
||||
TimeStampProviderInterface &timeStampProvider)
|
||||
{
|
||||
const auto id = extraId.empty() ? Utils::PathString{name}
|
||||
: Utils::PathString::join({name, "+", extraId});
|
||||
|
||||
const auto currentModifiedTime = timeStampProvider.timeStamp(name);
|
||||
const auto storageModifiedTime = storage.fetchModifiedImageTime(id);
|
||||
|
||||
if (currentModifiedTime != storageModifiedTime) {
|
||||
generator.generateImage(name,
|
||||
extraId,
|
||||
currentModifiedTime,
|
||||
ImageCache::CaptureImageWithSmallImageCallback{},
|
||||
ImageCache::AbortCallback{},
|
||||
std::move(auxiliaryData));
|
||||
}
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::clean()
|
||||
{
|
||||
clearEntries();
|
||||
m_generator.clean();
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::wait()
|
||||
{
|
||||
stopThread();
|
||||
m_condition.notify_all();
|
||||
if (m_backgroundThread.joinable())
|
||||
m_backgroundThread.join();
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::clearEntries()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
m_entries.clear();
|
||||
}
|
||||
|
||||
void AsynchronousImageFactory::stopThread()
|
||||
{
|
||||
std::unique_lock lock{m_mutex};
|
||||
m_finishing = true;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,103 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imagecacheauxiliarydata.h"
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class TimeStampProviderInterface;
|
||||
class ImageCacheStorageInterface;
|
||||
class ImageCacheGeneratorInterface;
|
||||
class ImageCacheCollectorInterface;
|
||||
|
||||
class AsynchronousImageFactory
|
||||
{
|
||||
public:
|
||||
AsynchronousImageFactory(ImageCacheStorageInterface &storage,
|
||||
ImageCacheGeneratorInterface &generator,
|
||||
TimeStampProviderInterface &timeStampProvider);
|
||||
|
||||
~AsynchronousImageFactory();
|
||||
|
||||
void generate(Utils::PathString name,
|
||||
Utils::SmallString extraId = {},
|
||||
ImageCache::AuxiliaryData auxiliaryData = {});
|
||||
void clean();
|
||||
|
||||
private:
|
||||
struct Entry
|
||||
{
|
||||
Entry() = default;
|
||||
Entry(Utils::PathString name,
|
||||
Utils::SmallString extraId,
|
||||
ImageCache::AuxiliaryData &&auxiliaryData)
|
||||
: name{std::move(name)}
|
||||
, extraId{std::move(extraId)}
|
||||
, auxiliaryData{std::move(auxiliaryData)}
|
||||
{}
|
||||
|
||||
Utils::PathString name;
|
||||
Utils::SmallString extraId;
|
||||
ImageCache::AuxiliaryData auxiliaryData;
|
||||
};
|
||||
|
||||
void addEntry(Utils::PathString &&name,
|
||||
Utils::SmallString &&extraId,
|
||||
ImageCache::AuxiliaryData &&auxiliaryData);
|
||||
bool isRunning();
|
||||
void waitForEntries();
|
||||
std::optional<Entry> getEntry();
|
||||
void request(Utils::SmallStringView name,
|
||||
Utils::SmallStringView extraId,
|
||||
ImageCache::AuxiliaryData auxiliaryData,
|
||||
ImageCacheStorageInterface &storage,
|
||||
ImageCacheGeneratorInterface &generator,
|
||||
TimeStampProviderInterface &timeStampProvider);
|
||||
void wait();
|
||||
void clearEntries();
|
||||
void stopThread();
|
||||
|
||||
private:
|
||||
std::deque<Entry> m_entries;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_condition;
|
||||
std::thread m_backgroundThread;
|
||||
ImageCacheStorageInterface &m_storage;
|
||||
ImageCacheGeneratorInterface &m_generator;
|
||||
TimeStampProviderInterface &m_timeStampProvider;
|
||||
bool m_finishing{false};
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "explicitimagecacheimageprovider.h"
|
||||
|
||||
#include <asynchronousexplicitimagecache.h>
|
||||
|
||||
#include <QMetaObject>
|
||||
#include <QQuickImageResponse>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ImageRespose : public QQuickImageResponse
|
||||
{
|
||||
public:
|
||||
ImageRespose(const QImage &defaultImage)
|
||||
: m_image(defaultImage)
|
||||
{}
|
||||
|
||||
QQuickTextureFactory *textureFactory() const override
|
||||
{
|
||||
return QQuickTextureFactory::textureFactoryForImage(m_image);
|
||||
}
|
||||
|
||||
void setImage(const QImage &image)
|
||||
{
|
||||
m_image = image;
|
||||
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void abort() { emit finished(); }
|
||||
|
||||
private:
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
QQuickImageResponse *ExplicitImageCacheImageProvider::requestImageResponse(const QString &id,
|
||||
const QSize &)
|
||||
{
|
||||
auto response = std::make_unique<ImageRespose>(m_defaultImage);
|
||||
|
||||
m_cache.requestImage(
|
||||
id,
|
||||
[response = QPointer<ImageRespose>(response.get())](const QImage &image) {
|
||||
QMetaObject::invokeMethod(
|
||||
response,
|
||||
[response, image] {
|
||||
if (response)
|
||||
response->setImage(image);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
},
|
||||
[response = QPointer<ImageRespose>(response.get())](ImageCache::AbortReason abortReason) {
|
||||
QMetaObject::invokeMethod(
|
||||
response,
|
||||
[response, abortReason] {
|
||||
switch (abortReason) {
|
||||
case ImageCache::AbortReason::Failed:
|
||||
if (response)
|
||||
response->abort();
|
||||
break;
|
||||
case ImageCache::AbortReason::Abort:
|
||||
response->cancel();
|
||||
break;
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
});
|
||||
|
||||
return response.release();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||