forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/qds/dev'
Change-Id: Id242ab4ca485527defdcc1555d204e12e50ddb7a
This commit is contained in:
@@ -113,6 +113,6 @@ SpacesInContainerLiterals: false
|
|||||||
SpacesInCStyleCastParentheses: false
|
SpacesInCStyleCastParentheses: false
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
Standard: c++11
|
Standard: c++17
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
@@ -36,8 +36,6 @@ qtc_link_with_qt()
|
|||||||
|
|
||||||
option(WITH_TESTS "Build Tests" ${ENV_QTC_WITH_TESTS})
|
option(WITH_TESTS "Build Tests" ${ENV_QTC_WITH_TESTS})
|
||||||
add_feature_info("Build tests" ${WITH_TESTS} "")
|
add_feature_info("Build tests" ${WITH_TESTS} "")
|
||||||
option(WITH_QMLDESIGNER "Build QmlDesigner" ${ENV_QTC_WITH_QMLDESIGNER})
|
|
||||||
add_feature_info("Build QmlDesigner and related code" ${WITH_QMLDESIGNER} "")
|
|
||||||
option(WITH_DEBUG_CMAKE "Enabled CMake project debugging functionality" OFF)
|
option(WITH_DEBUG_CMAKE "Enabled CMake project debugging functionality" OFF)
|
||||||
option(SHOW_BUILD_DATE "Show build date in about dialog" OFF)
|
option(SHOW_BUILD_DATE "Show build date in about dialog" OFF)
|
||||||
option(WITH_SANITIZE "Build with sanitizer enabled" OFF)
|
option(WITH_SANITIZE "Build with sanitizer enabled" OFF)
|
||||||
@@ -73,6 +71,14 @@ find_package(Qt6
|
|||||||
COMPONENTS Concurrent Core Gui Network PrintSupport Qml Sql Widgets Xml Core5Compat ${QT_TEST_COMPONENT}
|
COMPONENTS Concurrent Core Gui Network PrintSupport Qml Sql Widgets Xml Core5Compat ${QT_TEST_COMPONENT}
|
||||||
REQUIRED
|
REQUIRED
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (Qt6_VERSION VERSION_GREATER_EQUAL 6.4.3)
|
||||||
|
option(WITH_QMLDESIGNER "Build QmlDesigner" ${ENV_QTC_WITH_QMLDESIGNER})
|
||||||
|
else()
|
||||||
|
option(WITH_QMLDESIGNER "Build QmlDesigner" OFF)
|
||||||
|
endif()
|
||||||
|
add_feature_info("Build QmlDesigner and related code (only if Qt is 6.4.3 or newer)" ${WITH_QMLDESIGNER} "")
|
||||||
|
|
||||||
# hack for Qbs which still supports Qt5 and Qt6
|
# hack for Qbs which still supports Qt5 and Qt6
|
||||||
if (TARGET Qt6::Core5CompatPrivate)
|
if (TARGET Qt6::Core5CompatPrivate)
|
||||||
if (CMAKE_VERSION VERSION_LESS 3.18)
|
if (CMAKE_VERSION VERSION_LESS 3.18)
|
||||||
|
@@ -423,11 +423,11 @@ we thank the authors who made this possible:
|
|||||||
committee draft. It is compatible with C++11, but will use newer language
|
committee draft. It is compatible with C++11, but will use newer language
|
||||||
features if they are available.
|
features if they are available.
|
||||||
|
|
||||||
https://github.com/tcbrindle/span
|
https://github.com/martinmoene/span-lite
|
||||||
|
|
||||||
QtCreator/src/libs/3rdparty/span
|
QtCreator/src/libs/3rdparty/span
|
||||||
|
|
||||||
Copyright Tristan Brindle, 2018
|
Copyright 2018-2021 Martin Moene
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||||
|
@@ -125,7 +125,7 @@ endfunction()
|
|||||||
function(add_qtc_library name)
|
function(add_qtc_library name)
|
||||||
cmake_parse_arguments(_arg "STATIC;OBJECT;SHARED;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;FEATURE_INFO;SKIP_PCH;EXCLUDE_FROM_INSTALL"
|
cmake_parse_arguments(_arg "STATIC;OBJECT;SHARED;SKIP_TRANSLATION;ALLOW_ASCII_CASTS;FEATURE_INFO;SKIP_PCH;EXCLUDE_FROM_INSTALL"
|
||||||
"DESTINATION;COMPONENT;SOURCES_PREFIX;BUILD_DEFAULT"
|
"DESTINATION;COMPONENT;SOURCES_PREFIX;BUILD_DEFAULT"
|
||||||
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN}
|
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES" ${ARGN}
|
||||||
)
|
)
|
||||||
|
|
||||||
get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS})
|
get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS})
|
||||||
@@ -198,7 +198,9 @@ function(add_qtc_library name)
|
|||||||
SOURCES_PREFIX ${_arg_SOURCES_PREFIX}
|
SOURCES_PREFIX ${_arg_SOURCES_PREFIX}
|
||||||
SOURCES ${_arg_SOURCES}
|
SOURCES ${_arg_SOURCES}
|
||||||
INCLUDES ${_arg_INCLUDES}
|
INCLUDES ${_arg_INCLUDES}
|
||||||
|
SYSTEM_INCLUDES ${_arg_SYTEM_INCLUDES}
|
||||||
PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES}
|
PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES}
|
||||||
|
PUBLIC_SYSTEM_INCLUDES ${_arg_PUBLIC_SYSTEM_INCLUDES}
|
||||||
DEFINES ${default_defines_copy} ${_arg_DEFINES} ${TEST_DEFINES}
|
DEFINES ${default_defines_copy} ${_arg_DEFINES} ${TEST_DEFINES}
|
||||||
PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES}
|
PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES}
|
||||||
DEPENDS ${_arg_DEPENDS} ${IMPLICIT_DEPENDS}
|
DEPENDS ${_arg_DEPENDS} ${IMPLICIT_DEPENDS}
|
||||||
@@ -322,7 +324,7 @@ function(add_qtc_plugin target_name)
|
|||||||
cmake_parse_arguments(_arg
|
cmake_parse_arguments(_arg
|
||||||
"SKIP_INSTALL;INTERNAL_ONLY;SKIP_TRANSLATION;EXPORT;SKIP_PCH"
|
"SKIP_INSTALL;INTERNAL_ONLY;SKIP_TRANSLATION;EXPORT;SKIP_PCH"
|
||||||
"VERSION;COMPAT_VERSION;PLUGIN_PATH;PLUGIN_NAME;OUTPUT_NAME;BUILD_DEFAULT;PLUGIN_CLASS"
|
"VERSION;COMPAT_VERSION;PLUGIN_PATH;PLUGIN_NAME;OUTPUT_NAME;BUILD_DEFAULT;PLUGIN_CLASS"
|
||||||
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;PLUGIN_TEST_DEPENDS;PROPERTIES"
|
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PLUGIN_DEPENDS;PLUGIN_RECOMMENDS;PLUGIN_TEST_DEPENDS;PROPERTIES"
|
||||||
${ARGN}
|
${ARGN}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -465,7 +467,9 @@ function(add_qtc_plugin target_name)
|
|||||||
|
|
||||||
extend_qtc_target(${target_name}
|
extend_qtc_target(${target_name}
|
||||||
INCLUDES ${_arg_INCLUDES}
|
INCLUDES ${_arg_INCLUDES}
|
||||||
|
SYSTEM_INCLUDES ${_arg_SYSTEM_INCLUDES}
|
||||||
PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES}
|
PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES}
|
||||||
|
PUBLIC_SYSTEM_INCLUDES ${_arg_PUBLIC_SYSTEM_INCLUDES}
|
||||||
DEFINES ${DEFAULT_DEFINES} ${_arg_DEFINES} ${TEST_DEFINES}
|
DEFINES ${DEFAULT_DEFINES} ${_arg_DEFINES} ${TEST_DEFINES}
|
||||||
PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES}
|
PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES}
|
||||||
DEPENDS ${_arg_DEPENDS} ${_DEP_PLUGINS} ${IMPLICIT_DEPENDS}
|
DEPENDS ${_arg_DEPENDS} ${_DEP_PLUGINS} ${IMPLICIT_DEPENDS}
|
||||||
|
@@ -244,13 +244,13 @@ function(update_resource_files_list sources)
|
|||||||
endforeach()
|
endforeach()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(set_public_includes target includes)
|
function(set_public_includes target includes system)
|
||||||
foreach(inc_dir IN LISTS includes)
|
foreach(inc_dir IN LISTS includes)
|
||||||
if (NOT IS_ABSOLUTE ${inc_dir})
|
if (NOT IS_ABSOLUTE ${inc_dir})
|
||||||
set(inc_dir "${CMAKE_CURRENT_SOURCE_DIR}/${inc_dir}")
|
set(inc_dir "${CMAKE_CURRENT_SOURCE_DIR}/${inc_dir}")
|
||||||
endif()
|
endif()
|
||||||
file(RELATIVE_PATH include_dir_relative_path ${PROJECT_SOURCE_DIR} ${inc_dir})
|
file(RELATIVE_PATH include_dir_relative_path ${PROJECT_SOURCE_DIR} ${inc_dir})
|
||||||
target_include_directories(${target} PUBLIC
|
target_include_directories(${target} ${system} PUBLIC
|
||||||
$<BUILD_INTERFACE:${inc_dir}>
|
$<BUILD_INTERFACE:${inc_dir}>
|
||||||
$<INSTALL_INTERFACE:${_IDE_HEADER_INSTALL_PATH}/${include_dir_relative_path}>
|
$<INSTALL_INTERFACE:${_IDE_HEADER_INSTALL_PATH}/${include_dir_relative_path}>
|
||||||
)
|
)
|
||||||
@@ -463,7 +463,7 @@ function(extend_qtc_target target_name)
|
|||||||
cmake_parse_arguments(_arg
|
cmake_parse_arguments(_arg
|
||||||
""
|
""
|
||||||
"SOURCES_PREFIX;SOURCES_PREFIX_FROM_TARGET;FEATURE_INFO"
|
"SOURCES_PREFIX;SOURCES_PREFIX_FROM_TARGET;FEATURE_INFO"
|
||||||
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;PUBLIC_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;SOURCES_PROPERTIES"
|
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;SOURCES_PROPERTIES"
|
||||||
${ARGN}
|
${ARGN}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -504,8 +504,10 @@ function(extend_qtc_target target_name)
|
|||||||
PUBLIC ${_arg_PUBLIC_DEFINES}
|
PUBLIC ${_arg_PUBLIC_DEFINES}
|
||||||
)
|
)
|
||||||
target_include_directories(${target_name} PRIVATE ${_arg_INCLUDES})
|
target_include_directories(${target_name} PRIVATE ${_arg_INCLUDES})
|
||||||
|
target_include_directories(${target_name} SYSTEM PRIVATE ${_arg_SYSTEM_INCLUDES})
|
||||||
|
|
||||||
set_public_includes(${target_name} "${_arg_PUBLIC_INCLUDES}")
|
set_public_includes(${target_name} "${_arg_PUBLIC_INCLUDES}" "")
|
||||||
|
set_public_includes(${target_name} "${_arg_PUBLIC_SYSTEM_INCLUDES}" "SYSTEM")
|
||||||
|
|
||||||
if (_arg_SOURCES_PREFIX)
|
if (_arg_SOURCES_PREFIX)
|
||||||
foreach(source IN LISTS _arg_SOURCES)
|
foreach(source IN LISTS _arg_SOURCES)
|
||||||
|
@@ -35,6 +35,8 @@ macro.QMLD = "Qt Quick Designer"
|
|||||||
macro.QQV = "Qt QML Viewer"
|
macro.QQV = "Qt QML Viewer"
|
||||||
macro.QSDK = "Qt"
|
macro.QSDK = "Qt"
|
||||||
macro.QUL = "Qt Quick Ultralite"
|
macro.QUL = "Qt Quick Ultralite"
|
||||||
|
macro.QOI = "Qt Online Installer"
|
||||||
|
macro.QMT = "Qt Maintenance Tool"
|
||||||
macro.qtcversion = $QTC_VERSION
|
macro.qtcversion = $QTC_VERSION
|
||||||
macro.param = "\\e"
|
macro.param = "\\e"
|
||||||
macro.raisedaster.HTML = "<sup>*</sup>"
|
macro.raisedaster.HTML = "<sup>*</sup>"
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
sources. Because the client has a local cache for package storage, you can
|
sources. Because the client has a local cache for package storage, you can
|
||||||
work offline, as long as no new packages are needed from remote servers.
|
work offline, as long as no new packages are needed from remote servers.
|
||||||
|
|
||||||
To use Conan, install it by using the Qt installer or the tools that
|
To use Conan, install it by using \QOI or the tools that
|
||||||
your operating system has. For example, on Windows, you can use the
|
your operating system has. For example, on Windows, you can use the
|
||||||
\c {choco install conan} or \c {pip install conan} command.
|
\c {choco install conan} or \c {pip install conan} command.
|
||||||
|
|
||||||
|
@@ -169,7 +169,7 @@
|
|||||||
\section2 Debugging Tools for Windows
|
\section2 Debugging Tools for Windows
|
||||||
|
|
||||||
To use the CDB debugger, install the \e {Debugging Tools for Windows} when
|
To use the CDB debugger, install the \e {Debugging Tools for Windows} when
|
||||||
you install \QC either by using the Qt Online Installer (in \uicontrol Qt
|
you install \QC either by using \QOI (in \uicontrol Qt
|
||||||
> \uicontrol Tools > \uicontrol {\QC}) or by using the stand-alone \QC
|
> \uicontrol Tools > \uicontrol {\QC}) or by using the stand-alone \QC
|
||||||
installation packages.
|
installation packages.
|
||||||
|
|
||||||
|
@@ -102,21 +102,13 @@
|
|||||||
|
|
||||||
\e{Windows}
|
\e{Windows}
|
||||||
|
|
||||||
Check whether \QC has been compiled with OpenGL/Desktop, or ANGLE as
|
By default Qt Quick uses Direct3D 11. If you have problems, try updating
|
||||||
a backend. The official binaries are always built with ANGLE (a library that
|
your graphics drivers or update your DirectX version. Run \c dxdiag.exe to
|
||||||
maps OpenGL ES API to DirectX).
|
check whether \e{Direct3D Acceleration} is indeed enabled.
|
||||||
|
|
||||||
\list
|
You can also try setting the \c QSG_RHI_BACKEND environment variable to
|
||||||
|
\c vulkan or \c opengl. See \l {Qt for Windows - Graphics Acceleration}
|
||||||
\li ANGLE backend: This requires a Windows version newer than Windows XP.
|
for details.
|
||||||
If you have problems, try updating your graphics drivers or update
|
|
||||||
your DirectX version. Run \c dxdiag.exe to check whether
|
|
||||||
\e{Direct3D Acceleration} is indeed enabled.
|
|
||||||
|
|
||||||
\li OpenGL backend: Make sure your graphics driver supports OpenGL 2.1 or
|
|
||||||
newer. Try to update your graphics driver.
|
|
||||||
|
|
||||||
\endlist
|
|
||||||
|
|
||||||
\e{Unix}
|
\e{Unix}
|
||||||
|
|
||||||
|
@@ -83,7 +83,7 @@
|
|||||||
|
|
||||||
The data is transmitted to the backend storage using an encrypted
|
The data is transmitted to the backend storage using an encrypted
|
||||||
connection. The storage is located in the same Heroku backend as the
|
connection. The storage is located in the same Heroku backend as the
|
||||||
Qt installer backend. Physically, data is stored in the Amazon cloud.
|
\QOI backend. Physically, data is stored in the Amazon cloud.
|
||||||
|
|
||||||
\section1 Specify telemetry settings
|
\section1 Specify telemetry settings
|
||||||
|
|
||||||
|
@@ -22,10 +22,10 @@
|
|||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
You must install the tool chain for building applications for the targeted
|
You must install the tool chain for building applications for the targeted
|
||||||
embedded platform on the development PC and use the Qt Maintenance Tool to
|
embedded platform on the development PC and use \QMT to
|
||||||
install Qt libraries that are built for the platform. You can then add a
|
install Qt libraries that are built for the platform. You can then add a
|
||||||
\l{glossary-buildandrun-kit}{kit} with the tool chain and the Qt version
|
\l{glossary-buildandrun-kit}{kit} with the tool chain and the Qt version
|
||||||
for the device's architecture. When possible, the Maintenance Tool creates
|
for the device's architecture. When possible, \QMT creates
|
||||||
suitable kits for you.
|
suitable kits for you.
|
||||||
|
|
||||||
You can connect embedded devices to the development PC to run, debug, and
|
You can connect embedded devices to the development PC to run, debug, and
|
||||||
|
@@ -54,7 +54,7 @@
|
|||||||
\section2 MCU Plugin
|
\section2 MCU Plugin
|
||||||
|
|
||||||
To be able to develop applications for MCUs, you need the MCU plugin.
|
To be able to develop applications for MCUs, you need the MCU plugin.
|
||||||
This plugin is enabled automatically by the Qt Installer when you
|
This plugin is enabled automatically by \QOI when you
|
||||||
install \QMCU.
|
install \QMCU.
|
||||||
|
|
||||||
\section2 Specifying MCU Settings
|
\section2 Specifying MCU Settings
|
||||||
|
@@ -376,7 +376,7 @@
|
|||||||
the C++20 committee draft. It is compatible with C++11, but will use
|
the C++20 committee draft. It is compatible with C++11, but will use
|
||||||
newer language features if they are available.
|
newer language features if they are available.
|
||||||
|
|
||||||
Copyright Tristan Brindle, 2018
|
Copyright 2018-2021 Martin Moene
|
||||||
|
|
||||||
Distributed under the \l {http://boost.org/LICENSE_1_0.txt}
|
Distributed under the \l {http://boost.org/LICENSE_1_0.txt}
|
||||||
{Boost Software License, Version 1.0}.
|
{Boost Software License, Version 1.0}.
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
|
|
||||||
The source code can be found here:
|
The source code can be found here:
|
||||||
\list
|
\list
|
||||||
\li \l{https://github.com/tcbrindle/span}
|
\li \l{https://github.com/martinmoene/span-lite}
|
||||||
\li QtCreator/src/libs/3rdparty/span
|
\li QtCreator/src/libs/3rdparty/span
|
||||||
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/span}
|
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/span}
|
||||||
\endlist
|
\endlist
|
||||||
@@ -394,180 +394,6 @@
|
|||||||
Roberto Raggi <roberto.raggi@gmail.com>\br
|
Roberto Raggi <roberto.raggi@gmail.com>\br
|
||||||
QtCreator/src/libs/3rdparty/cplusplus\br\br
|
QtCreator/src/libs/3rdparty/cplusplus\br\br
|
||||||
|
|
||||||
\li \b{ANGLE Library (Windows)}
|
|
||||||
|
|
||||||
Used on Windows to implement OpenGL ES on top of DirectX.
|
|
||||||
|
|
||||||
The source code of ANGLE is part of the Qt libraries. For more
|
|
||||||
information about the licenses used in Qt GUI, see
|
|
||||||
\l{https://doc.qt.io/qt-5.11/licenses-used-in-qt.html#qt-gui}{Qt GUI}.
|
|
||||||
|
|
||||||
\l{https://spdx.org/licenses/BSD-3-Clause.html}
|
|
||||||
{BSD 3-clause "New" or "Revised" License}
|
|
||||||
|
|
||||||
\badcode
|
|
||||||
Copyright (C) 2002-2013 The ANGLE Project Authors.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials provided
|
|
||||||
with the distribution.
|
|
||||||
|
|
||||||
Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
|
|
||||||
Ltd., nor the names of their contributors may be used to endorse
|
|
||||||
or promote products derived from this software without specific
|
|
||||||
prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\li \b{ANGLE Array Bounds Clamper for WebKit (Windows)}
|
|
||||||
|
|
||||||
Implements clamping of array indexing expressions during shader
|
|
||||||
translation.
|
|
||||||
|
|
||||||
Used on Windows to implement OpenGL ES on top of DirectX. Configure with
|
|
||||||
\c {-no-opengl}, or \c {-opengl desktop} to exclude.
|
|
||||||
|
|
||||||
The sources can be found in
|
|
||||||
\c qtbase/src/3rdparty/angle/src/third_party/compiler.
|
|
||||||
|
|
||||||
BSD 2-clause "Simplified" License.
|
|
||||||
|
|
||||||
\badcode
|
|
||||||
Copyright (C) 2012 Apple Inc. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
||||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\li \b{ANGLE: Murmurhash (Windows)}
|
|
||||||
|
|
||||||
Used on Windows to implement OpenGL ES on top of DirectX. Configure
|
|
||||||
with \c {-no-opengl}, or \c {-opengl desktop} to exclude.
|
|
||||||
|
|
||||||
The sources can be found in
|
|
||||||
\c qtbase/src/3rdparty/angle/src/third_party/murmurhash.
|
|
||||||
|
|
||||||
\badcode
|
|
||||||
MurmurHash3 was written by Austin Appleby, and is placed in the public
|
|
||||||
domain. The author hereby disclaims copyright to this source code.
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
Public Domain.
|
|
||||||
|
|
||||||
\li \b{ANGLE: Systeminfo (Windows)}
|
|
||||||
|
|
||||||
Used on Windows to implement OpenGL ES on top of DirectX. Configure
|
|
||||||
with \c {-no-opengl}, or \c {-opengl desktop} to exclude.
|
|
||||||
|
|
||||||
The sources can be found in
|
|
||||||
\c qtbase/src/3rdparty/angle/src/third_party/systeminfo.
|
|
||||||
|
|
||||||
BSD 2-clause "Simplified" License.
|
|
||||||
|
|
||||||
\badcode
|
|
||||||
Copyright (C) 2009 Apple Inc. All Rights Reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
|
||||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
||||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\li \b{ANGLE: trace_event (Windows)}
|
|
||||||
|
|
||||||
Used on Windows to implement OpenGL ES on top of DirectX. Configure
|
|
||||||
with \c {-no-opengl}, or \c {-opengl desktop} to exclude.
|
|
||||||
|
|
||||||
The sources can be found in
|
|
||||||
\c qtbase/src/3rdparty/angle/src/third_party/trace_event.
|
|
||||||
|
|
||||||
BSD 3-clause "New" or "Revised" License.
|
|
||||||
|
|
||||||
\badcode
|
|
||||||
Copyright 2013 The Chromium Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following disclaimer
|
|
||||||
in the documentation and/or other materials provided with the
|
|
||||||
distribution.
|
|
||||||
* Neither the name of Google Inc. nor the names of its
|
|
||||||
contributors may be used to endorse or promote products derived from
|
|
||||||
this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
\li \b{SQLite (version 3.8.10.2)}
|
\li \b{SQLite (version 3.8.10.2)}
|
||||||
|
|
||||||
SQLite is a C-language library that implements a small, fast,
|
SQLite is a C-language library that implements a small, fast,
|
||||||
@@ -586,14 +412,6 @@
|
|||||||
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/sqlite}
|
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/sqlite}
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\li \b{three.js}
|
|
||||||
|
|
||||||
Copyright (C) 2010-2015 three.js authors
|
|
||||||
|
|
||||||
MIT License.
|
|
||||||
|
|
||||||
share/qtcreator/templates/wizards/projects/qmake/qtcanvas3dapplication
|
|
||||||
|
|
||||||
\li \b{OpenSSL}
|
\li \b{OpenSSL}
|
||||||
|
|
||||||
The OpenSSL toolkit stays under a double license, i.e. both the conditions of
|
The OpenSSL toolkit stays under a double license, i.e. both the conditions of
|
||||||
|
@@ -34,13 +34,13 @@
|
|||||||
\section1 Checking Build and Run Settings
|
\section1 Checking Build and Run Settings
|
||||||
|
|
||||||
\QC is an integrated development environment (IDE) that you can use to
|
\QC is an integrated development environment (IDE) that you can use to
|
||||||
develop Qt applications. While you can use the Qt Installer to install \QC,
|
develop Qt applications. While you can use \QOI to install \QC,
|
||||||
the stand-alone \QC installer never installs Qt or any Qt tools, such as
|
the stand-alone \QC installer never installs Qt or any Qt tools, such as
|
||||||
qmake. To use \QC for Qt development, you also need to install a Qt version
|
qmake. To use \QC for Qt development, you also need to install a Qt version
|
||||||
and a compiler. If you update the compiler version later, you
|
and a compiler. If you update the compiler version later, you
|
||||||
can register it into \QC.
|
can register it into \QC.
|
||||||
|
|
||||||
The Qt Installer attempts to auto-detect compilers and Qt versions. If it
|
\QOI attempts to auto-detect compilers and Qt versions. If it
|
||||||
succeeds, the relevant kits will automatically become
|
succeeds, the relevant kits will automatically become
|
||||||
available in \QC. If it does not, you must add the kits yourself to tell
|
available in \QC. If it does not, you must add the kits yourself to tell
|
||||||
\QC where everything is.
|
\QC where everything is.
|
||||||
|
@@ -46,8 +46,8 @@
|
|||||||
\row
|
\row
|
||||||
\li \b {\l{Building and Running an Example}}
|
\li \b {\l{Building and Running an Example}}
|
||||||
|
|
||||||
To check that the \l{https://www.qt.io/download-qt-installer}
|
To check that \l{https://www.qt.io/download-qt-installer}
|
||||||
{Qt Online Installer} created \l{glossary-buildandrun-kit}
|
{\QOI} created \l{glossary-buildandrun-kit}
|
||||||
{build and run kits}, open an example application and run it.
|
{build and run kits}, open an example application and run it.
|
||||||
If you have not done so before, go to
|
If you have not done so before, go to
|
||||||
\l{Building and Running an Example}.
|
\l{Building and Running an Example}.
|
||||||
|
@@ -19,10 +19,10 @@
|
|||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
You must install the tool chain for building applications for the targeted
|
You must install the tool chain for building applications for the targeted
|
||||||
mobile platform on the development PC and use the Qt Maintenance Tool to
|
mobile platform on the development PC and use \QMT to
|
||||||
install Qt libraries that are built for the platform. You can then add a
|
install Qt libraries that are built for the platform. You can then add a
|
||||||
\l{glossary-buildandrun-kit}{kit} with the tool chain and the Qt version
|
\l{glossary-buildandrun-kit}{kit} with the tool chain and the Qt version
|
||||||
for the device's architecture. When possible, the Maintenance Tool creates
|
for the device's architecture. When possible, \QMT creates
|
||||||
suitable kits for you.
|
suitable kits for you.
|
||||||
|
|
||||||
You can connect mobile devices to the development PC and select the
|
You can connect mobile devices to the development PC and select the
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
specifies the compiler and other necessary tools for building an application
|
specifies the compiler and other necessary tools for building an application
|
||||||
for and running it on a particular platform.
|
for and running it on a particular platform.
|
||||||
|
|
||||||
\QC automatically detects the compilers that your system or the Qt Installer
|
\QC automatically detects the compilers that your system or \QOI
|
||||||
registers and lists them in \uicontrol Edit > \uicontrol Preferences >
|
registers and lists them in \uicontrol Edit > \uicontrol Preferences >
|
||||||
\uicontrol Kits > \uicontrol Compilers.
|
\uicontrol Kits > \uicontrol Compilers.
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
To remove invalid Qt versions, select \uicontrol {Clean Up}.
|
To remove invalid Qt versions, select \uicontrol {Clean Up}.
|
||||||
|
|
||||||
You can link to a Qt that the Qt Installer installed to
|
You can link to a Qt that \QOI installed to
|
||||||
automatically detect the installed Qt versions. However, you cannot link
|
automatically detect the installed Qt versions. However, you cannot link
|
||||||
to a Qt that the system installed with some other package
|
to a Qt that the system installed with some other package
|
||||||
manager, such as your Linux distribution, brew on \macos, or Chocolatey on
|
manager, such as your Linux distribution, brew on \macos, or Chocolatey on
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
output exist. When \QC complains about the installation of a self-built Qt
|
output exist. When \QC complains about the installation of a self-built Qt
|
||||||
version, try running \c {make install} in the build directory to actually
|
version, try running \c {make install} in the build directory to actually
|
||||||
install Qt into the configured location. If you installed Qt using the Qt
|
install Qt into the configured location. If you installed Qt using the Qt
|
||||||
Installer, run the Qt maintenance tool to check for updates or to reinstall
|
Installer, run \QMT to check for updates or to reinstall
|
||||||
the Qt version.
|
the Qt version.
|
||||||
|
|
||||||
\section1 Minimum Requirements
|
\section1 Minimum Requirements
|
||||||
|
@@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
\title Configuring Projects
|
\title Configuring Projects
|
||||||
|
|
||||||
When you install Qt for a target platform, such as Android or QNX, the
|
When you install Qt for a target platform, such as Android or QNX,
|
||||||
\l{https://www.qt.io/download-qt-installer}{Qt Online Installer}
|
\l{https://www.qt.io/download-qt-installer}{\QOI}
|
||||||
creates \l{glossary-buildandrun-kit}{kits} for the development
|
creates \l{glossary-buildandrun-kit}{kits} for the development
|
||||||
targets.
|
targets.
|
||||||
|
|
||||||
|
@@ -83,8 +83,8 @@
|
|||||||
|
|
||||||
\note If you have not installed the Qt Virtual Keyboard module when
|
\note If you have not installed the Qt Virtual Keyboard module when
|
||||||
you installed Qt, an error message will appear when you try to open
|
you installed Qt, an error message will appear when you try to open
|
||||||
\e Main.qml for editing. You can use the \l {Installing Qt}
|
\e Main.qml for editing. You can use \l {Installing Qt}
|
||||||
{Qt Maintenance Tool} to install Qt Virtual Keyboard.
|
{\QMT} to install Qt Virtual Keyboard.
|
||||||
|
|
||||||
\li Select \uicontrol Next to open the \uicontrol {Kit Selection}
|
\li Select \uicontrol Next to open the \uicontrol {Kit Selection}
|
||||||
dialog.
|
dialog.
|
||||||
|
@@ -119,6 +119,9 @@
|
|||||||
name of the main QML file in the Qt Quick UI project.
|
name of the main QML file in the Qt Quick UI project.
|
||||||
\li Select \uicontrol Build > \uicontrol Run to build and run your
|
\li Select \uicontrol Build > \uicontrol Run to build and run your
|
||||||
project.
|
project.
|
||||||
|
|
||||||
|
\note If you get error messages related to modules, perfom the steps
|
||||||
|
described in \l{Adding Qt Quick Designer Components to Qt Installations}.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
For example, if you copy the source files of the \e ProgressBar
|
For example, if you copy the source files of the \e ProgressBar
|
||||||
|
@@ -30,6 +30,11 @@
|
|||||||
You can use the \l{http://code.google.com/p/gerrit/}{Gerrit} code review
|
You can use the \l{http://code.google.com/p/gerrit/}{Gerrit} code review
|
||||||
tool for projects that use Git.
|
tool for projects that use Git.
|
||||||
|
|
||||||
|
\if defined(qtdesignstudio)
|
||||||
|
\include creator-vcs-options.qdocinc vcs options
|
||||||
|
\endif
|
||||||
|
|
||||||
|
\if defined(qtcreator)
|
||||||
\section1 Using Git for Windows
|
\section1 Using Git for Windows
|
||||||
|
|
||||||
If you configure Git for use with \c {git bash}, only, and use SSH
|
If you configure Git for use with \c {git bash}, only, and use SSH
|
||||||
@@ -48,6 +53,16 @@
|
|||||||
authorization works as it would with \c {git bash}.
|
authorization works as it would with \c {git bash}.
|
||||||
|
|
||||||
\image qtcreator-preferences-vcs-git.webp {Git preferences}
|
\image qtcreator-preferences-vcs-git.webp {Git preferences}
|
||||||
|
\endif
|
||||||
|
|
||||||
|
\section1 Initializing Git Repositories
|
||||||
|
|
||||||
|
To start controlling a project directory that is currently not under
|
||||||
|
version control, select \uicontrol Tools > \uicontrol Git >
|
||||||
|
\uicontrol {Create Repository}. \QC creates a new subdirectory named .git
|
||||||
|
that has all the necessary repository files. However, Git does not track
|
||||||
|
anything in the project yet, so you will need to create an initial commit to
|
||||||
|
start tracking the project files.
|
||||||
|
|
||||||
\section1 Working with the Current File
|
\section1 Working with the Current File
|
||||||
|
|
||||||
@@ -183,7 +198,7 @@
|
|||||||
|
|
||||||
\section2 Cleaning Projects
|
\section2 Cleaning Projects
|
||||||
|
|
||||||
To clean the working directory, select \uicontrol {Build Project} > \uicontrol {Clean}.
|
To clean the working directory, select \uicontrol {Clean Project}.
|
||||||
All files that are not under version control are displayed in
|
All files that are not under version control are displayed in
|
||||||
the \uicontrol {Clean Repository} dialog. Ignored files are deselected by
|
the \uicontrol {Clean Repository} dialog. Ignored files are deselected by
|
||||||
default. Select the files to delete, and then select \uicontrol Delete.
|
default. Select the files to delete, and then select \uicontrol Delete.
|
||||||
@@ -465,15 +480,6 @@
|
|||||||
\li Show the commit in the diff editor.
|
\li Show the commit in the diff editor.
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
\section1 Initializing Git Repositories
|
|
||||||
|
|
||||||
To start controlling a project directory that is currently not under
|
|
||||||
version control, select \uicontrol Tools > \uicontrol Git >
|
|
||||||
\uicontrol {Create Repository}. \QC creates a new subdirectory named .git
|
|
||||||
that has all the necessary repository files. However, Git does not track
|
|
||||||
anything in the project yet, so you will need to create an initial commit to
|
|
||||||
start tracking the project files.
|
|
||||||
|
|
||||||
\section1 Working with Remote Repositories
|
\section1 Working with Remote Repositories
|
||||||
|
|
||||||
To work with remote repositories, select the commands in \uicontrol Tools >
|
To work with remote repositories, select the commands in \uicontrol Tools >
|
||||||
|
@@ -39,7 +39,7 @@
|
|||||||
\section1 Setting Up the Development Environment
|
\section1 Setting Up the Development Environment
|
||||||
|
|
||||||
You need to install and configure Qt for WebAssembly and the tool chain for
|
You need to install and configure Qt for WebAssembly and the tool chain for
|
||||||
compiling to WebAssembly. The Qt Installer automatically adds a build and
|
compiling to WebAssembly. \QOI automatically adds a build and
|
||||||
run kit to \QC.
|
run kit to \QC.
|
||||||
|
|
||||||
\section2 Setting Up Qt for WebAssembly
|
\section2 Setting Up Qt for WebAssembly
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
To set up Qt for WebAssembly:
|
To set up Qt for WebAssembly:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
\li Use the Qt maintenance tool to install Qt for WebAssembly and, on
|
\li Use \QMT to install Qt for WebAssembly and, on
|
||||||
Windows, \MinGW (found in \uicontrol {Developer and Designer Tools}).
|
Windows, \MinGW (found in \uicontrol {Developer and Designer Tools}).
|
||||||
\li Check out a known-good Emscripten version supported by the Qt for
|
\li Check out a known-good Emscripten version supported by the Qt for
|
||||||
WebAssembly version that you installed, and install and activate
|
WebAssembly version that you installed, and install and activate
|
||||||
|
@@ -44,9 +44,9 @@
|
|||||||
When developing your plugin, point the \c {CMAKE_PREFIX_PATH} to the
|
When developing your plugin, point the \c {CMAKE_PREFIX_PATH} to the
|
||||||
installation location of \QC, or the \QC app on macOS.
|
installation location of \QC, or the \QC app on macOS.
|
||||||
|
|
||||||
Get prebuilt packages either from the
|
Get prebuilt packages either from
|
||||||
\l{https://download.qt.io/official_releases/online_installers/}
|
\l{https://download.qt.io/official_releases/online_installers/}
|
||||||
{Qt online installer}, or a standalone \QC installer either for a
|
{\QOI}, or a standalone \QC installer either for a
|
||||||
\l{https://download.qt.io/official_releases/qtcreator/}
|
\l{https://download.qt.io/official_releases/qtcreator/}
|
||||||
{released \QC version} or a \l{https://download.qt.io/snapshots/qtcreator/}
|
{released \QC version} or a \l{https://download.qt.io/snapshots/qtcreator/}
|
||||||
{development snapshot}.
|
{development snapshot}.
|
||||||
|
BIN
doc/qtdesignstudio/images/icons/snapping-3d-conf.png
Normal file
BIN
doc/qtdesignstudio/images/icons/snapping-3d-conf.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
BIN
doc/qtdesignstudio/images/icons/snapping-3d.png
Normal file
BIN
doc/qtdesignstudio/images/icons/snapping-3d.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 50 KiB |
BIN
doc/qtdesignstudio/images/qt-insight-view.png
Normal file
BIN
doc/qtdesignstudio/images/qt-insight-view.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
BIN
doc/qtdesignstudio/images/studio-preset-for-mcus.png
Normal file
BIN
doc/qtdesignstudio/images/studio-preset-for-mcus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@@ -107,8 +107,6 @@
|
|||||||
> \uicontrol {My Components}, and you can use instances of them to build
|
> \uicontrol {My Components}, and you can use instances of them to build
|
||||||
more components.
|
more components.
|
||||||
|
|
||||||
\include qtquick-mcu-support.qdocinc mcu qtquick components
|
|
||||||
|
|
||||||
\section1 Merging Files with Templates
|
\section1 Merging Files with Templates
|
||||||
|
|
||||||
You can merge the current component file against an existing second
|
You can merge the current component file against an existing second
|
||||||
|
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
|
||||||
|
|
||||||
/*!
|
|
||||||
//! [mcu qtquick components]
|
|
||||||
|
|
||||||
\section1 Creating UIs for MCUs
|
|
||||||
|
|
||||||
\l{\QMCU} enables you to use subsets of components to create UIs for
|
|
||||||
devices that are powered by microcontroller units (MCU). The subset of
|
|
||||||
supported components depends on the \QMCU version that you use for
|
|
||||||
development. In this manual, we indicate which components are supported at
|
|
||||||
the time of writing.
|
|
||||||
|
|
||||||
To develop for MCUs, \l{Creating a Project}{create an MCU project}. Only
|
|
||||||
the components available on MCUs are displayed in \l Components. Only a
|
|
||||||
subset of properties is supported for the supported components. The
|
|
||||||
properties that are not available on MCUs are marked in the \l Properties
|
|
||||||
view with strikethrough text.
|
|
||||||
|
|
||||||
\image qmldesigner-mcu-support.png "Components and Text properties supported for MCUs"
|
|
||||||
|
|
||||||
For more information about the supported components and their properties,
|
|
||||||
see \l{\QMCU - All QML Types}.
|
|
||||||
|
|
||||||
//! [mcu qtquick components]
|
|
||||||
*/
|
|
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\previouspage studio-on-mcus.html
|
\previouspage studio-mcu-framework.html
|
||||||
\page studio-compatibility-with-mcu-sdks.html
|
\page studio-compatibility-with-mcu-sdks.html
|
||||||
\nextpage studio-features-on-mcu-projects.html
|
\nextpage studio-features-on-mcu-projects.html
|
||||||
|
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
/ Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-connecting-mcus-with-creator.html
|
||||||
|
\previouspage studio-developing-apps-for-mcus.html
|
||||||
|
\nextpage studio-help.html
|
||||||
|
|
||||||
|
\title Connecting MCUs with Qt Creator
|
||||||
|
|
||||||
|
\l {Connecting MCUs} {Connect MCU boards} to a development host to
|
||||||
|
build applications for them using the GNU Arm Embedded GCC compiler, libraries,
|
||||||
|
and other GNU tools necessary for BareMetal software development on devices
|
||||||
|
based on the Arm Cortex-M processors. Deploy the applications on MCUs to run
|
||||||
|
and debug them using Qt Creator.
|
||||||
|
|
||||||
|
The toolchains are available for cross-compilation on Microsoft Windows,
|
||||||
|
Linux, and macOS. However, the \QMCU SDK is currently only available for
|
||||||
|
Windows and Linux.
|
||||||
|
|
||||||
|
For more information on how to manage the complete cycle of developing \QMCU
|
||||||
|
applications using Qt tools, see:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li \l {Infineon Traveo II quick start guide}
|
||||||
|
\li \l {NXP i.MX RT1170 quick start guide}
|
||||||
|
\li \l {Renesas EK-RA6M3G quick start guide}
|
||||||
|
\li \l {Renesas RH850-D1M1A quick start guide}
|
||||||
|
\endlist
|
||||||
|
*/
|
@@ -0,0 +1,148 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\previouspage studio-features-on-mcu-projects.html
|
||||||
|
\page studio-projects-for-mcus.html
|
||||||
|
\nextpage studio-creating-uis-for-mcus.html
|
||||||
|
|
||||||
|
\title Creating Projects for MCUs
|
||||||
|
|
||||||
|
Use the \uicontrol {\QMCU} preset in the \QDS wizard to set up a new \QMCU
|
||||||
|
project. When you create a project with the wizard, all the necessary files
|
||||||
|
are created, you can adjust the project settings, and save custom presets.
|
||||||
|
|
||||||
|
\image studio-preset-for-mcus.png
|
||||||
|
|
||||||
|
Using the \uicontrol {\QMCU} preset creates an application that uses a subset
|
||||||
|
of the default components that you can deploy, run, and debug on MCU boards.
|
||||||
|
|
||||||
|
\note For more information on the default components available for MCU
|
||||||
|
projects, see \l {Qt Design Studio Features on MCU Projects}.
|
||||||
|
|
||||||
|
\section1 Creating an MCU Project
|
||||||
|
|
||||||
|
To create an MCU project:
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Select \uicontrol {File} > \uicontrol {New Project}.
|
||||||
|
\li In the \uicontrol {Presets} tab, select the \uicontrol {\QMCU} preset.
|
||||||
|
\li In the \uicontrol {Details} tab:
|
||||||
|
\list
|
||||||
|
\li Select the path for the project files. You can move the project
|
||||||
|
folders later.
|
||||||
|
\li Set the screen size to match the device screen, which also enables
|
||||||
|
previewing on the desktop. You can change the screen size later in
|
||||||
|
\l {Properties}.
|
||||||
|
\endlist
|
||||||
|
\li Select \uicontrol {Create} to create the project.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\QDS creates the following files and folders:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li .qmlproject project file defines that all component and image files
|
||||||
|
in the project folder belong to the project. All files are added
|
||||||
|
automatically to their respective Files node based on their
|
||||||
|
type.
|
||||||
|
\note \QMCU does not recommend using the directory property to
|
||||||
|
individually list the files in the project.
|
||||||
|
\li .qml files define the functionality and appearance of application
|
||||||
|
components.
|
||||||
|
\li \e Screen01.ui.qml defines a custom component that you can edit in
|
||||||
|
the \l {2D} view. For more information, see \l {UI Files}.
|
||||||
|
|
||||||
|
While the custom component is a good starting point for new users,
|
||||||
|
you don't have to use it. Specifically, if you export and import
|
||||||
|
designs using \QB, your file is most likely called something
|
||||||
|
else. For more information, see \l {Exporting from Design Tools}.
|
||||||
|
|
||||||
|
\note For MCU projects you can only import 2D assets.
|
||||||
|
\li \e CMakeLists.txt project configuration file allowing you to
|
||||||
|
share your project as a fully working C++ application with
|
||||||
|
developers.
|
||||||
|
\li qtquickcontrols2.conf file specifies the preferred style and some
|
||||||
|
style-specific arguments.
|
||||||
|
\li \e fonts folder contains font files that you have added in
|
||||||
|
\uicontrol Assets.
|
||||||
|
\li \e imports folder contains a \e {Constants.qml} file that specifies
|
||||||
|
a font loader for the Arial font and the screen resolution. The size
|
||||||
|
of the default Screen.ui.qml \l{basic-rectangle}{Rectangle} should
|
||||||
|
be set as \c {width: Constants.width} & \c {height: Constants.height}
|
||||||
|
so that it inherits the global resolution saved here.
|
||||||
|
\li \e MCUDefaultStyle folder contains the default UI images and
|
||||||
|
components available for the MCU project.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
To use image files in the UI, select \uicontrol Assets > \inlineimage icons/plus.png
|
||||||
|
.
|
||||||
|
|
||||||
|
\sa {Using Custom Presets}
|
||||||
|
|
||||||
|
\section1 Adding Files to MCU Projects
|
||||||
|
|
||||||
|
You can use wizard templates to add individual files to projects.
|
||||||
|
|
||||||
|
The wizard templates in the \uicontrol {Qt Quick Controls} category create
|
||||||
|
stylable versions of the components in the \uicontrol {Qt Quick Controls}
|
||||||
|
module. For more information, see \l{Creating Custom Controls}.
|
||||||
|
|
||||||
|
You can create the following types of files:
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Category
|
||||||
|
\li Wizard Template
|
||||||
|
\li Purpose
|
||||||
|
\row
|
||||||
|
\li {1,5} Qt Quick Files
|
||||||
|
\row
|
||||||
|
\li Qt Quick File
|
||||||
|
\li Generates a component with one of the following default components
|
||||||
|
or \l{Using Positioners}{positioners} as the root component:
|
||||||
|
\l {basic-item}{Item}, \l {basic-rectangle}{Rectangle}, \l {Images}
|
||||||
|
{Image}, \l {Border Image}, \l Flickable, Row, Column, Flow, or
|
||||||
|
Grid.
|
||||||
|
\row
|
||||||
|
\li Qt Quick UI File
|
||||||
|
\li Generates a UI file with one of the above components as the root
|
||||||
|
component.
|
||||||
|
\row
|
||||||
|
\li Qt Quick Views
|
||||||
|
\li Generates a List View. For more information, see
|
||||||
|
\l{List and Grid Views}.
|
||||||
|
\row
|
||||||
|
\li Qt Quick UI Form
|
||||||
|
\li Creates a UI file along with a matching QML file for
|
||||||
|
implementation purposes.
|
||||||
|
\row
|
||||||
|
\li {1,8} Qt Quick Controls
|
||||||
|
\li Custom Button
|
||||||
|
\li Creates a \l {Button}{push button} with a text label.
|
||||||
|
\row
|
||||||
|
\li Custom \CheckBox
|
||||||
|
\li Creates a \l {Check Box}{check box}.
|
||||||
|
\row
|
||||||
|
\li Custom Dial
|
||||||
|
\li Creates a \l {Slider and Dial}{dial}.
|
||||||
|
\row
|
||||||
|
\li Custom Slider
|
||||||
|
\li Creates a \l {Slider and Dial}{slider}.
|
||||||
|
\row
|
||||||
|
\li Custom \SpinBox
|
||||||
|
\li Creates a \l {Spin Box}{spin box}.
|
||||||
|
\row
|
||||||
|
\li Custom Switch
|
||||||
|
\li Creates a \l {Switch}{switch} with on and off states.
|
||||||
|
\row
|
||||||
|
\li \l Pane
|
||||||
|
\li Provides a background that matches the UI style and theme.
|
||||||
|
\row
|
||||||
|
\li SwipeView
|
||||||
|
\li Enables users to navigate pages by swiping sideways.
|
||||||
|
\row
|
||||||
|
\li QML Files
|
||||||
|
\li ListModel
|
||||||
|
\li Adds a \l{Editing List Models}{list model} to the project.
|
||||||
|
\endtable
|
||||||
|
*/
|
@@ -0,0 +1,52 @@
|
|||||||
|
/ Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-creating-uis-for-mcus.html
|
||||||
|
\previouspage studio-projects-for-mcus.html
|
||||||
|
\nextpage studio-developing-apps-for-mcus.html
|
||||||
|
|
||||||
|
\title Creating UIs for MCUs
|
||||||
|
|
||||||
|
As a technical artist or a designer, you can use specialized UI design tools,
|
||||||
|
such as Adobe Photoshop, Sketch, Figma, Blender, or Maya, to create the
|
||||||
|
original UI design files for your MCU application. After the initial design
|
||||||
|
work, export your design from the design tools, and import your 2D and 3D UI
|
||||||
|
design assets into \QDS, which can convert them into code for developers.
|
||||||
|
For more information on managing the original assets created with
|
||||||
|
specialized UI design tools, see \l {Asset Creation with Other Tools}.
|
||||||
|
|
||||||
|
Once your UI design assets are in \QDS, use it to \l {Wireframing} {wireframe}
|
||||||
|
your MCU application, to visualize its structure. To modify the look and feel
|
||||||
|
of your UI further, utilize the preset UI components available in \QDS.
|
||||||
|
|
||||||
|
\section1 Using MCU Components
|
||||||
|
|
||||||
|
With \QDS, you can use subsets of components to create UIs for
|
||||||
|
devices that are powered by microcontroller units (MCU). The subset of
|
||||||
|
supported components depends on the \QMCU version that you use for
|
||||||
|
development.
|
||||||
|
|
||||||
|
To develop for MCUs, \l{Creating Projects for MCUs}{create an MCU project}.
|
||||||
|
Only the components available on MCUs are displayed in \l Components. Also,
|
||||||
|
only a subset of properties is supported for the supported components. The
|
||||||
|
properties that are not available on MCUs are marked in the \l Properties
|
||||||
|
view with strikethrough text.
|
||||||
|
|
||||||
|
\image studio-mcu-components-and-properties.webp "Components and Text properties supported for MCUs"
|
||||||
|
|
||||||
|
For more information on the supported views and features, see \l{\QDS Features on MCU Projects}.
|
||||||
|
|
||||||
|
For an example on how to create a UI that runs both on the desktop and
|
||||||
|
on MCUs, see \l {Washing Machine UI}. For step-by-step instructions on how
|
||||||
|
to use \QDS to design a UI for a specific MCU target device, see:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li \l {Designing a UI for Infineon Traveo II}
|
||||||
|
\li \l {Designing a UI for NXP i.MX RT1170}
|
||||||
|
\li \l {Designing a UI for Renesas RA6M3G}
|
||||||
|
\li \l {Designing a UI for Renesas RH850-D1M1A}
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\sa {Specifying Component Properties}
|
||||||
|
*/
|
@@ -0,0 +1,28 @@
|
|||||||
|
/ Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-developing-apps-for-mcus.html
|
||||||
|
\previouspage studio-creating-uis-for-mcus.html
|
||||||
|
\nextpage studio-connecting-mcus-with-creator.html
|
||||||
|
|
||||||
|
\title Developing Applications for MCUs
|
||||||
|
|
||||||
|
As a GUI/application developer, use \QDS to bring your designs to life. Add
|
||||||
|
further functionality to your applications and utilize the \l {Prototyping}
|
||||||
|
{prototyping} features of \QDS to simulate and validate interactions and
|
||||||
|
their dynamic behavior.
|
||||||
|
|
||||||
|
You can also test, preview, and fine-tune your designs to pixel-perfection
|
||||||
|
live on the desktop or on an actual MCU target device. For more information,
|
||||||
|
see \l {Validating with Target Hardware}.
|
||||||
|
|
||||||
|
\image qds-mcu-target-deployment.png
|
||||||
|
|
||||||
|
With \QDS, designers and developers can work together on common projects to
|
||||||
|
develop applications. As a designer you can use the views in the \e Design
|
||||||
|
mode to modify UI files (.ui.qml). As a developer you can use Qt Creator to
|
||||||
|
work on the Qt Quick (.qml) and other files that are needed to implement the
|
||||||
|
application logic and to prepare the application for production. For more
|
||||||
|
information, see \l {Implementing Applications}.
|
||||||
|
*/
|
@@ -4,7 +4,7 @@
|
|||||||
/*!
|
/*!
|
||||||
\previouspage studio-compatibility-with-mcu-sdks.html
|
\previouspage studio-compatibility-with-mcu-sdks.html
|
||||||
\page studio-features-on-mcu-projects.html
|
\page studio-features-on-mcu-projects.html
|
||||||
\nextpage studio-help.html
|
\nextpage studio-projects-for-mcus.html
|
||||||
|
|
||||||
\title \QDS Features on MCU Projects
|
\title \QDS Features on MCU Projects
|
||||||
|
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
/ Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-mcu-framework.html
|
||||||
|
\previouspage studio-on-mcus.html
|
||||||
|
\nextpage studio-compatibility-with-mcu-sdks.html
|
||||||
|
|
||||||
|
\title \QMCU Framework
|
||||||
|
|
||||||
|
\QMCU is a comprehensive framework that supports various hardware ecosystems
|
||||||
|
and platforms. One of the most important libraries provided by the \QMCU
|
||||||
|
framework is \QUL (QUL), a lightweight implementation of the Qt Quick
|
||||||
|
framework. \QUL provides a QML API and an efficient graphics rendering engine
|
||||||
|
that has a low memory footprint and is optimized for MCUs and other
|
||||||
|
resource-constrained devices.
|
||||||
|
|
||||||
|
In addition to a lightweight graphics framework, \QMCU offers a toolkit that
|
||||||
|
enables you to design, develop, and deploy graphical user interfaces (GUI)
|
||||||
|
on microcontrollers (MCU). Also, it lets you run the applications either
|
||||||
|
on BareMetal or a real-time operating system (RTOS).
|
||||||
|
|
||||||
|
\note In addition to BareMetal and RTOS, you can use the desktop kit to run
|
||||||
|
and test the application on desktop without flashing it each time.
|
||||||
|
|
||||||
|
For more information on \QMCU, see \l {\QMCU documentation}.
|
||||||
|
*/
|
@@ -4,89 +4,49 @@
|
|||||||
/*!
|
/*!
|
||||||
\previouspage creator-editor-external.html
|
\previouspage creator-editor-external.html
|
||||||
\page studio-on-mcus.html
|
\page studio-on-mcus.html
|
||||||
\nextpage studio-compatibility-with-mcu-sdks.html
|
\nextpage studio-mcu-framework.html
|
||||||
|
|
||||||
\title \QDS on MCUs
|
\title \QDS on MCUs
|
||||||
|
|
||||||
\QMCU is a comprehensive framework that supports various hardware ecosystems
|
\table
|
||||||
and platforms. One of the most important libraries provided by the \QMCU
|
\row
|
||||||
framework is \QUL (QUL), a lightweight implementation of the Qt Quick
|
\li \image qds-front-gs.png
|
||||||
framework. \QUL provides a QML API and an efficient graphics rendering engine
|
\li With \QDS, you can use subsets of components to create UIs
|
||||||
that has a low memory footprint and is optimized for MCUs and other
|
for devices that are powered by microcontroller units (MCU). Use
|
||||||
resource-constrained devices.
|
the \uicontrol {\QMCU} preset in the \QDS wizard to set up a new
|
||||||
|
\QMCU project. Using the \uicontrol {\QMCU} preset creates an
|
||||||
In addition to a lightweight graphics framework, \QMCU offers a toolkit that
|
application that utilizes a subset of the default components that
|
||||||
enables you to design, develop, and deploy graphical user interfaces (GUI)
|
you can deploy, run, and debug on MCU boards.
|
||||||
on microcontrollers (MCU). Also, it lets you run the applications either
|
\endtable
|
||||||
on BareMetal or a real-time operating system (RTOS).
|
|
||||||
|
|
||||||
For more information on \QMCU, see \l {\QMCU documentation}.
|
|
||||||
|
|
||||||
\section1 Designing application UIs for MCU devices with \QDS
|
|
||||||
|
|
||||||
As a technical artist or a designer you can use specialized UI design tools,
|
|
||||||
such as Adobe Photoshop, Sketch, Figma, Blender, or Maya to create the
|
|
||||||
original UI design files for your MCU application. After the initial design
|
|
||||||
work, export your design from the design tools, and import your 2D and 3D UI
|
|
||||||
design assets into \QDS, which can convert them into code for developers.
|
|
||||||
For more information on managing the original assets created with
|
|
||||||
specialized UI design tools, see \l {Asset Creation with Other Tools}.
|
|
||||||
|
|
||||||
Once your UI design assets are in \QDS, use it to \l {Wireframing} {wireframe}
|
|
||||||
your MCU application, to visualize its structure. To modify the look and feel
|
|
||||||
of your UI further, utilize the preset UI components available in \QDS.
|
|
||||||
|
|
||||||
For an example on how to create a UI that runs both on the desktop and
|
|
||||||
on MCUs, see \l {Washing Machine UI}. For step-by-step instructions on how
|
|
||||||
to use \QDS to design a UI for a specific MCU target device, see:
|
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li \l {Designing a UI for Infineon Traveo II}
|
\li \l {\QMCU Framework}
|
||||||
\li \l {Designing a UI for NXP i.MX RT1170}
|
|
||||||
\li \l {Designing a UI for Renesas RA6M3G}
|
Provides an overview of the \QMCU framework.
|
||||||
\li \l {Designing a UI for Renesas RH850-D1M1A}
|
\li \l {\QDS Version Compatibility with \QMCU SDKs}
|
||||||
|
|
||||||
|
Lists how the \QDS versions match with particular \QMCU SDKs.
|
||||||
|
\li \l {\QDS Features on MCU Projects}
|
||||||
|
|
||||||
|
Specifies how the \QDS features are supported for developing MCU projects.
|
||||||
|
\li \l {Creating Projects for MCUs}
|
||||||
|
|
||||||
|
Describes how to use the \QDS wizard and \uicontrol {\QMCU} preset
|
||||||
|
to set up a new \QMCU project.
|
||||||
|
\li \l {Creating UIs for MCUs}
|
||||||
|
|
||||||
|
Provides an overview of how to create UIs for MCUs from a technical
|
||||||
|
artist/designer perspective. Also, offers links to detailed instructions
|
||||||
|
for designing UIs for specific MCU target devices.
|
||||||
|
\li \l {Developing applications for MCUs}
|
||||||
|
|
||||||
|
Provides an overview of how to develop, prototype, validate, and
|
||||||
|
implement applications for MCUs from a GUI/application developer
|
||||||
|
perspective.
|
||||||
|
\li \l {Connecting MCUs with Qt Creator}
|
||||||
|
|
||||||
|
Describes how to connect MCUs with Qt Creator. Also, offers links to
|
||||||
|
detailed instructions on how to manage the complete cycle of developing
|
||||||
|
\QMCU applications using Qt tools.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\section1 Developing applications for MCU devices with \QDS
|
|
||||||
|
|
||||||
As a GUI/application developer, use \QDS to bring your designs to life. Add
|
|
||||||
further functionality to your applications and utilize the \l {Prototyping}
|
|
||||||
{prototyping} features of \QDS to simulate and validate interactions and
|
|
||||||
their dynamic behavior.
|
|
||||||
|
|
||||||
You can also test, preview, and fine-tune your designs to pixel-perfection
|
|
||||||
live on the desktop or on an actual MCU target device. For more information,
|
|
||||||
see \l {Validating with Target Hardware}.
|
|
||||||
|
|
||||||
\image qds-mcu-target-deployment.png
|
|
||||||
|
|
||||||
\QDS enables designers and developers to work together on common projects to
|
|
||||||
develop applications. Designers can use the views in the Design mode to modify
|
|
||||||
UI files (.ui.qml), whereas developers can use Qt Creator to work on the Qt
|
|
||||||
Quick (.qml) and other files that are needed to implement the application
|
|
||||||
logic and to prepare the application for production. For more information,
|
|
||||||
see \l {Implementing Applications}.
|
|
||||||
|
|
||||||
\section1 Connecting MCUs with Qt Creator
|
|
||||||
|
|
||||||
\l {Connecting MCUs} {Connect MCU boards} to a development host to
|
|
||||||
build applications for them using the GNU Arm Embedded GCC compiler, libraries,
|
|
||||||
and other GNU tools necessary for BareMetal software development on devices
|
|
||||||
based on the Arm Cortex-M processors. Deploy the applications on MCUs to run
|
|
||||||
and debug them using Qt Creator.
|
|
||||||
|
|
||||||
The toolchains are available for cross-compilation on Microsoft Windows,
|
|
||||||
Linux, and macOS. However, the \QMCU SDK is currently only available for
|
|
||||||
Windows and Linux.
|
|
||||||
|
|
||||||
For more information on how to manage the complete cycle of developing \QMCU
|
|
||||||
applications using Qt tools, see:
|
|
||||||
|
|
||||||
\list
|
|
||||||
\li \l {Infineon Traveo II quick start guide}
|
|
||||||
\li \l {NXP i.MX RT1170 quick start guide}
|
|
||||||
\li \l {Renesas EK-RA6M3G quick start guide}
|
|
||||||
\li \l {Renesas RH850-D1M1A quick start guide}
|
|
||||||
\endlist
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@@ -170,6 +170,36 @@
|
|||||||
\c {QtQuick.Studio.Components 1.0}. You can add components from all
|
\c {QtQuick.Studio.Components 1.0}. You can add components from all
|
||||||
the available modules in \QDS later. You can also import a module as
|
the available modules in \QDS later. You can also import a module as
|
||||||
an \e alias.
|
an \e alias.
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Properties}
|
||||||
|
\li Specify new properties or assign values to the existing properties of
|
||||||
|
the component. You can also add and modify properties in \QDS.
|
||||||
|
The following are a few examples of the properties:
|
||||||
|
\code
|
||||||
|
property int counter: 5
|
||||||
|
property string label: "ok"
|
||||||
|
antialiasing : true
|
||||||
|
width: parent.width / 2
|
||||||
|
\endcode
|
||||||
|
To remove a property, write a "dash" (-) followed by the "property name".
|
||||||
|
For example:
|
||||||
|
\code
|
||||||
|
- width
|
||||||
|
\endcode
|
||||||
|
will remove the property \e width from the generated code.
|
||||||
|
\row
|
||||||
|
\li \uicontrol {Snippet}
|
||||||
|
\li Specify component to be added as child under this component.
|
||||||
|
Following example adds a Connection component:
|
||||||
|
\code
|
||||||
|
Connections {
|
||||||
|
target: myItem
|
||||||
|
onVisibleChanged: console.log(original_Text.visible)
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\note The code must have a scope of a component(e.g. Item, MouseArea,
|
||||||
|
Connections etc.) with a valid syntax for \l {UI Files}.
|
||||||
|
\note Add respective imports for your snippet in \uicontrol {Imports}.
|
||||||
\row
|
\row
|
||||||
\li \uicontrol Alias
|
\li \uicontrol Alias
|
||||||
\li Exports the component generated from this layer as an alias in the
|
\li Exports the component generated from this layer as an alias in the
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
\section1 2D Assets
|
\section1 2D Assets
|
||||||
|
|
||||||
You can use the Qt Installer to install \QB if you have a
|
You can use \QOI to install \QB if you have a
|
||||||
\QDS enterprise license.
|
\QDS enterprise license.
|
||||||
|
|
||||||
\table
|
\table
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
\QBPS is included in the
|
\QBPS is included in the
|
||||||
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
||||||
You can use the Qt Installer to have the \QBPS plugin package copied to the
|
You can use \QOI to have the \QBPS plugin package copied to the
|
||||||
following path in your Qt installation folder:
|
following path in your Qt installation folder:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
@@ -187,8 +187,22 @@
|
|||||||
Components 1.0, you need the import statement
|
Components 1.0, you need the import statement
|
||||||
\c {QtQuick.Studio.Components 1.0}. You can also import a module
|
\c {QtQuick.Studio.Components 1.0}. You can also import a module
|
||||||
as an alias.
|
as an alias.
|
||||||
\li In the \uicontrol {Properties} field, specify properties for
|
\li In the \uicontrol {Properties} field, specify new properties or assign
|
||||||
the component. You can add and modify properties in \QDS.
|
values to the existing properties of the component. You can also add and modify
|
||||||
|
properties in \QDS.
|
||||||
|
The following are a few examples of the properties:
|
||||||
|
\code
|
||||||
|
property int counter: 5
|
||||||
|
property string label: "ok"
|
||||||
|
antialiasing : true
|
||||||
|
width: parent.width / 2
|
||||||
|
\endcode
|
||||||
|
To remove a property, write a "dash" (-) followed by the "property name".
|
||||||
|
For example:
|
||||||
|
\code
|
||||||
|
- width
|
||||||
|
\endcode
|
||||||
|
will remove the property \e width from the generated code.
|
||||||
\li Select the \uicontrol {Clip Contents} check box to enable clipping
|
\li Select the \uicontrol {Clip Contents} check box to enable clipping
|
||||||
in the type generated from the layer. The generated type will clip
|
in the type generated from the layer. The generated type will clip
|
||||||
its own painting, as well as the painting of its children, to its
|
its own painting, as well as the painting of its children, to its
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
\QBSK is included in the
|
\QBSK is included in the
|
||||||
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
||||||
You can use the Qt Installer to have the \QBSK plugin package copied to the
|
You can use \QOI to have the \QBSK plugin package copied to the
|
||||||
following path in your Qt installation folder:
|
following path in your Qt installation folder:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
@@ -209,8 +209,22 @@
|
|||||||
\c {QtQuick.Controls 2.3} and to use Qt Quick Studio Components 1.0,
|
\c {QtQuick.Controls 2.3} and to use Qt Quick Studio Components 1.0,
|
||||||
you need the import statement \c {QtQuick.Studio.Components 1.0}.
|
you need the import statement \c {QtQuick.Studio.Components 1.0}.
|
||||||
You can also import a module as an alias.
|
You can also import a module as an alias.
|
||||||
\li In the \uicontrol {Properties} field, specify properties for the
|
\li In the \uicontrol {Properties} field, specify new properties or assign
|
||||||
component. You can add and modify properties in \QDS.
|
values to the existing properties of the component. You can also add and modify
|
||||||
|
properties in \QDS.
|
||||||
|
The following are a few examples of the properties:
|
||||||
|
\code
|
||||||
|
property int counter: 5
|
||||||
|
property string label: "ok"
|
||||||
|
antialiasing : true
|
||||||
|
width: parent.width / 2
|
||||||
|
\endcode
|
||||||
|
To remove a property, write a "dash" (-) followed by the "property name".
|
||||||
|
For example:
|
||||||
|
\code
|
||||||
|
- width
|
||||||
|
\endcode
|
||||||
|
will remove the property \e width from the generated code.
|
||||||
\li Select the \uicontrol Alias check box to export the item generated
|
\li Select the \uicontrol Alias check box to export the item generated
|
||||||
from this layer as an alias in the parent component.
|
from this layer as an alias in the parent component.
|
||||||
\li Select the \uicontrol Clip check box to enable clipping in the
|
\li Select the \uicontrol Clip check box to enable clipping in the
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
\QBXD is included in the
|
\QBXD is included in the
|
||||||
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
||||||
You can use the Qt Installer to have the \QBXD plugin package copied to the
|
You can use \QOI to have the \QBXD plugin package copied to the
|
||||||
following path in your Qt installation folder:
|
following path in your Qt installation folder:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
@@ -114,15 +114,21 @@
|
|||||||
you need the import statement \c {QtQuick.Studio.Components 1.0}.
|
you need the import statement \c {QtQuick.Studio.Components 1.0}.
|
||||||
You can also import a module as an alias.
|
You can also import a module as an alias.
|
||||||
\li In the \uicontrol {Properties} field, specify new properties or assign
|
\li In the \uicontrol {Properties} field, specify new properties or assign
|
||||||
value to the existing properties of the component. You can also add and modify
|
values to the existing properties of the component. You can also add and modify
|
||||||
properties in \QDS.
|
properties in \QDS.
|
||||||
Following are few examples of properties:
|
The following are a few examples of the properties:
|
||||||
\code
|
\code
|
||||||
property int counter: 5
|
property int counter: 5
|
||||||
property string label: "ok"
|
property string label: "ok"
|
||||||
antialiasing : true
|
antialiasing : true
|
||||||
width: parent.width / 2
|
width: parent.width / 2
|
||||||
\endcode
|
\endcode
|
||||||
|
To remove a property, write a "dash" (-) followed by the "property name".
|
||||||
|
For example:
|
||||||
|
\code
|
||||||
|
- width
|
||||||
|
\endcode
|
||||||
|
will remove the property \e width from the generated code.
|
||||||
\li In the \uicontrol {Snippet} field, specify component to be added as child under this
|
\li In the \uicontrol {Snippet} field, specify component to be added as child under this
|
||||||
component.
|
component.
|
||||||
Following example adds a Connection component:
|
Following example adds a Connection component:
|
||||||
@@ -134,6 +140,7 @@
|
|||||||
\endcode
|
\endcode
|
||||||
\note The code must have a scope of a component(e.g. Item, MouseArea, Connections etc.)
|
\note The code must have a scope of a component(e.g. Item, MouseArea, Connections etc.)
|
||||||
with a valid syntax for \l {UI Files}.
|
with a valid syntax for \l {UI Files}.
|
||||||
|
\note Add respective imports for your snippet in \uicontrol Imports.
|
||||||
\li Select the \uicontrol Clip check box to enable clipping in the
|
\li Select the \uicontrol Clip check box to enable clipping in the
|
||||||
component generated from the layer. The generated component will clip
|
component generated from the layer. The generated component will clip
|
||||||
its own painting, as well as the painting of its children, to its
|
its own painting, as well as the painting of its children, to its
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
\li \l {Installation}
|
\li \l {Installation}
|
||||||
|
|
||||||
\QDS is available either as a standalone installation package or
|
\QDS is available either as a standalone installation package or
|
||||||
as an option in the Qt online installer.
|
as an option in \QOI.
|
||||||
\li \l {Tutorials}
|
\li \l {Tutorials}
|
||||||
|
|
||||||
Follow a set of hands-on tutorials that illustrate how to use the
|
Follow a set of hands-on tutorials that illustrate how to use the
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\page studio-help.html
|
\page studio-help.html
|
||||||
\previouspage studio-features-on-mcu-projects.html
|
\previouspage studio-connecting-mcus-with-creator.html
|
||||||
\nextpage creator-how-to-get-help.html
|
\nextpage creator-how-to-get-help.html
|
||||||
|
|
||||||
\title Help
|
\title Help
|
||||||
|
@@ -8,15 +8,15 @@
|
|||||||
|
|
||||||
\title Installation
|
\title Installation
|
||||||
|
|
||||||
You can install \QDS either using a stand-alone installation package or the
|
You can install \QDS either using a stand-alone installation package or \QOI.
|
||||||
Qt online installer. The installers copy all the modules and tools you need
|
The installers copy all the modules and tools you need
|
||||||
to design UIs and preview them on the desktop to your computer and configure
|
to design UIs and preview them on the desktop to your computer and configure
|
||||||
them for you. \QDS is available for Linux, \macOS, and Windows operating
|
them for you. \QDS is available for Linux, \macOS, and Windows operating
|
||||||
systems. For more information, see \l{Supported Platforms}.
|
systems. For more information, see \l{Supported Platforms}.
|
||||||
|
|
||||||
To begin, create a \l{Qt Account}. This account gives you access to a web
|
To begin, create a \l{Qt Account}. This account gives you access to a web
|
||||||
portal to manage your licenses and download the standalone \QDS package or
|
portal to manage your licenses and download the standalone \QDS package or
|
||||||
the Qt online installer. Alternatively, you can download an evaluation
|
\QOI. Alternatively, you can download an evaluation
|
||||||
package \l{https://www.qt.io/product/ui-design-tools}{here}.
|
package \l{https://www.qt.io/product/ui-design-tools}{here}.
|
||||||
|
|
||||||
After the installation, you can start exploring \QDS by following
|
After the installation, you can start exploring \QDS by following
|
||||||
@@ -31,15 +31,15 @@
|
|||||||
would for any other software, and follow the instructions of the
|
would for any other software, and follow the instructions of the
|
||||||
installer to complete it.
|
installer to complete it.
|
||||||
|
|
||||||
\section1 Using Qt Online Installer
|
\section1 Using \QOI
|
||||||
|
|
||||||
You can download the Qt online installer for your operating system
|
You can download \QOI for your operating system
|
||||||
from your Qt Account.
|
from your Qt Account.
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
\li Start the Qt online installer.
|
\li Start \QOI.
|
||||||
\li Select \uicontrol {Design Tools}.
|
\li Select \uicontrol {Design Tools}.
|
||||||
\image studio-installation.png "Design Tools selected in Qt online installer"
|
\image studio-installation.png "Design Tools selected in Qt Online Installer"
|
||||||
\li Select \uicontrol Next and follow the instructions of the
|
\li Select \uicontrol Next and follow the instructions of the
|
||||||
installer to complete the installation.
|
installer to complete the installation.
|
||||||
\endlist
|
\endlist
|
||||||
|
@@ -51,7 +51,7 @@
|
|||||||
\li MCU
|
\li MCU
|
||||||
\li Creates an application that uses a subset of default components
|
\li Creates an application that uses a subset of default components
|
||||||
(as supported by \QMCU) that you can deploy, run, and debug
|
(as supported by \QMCU) that you can deploy, run, and debug
|
||||||
on MCU boards.
|
on MCU boards. For more information, see \l {Creating Projects for MCUs}.
|
||||||
\row
|
\row
|
||||||
\li {1,3} Mobile
|
\li {1,3} Mobile
|
||||||
\li Scroll
|
\li Scroll
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
\li \l{Open Documents}
|
\li \l{Open Documents}
|
||||||
\li \l{Content Library}
|
\li \l{Content Library}
|
||||||
\li \l{Texture Editor}
|
\li \l{Texture Editor}
|
||||||
|
\li \l{Qt Insight}
|
||||||
\endlist
|
\endlist
|
||||||
\li \l{Managing Workspaces}
|
\li \l{Managing Workspaces}
|
||||||
\li \l{Managing Sessions}
|
\li \l{Managing Sessions}
|
||||||
@@ -254,8 +255,13 @@
|
|||||||
\li \l{Use external tools}
|
\li \l{Use external tools}
|
||||||
\li \l{\QDS on MCUs}
|
\li \l{\QDS on MCUs}
|
||||||
\list
|
\list
|
||||||
|
\li \l {\QMCU Framework}
|
||||||
\li \l {\QDS Version Compatibility with \QMCU SDKs}
|
\li \l {\QDS Version Compatibility with \QMCU SDKs}
|
||||||
\li \l {\QDS Features on MCU Projects}
|
\li \l {\QDS Features on MCU Projects}
|
||||||
|
\li \l {Creating Projects for MCUs}
|
||||||
|
\li \l {Creating UIs for MCUs}
|
||||||
|
\li \l {Developing Applications for MCUs}
|
||||||
|
\li \l {Connecting MCUs with Qt Creator}
|
||||||
\endlist
|
\endlist
|
||||||
\endlist
|
\endlist
|
||||||
\li \l Help
|
\li \l Help
|
||||||
|
@@ -183,7 +183,7 @@
|
|||||||
and drag the component along the axis.
|
and drag the component along the axis.
|
||||||
\li To move components on a plane, click the plane handle and drag the
|
\li To move components on a plane, click the plane handle and drag the
|
||||||
component on the plane.
|
component on the plane.
|
||||||
\li To move an component freely in the 3D view, click and drag the gray
|
\li To move components freely in the 3D view, click and drag the gray
|
||||||
handle at the center of the move gizmo.
|
handle at the center of the move gizmo.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
@@ -221,6 +221,35 @@
|
|||||||
gray handle at the center of the component.
|
gray handle at the center of the component.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
\section1 Snapping
|
||||||
|
|
||||||
|
With snapping turned on, the objects in the \uicontrol 3D view snap to certain
|
||||||
|
intervals during transformation (move, rotate, scale).
|
||||||
|
|
||||||
|
You can toggle snapping in the following ways:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li Select \inlineimage icons/snapping-3d.png
|
||||||
|
in the \uicontrol 3D view toolbar.
|
||||||
|
\li Hold down the \key Ctrl key.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
With snapping turned on, you can press and hold \key Shift to snap objects to one tenth of
|
||||||
|
the specified snap interval.
|
||||||
|
|
||||||
|
\section2 Configuring Snapping
|
||||||
|
|
||||||
|
To edit snapping settings, select \inlineimage icons/snapping-3d-conf.png
|
||||||
|
in the \uicontrol 3D view toolbar.
|
||||||
|
|
||||||
|
In the configure dialog, you can do the following:
|
||||||
|
\list
|
||||||
|
\li Turn on and off snapping separately for the different transformations
|
||||||
|
(move, rotate, scale).
|
||||||
|
\li Set snap intervals.
|
||||||
|
\li Toggle if the position snaps to absolute or relative values.
|
||||||
|
\endlist
|
||||||
|
|
||||||
\section1 Aligning Views and Cameras
|
\section1 Aligning Views and Cameras
|
||||||
|
|
||||||
To align a camera to the \uicontrol{3D} view:
|
To align a camera to the \uicontrol{3D} view:
|
||||||
@@ -375,6 +404,16 @@
|
|||||||
\li Toggle Edit Light On/Off
|
\li Toggle Edit Light On/Off
|
||||||
\li \key U
|
\li \key U
|
||||||
\li \l{Using Edit Light}
|
\li \l{Using Edit Light}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/snapping-3d.png
|
||||||
|
\li Toggle Snapping During Node Drag
|
||||||
|
\li \key Shift + \key Tab
|
||||||
|
\li \l{Snapping}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/snapping-3d-conf.png
|
||||||
|
\li Open Snap Configuration Dialog
|
||||||
|
\li
|
||||||
|
\li \l{Configuring Snapping}
|
||||||
\row
|
\row
|
||||||
\li \inlineimage icons/align-camera-on.png
|
\li \inlineimage icons/align-camera-on.png
|
||||||
\li Align Selected Cameras to View
|
\li Align Selected Cameras to View
|
||||||
|
28
doc/qtdesignstudio/src/views/studio-qtinsight.qdoc
Normal file
28
doc/qtdesignstudio/src/views/studio-qtinsight.qdoc
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-qt-insight.html
|
||||||
|
\previouspage studio-texture-editor.html
|
||||||
|
\nextpage creator-project-managing-workspaces.html
|
||||||
|
|
||||||
|
\title Qt Insight
|
||||||
|
|
||||||
|
In the \uicontrol {Qt Insight} view, you manage your Qt Insight.
|
||||||
|
|
||||||
|
Qt Insight is an analytics solution that provides real user insights on the usage of Qt
|
||||||
|
applications. It shows, for example, an application’s performance, usage, and user data.
|
||||||
|
|
||||||
|
For more information, see the
|
||||||
|
\l{https://www.qt.io/product/insight/onboarding-instructions}{Getting Started with Qt Insight}
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
\image qt-insight-view.png
|
||||||
|
|
||||||
|
In \QDS, you can do the following with Qt Insight:
|
||||||
|
\list
|
||||||
|
\li Turn on and off tracking
|
||||||
|
\li Set send cadence
|
||||||
|
\li Manage categories
|
||||||
|
\endlist
|
||||||
|
*/
|
@@ -4,7 +4,7 @@
|
|||||||
/*!
|
/*!
|
||||||
\page studio-texture-editor.html
|
\page studio-texture-editor.html
|
||||||
\previouspage studio-content-library.html
|
\previouspage studio-content-library.html
|
||||||
\nextpage creator-project-managing-workspaces.html
|
\nextpage studio-qt-insight.html
|
||||||
|
|
||||||
\title Texture Editor
|
\title Texture Editor
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\page creator-project-managing-workspaces.html
|
\page creator-project-managing-workspaces.html
|
||||||
\previouspage studio-texture-editor.html
|
\previouspage studio-qt-insight.html
|
||||||
\nextpage creator-project-managing-sessions.html
|
\nextpage creator-project-managing-sessions.html
|
||||||
|
|
||||||
\title Managing Workspaces
|
\title Managing Workspaces
|
||||||
|
@@ -156,7 +156,7 @@ TreeViewDelegate {
|
|||||||
mouseArea.allowTooltip = true
|
mouseArea.allowTooltip = true
|
||||||
}
|
}
|
||||||
|
|
||||||
onPositionChanged: tooltipBackend.reposition()
|
onPositionChanged: AssetsLibraryBackend.tooltipBackend.reposition()
|
||||||
|
|
||||||
onPressed: (mouse) => {
|
onPressed: (mouse) => {
|
||||||
mouseArea.forceActiveFocus()
|
mouseArea.forceActiveFocus()
|
||||||
|
@@ -145,11 +145,11 @@ Item {
|
|||||||
Column {
|
Column {
|
||||||
id: toolbarColumn
|
id: toolbarColumn
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin: 6
|
anchors.topMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||||
anchors.bottomMargin: 6
|
anchors.bottomMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||||
anchors.leftMargin: 10
|
anchors.leftMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
anchors.rightMargin: 10
|
anchors.rightMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
spacing: 12
|
spacing: StudioTheme.Values.toolbarColumnSpacing
|
||||||
|
|
||||||
StudioControls.SearchBox {
|
StudioControls.SearchBox {
|
||||||
id: searchBox
|
id: searchBox
|
||||||
@@ -260,10 +260,13 @@ Item {
|
|||||||
|
|
||||||
AssetsView {
|
AssetsView {
|
||||||
id: assetsView
|
id: assetsView
|
||||||
assetsRoot: root
|
|
||||||
contextMenu: contextMenu
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - assetsView.y
|
height: parent.height - assetsView.y
|
||||||
|
|
||||||
|
assetsRoot: root
|
||||||
|
contextMenu: contextMenu
|
||||||
|
focus: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,11 @@ TreeView {
|
|||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
rowSpacing: 5
|
rowSpacing: 5
|
||||||
|
|
||||||
|
property bool adsFocus: false
|
||||||
|
// objectName is used by the dock widget to find this particular ScrollView
|
||||||
|
// and set the ads focus on it.
|
||||||
|
objectName: "__mainSrollView"
|
||||||
|
|
||||||
property var assetsModel: AssetsLibraryBackend.assetsModel
|
property var assetsModel: AssetsLibraryBackend.assetsModel
|
||||||
property var rootView: AssetsLibraryBackend.rootView
|
property var rootView: AssetsLibraryBackend.rootView
|
||||||
property var tooltipBackend: AssetsLibraryBackend.tooltipBackend
|
property var tooltipBackend: AssetsLibraryBackend.tooltipBackend
|
||||||
@@ -46,9 +51,18 @@ TreeView {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollBar.vertical: HelperWidgets.VerticalScrollBar {
|
HoverHandler { id: hoverHandler }
|
||||||
|
|
||||||
|
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||||
id: verticalScrollBar
|
id: verticalScrollBar
|
||||||
scrollBarVisible: root.contentHeight > root.height
|
parent: root
|
||||||
|
x: root.width - verticalScrollBar.width
|
||||||
|
y: 0
|
||||||
|
height: root.availableHeight
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
show: (hoverHandler.hovered || root.adsFocus || verticalScrollBar.inUse)
|
||||||
|
&& verticalScrollBar.isNeeded
|
||||||
}
|
}
|
||||||
|
|
||||||
model: assetsModel
|
model: assetsModel
|
||||||
@@ -348,22 +362,21 @@ TreeView {
|
|||||||
root.currentFilePath = filePath
|
root.currentFilePath = filePath
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.enabled: true
|
function moveSelection(amount)
|
||||||
|
{
|
||||||
Keys.onUpPressed: {
|
if (!assetsModel.haveFiles || !amount)
|
||||||
if (!root.currentFilePath)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
let index = assetsModel.indexForPath(root.currentFilePath)
|
let index = root.currentFilePath ? assetsModel.indexForPath(root.currentFilePath)
|
||||||
|
: root.__modelIndex(root.firstRow)
|
||||||
let row = root.rowAtIndex(index)
|
let row = root.rowAtIndex(index)
|
||||||
let nextRow = row
|
let nextRow = row
|
||||||
let nextIndex = index
|
let nextIndex = index
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (nextRow <= root.firstRow)
|
nextRow = nextRow + amount
|
||||||
return // don't select hidden rows
|
if ((amount < 0 && nextRow < root.firstRow) || (amount > 0 && nextRow > root.lastRow))
|
||||||
|
return
|
||||||
nextRow--
|
|
||||||
nextIndex = root.__modelIndex(nextRow)
|
nextIndex = root.__modelIndex(nextRow)
|
||||||
} while (assetsModel.isDirectory(nextIndex))
|
} while (assetsModel.isDirectory(nextIndex))
|
||||||
|
|
||||||
@@ -371,26 +384,14 @@ TreeView {
|
|||||||
root.positionViewAtRow(nextRow, TableView.Contain)
|
root.positionViewAtRow(nextRow, TableView.Contain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.enabled: true
|
||||||
|
|
||||||
|
Keys.onUpPressed: {
|
||||||
|
moveSelection(-1)
|
||||||
|
}
|
||||||
|
|
||||||
Keys.onDownPressed: {
|
Keys.onDownPressed: {
|
||||||
if (!root.currentFilePath)
|
moveSelection(1)
|
||||||
return
|
|
||||||
|
|
||||||
let index = assetsModel.indexForPath(root.currentFilePath)
|
|
||||||
let row = root.rowAtIndex(index)
|
|
||||||
|
|
||||||
let nextRow = row
|
|
||||||
let nextIndex = index
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (nextRow >= root.lastRow)
|
|
||||||
return // don't select hidden rows
|
|
||||||
|
|
||||||
nextRow++
|
|
||||||
nextIndex = root.__modelIndex(nextRow)
|
|
||||||
} while (assetsModel.isDirectory(nextIndex))
|
|
||||||
|
|
||||||
root.__selectRow(nextRow)
|
|
||||||
root.positionViewAtRow(nextRow, TableView.Contain)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfirmDeleteFilesDialog {
|
ConfirmDeleteFilesDialog {
|
||||||
|
@@ -0,0 +1,288 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Qt.labs.platform as PlatformWidgets
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
implicitWidth: 300
|
||||||
|
implicitHeight: innerRect.height + 6
|
||||||
|
|
||||||
|
property color textColor
|
||||||
|
|
||||||
|
signal selectItem(int itemIndex)
|
||||||
|
signal deleteItem()
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: boundingRect
|
||||||
|
|
||||||
|
anchors.centerIn: root
|
||||||
|
width: root.width - 24
|
||||||
|
height: nameHolder.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: itemMouse
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
propagateComposedEvents: true
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: (event) => {
|
||||||
|
if (!collectionIsSelected) {
|
||||||
|
collectionIsSelected = true
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: innerRect
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width - threeDots.width
|
||||||
|
leftPadding: 20
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: moveTool
|
||||||
|
|
||||||
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
|
||||||
|
width: moveTool.style.squareControlSize.width
|
||||||
|
height: nameHolder.height
|
||||||
|
|
||||||
|
text: StudioTheme.Constants.dragmarks
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: moveTool.style.baseIconFontSize
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: nameHolder
|
||||||
|
|
||||||
|
text: collectionName
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
color: textColor
|
||||||
|
leftPadding: 5
|
||||||
|
topPadding: 8
|
||||||
|
rightPadding: 8
|
||||||
|
bottomPadding: 8
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: threeDots
|
||||||
|
|
||||||
|
text: "..."
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
color: textColor
|
||||||
|
anchors.right: boundingRect.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
rightPadding: 12
|
||||||
|
topPadding: nameHolder.topPadding
|
||||||
|
bottomPadding: nameHolder.bottomPadding
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton + Qt.LeftButton
|
||||||
|
onClicked: (event) => {
|
||||||
|
collectionMenu.open()
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformWidgets.Menu {
|
||||||
|
id: collectionMenu
|
||||||
|
|
||||||
|
PlatformWidgets.MenuItem {
|
||||||
|
text: qsTr("Delete")
|
||||||
|
shortcut: StandardKey.Delete
|
||||||
|
onTriggered: deleteDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformWidgets.MenuItem {
|
||||||
|
text: qsTr("Rename")
|
||||||
|
shortcut: StandardKey.Replace
|
||||||
|
onTriggered: renameDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.Dialog {
|
||||||
|
id: deleteDialog
|
||||||
|
|
||||||
|
title: qsTr("Deleting whole collection")
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Are you sure that you want to delete collection \"" + collectionName + "\"?")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // spacer
|
||||||
|
width: 1
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: btnDelete
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
text: qsTr("Delete")
|
||||||
|
onClicked: root.deleteItem(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: deleteDialog.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.Dialog {
|
||||||
|
id: renameDialog
|
||||||
|
|
||||||
|
title: qsTr("Rename collection")
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (newNameField.text !== "")
|
||||||
|
collectionName = newNameField.text
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
newNameField.text = collectionName
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Previous name: " + collectionName)
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 10
|
||||||
|
Text {
|
||||||
|
text: qsTr("New name:")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: newNameField
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
actionIndicator.visible: false
|
||||||
|
translationIndicator.visible: false
|
||||||
|
validator: newNameValidator
|
||||||
|
|
||||||
|
Keys.onEnterPressed: renameDialog.accept()
|
||||||
|
Keys.onReturnPressed: renameDialog.accept()
|
||||||
|
Keys.onEscapePressed: renameDialog.reject()
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
btnRename.enabled = newNameField.text !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // spacer
|
||||||
|
width: 1
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: btnRename
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: qsTr("Rename")
|
||||||
|
onClicked: renameDialog.accept()
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: renameDialog.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.RegExpValidator {
|
||||||
|
id: newNameValidator
|
||||||
|
regExp: /^\w+$/
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: !collectionIsSelected && !itemMouse.containsMouse
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: innerRect
|
||||||
|
opacity: 0.6
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
textColor: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "hovered"
|
||||||
|
when: !collectionIsSelected && itemMouse.containsMouse
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: innerRect
|
||||||
|
opacity: 0.8
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundHover
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
textColor: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "selected"
|
||||||
|
when: collectionIsSelected
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: innerRect
|
||||||
|
opacity: 1
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundInteraction
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
textColor: StudioTheme.Values.themeIconColorSelected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,154 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuickDesignerTheme 1.0
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import CollectionEditorBackend
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
property var rootView: CollectionEditorBackend.rootView
|
||||||
|
property var model: CollectionEditorBackend.model
|
||||||
|
property var singleCollectionModel: CollectionEditorBackend.singleCollectionModel
|
||||||
|
|
||||||
|
function showWarning(title, message) {
|
||||||
|
warningDialog.title = title
|
||||||
|
warningDialog.message = message
|
||||||
|
warningDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonImport {
|
||||||
|
id: jsonImporter
|
||||||
|
|
||||||
|
backendValue: root.rootView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
CsvImport {
|
||||||
|
id: csvImporter
|
||||||
|
|
||||||
|
backendValue: root.rootView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
NewCollectionDialog {
|
||||||
|
id: newCollection
|
||||||
|
|
||||||
|
backendValue: root.rootView
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Message {
|
||||||
|
id: warningDialog
|
||||||
|
|
||||||
|
title: ""
|
||||||
|
message: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: collectionsRect
|
||||||
|
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
width: 300
|
||||||
|
height: root.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.height + 5
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: collectionText
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: qsTr("Collections")
|
||||||
|
font.pixelSize: StudioTheme.Values.mediumIconFont
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
leftPadding: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
rightPadding: 12
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
HelperWidgets.IconButton {
|
||||||
|
icon: StudioTheme.Constants.translationImport
|
||||||
|
tooltip: qsTr("Import Json")
|
||||||
|
|
||||||
|
onClicked: jsonImporter.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.IconButton {
|
||||||
|
icon: StudioTheme.Constants.translationImport
|
||||||
|
tooltip: qsTr("Import CSV")
|
||||||
|
|
||||||
|
onClicked: csvImporter.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { // Collections
|
||||||
|
width: parent.width
|
||||||
|
color: StudioTheme.Values.themeBackgroundColorNormal
|
||||||
|
height: 330
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
propagateComposedEvents: true
|
||||||
|
onClicked: (event) => {
|
||||||
|
root.model.deselect()
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: collectionListView
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: contentHeight
|
||||||
|
model: root.model
|
||||||
|
|
||||||
|
delegate: CollectionItem {
|
||||||
|
onDeleteItem: root.model.removeRow(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: addCollectionButton.height
|
||||||
|
color: StudioTheme.Values.themeBackgroundColorNormal
|
||||||
|
|
||||||
|
IconTextButton {
|
||||||
|
id: addCollectionButton
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: qsTr("Add new collection")
|
||||||
|
icon: StudioTheme.Constants.create_medium
|
||||||
|
onClicked: newCollection.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SingleCollectionView {
|
||||||
|
model: root.singleCollectionModel
|
||||||
|
anchors {
|
||||||
|
left: collectionsRect.right
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,188 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuickDesignerTheme 1.0
|
||||||
|
import Qt.labs.platform as PlatformWidgets
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
StudioControls.Dialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title: qsTr("Import A CSV File")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
required property var backendValue
|
||||||
|
|
||||||
|
property bool fileExists: false
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
collectionName.text = "Collection_"
|
||||||
|
fileName.text = qsTr("New CSV File")
|
||||||
|
fileName.selectAll()
|
||||||
|
fileName.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
onRejected: {
|
||||||
|
fileName.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.RegExpValidator {
|
||||||
|
id: fileNameValidator
|
||||||
|
regExp: /^(\w[^*><?|]*)[^/\\:*><?|]$/
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformWidgets.FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
onAccepted: fileName.text = fileDialog.file
|
||||||
|
}
|
||||||
|
|
||||||
|
Message {
|
||||||
|
id: creationFailedDialog
|
||||||
|
|
||||||
|
title: qsTr("Could not load the file")
|
||||||
|
message: qsTr("An error occurred while trying to load the file.")
|
||||||
|
|
||||||
|
onClosed: root.reject()
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 10
|
||||||
|
Text {
|
||||||
|
text: qsTr("File name: ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: fileName
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
actionIndicator.visible: false
|
||||||
|
translationIndicator.visible: false
|
||||||
|
validator: fileNameValidator
|
||||||
|
|
||||||
|
Keys.onEnterPressed: btnCreate.onClicked()
|
||||||
|
Keys.onReturnPressed: btnCreate.onClicked()
|
||||||
|
Keys.onEscapePressed: root.reject()
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
root.fileExists = root.backendValue.isCsvFile(fileName.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: fileDialogButton
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: qsTr("Open")
|
||||||
|
onClicked: fileDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 10
|
||||||
|
Text {
|
||||||
|
text: qsTr("Collection name: ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: collectionName
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
actionIndicator.visible: false
|
||||||
|
translationIndicator.visible: false
|
||||||
|
validator: HelperWidgets.RegExpValidator {
|
||||||
|
regExp: /^\w+$/
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: btnCreate.onClicked()
|
||||||
|
Keys.onReturnPressed: btnCreate.onClicked()
|
||||||
|
Keys.onEscapePressed: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: fieldErrorText
|
||||||
|
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: fileName.text !== "" && collectionName.text !== ""
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: fieldErrorText
|
||||||
|
text: ""
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "fileError"
|
||||||
|
when: fileName.text === ""
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: fieldErrorText
|
||||||
|
text: qsTr("File name can not be empty")
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "collectionNameError"
|
||||||
|
when: collectionName.text === ""
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: fieldErrorText
|
||||||
|
text: qsTr("Collection name can not be empty")
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // spacer
|
||||||
|
width: 1
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: btnCreate
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: qsTr("Import")
|
||||||
|
enabled: root.fileExists && collectionName.text !== ""
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
let csvLoaded = root.backendValue.loadCsvFile(collectionName.text, fileName.text)
|
||||||
|
|
||||||
|
if (csvLoaded)
|
||||||
|
root.accept()
|
||||||
|
else
|
||||||
|
creationFailedDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,85 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property string text
|
||||||
|
required property string icon
|
||||||
|
|
||||||
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
|
||||||
|
implicitHeight: style.squareControlSize.height
|
||||||
|
implicitWidth: rowAlign.width
|
||||||
|
|
||||||
|
signal clicked()
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: rowAlign
|
||||||
|
spacing: 0
|
||||||
|
leftPadding: StudioTheme.Values.inputHorizontalPadding
|
||||||
|
rightPadding: StudioTheme.Values.inputHorizontalPadding
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: iconItem
|
||||||
|
width: root.style.squareControlSize.width
|
||||||
|
height: root.height
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: root.icon
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: root.style.baseIconFontSize
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: textItem
|
||||||
|
height: root.height
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: root.text
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.family: StudioTheme.Constants.font.family
|
||||||
|
font.pixelSize: root.style.baseIconFontSize
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: root.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: !mouseArea.pressed && !mouseArea.containsMouse
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
color: StudioTheme.Values.themeBackgroundColorNormal
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "Pressed"
|
||||||
|
when: mouseArea.pressed
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundInteraction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "Hovered"
|
||||||
|
when: !mouseArea.pressed && mouseArea.containsMouse
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
color: StudioTheme.Values.themeControlBackgroundHover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,127 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuickDesignerTheme 1.0
|
||||||
|
import Qt.labs.platform as PlatformWidgets
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
StudioControls.Dialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title: qsTr("Import Collections")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
required property var backendValue
|
||||||
|
property bool fileExists: false
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
fileName.text = qsTr("New Json File")
|
||||||
|
fileName.selectAll()
|
||||||
|
fileName.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
onRejected: {
|
||||||
|
fileName.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.RegExpValidator {
|
||||||
|
id: fileNameValidator
|
||||||
|
regExp: /^(\w[^*><?|]*)[^/\\:*><?|]$/
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformWidgets.FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
onAccepted: fileName.text = fileDialog.file
|
||||||
|
}
|
||||||
|
|
||||||
|
Message {
|
||||||
|
id: creationFailedDialog
|
||||||
|
|
||||||
|
title: qsTr("Could not load the file")
|
||||||
|
message: qsTr("An error occurred while trying to load the file.")
|
||||||
|
|
||||||
|
onClosed: root.reject()
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 10
|
||||||
|
Text {
|
||||||
|
text: qsTr("File name: ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: fileName
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
actionIndicator.visible: false
|
||||||
|
translationIndicator.visible: false
|
||||||
|
validator: fileNameValidator
|
||||||
|
|
||||||
|
Keys.onEnterPressed: btnCreate.onClicked()
|
||||||
|
Keys.onReturnPressed: btnCreate.onClicked()
|
||||||
|
Keys.onEscapePressed: root.reject()
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
root.fileExists = root.backendValue.isJsonFile(fileName.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: fileDialogButton
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: qsTr("Open")
|
||||||
|
onClicked: fileDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("File name cannot be empty.")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
anchors.right: parent.right
|
||||||
|
visible: fileName.text === ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // spacer
|
||||||
|
width: 1
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: btnCreate
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
text: qsTr("Import")
|
||||||
|
enabled: root.fileExists
|
||||||
|
onClicked: {
|
||||||
|
let jsonLoaded = root.backendValue.loadJsonFile(fileName.text)
|
||||||
|
|
||||||
|
if (jsonLoaded)
|
||||||
|
root.accept()
|
||||||
|
else
|
||||||
|
creationFailedDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
StudioControls.Dialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property string message
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
implicitWidth: 300
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 20
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: root.message
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
width: root.width
|
||||||
|
leftPadding: 10
|
||||||
|
rightPadding: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Close")
|
||||||
|
anchors.right: parent.right
|
||||||
|
onClicked: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpened: root.forceActiveFocus()
|
||||||
|
}
|
@@ -0,0 +1,93 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuickDesignerTheme 1.0
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
StudioControls.Dialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title: qsTr("Add a new Collection")
|
||||||
|
anchors.centerIn: parent
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
modal: true
|
||||||
|
|
||||||
|
required property var backendValue
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
collectionName.text = "Collection"
|
||||||
|
}
|
||||||
|
|
||||||
|
onRejected: {
|
||||||
|
collectionName.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
if (collectionName.text !== "")
|
||||||
|
root.backendValue.addCollection(collectionName.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
spacing: 10
|
||||||
|
Row {
|
||||||
|
spacing: 10
|
||||||
|
Text {
|
||||||
|
text: qsTr("Collection name: ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: collectionName
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
actionIndicator.visible: false
|
||||||
|
translationIndicator.visible: false
|
||||||
|
validator: HelperWidgets.RegExpValidator {
|
||||||
|
regExp: /^\w+$/
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: btnCreate.onClicked()
|
||||||
|
Keys.onReturnPressed: btnCreate.onClicked()
|
||||||
|
Keys.onEscapePressed: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: fieldErrorText
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: qsTr("Collection name can not be empty")
|
||||||
|
visible: collectionName.text === ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // spacer
|
||||||
|
width: 1
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
id: btnCreate
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
text: qsTr("Create")
|
||||||
|
enabled: collectionName.text !== ""
|
||||||
|
onClicked: root.accept()
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Cancel")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
onClicked: root.reject()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,134 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var model
|
||||||
|
|
||||||
|
property alias leftPadding: topRow.leftPadding
|
||||||
|
property real rightPadding: topRow.rightPadding
|
||||||
|
|
||||||
|
color: StudioTheme.Values.themeBackgroundColorAlternate
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: topRow
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
width: parent.width
|
||||||
|
leftPadding: 20
|
||||||
|
rightPadding: 0
|
||||||
|
topPadding: 5
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: collectionNameText
|
||||||
|
|
||||||
|
leftPadding: 8
|
||||||
|
rightPadding: 8
|
||||||
|
topPadding: 3
|
||||||
|
bottomPadding: 3
|
||||||
|
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
text: root.model.collectionName
|
||||||
|
font.pixelSize: StudioTheme.Values.mediumIconFont
|
||||||
|
elide: Text.ElideRight
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
z: parent.z - 1
|
||||||
|
color: StudioTheme.Values.themeBackgroundColorNormal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // spacer
|
||||||
|
width: 1
|
||||||
|
height: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalHeaderView {
|
||||||
|
id: headerView
|
||||||
|
|
||||||
|
property real topPadding: 5
|
||||||
|
property real bottomPadding: 5
|
||||||
|
|
||||||
|
height: headerMetrics.height + topPadding + bottomPadding
|
||||||
|
|
||||||
|
syncView: tableView
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
implicitWidth: 100
|
||||||
|
implicitHeight: headerText.height
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
border.width: 2
|
||||||
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: headerText
|
||||||
|
|
||||||
|
topPadding: headerView.topPadding
|
||||||
|
bottomPadding: headerView.bottomPadding
|
||||||
|
leftPadding: 5
|
||||||
|
rightPadding: 5
|
||||||
|
text: display
|
||||||
|
font.pixelSize: headerMetrics.font
|
||||||
|
color: StudioTheme.Values.themeIdleGreen
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
anchors.centerIn: parent
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: headerMetrics
|
||||||
|
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
text: "Xq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TableView {
|
||||||
|
id: tableView
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: topRow.bottom
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
leftMargin: root.leftPadding
|
||||||
|
rightMargin: root.rightPadding
|
||||||
|
}
|
||||||
|
|
||||||
|
model: root.model
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
implicitWidth: 100
|
||||||
|
implicitHeight: itemText.height
|
||||||
|
color: StudioTheme.Values.themeControlBackground
|
||||||
|
border.width: 1
|
||||||
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: itemText
|
||||||
|
|
||||||
|
text: display
|
||||||
|
width: parent.width
|
||||||
|
leftPadding: 5
|
||||||
|
topPadding: 3
|
||||||
|
bottomPadding: 3
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,12 +2,39 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
|
||||||
PopupDialog {
|
PopupDialog {
|
||||||
property alias backend: form.backend
|
property alias backend: form.backend
|
||||||
|
titleBar: Row {
|
||||||
|
spacing: 30 // TODO
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
text: qsTr("Owner")
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
tooltip: qsTr("The owner of the property")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: form.backend.targetNode
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
BindingsDialogForm {
|
BindingsDialogForm {
|
||||||
id: form
|
id: form
|
||||||
y: 32
|
y: 32
|
||||||
|
height: 160
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,84 +3,58 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import StudioControls
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
Rectangle {
|
Column {
|
||||||
width: 400
|
id: root
|
||||||
height: 800
|
|
||||||
color: "#1b1b1b"
|
readonly property real horizontalSpacing: 10
|
||||||
|
readonly property real verticalSpacing: 16
|
||||||
|
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||||
|
|
||||||
property var backend
|
property var backend
|
||||||
|
|
||||||
Text {
|
y: StudioTheme.Values.popupMargin
|
||||||
id: text1
|
width: parent.width
|
||||||
x: 10
|
spacing: root.verticalSpacing
|
||||||
y: 25
|
|
||||||
color: "#ffffff"
|
Row {
|
||||||
text: qsTr("Target")
|
spacing: root.horizontalSpacing
|
||||||
font.pixelSize: 15
|
|
||||||
|
PopupLabel { text: qsTr("From") ; tooltip: qsTr("The Property to assign from.")}
|
||||||
|
PopupLabel { text: qsTr("To"); tooltip: qsTr("The Property to assign to.") }
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Row {
|
||||||
id: text111
|
spacing: root.horizontalSpacing
|
||||||
x: 80
|
|
||||||
y: 25
|
|
||||||
color: "red"
|
|
||||||
text: backend.targetNode
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
id: target
|
|
||||||
x: 101
|
|
||||||
width: 210
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -335
|
|
||||||
model: backend.property.model ?? []
|
|
||||||
enabled: false
|
|
||||||
//I see no use case to actually change the property name
|
|
||||||
//onActivated: backend.targetNode.activateIndex(target.currentIndex)
|
|
||||||
property int currentTypeIndex: backend.property.currentIndex ?? 0
|
|
||||||
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: text2
|
|
||||||
x: 13
|
|
||||||
y: 111
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Source Propety")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: sourceNode
|
id: sourceNode
|
||||||
x: 135
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
y: 98
|
width: root.columnWidth
|
||||||
width: 156
|
|
||||||
|
|
||||||
model: backend.sourceNode.model ?? []
|
model: backend.sourceNode.model ?? []
|
||||||
|
|
||||||
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||||
|
|
||||||
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
||||||
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
||||||
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
PopupLabel {
|
||||||
x: 13
|
width: root.columnWidth
|
||||||
y: 88
|
text: backend.targetNode
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Source Node")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TopLevelComboBox {
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
id: sourceProperty
|
id: sourceProperty
|
||||||
x: 140
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
y: 121
|
width: root.columnWidth
|
||||||
width: 156
|
|
||||||
|
|
||||||
model: backend.sourceProperty.model ?? []
|
model: backend.sourceProperty.model ?? []
|
||||||
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||||
@@ -90,12 +64,16 @@ Rectangle {
|
|||||||
onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
StudioControls.TopLevelComboBox {
|
||||||
id: text3
|
id: name
|
||||||
x: 10
|
width: root.columnWidth
|
||||||
y: 55
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Property")
|
model: backend.property.model ?? []
|
||||||
font.pixelSize: 15
|
|
||||||
|
onActivated: backend.property.activateIndex(name.currentIndex)
|
||||||
|
property int currentTypeIndex: backend.property.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: name.currentIndex = name.currentTypeIndex
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,121 +3,188 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import ConnectionsEditor
|
|
||||||
import HelperWidgets 2.0 as HelperWidgets
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
import StudioControls 1.0 as StudioControls
|
import StudioControls 1.0 as StudioControls
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import ConnectionsEditorEditorBackend
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: listView
|
id: root
|
||||||
width: 606
|
|
||||||
height: 160
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||||
interactive: false
|
|
||||||
|
property bool adsFocus: false
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
interactive: true
|
||||||
highlightMoveDuration: 0
|
highlightMoveDuration: 0
|
||||||
|
highlightResizeDuration: 0
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
HoverHandler { id: hoverHandler }
|
||||||
|
|
||||||
|
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||||
|
id: verticalScrollBar
|
||||||
|
parent: root
|
||||||
|
x: root.width - verticalScrollBar.width
|
||||||
|
y: 0
|
||||||
|
height: root.availableHeight
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
show: (hoverHandler.hovered || root.focus || verticalScrollBar.inUse || root.adsFocus)
|
||||||
|
&& verticalScrollBar.isNeeded
|
||||||
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
dialog.hide()
|
dialog.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
property int modelCurrentIndex: listView.model.currentIndex ?? 0
|
property int modelCurrentIndex: root.model.currentIndex ?? 0
|
||||||
|
|
||||||
|
// Something weird with currentIndex happens when items are removed added.
|
||||||
|
// listView.model.currentIndex contains the persistent index.
|
||||||
|
|
||||||
/* Something weird with currentIndex happens when items are removed added.
|
|
||||||
listView.model.currentIndex contains the persistent index.
|
|
||||||
*/
|
|
||||||
onModelCurrentIndexChanged: {
|
onModelCurrentIndexChanged: {
|
||||||
listView.currentIndex = listView.model.currentIndex
|
root.currentIndex = root.model.currentIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
listView.currentIndex = listView.model.currentIndex
|
root.currentIndex = root.model.currentIndex
|
||||||
dialog.backend.currentRow = listView.currentIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of columns
|
||||||
|
readonly property int numColumns: 4
|
||||||
|
// Proper row width calculation
|
||||||
|
readonly property int rowSpacing: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
|
readonly property int rowSpace: root.width - (root.rowSpacing * (root.numColumns + 1))
|
||||||
|
- root.style.squareControlSize.width
|
||||||
|
property int rowWidth: root.rowSpace / root.numColumns
|
||||||
|
property int rowRest: root.rowSpace % root.numColumns
|
||||||
|
|
||||||
data: [
|
data: [
|
||||||
BindingsDialog {
|
BindingsDialog {
|
||||||
id: dialog
|
id: dialog
|
||||||
visible: false
|
visible: false
|
||||||
backend: listView.model.delegate
|
backend: root.model.delegate
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
delegate: Item {
|
|
||||||
|
|
||||||
width: 600
|
delegate: Rectangle {
|
||||||
height: 18
|
id: itemDelegate
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
required property string target
|
||||||
|
required property string targetProperty
|
||||||
|
required property string source
|
||||||
|
required property string sourceProperty
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
|
height: root.style.squareControlSize.height
|
||||||
|
color: mouseArea.containsMouse ?
|
||||||
|
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||||
|
: root.style.background.hover
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
listView.model.currentIndex = index
|
root.model.currentIndex = itemDelegate.index
|
||||||
listView.currentIndex = index
|
root.currentIndex = itemDelegate.index
|
||||||
dialog.backend.currentRow = index
|
|
||||||
dialog.popup(mouseArea)
|
dialog.popup(mouseArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
property int currentIndex: listView.currentIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: row1
|
id: row
|
||||||
x: 0
|
|
||||||
y: 0
|
property color textColor: itemDelegate.ListView.isCurrentItem ? root.style.text.selectedText
|
||||||
width: 600
|
: root.style.icon.idle
|
||||||
height: 16
|
|
||||||
spacing: 10
|
height: itemDelegate.height
|
||||||
|
spacing: root.rowSpacing
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth + root.rowRest
|
||||||
color: "#ffffff"
|
height: itemDelegate.height
|
||||||
text: target ?? ""
|
color: row.textColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
text: itemDelegate.target ?? ""
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
leftPadding: root.rowSpacing
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth
|
||||||
text: targetProperty ?? ""
|
height: itemDelegate.height
|
||||||
color: "#ffffff"
|
text: itemDelegate.targetProperty ?? ""
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
color: row.textColor
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth
|
||||||
text: source ?? ""
|
height: itemDelegate.height
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
text: itemDelegate.source ?? ""
|
||||||
color: "#ffffff"
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: row.textColor
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth
|
||||||
text: sourceProperty ?? ""
|
height: itemDelegate.height
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
text: itemDelegate.sourceProperty ?? ""
|
||||||
color: "#ffffff"
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: row.textColor
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Rectangle {
|
||||||
width: 120
|
width: root.style.squareControlSize.width
|
||||||
|
height: root.style.squareControlSize.height
|
||||||
|
|
||||||
text: "-"
|
color: toolTipArea.containsMouse ?
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||||
horizontalAlignment: Text.AlignRight
|
: root.style.background.hover
|
||||||
font.pointSize: 14
|
: "transparent"
|
||||||
color: "#ffffff"
|
|
||||||
font.bold: true
|
Text {
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: listView.model.remove(index)
|
|
||||||
|
text: StudioTheme.Constants.remove_medium
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: root.style.baseIconFontSize
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
color: row.textColor
|
||||||
|
renderType: Text.QtRendering
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
id: toolTipArea
|
||||||
|
tooltip: qsTr("This is a test.")
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.model.remove(itemDelegate.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
highlight: Rectangle {
|
highlight: Rectangle {
|
||||||
color: "#2a5593"
|
color: root.style.interaction
|
||||||
width: 600
|
width: 600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,44 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
|
||||||
PopupDialog {
|
PopupDialog {
|
||||||
|
|
||||||
|
property alias backend: form.backend
|
||||||
|
|
||||||
|
titleBar: Row {
|
||||||
|
spacing: 30 // TODO
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
text: qsTr("Target")
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
tooltip: qsTr("Choose the target for the signal.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: target
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: 180
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
model: backend.signal.id.model ?? 0
|
||||||
|
|
||||||
|
onActivated: backend.signal.id.activateIndex(target.currentIndex)
|
||||||
|
property int currentTypeIndex: backend.signal.id.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ConnectionsDialogForm {
|
ConnectionsDialogForm {
|
||||||
y: 32
|
id: form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,242 +1,207 @@
|
|||||||
|
|
||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import StudioControls
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
Rectangle {
|
Column {
|
||||||
width: 400
|
id: root
|
||||||
height: 800
|
|
||||||
color: "#1b1b1b"
|
|
||||||
|
|
||||||
Text {
|
readonly property real horizontalSpacing: 10
|
||||||
id: text1
|
readonly property real verticalSpacing: 16
|
||||||
x: 10
|
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||||
y: 25
|
|
||||||
color: "#ffffff"
|
property var backend
|
||||||
text: qsTr("Target:")
|
|
||||||
font.pixelSize: 15
|
y: StudioTheme.Values.popupMargin
|
||||||
|
width: parent.width
|
||||||
|
spacing: root.verticalSpacing
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
onTapped: root.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
TopLevelComboBox {
|
Row {
|
||||||
id: target
|
spacing: root.horizontalSpacing
|
||||||
x: 95
|
|
||||||
width: 210
|
PopupLabel { text: qsTr("Signal"); tooltip: qsTr("The name of the signal.") }
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
PopupLabel { text: qsTr("Action"); tooltip: qsTr("The type of the action.") }
|
||||||
anchors.verticalCenterOffset: -367
|
|
||||||
model: ["mySpinbox", "foo", "backendObject"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Row {
|
||||||
id: text2
|
spacing: root.horizontalSpacing
|
||||||
x: 10
|
|
||||||
y: 131
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Signal")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
id: signal
|
id: signal
|
||||||
x: 10
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
y: 7
|
width: root.columnWidth
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
model: backend.signal.name.model ?? 0
|
||||||
anchors.verticalCenterOffset: -207
|
|
||||||
model: ["onClicked", "onPressed", "onReleased"]
|
onActivated: backend.signal.name.activateIndex(signal.currentIndex)
|
||||||
|
property int currentTypeIndex: backend.signal.name.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: signal.currentIndex = signal.currentTypeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
id: action
|
id: action
|
||||||
x: 207
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
y: 7
|
width: root.columnWidth
|
||||||
width: 156
|
textRole: "text"
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
valueRole: "value"
|
||||||
anchors.verticalCenterOffset: -207
|
///model.getData(currentIndex, "role")
|
||||||
model: ["Call Function", "Assign", "ChnageState"]
|
property int indexFromBackend: indexOfValue(backend.actionType)
|
||||||
|
onIndexFromBackendChanged: action.currentIndex = action.indexFromBackend
|
||||||
|
onActivated: backend.changeActionType(action.currentValue)
|
||||||
|
|
||||||
|
model: [
|
||||||
|
{ value: ConnectionModelStatementDelegate.CallFunction, text: qsTr("Call Function") },
|
||||||
|
{ value: ConnectionModelStatementDelegate.Assign, text: qsTr("Assign") },
|
||||||
|
{ value: ConnectionModelStatementDelegate.ChangeState, text: qsTr("Change State") },
|
||||||
|
{ value: ConnectionModelStatementDelegate.SetProperty, text: qsTr("Set Property") },
|
||||||
|
{ value: ConnectionModelStatementDelegate.PrintMessage, text: qsTr("Print Message") },
|
||||||
|
{ value: ConnectionModelStatementDelegate.Custom, text: qsTr("Unknown") }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatementEditor {
|
||||||
|
actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom
|
||||||
|
horizontalSpacing: root.horizontalSpacing
|
||||||
|
columnWidth: root.columnWidth
|
||||||
|
statement: backend.okStatement
|
||||||
|
spacing: root.verticalSpacing
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
style: StudioTheme.Values.connectionPopupButtonStyle
|
||||||
|
width: 160
|
||||||
|
buttonIcon: qsTr("Add Condition")
|
||||||
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && !backend.hasCondition
|
||||||
|
|
||||||
|
onClicked: backend.addCondition()
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
style: StudioTheme.Values.connectionPopupButtonStyle
|
||||||
|
width: 160
|
||||||
|
buttonIcon: qsTr("Remove Condition")
|
||||||
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition
|
||||||
|
|
||||||
|
onClicked: backend.removeCondition()
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpressionBuilder {
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.width
|
||||||
|
|
||||||
|
visible: backend.hasCondition
|
||||||
|
model: backend.conditionListModel
|
||||||
|
|
||||||
|
onRemove: function(index) {
|
||||||
|
//console.log("remove", index)
|
||||||
|
backend.conditionListModel.removeToken(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdate: function(index, value) {
|
||||||
|
//console.log("update", index, value)
|
||||||
|
backend.conditionListModel.updateToken(index, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd: function(value) {
|
||||||
|
//console.log("add", value)
|
||||||
|
backend.conditionListModel.appendToken(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onInsert: function(index, value, type) {
|
||||||
|
//console.log("insert", index, value, type)
|
||||||
|
if (type === ConditionListModel.Intermediate)
|
||||||
|
backend.conditionListModel.insertIntermediateToken(index, value)
|
||||||
|
else if (type === ConditionListModel.Shadow)
|
||||||
|
backend.conditionListModel.insertShadowToken(index, value)
|
||||||
|
else
|
||||||
|
backend.conditionListModel.insertToken(index, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onSetValue: function(index, value) {
|
||||||
|
//console.log("setValue", index, value)
|
||||||
|
backend.conditionListModel.setShadowToken(index, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
style: StudioTheme.Values.connectionPopupButtonStyle
|
||||||
|
width: 160
|
||||||
|
buttonIcon: qsTr("Add Else Statement")
|
||||||
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
|
||||||
|
&& backend.hasCondition && !backend.hasElse
|
||||||
|
|
||||||
|
onClicked: backend.addElse()
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
style: StudioTheme.Values.connectionPopupButtonStyle
|
||||||
|
width: 160
|
||||||
|
buttonIcon: qsTr("Remove Else Statement")
|
||||||
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
|
||||||
|
&& backend.hasCondition && backend.hasElse
|
||||||
|
|
||||||
|
onClicked: backend.removeElse()
|
||||||
|
}
|
||||||
|
|
||||||
|
//Else Statement
|
||||||
|
StatementEditor {
|
||||||
|
actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom
|
||||||
|
horizontalSpacing: root.horizontalSpacing
|
||||||
|
columnWidth: root.columnWidth
|
||||||
|
statement: backend.koStatement
|
||||||
|
spacing: root.verticalSpacing
|
||||||
|
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
|
||||||
|
&& backend.hasCondition && backend.hasElse
|
||||||
|
}
|
||||||
|
|
||||||
|
// Editor
|
||||||
|
Rectangle {
|
||||||
|
id: editor
|
||||||
|
width: parent.width
|
||||||
|
height: 150
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: text3
|
width: parent.width - 8 // twice the editor button margins
|
||||||
x: 207
|
anchors.centerIn: parent
|
||||||
y: 131
|
text: backend.source
|
||||||
color: "#ffffff"
|
color: StudioTheme.Values.themeTextColor
|
||||||
text: qsTr("Action")
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
font.pixelSize: 15
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
HelperWidgets.AbstractButton {
|
||||||
id: functionGroup
|
id: editorButton
|
||||||
x: 0
|
|
||||||
y: 276
|
|
||||||
width: 400
|
|
||||||
height: 176
|
|
||||||
|
|
||||||
Text {
|
anchors.top: parent.top
|
||||||
id: text4
|
anchors.right: parent.right
|
||||||
x: 17
|
anchors.margins: 4
|
||||||
y: -11
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Target")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
id: functionTarget
|
buttonIcon: StudioTheme.Constants.edit_medium
|
||||||
x: 10
|
tooltip: qsTr("Add something.")
|
||||||
y: 7
|
onClicked: console.log("OPEN EDITOR")
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -48
|
|
||||||
model: ["mySpinBox", "backendObject", "someButton"]
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: functionName
|
|
||||||
x: 203
|
|
||||||
y: 7
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -48
|
|
||||||
model: ["start", "trigger", "stop"]
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: text5
|
|
||||||
x: 203
|
|
||||||
y: -11
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Function")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: statesGroup
|
|
||||||
x: 0
|
|
||||||
y: 383
|
|
||||||
width: 400
|
|
||||||
height: 106
|
|
||||||
Text {
|
|
||||||
id: text6
|
|
||||||
x: 17
|
|
||||||
y: -11
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("State Group")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: stateGroup
|
|
||||||
x: 10
|
|
||||||
y: 7
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -12
|
|
||||||
model: ["default", "State Group 01", "State Group 02"]
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: stateName
|
|
||||||
x: 209
|
|
||||||
y: 7
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -12
|
|
||||||
model: ["State 01", "State 02", "State 03"]
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: text7
|
|
||||||
x: 209
|
|
||||||
y: -11
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("State")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: assignment
|
|
||||||
x: 10
|
|
||||||
y: 505
|
|
||||||
width: 400
|
|
||||||
height: 106
|
|
||||||
Text {
|
|
||||||
id: text8
|
|
||||||
x: 17
|
|
||||||
y: -11
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("target")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: valueTarget
|
|
||||||
x: 10
|
|
||||||
y: 7
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -12
|
|
||||||
model: ["mySpinBox", "myButton", "backendObject"]
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: valueSource
|
|
||||||
x: 209
|
|
||||||
y: 7
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -12
|
|
||||||
model: ["mySpinBox", "myButton", "backendObject"]
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: text9
|
|
||||||
x: 209
|
|
||||||
y: -11
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("source")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: text10
|
|
||||||
x: 17
|
|
||||||
y: 76
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("value")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: valueOut
|
|
||||||
x: 10
|
|
||||||
y: -2
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: 84
|
|
||||||
model: ["width", "height", "opacity"]
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: valueIn
|
|
||||||
x: 209
|
|
||||||
y: -2
|
|
||||||
width: 156
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: 84
|
|
||||||
model: ["width", "height", "x", "y"]
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: text11
|
|
||||||
x: 209
|
|
||||||
y: 76
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("value")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,113 +3,178 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import ConnectionsEditor
|
|
||||||
import HelperWidgets 2.0 as HelperWidgets
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
import StudioControls 1.0 as StudioControls
|
import StudioControls 1.0 as StudioControls
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import ConnectionsEditorEditorBackend
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: listView
|
id: root
|
||||||
width: 606
|
|
||||||
height: 160
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||||
interactive: false
|
|
||||||
|
property bool adsFocus: false
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
interactive: true
|
||||||
highlightMoveDuration: 0
|
highlightMoveDuration: 0
|
||||||
|
highlightResizeDuration: 0
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
HoverHandler { id: hoverHandler }
|
||||||
|
|
||||||
|
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||||
|
id: verticalScrollBar
|
||||||
|
parent: root
|
||||||
|
x: root.width - verticalScrollBar.width
|
||||||
|
y: 0
|
||||||
|
height: root.availableHeight
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
show: (hoverHandler.hovered || root.focus || verticalScrollBar.inUse || root.adsFocus)
|
||||||
|
&& verticalScrollBar.isNeeded
|
||||||
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
dialog.hide()
|
dialog.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
property int modelCurrentIndex: listView.model.currentIndex ?? 0
|
property int modelCurrentIndex: root.model.currentIndex ?? 0
|
||||||
|
|
||||||
|
// Something weird with currentIndex happens when items are removed added.
|
||||||
|
// listView.model.currentIndex contains the persistent index.
|
||||||
|
|
||||||
/*
|
|
||||||
Something weird with currentIndex happens when items are removed added.
|
|
||||||
listView.model.currentIndex contains the persistent index.
|
|
||||||
*/
|
|
||||||
onModelCurrentIndexChanged: {
|
onModelCurrentIndexChanged: {
|
||||||
listView.currentIndex = listView.model.currentIndex
|
root.currentIndex = root.model.currentIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
listView.currentIndex = listView.model.currentIndex
|
root.currentIndex = root.model.currentIndex
|
||||||
|
dialog.backend.currentRow = root.currentIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of columns
|
||||||
|
readonly property int numColumns: 3
|
||||||
|
// Proper row width calculation
|
||||||
|
readonly property int rowSpacing: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
|
readonly property int rowSpace: root.width - (root.rowSpacing * (root.numColumns + 1))
|
||||||
|
- root.style.squareControlSize.width
|
||||||
|
property int rowWidth: root.rowSpace / root.numColumns
|
||||||
|
property int rowRest: root.rowSpace % root.numColumns
|
||||||
|
|
||||||
data: [
|
data: [
|
||||||
ConnectionsDialog {
|
ConnectionsDialog {
|
||||||
id: dialog
|
id: dialog
|
||||||
visible: false
|
visible: false
|
||||||
|
backend: root.model.delegate
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Rectangle {
|
||||||
|
id: itemDelegate
|
||||||
|
|
||||||
width: 600
|
required property int index
|
||||||
height: 18
|
|
||||||
|
required property string signal
|
||||||
|
required property string target
|
||||||
|
required property string action
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
|
height: root.style.squareControlSize.height
|
||||||
|
color: mouseArea.containsMouse ?
|
||||||
|
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||||
|
: root.style.background.hover
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
listView.model.currentIndex = index
|
root.model.currentIndex = itemDelegate.index
|
||||||
listView.currentIndex = index
|
root.currentIndex = itemDelegate.index
|
||||||
|
dialog.backend.currentRow = itemDelegate.index
|
||||||
dialog.popup(mouseArea)
|
dialog.popup(mouseArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
property int currentIndex: listView.currentIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: row1
|
id: row
|
||||||
x: 0
|
|
||||||
y: 0
|
property color textColor: itemDelegate.ListView.isCurrentItem ? root.style.text.selectedText
|
||||||
width: 600
|
: root.style.icon.idle
|
||||||
height: 16
|
|
||||||
spacing: 10
|
height: itemDelegate.height
|
||||||
|
spacing: root.rowSpacing
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth + root.rowRest
|
||||||
color: "#ffffff"
|
height: itemDelegate.height
|
||||||
text: target
|
color: row.textColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
text: itemDelegate.target
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
leftPadding: root.rowSpacing
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth
|
||||||
text: signal
|
height: itemDelegate.height
|
||||||
color: "#ffffff"
|
text: itemDelegate.signal
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
color: row.textColor
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth
|
||||||
|
height: itemDelegate.height
|
||||||
text: action
|
text: itemDelegate.action
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
color: "#ffffff"
|
color: row.textColor
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Rectangle {
|
||||||
width: 120
|
width: root.style.squareControlSize.width
|
||||||
|
height: root.style.squareControlSize.height
|
||||||
|
|
||||||
text: "-"
|
color: toolTipArea.containsMouse ?
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||||
horizontalAlignment: Text.AlignRight
|
: root.style.background.hover
|
||||||
font.pointSize: 14
|
: "transparent"
|
||||||
color: "#ffffff"
|
|
||||||
font.bold: true
|
Text {
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: listView.model.remove(index)
|
|
||||||
|
text: StudioTheme.Constants.remove_medium
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: root.style.baseIconFontSize
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
color: row.textColor
|
||||||
|
renderType: Text.QtRendering
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
id: toolTipArea
|
||||||
|
tooltip: qsTr("This is a test.")
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.model.remove(itemDelegate.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
highlight: Rectangle {
|
highlight: Rectangle {
|
||||||
color: "#2a5593"
|
color: root.style.interaction
|
||||||
width: 600
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,495 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
|
||||||
|
|
||||||
|
property var conditionListModel: ConnectionsEditorEditorBackend.connectionModel.delegate.conditionListModel
|
||||||
|
|
||||||
|
property alias model: repeater.model
|
||||||
|
property int shadowPillIndex: -1
|
||||||
|
property bool shadowPillVisible: root.shadowPillIndex !== -1
|
||||||
|
|
||||||
|
// Make expression editor at least 20 px high, especially when empty
|
||||||
|
property int baseHeight: Math.max(20, flow.childrenRect.height)
|
||||||
|
property int heightBeforeShadowPill: root.baseHeight
|
||||||
|
property int expressionHeight: {
|
||||||
|
// If expression is empty or the only item is a shadow pill
|
||||||
|
if (repeater.count === 0 || (repeater.count === 1 && root.shadowPillVisible))
|
||||||
|
return root.heightBeforeShadowPill
|
||||||
|
|
||||||
|
if (popup.visible)
|
||||||
|
return root.heightBeforeShadowPill + flow.spacing + 20
|
||||||
|
|
||||||
|
return root.heightBeforeShadowPill
|
||||||
|
}
|
||||||
|
|
||||||
|
signal remove(int index)
|
||||||
|
signal update(int index, var value)
|
||||||
|
signal add(var value)
|
||||||
|
signal insert(int index, var value, int type)
|
||||||
|
|
||||||
|
signal setValue(int index, var value)
|
||||||
|
signal setValueType(int index, var value, int type)
|
||||||
|
|
||||||
|
width: 400
|
||||||
|
height: root.expressionHeight + 2 * StudioTheme.Values.flowMargin
|
||||||
|
color: {
|
||||||
|
if (focusScope.activeFocus || popup.searchActive)
|
||||||
|
return root.style.background.interaction
|
||||||
|
|
||||||
|
if (mouseArea.containsMouse)
|
||||||
|
return root.style.background.hover
|
||||||
|
|
||||||
|
return root.style.background.idle
|
||||||
|
}
|
||||||
|
border {
|
||||||
|
color: {
|
||||||
|
if (!root.conditionListModel.valid)
|
||||||
|
return StudioTheme.Values.themeError
|
||||||
|
|
||||||
|
if (focusScope.activeFocus)
|
||||||
|
return root.style.border.interaction
|
||||||
|
|
||||||
|
if (mouseArea.containsMouse)
|
||||||
|
return root.style.border.hover
|
||||||
|
|
||||||
|
return root.style.border.idle
|
||||||
|
}
|
||||||
|
width: root.style.borderWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (!root.visible)
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is text input for creating new items currently used.
|
||||||
|
function textInputActive() { // TODO Make property
|
||||||
|
return newTextInput.activeFocus && newTextInput.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMappedItemRect(index: int) : rect {
|
||||||
|
let item = repeater.itemAt(index)
|
||||||
|
let itemRect = Qt.rect(item.x, item.y, item.width, item.height)
|
||||||
|
return flow.mapToItem(root, itemRect)
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeCursor(index: int) : void {
|
||||||
|
var textInputPosition = Qt.point(0, 0)
|
||||||
|
|
||||||
|
if (!repeater.count) { // Empty repeater
|
||||||
|
let mappedItemRect = flow.mapToItem(root, 0, 0, 0, 0)
|
||||||
|
|
||||||
|
textInputPosition = Qt.point(mappedItemRect.x, mappedItemRect.y)
|
||||||
|
index = 0
|
||||||
|
} else { // Repeater is not empty
|
||||||
|
// Clamp index to 0 and num items in repeater
|
||||||
|
index = Math.min(Math.max(index, 0), repeater.count)
|
||||||
|
|
||||||
|
if (index === 0) {
|
||||||
|
// Needs to be placed in front of first repeater item
|
||||||
|
let mappedItemRect = root.getMappedItemRect(index)
|
||||||
|
textInputPosition = Qt.point(mappedItemRect.x - 4, // - 4 due to spacing of flow
|
||||||
|
mappedItemRect.y)
|
||||||
|
} else {
|
||||||
|
let mappedItemRect = root.getMappedItemRect(index - 1)
|
||||||
|
textInputPosition = Qt.point(mappedItemRect.x + mappedItemRect.width + 3,
|
||||||
|
mappedItemRect.y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position text input, make it visible and set focus
|
||||||
|
newTextInput.x = textInputPosition.x
|
||||||
|
newTextInput.y = textInputPosition.y
|
||||||
|
newTextInput.index = index
|
||||||
|
newTextInput.visible = true
|
||||||
|
newTextInput.forceActiveFocus()
|
||||||
|
|
||||||
|
if (!root.shadowPillVisible)
|
||||||
|
popup.showOperators = root.conditionListModel.operatorAllowed(index)
|
||||||
|
|
||||||
|
// Open suggestion popup
|
||||||
|
popup.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: __operatorModel
|
||||||
|
function convertValueToName(value) {
|
||||||
|
for (var i = 0; i < __operatorModel.count; ++i) {
|
||||||
|
let element = __operatorModel.get(i)
|
||||||
|
if (element.value === value )
|
||||||
|
return element.name
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
ListElement {
|
||||||
|
name: "AND"
|
||||||
|
value: "&&"
|
||||||
|
tooltip: QT_TR_NOOP("This is AND (&&)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "OR"
|
||||||
|
value: "||"
|
||||||
|
tooltip: QT_TR_NOOP("This is OR (||)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "EQUAL"
|
||||||
|
value: "==="
|
||||||
|
tooltip: QT_TR_NOOP("This is EQUAL (===)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "NOT EQUAL"
|
||||||
|
value: "!=="
|
||||||
|
tooltip: QT_TR_NOOP("This is NOT EQUAL (!==)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "GREATER"
|
||||||
|
value: ">"
|
||||||
|
tooltip: QT_TR_NOOP("This is GREATER (>)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "LESS"
|
||||||
|
value: "<"
|
||||||
|
tooltip: QT_TR_NOOP("This is LESS (<)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "GREATER OR EQUAL"
|
||||||
|
value: ">="
|
||||||
|
tooltip: QT_TR_NOOP("This is GREATER OR EQUAL (>=)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "LESS OR EQUAL"
|
||||||
|
value: "<="
|
||||||
|
tooltip: QT_TR_NOOP("This is LESS OR EQUAL (<=)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.ToolTip {
|
||||||
|
id: toolTip
|
||||||
|
visible: mouseArea.containsMouse && toolTip.text !== ""
|
||||||
|
delay: 1000
|
||||||
|
text: root.conditionListModel.error
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onPressed: function (event) {
|
||||||
|
// Check if empty
|
||||||
|
if (!repeater.count) {
|
||||||
|
root.placeCursor(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map to flow item
|
||||||
|
let point = mouseArea.mapToItem(flow, Qt.point(event.x, event.y))
|
||||||
|
|
||||||
|
let horizontalDistance = Number.MAX_VALUE
|
||||||
|
let verticalDistance = Number.MAX_VALUE
|
||||||
|
let cursorPosition = 0
|
||||||
|
|
||||||
|
for (var i = 0; i < repeater.count; ++i) {
|
||||||
|
let item = repeater.itemAt(i)
|
||||||
|
|
||||||
|
let y = item.y + (item.height / 2)
|
||||||
|
|
||||||
|
// Vertical distance
|
||||||
|
let vDistance = Math.abs(point.y - y)
|
||||||
|
|
||||||
|
// Horizontal distance
|
||||||
|
let hLeftDistance = Math.abs(point.x - item.x)
|
||||||
|
let hRightDistance = Math.abs(point.x - (item.x + item.width))
|
||||||
|
|
||||||
|
// Early return if vertical distance increases
|
||||||
|
if (vDistance > verticalDistance)
|
||||||
|
break
|
||||||
|
|
||||||
|
if (vDistance <= verticalDistance) {
|
||||||
|
// Rest horizontal distance if vertical distance is smaller than before
|
||||||
|
if (vDistance !== verticalDistance)
|
||||||
|
horizontalDistance = Number.MAX_VALUE
|
||||||
|
|
||||||
|
if (hLeftDistance < horizontalDistance) {
|
||||||
|
horizontalDistance = hLeftDistance
|
||||||
|
cursorPosition = i
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hRightDistance < horizontalDistance) {
|
||||||
|
horizontalDistance = hRightDistance
|
||||||
|
cursorPosition = i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verticalDistance = vDistance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
root.placeCursor(cursorPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: StudioTheme.Values.flowMargin
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: placeholder
|
||||||
|
height: 20
|
||||||
|
topPadding: 1
|
||||||
|
font.pixelSize: root.style.baseFontSize
|
||||||
|
color: (focusScope.activeFocus || popup.searchActive)
|
||||||
|
? root.style.text.placeholderInteraction
|
||||||
|
: root.style.text.placeholder
|
||||||
|
visible: !repeater.count
|
||||||
|
text: qsTr("Condition")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
id: focusScope
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (!focusScope.activeFocus && !popup.searchActive)
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Flow {
|
||||||
|
id: flow
|
||||||
|
|
||||||
|
property int focusIndex: -1
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: StudioTheme.Values.flowMargin
|
||||||
|
spacing: StudioTheme.Values.flowSpacing
|
||||||
|
|
||||||
|
onPositioningComplete: {
|
||||||
|
if (root.textInputActive())
|
||||||
|
root.placeCursor(newTextInput.index)
|
||||||
|
|
||||||
|
if (!root.shadowPillVisible)
|
||||||
|
root.heightBeforeShadowPill = root.baseHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
|
||||||
|
onItemRemoved: function(index, item) {
|
||||||
|
if (!root.textInputActive())
|
||||||
|
return
|
||||||
|
|
||||||
|
// Udpate the cursor position
|
||||||
|
if (index < newTextInput.index)
|
||||||
|
newTextInput.index = newTextInput.index - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
onItemAdded: function(index, item) {
|
||||||
|
if (!root.textInputActive())
|
||||||
|
return
|
||||||
|
|
||||||
|
if (index >= newTextInput.index)
|
||||||
|
newTextInput.index = newTextInput.index + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Pill {
|
||||||
|
id: pill
|
||||||
|
|
||||||
|
operatorModel: __operatorModel
|
||||||
|
|
||||||
|
onRemove: function() {
|
||||||
|
// If pill has focus due to selection or keyboard navigation
|
||||||
|
if (pill.focus)
|
||||||
|
root.placeCursor(pill.index)
|
||||||
|
|
||||||
|
Qt.callLater(root.remove, pill.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
onUpdate: function(value) {
|
||||||
|
if (value === "")
|
||||||
|
Qt.callLater(root.remove, pill.index) // Otherwise crash
|
||||||
|
else
|
||||||
|
Qt.callLater(root.update, pill.index, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocusChanged: function() {
|
||||||
|
if (pill.focus)
|
||||||
|
flow.focusIndex = pill.index
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit: function (cursorPosition) {
|
||||||
|
let index = pill.index
|
||||||
|
// If cursor position is 0 the user moved the cursor out to left side,
|
||||||
|
// so place the cursor before the pill
|
||||||
|
if (cursorPosition !== 0)
|
||||||
|
index++
|
||||||
|
|
||||||
|
root.placeCursor(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: newTextInput
|
||||||
|
|
||||||
|
property int index
|
||||||
|
|
||||||
|
height: 20
|
||||||
|
topPadding: 1
|
||||||
|
font.pixelSize: root.style.baseFontSize
|
||||||
|
color: root.style.text.idle
|
||||||
|
visible: false
|
||||||
|
validator: RegularExpressionValidator { regularExpression: /^\S.+/ }
|
||||||
|
|
||||||
|
onTextEdited: {
|
||||||
|
if (newTextInput.text === "")
|
||||||
|
return
|
||||||
|
|
||||||
|
newTextInput.visible = false
|
||||||
|
|
||||||
|
root.insert(newTextInput.index, newTextInput.text, ConditionListModel.Intermediate)
|
||||||
|
|
||||||
|
newTextInput.clear()
|
||||||
|
|
||||||
|
// Set focus on the newly created item
|
||||||
|
let newItem = repeater.itemAt(newTextInput.index)
|
||||||
|
newItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: function (event) {
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
|
if (root.textInputActive()) {
|
||||||
|
let previousIndex = newTextInput.index - 1
|
||||||
|
if (previousIndex < 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = repeater.itemAt(previousIndex)
|
||||||
|
item.setCursorEnd()
|
||||||
|
item.forceActiveFocus()
|
||||||
|
popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SuggestionPopup {
|
||||||
|
id: popup
|
||||||
|
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: root.height
|
||||||
|
width: root.width
|
||||||
|
operatorModel: __operatorModel
|
||||||
|
|
||||||
|
//onOpened: console.log("POPUP opened")
|
||||||
|
//onClosed: console.log("POPUP closed")
|
||||||
|
|
||||||
|
onAboutToHide: {
|
||||||
|
newTextInput.visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect: function(value) {
|
||||||
|
newTextInput.visible = true
|
||||||
|
newTextInput.forceActiveFocus()
|
||||||
|
|
||||||
|
if (root.shadowPillVisible) { // Active shadow pill
|
||||||
|
root.remove(root.shadowPillIndex)
|
||||||
|
root.shadowPillIndex = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
root.insert(newTextInput.index, value, ConditionListModel.Variable)
|
||||||
|
|
||||||
|
// Clear search, reset stack view and tree model
|
||||||
|
popup.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearchActiveChanged: {
|
||||||
|
if (popup.searchActive) {
|
||||||
|
root.heightBeforeShadowPill = root.baseHeight
|
||||||
|
root.insert(newTextInput.index, "...", ConditionListModel.Shadow)
|
||||||
|
root.shadowPillIndex = newTextInput.index
|
||||||
|
} else {
|
||||||
|
if (!root.shadowPillVisible)
|
||||||
|
return
|
||||||
|
|
||||||
|
root.remove(root.shadowPillIndex)
|
||||||
|
root.shadowPillIndex = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEntered: function(value) {
|
||||||
|
if (!popup.searchActive) {
|
||||||
|
if (!root.shadowPillVisible) {
|
||||||
|
root.heightBeforeShadowPill = root.baseHeight
|
||||||
|
root.shadowPillIndex = newTextInput.index
|
||||||
|
root.insert(newTextInput.index, value, ConditionListModel.Shadow)
|
||||||
|
} else {
|
||||||
|
root.setValue(root.shadowPillIndex, value)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
root.setValue(root.shadowPillIndex, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExited: function(value) {
|
||||||
|
let shadowItem = repeater.itemAt(root.shadowPillIndex)
|
||||||
|
|
||||||
|
if (!popup.searchActive) {
|
||||||
|
if (root.shadowPillVisible && shadowItem?.value === value) {
|
||||||
|
root.remove(root.shadowPillIndex)
|
||||||
|
root.shadowPillIndex = -1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Reset to 3 dots if still the same value as the exited item
|
||||||
|
if (shadowItem?.value === value)
|
||||||
|
root.setValue(root.shadowPillIndex, "...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: function (event) {
|
||||||
|
if (event.key === Qt.Key_Left) {
|
||||||
|
if (root.textInputActive()) {
|
||||||
|
let previousIndex = newTextInput.index - 1
|
||||||
|
if (previousIndex < 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = repeater.itemAt(previousIndex)
|
||||||
|
item.setCursorEnd()
|
||||||
|
item.forceActiveFocus()
|
||||||
|
popup.close()
|
||||||
|
} else {
|
||||||
|
if (flow.focusIndex < 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
root.placeCursor(flow.focusIndex)
|
||||||
|
}
|
||||||
|
} else if (event.key === Qt.Key_Right) {
|
||||||
|
if (root.textInputActive()) {
|
||||||
|
let nextIndex = newTextInput.index
|
||||||
|
if (nextIndex >= repeater.count)
|
||||||
|
return
|
||||||
|
|
||||||
|
let item = repeater.itemAt(nextIndex)
|
||||||
|
item.setCursorBegin()
|
||||||
|
item.forceActiveFocus()
|
||||||
|
popup.close()
|
||||||
|
} else {
|
||||||
|
root.placeCursor(flow.focusIndex + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -4,50 +4,59 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import ConnectionsEditor
|
import HelperWidgets as HelperWidgets
|
||||||
import HelperWidgets 2.0 as HelperWidgets
|
import StudioControls as StudioControls
|
||||||
import StudioControls 1.0 as StudioControls
|
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import ConnectionsEditorEditorBackend
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 640
|
id: root
|
||||||
height: 1080
|
|
||||||
color: "#232222"
|
color: StudioTheme.Values.themePanelBackground
|
||||||
|
|
||||||
|
property bool adsFocus: false
|
||||||
|
// objectName is used by the dock widget to find this particular ScrollView
|
||||||
|
// and set the ads focus on it.
|
||||||
|
objectName: "__mainSrollView"
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: column
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 8 // TODO
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: rectangle
|
id: toolbar
|
||||||
x: 10
|
width: parent.width
|
||||||
y: 10
|
height: StudioTheme.Values.doubleToolbarHeight
|
||||||
width: 620
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
height: 97
|
|
||||||
color: "#333333"
|
|
||||||
|
|
||||||
Rectangle {
|
Column {
|
||||||
id: rectangle1
|
anchors.fill: parent
|
||||||
x: 10
|
anchors.topMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||||
y: 10
|
anchors.bottomMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||||
width: 600
|
anchors.leftMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
height: 34
|
anchors.rightMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
color: "#00ffffff"
|
spacing: StudioTheme.Values.toolbarColumnSpacing
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Text {
|
StudioControls.SearchBox {
|
||||||
id: text1
|
id: searchBox
|
||||||
x: 10
|
width: parent.width
|
||||||
y: 10
|
style: StudioTheme.Values.searchControlStyle
|
||||||
color: "#b5b2b2"
|
|
||||||
text: qsTr("Search")
|
onSearchChanged: function(searchText) {}
|
||||||
font.pixelSize: 12
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
Row {
|
||||||
x: 10
|
id: row
|
||||||
y: 50
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.toolbarHeight
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
TabCheckButton {
|
TabCheckButton {
|
||||||
id: connections
|
id: connections
|
||||||
text: "Connections"
|
buttonIcon: StudioTheme.Constants.connections_medium
|
||||||
|
text: qsTr("Connections")
|
||||||
|
tooltip: qsTr("This is a tooltip.")
|
||||||
checked: true
|
checked: true
|
||||||
autoExclusive: true
|
autoExclusive: true
|
||||||
checkable: true
|
checkable: true
|
||||||
@@ -55,34 +64,35 @@ Rectangle {
|
|||||||
|
|
||||||
TabCheckButton {
|
TabCheckButton {
|
||||||
id: bindings
|
id: bindings
|
||||||
text: "Bindings"
|
buttonIcon: StudioTheme.Constants.binding_medium
|
||||||
|
text: qsTr("Bindings")
|
||||||
|
tooltip: qsTr("This is a tooltip.")
|
||||||
autoExclusive: true
|
autoExclusive: true
|
||||||
checkable: true
|
checkable: true
|
||||||
}
|
}
|
||||||
|
|
||||||
TabCheckButton {
|
TabCheckButton {
|
||||||
id: properties
|
id: properties
|
||||||
text: "Properties"
|
buttonIcon: StudioTheme.Constants.properties_medium
|
||||||
|
text: qsTr("Properties")
|
||||||
|
tooltip: qsTr("This is a tooltip.")
|
||||||
autoExclusive: true
|
autoExclusive: true
|
||||||
checkable: true
|
checkable: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: spacer
|
||||||
|
width: row.width - connections.width - bindings.width
|
||||||
|
- properties.width - addButton.width - row.spacing * 4
|
||||||
|
height: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
HelperWidgets.AbstractButton {
|
||||||
id: text2
|
id: addButton
|
||||||
x: 577
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
y: 58
|
buttonIcon: StudioTheme.Constants.add_medium
|
||||||
color: "#ffffff"
|
tooltip: qsTr("Add something.")
|
||||||
text: qsTr("+")
|
|
||||||
font.pixelSize: 18
|
|
||||||
font.bold: true
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
print(ConnectionsEditorEditorBackend.dynamicPropertiesModel.delegate)
|
|
||||||
print(ConnectionsEditorEditorBackend.dynamicPropertiesModel.delegate.type)
|
|
||||||
print(ConnectionsEditorEditorBackend.dynamicPropertiesModel.delegate.type.model)
|
|
||||||
|
|
||||||
if (connections.checked)
|
if (connections.checked)
|
||||||
ConnectionsEditorEditorBackend.connectionModel.add()
|
ConnectionsEditorEditorBackend.connectionModel.add()
|
||||||
else if (bindings.checked)
|
else if (bindings.checked)
|
||||||
@@ -93,25 +103,30 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConnectionsListView {
|
ConnectionsListView {
|
||||||
visible: connections.checked
|
visible: connections.checked
|
||||||
x: 17
|
width: parent.width
|
||||||
y: 124
|
height: parent.height - toolbar.height - column.spacing
|
||||||
model: ConnectionsEditorEditorBackend.connectionModel
|
model: ConnectionsEditorEditorBackend.connectionModel
|
||||||
|
adsFocus: root.adsFocus
|
||||||
}
|
}
|
||||||
|
|
||||||
BindingsListView {
|
BindingsListView {
|
||||||
visible: bindings.checked
|
visible: bindings.checked
|
||||||
x: 17
|
width: parent.width
|
||||||
y: 124
|
height: parent.height - toolbar.height - column.spacing
|
||||||
model: ConnectionsEditorEditorBackend.bindingModel
|
model: ConnectionsEditorEditorBackend.bindingModel
|
||||||
|
adsFocus: root.adsFocus
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertiesListView {
|
PropertiesListView {
|
||||||
visible: properties.checked
|
visible: properties.checked
|
||||||
x: 17
|
width: parent.width
|
||||||
y: 124
|
height: parent.height - toolbar.height - column.spacing
|
||||||
model: ConnectionsEditorEditorBackend.dynamicPropertiesModel
|
model: ConnectionsEditorEditorBackend.dynamicPropertiesModel
|
||||||
|
adsFocus: root.adsFocus
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
id: control
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
leftPadding: 8
|
||||||
|
rightPadding: 8
|
||||||
|
text: control.text
|
||||||
|
font: control.font
|
||||||
|
opacity: enabled ? 1.0 : 0.3
|
||||||
|
color: control.hovered ? "#111111" : "white"
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: 200
|
||||||
|
implicitHeight: 30
|
||||||
|
opacity: enabled ? 1 : 0.3
|
||||||
|
color: control.hovered ? "#4DBFFF" : "transparent"
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Templates as T
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
T.TreeViewDelegate {
|
||||||
|
id: control
|
||||||
|
hoverEnabled: true
|
||||||
|
implicitWidth: 200
|
||||||
|
implicitHeight: 30
|
||||||
|
indentation: 12
|
||||||
|
leftPadding: control.leftMargin + control.__contentIndent
|
||||||
|
|
||||||
|
readonly property int customDepth: control.depth - 1
|
||||||
|
|
||||||
|
readonly property real __contentIndent: !control.isTreeNode ? 0
|
||||||
|
: (control.customDepth * control.indentation)
|
||||||
|
+ (control.indicator ? control.indicator.width + control.spacing : 0)
|
||||||
|
|
||||||
|
indicator: Item {
|
||||||
|
x: control.leftMargin + (control.customDepth * control.indentation)
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: icon
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: StudioTheme.Values.smallIconFontSize
|
||||||
|
color: control.hovered ? "#111111" : "white" // TODO colors
|
||||||
|
text: StudioTheme.Constants.sectionToggle
|
||||||
|
rotation: control.expanded ? 0 : -90
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: 200
|
||||||
|
implicitHeight: 30
|
||||||
|
color: control.hovered ? "#4DBFFF" : "transparent"
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
text: control.text
|
||||||
|
font: control.font
|
||||||
|
opacity: enabled ? 1.0 : 0.3
|
||||||
|
color: control.hovered ? "#111111" : "white"
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
163
share/qtcreator/qmldesigner/connectionseditor/Pill.qml
Normal file
163
share/qtcreator/qmldesigner/connectionseditor/Pill.qml
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property string value
|
||||||
|
required property int type
|
||||||
|
|
||||||
|
function setCursorBegin() { textInput.cursorPosition = 0 }
|
||||||
|
function setCursorEnd() { textInput.cursorPosition = textInput.text.length }
|
||||||
|
|
||||||
|
function isEditable() { return root.type === ConditionListModel.Intermediate
|
||||||
|
|| root.type === ConditionListModel.Literal
|
||||||
|
|| root.type === ConditionListModel.Invalid }
|
||||||
|
|
||||||
|
function isIntermediate() { return root.type === ConditionListModel.Intermediate }
|
||||||
|
function isLiteral() { return root.type === ConditionListModel.Literal }
|
||||||
|
function isOperator() { return root.type === ConditionListModel.Operator }
|
||||||
|
function isProperty() { return root.type === ConditionListModel.Variable }
|
||||||
|
function isShadow() { return root.type === ConditionListModel.Shadow }
|
||||||
|
function isInvalid() { return root.type === ConditionListModel.Invalid }
|
||||||
|
|
||||||
|
signal remove()
|
||||||
|
signal update(var value)
|
||||||
|
signal submit(int cursorPosition)
|
||||||
|
|
||||||
|
readonly property int margin: StudioTheme.Values.flowPillMargin
|
||||||
|
property var operatorModel
|
||||||
|
|
||||||
|
width: {
|
||||||
|
if (root.isEditable()) {
|
||||||
|
if (root.isInvalid())
|
||||||
|
return textInput.width + 1 + 2 * root.margin
|
||||||
|
else
|
||||||
|
return textInput.width + 1
|
||||||
|
}
|
||||||
|
return textItem.contentWidth + icon.width + root.margin
|
||||||
|
}
|
||||||
|
height: StudioTheme.Values.flowPillHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (root.activeFocus && root.isEditable())
|
||||||
|
textInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: function (event) {
|
||||||
|
if (root.isEditable())
|
||||||
|
return
|
||||||
|
|
||||||
|
if (event.key === Qt.Key_Backspace || event.key === Qt.Key_Delete)
|
||||||
|
root.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: rootMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: root.isEditable() ? Qt.IBeamCursor : Qt.ArrowCursor
|
||||||
|
onClicked: root.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: pill
|
||||||
|
anchors.fill: parent
|
||||||
|
color: {
|
||||||
|
if (root.isShadow())
|
||||||
|
return StudioTheme.Values.themeInteraction
|
||||||
|
if (root.isEditable())
|
||||||
|
return "transparent"
|
||||||
|
|
||||||
|
return StudioTheme.Values.themePillBackground
|
||||||
|
}
|
||||||
|
border.color: root.isInvalid() ? StudioTheme.Values.themeWarning : "white" // TODO colors
|
||||||
|
border.width: {
|
||||||
|
if (root.isShadow())
|
||||||
|
return 0
|
||||||
|
if (root.isInvalid())
|
||||||
|
return 1
|
||||||
|
if (root.isEditable())
|
||||||
|
return 0
|
||||||
|
if (rootMouseArea.containsMouse || root.focus)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
radius: StudioTheme.Values.flowPillRadius
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: row
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: root.margin
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: root.isOperator() || root.isProperty() || root.isShadow()
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: textItem
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
color: root.isShadow() ? StudioTheme.Values.themeTextSelectedTextColor
|
||||||
|
: StudioTheme.Values.themeTextColor
|
||||||
|
text: root.isOperator() ? root.operatorModel.convertValueToName(root.value)
|
||||||
|
: root.value
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: icon
|
||||||
|
width: root.isShadow() ? root.margin : StudioTheme.Values.flowPillHeight
|
||||||
|
height: StudioTheme.Values.flowPillHeight
|
||||||
|
visible: !root.isShadow()
|
||||||
|
|
||||||
|
Text {
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: StudioTheme.Values.smallIconFontSize
|
||||||
|
color: StudioTheme.Values.themeIconColor
|
||||||
|
text: StudioTheme.Constants.close_small
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: textInput
|
||||||
|
|
||||||
|
x: root.isInvalid() ? root.margin : 0
|
||||||
|
height: StudioTheme.Values.flowPillHeight
|
||||||
|
topPadding: 1
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
color: (rootMouseArea.containsMouse || textInput.activeFocus) ? StudioTheme.Values.themeIconColor
|
||||||
|
: StudioTheme.Values.themeTextColor
|
||||||
|
text: root.value
|
||||||
|
visible: root.isEditable()
|
||||||
|
enabled: root.isEditable()
|
||||||
|
|
||||||
|
//validator: RegularExpressionValidator { regularExpression: /^\S+/ }
|
||||||
|
|
||||||
|
onEditingFinished: {
|
||||||
|
root.update(textInput.text) // emit
|
||||||
|
root.submit(textInput.cursorPosition) // emit
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: function (event) {
|
||||||
|
if (event.key === Qt.Key_Backspace) {
|
||||||
|
if (textInput.text !== "")
|
||||||
|
return
|
||||||
|
|
||||||
|
root.remove() // emit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -3,70 +3,100 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
Window {
|
Window {
|
||||||
id: window
|
id: window
|
||||||
width: 400
|
|
||||||
height: 800
|
property alias titleBar: titleBarContent.children
|
||||||
|
default property alias content: mainContent.children
|
||||||
|
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
|
||||||
|
|
||||||
|
width: 320
|
||||||
|
height: column.implicitHeight
|
||||||
visible: true
|
visible: true
|
||||||
flags: Qt.FramelessWindowHint || Qt.Dialog
|
flags: Qt.FramelessWindowHint | Qt.Dialog
|
||||||
|
color: StudioTheme.Values.themePopoutBackground
|
||||||
|
|
||||||
color: Qt.transparent
|
function ensureVerticalPosition() {
|
||||||
|
if ((window.y + window.height) > (Screen.height - window.style.dialogScreenMargin)) {
|
||||||
|
window.y = (Screen.height - window.height - window.style.dialogScreenMargin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property int bw: 5
|
onHeightChanged: window.ensureVerticalPosition()
|
||||||
|
|
||||||
function popup(item) {
|
function popup(item) {
|
||||||
print("popup " + item)
|
|
||||||
var padding = 12
|
var padding = 12
|
||||||
var p = item.mapToGlobal(0, 0)
|
var p = item.mapToGlobal(0, 0)
|
||||||
dialog.x = p.x - dialog.width - padding
|
window.x = p.x - window.width - padding
|
||||||
if (dialog.x < 0)
|
if (window.x < 0)
|
||||||
dialog.x = p.x + item.width + padding
|
window.x = p.x + item.width + padding
|
||||||
dialog.y = p.y
|
window.y = p.y
|
||||||
dialog.show()
|
|
||||||
dialog.raise()
|
window.ensureVerticalPosition()
|
||||||
|
|
||||||
|
window.show()
|
||||||
|
window.raise()
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Column {
|
||||||
id: rectangle1
|
id: column
|
||||||
color: "#d7d7d7"
|
|
||||||
border.color: "#232323"
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: titleBarItem
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.titleBarHeight
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: rectangle
|
|
||||||
height: 32
|
|
||||||
color: "#797979"
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 0
|
|
||||||
anchors.leftMargin: 0
|
|
||||||
anchors.rightMargin: 0
|
|
||||||
DragHandler {
|
DragHandler {
|
||||||
grabPermissions: TapHandler.CanTakeOverFromAnything
|
id: dragHandler
|
||||||
onActiveChanged: if (active) { window.startSystemMove(); }
|
|
||||||
|
target: null
|
||||||
|
grabPermissions: PointerHandler.CanTakeOverFromAnything
|
||||||
|
onActiveChanged: {
|
||||||
|
if (dragHandler.active)
|
||||||
|
window.startSystemMove() // QTBUG-102488
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Row {
|
||||||
id: rectangle2
|
id: row
|
||||||
x: 329
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
color: "#ffffff"
|
|
||||||
radius: 4
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 6
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: StudioTheme.Values.popupMargin
|
||||||
|
anchors.rightMargin: StudioTheme.Values.popupMargin
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: titleBarContent
|
||||||
|
width: row.width - closeIndicator.width //- row.anchors.leftMargin
|
||||||
|
height: row.height
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.IconIndicator {
|
||||||
|
id: closeIndicator
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
icon: StudioTheme.Constants.colorPopupClose
|
||||||
|
pixelSize: StudioTheme.Values.myIconFontSize// * 1.4
|
||||||
onClicked: window.close()
|
onClicked: window.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width - 8
|
||||||
|
height: 1
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
color: "#636363"
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: mainContent
|
||||||
|
width: parent.width - 2 * StudioTheme.Values.popupMargin
|
||||||
|
height: mainContent.childrenRect.height + 2 * StudioTheme.Values.popupMargin
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
share/qtcreator/qmldesigner/connectionseditor/PopupLabel.qml
Normal file
20
share/qtcreator/qmldesigner/connectionseditor/PopupLabel.qml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Text {
|
||||||
|
width: root.columnWidth
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
property alias tooltip: area.tooltip
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
id: area
|
||||||
|
anchors.fill: parent
|
||||||
|
tooltip: qsTr("missing")
|
||||||
|
}
|
||||||
|
}
|
@@ -2,12 +2,39 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
|
||||||
PopupDialog {
|
PopupDialog {
|
||||||
property alias backend: form.backend
|
property alias backend: form.backend
|
||||||
|
|
||||||
|
titleBar: Row {
|
||||||
|
spacing: 30 // TODO
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
text: qsTr("Owner")
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
tooltip: qsTr("The owner of the property")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: form.backend.targetNode
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
PropertiesDialogForm {
|
PropertiesDialogForm {
|
||||||
id: form
|
id: form
|
||||||
y: 32
|
y: 32
|
||||||
|
height: 180
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,76 +1,73 @@
|
|||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick 2.15
|
import QtQuick
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
import StudioControls
|
Column {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property real horizontalSpacing: 10
|
||||||
|
readonly property real verticalSpacing: 16
|
||||||
|
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 400
|
|
||||||
height: 800
|
|
||||||
color: "#1b1b1b"
|
|
||||||
property var backend
|
property var backend
|
||||||
|
|
||||||
Text {
|
y: StudioTheme.Values.popupMargin
|
||||||
id: text1
|
width: parent.width
|
||||||
x: 10
|
spacing: root.verticalSpacing
|
||||||
y: 25
|
|
||||||
color: "#ffffff"
|
PopupLabel {
|
||||||
text: qsTr("Type:")
|
text: qsTr("Type")
|
||||||
font.pixelSize: 15
|
tooltip: qsTr("The type of the property")
|
||||||
}
|
}
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: type
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
//width: root.width
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: target
|
|
||||||
x: 95
|
|
||||||
width: 210
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.verticalCenterOffset: -367
|
|
||||||
model: backend.type.model ?? []
|
model: backend.type.model ?? []
|
||||||
onActivated: backend.type.activateIndex(target.currentIndex)
|
onActivated: backend.type.activateIndex(type.currentIndex)
|
||||||
property int currentTypeIndex: backend.type.currentIndex ?? 0
|
property int currentTypeIndex: backend.type.currentIndex ?? 0
|
||||||
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
onCurrentTypeIndexChanged: type.currentIndex = type.currentTypeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Row {
|
||||||
id: text2
|
spacing: root.horizontalSpacing
|
||||||
x: 10
|
|
||||||
y: 131
|
PopupLabel { text: qsTr("Name") ; tooltip: qsTr("The name of the property.")}
|
||||||
color: "#ffffff"
|
PopupLabel { text: qsTr("Value"); tooltip: qsTr("The value of the property.") }
|
||||||
text: qsTr("Name")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextInput {
|
Row {
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
StudioControls.TextField {
|
||||||
id: name
|
id: name
|
||||||
x: 70
|
|
||||||
y: 131
|
width: root.columnWidth
|
||||||
color: "white"
|
actionIndicatorVisible: false
|
||||||
width: 156
|
translationIndicatorVisible: false
|
||||||
|
|
||||||
text: backend.name.text ?? ""
|
text: backend.name.text ?? ""
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
backend.name.activateText(name.text)
|
backend.name.activateText(name.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
StudioControls.TextField {
|
||||||
Text {
|
|
||||||
x: 10
|
|
||||||
y: 81
|
|
||||||
color: "#ffffff"
|
|
||||||
text: qsTr("Value")
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TextInput {
|
|
||||||
id: value
|
id: value
|
||||||
color: "red"
|
|
||||||
x: 70
|
width: root.columnWidth
|
||||||
y: 81
|
actionIndicatorVisible: false
|
||||||
width: 156
|
translationIndicatorVisible: false
|
||||||
|
|
||||||
|
|
||||||
text: backend.value.text ?? ""
|
text: backend.value.text ?? ""
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
backend.value.activateText(value.text)
|
backend.value.activateText(value.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@@ -3,126 +3,191 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import ConnectionsEditor
|
|
||||||
import HelperWidgets 2.0 as HelperWidgets
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
import StudioControls 1.0 as StudioControls
|
import StudioControls 1.0 as StudioControls
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import ConnectionsEditorEditorBackend
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: listView
|
id: root
|
||||||
width: 606
|
|
||||||
height: 160
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||||
interactive: false
|
|
||||||
|
property bool adsFocus: false
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
interactive: true
|
||||||
highlightMoveDuration: 0
|
highlightMoveDuration: 0
|
||||||
|
highlightResizeDuration: 0
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
HoverHandler { id: hoverHandler }
|
||||||
|
|
||||||
|
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||||
|
id: verticalScrollBar
|
||||||
|
parent: root
|
||||||
|
x: root.width - verticalScrollBar.width
|
||||||
|
y: 0
|
||||||
|
height: root.availableHeight
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
show: (hoverHandler.hovered || root.focus || verticalScrollBar.inUse || root.adsFocus)
|
||||||
|
&& verticalScrollBar.isNeeded
|
||||||
|
}
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
dialog.hide()
|
dialog.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
property int modelCurrentIndex: listView.model.currentIndex ?? 0
|
property int modelCurrentIndex: root.model.currentIndex ?? 0
|
||||||
|
|
||||||
|
// Something weird with currentIndex happens when items are removed added.
|
||||||
|
// listView.model.currentIndex contains the persistent index.
|
||||||
|
|
||||||
/* Something weird with currentIndex happens when items are removed added.
|
|
||||||
listView.model.currentIndex contains the persistent index.
|
|
||||||
*/
|
|
||||||
onModelCurrentIndexChanged: {
|
onModelCurrentIndexChanged: {
|
||||||
listView.currentIndex = listView.model.currentIndex
|
root.currentIndex = root.model.currentIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
listView.currentIndex = listView.model.currentIndex
|
root.currentIndex = root.model.currentIndex
|
||||||
dialog.backend.currentRow = listView.currentIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Number of columns
|
||||||
|
readonly property int numColumns: 4
|
||||||
|
// Proper row width calculation
|
||||||
|
readonly property int rowSpacing: StudioTheme.Values.toolbarHorizontalMargin
|
||||||
|
readonly property int rowSpace: root.width - (root.rowSpacing * (root.numColumns + 1))
|
||||||
|
- root.style.squareControlSize.width
|
||||||
|
property int rowWidth: root.rowSpace / root.numColumns
|
||||||
|
property int rowRest: root.rowSpace % root.numColumns
|
||||||
|
|
||||||
data: [
|
data: [
|
||||||
PropertiesDialog {
|
PropertiesDialog {
|
||||||
id: dialog
|
id: dialog
|
||||||
visible: false
|
visible: false
|
||||||
backend: listView.model.delegate
|
backend: root.model.delegate
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Rectangle {
|
||||||
|
id: itemDelegate
|
||||||
|
|
||||||
width: 600
|
required property int index
|
||||||
height: 18
|
|
||||||
|
required property string target
|
||||||
|
required property string name
|
||||||
|
required property string type
|
||||||
|
required property string value
|
||||||
|
|
||||||
|
width: ListView.view.width
|
||||||
|
height: root.style.squareControlSize.height
|
||||||
|
color: mouseArea.containsMouse ?
|
||||||
|
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||||
|
: root.style.background.hover
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
property int currentIndex: listView.currentIndex
|
property int currentIndex: root.currentIndex
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: mouseArea
|
target: mouseArea
|
||||||
function onClicked() {
|
function onClicked() {
|
||||||
listView.model.currentIndex = index
|
root.model.currentIndex = itemDelegate.index
|
||||||
listView.currentIndex = index
|
root.currentIndex = itemDelegate.index
|
||||||
dialog.backend.currentRow = index
|
|
||||||
dialog.popup(mouseArea)
|
dialog.popup(mouseArea)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: row1
|
id: row
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
width: 600
|
|
||||||
height: 16
|
|
||||||
spacing: 10
|
|
||||||
|
|
||||||
|
height: itemDelegate.height
|
||||||
|
spacing: root.rowSpacing
|
||||||
|
|
||||||
|
property color textColor: itemDelegate.ListView.isCurrentItem ? root.style.text.selectedText
|
||||||
|
: root.style.icon.idle
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth + root.rowRest
|
||||||
color: "#ffffff"
|
height: itemDelegate.height
|
||||||
text: target ?? ""
|
color: row.textColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
text: itemDelegate.target ?? ""
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
leftPadding: root.rowSpacing
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth
|
||||||
text: name ?? ""
|
height: itemDelegate.height
|
||||||
color: "#ffffff"
|
color: row.textColor
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
text: itemDelegate.name ?? ""
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth + root.rowRest
|
||||||
text: type ?? ""
|
height: itemDelegate.height
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
color: row.textColor
|
||||||
color: "#ffffff"
|
text: itemDelegate.type ?? ""
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
width: 120
|
width: root.rowWidth + root.rowRest
|
||||||
text: value ?? ""
|
height: itemDelegate.height
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
color: row.textColor
|
||||||
color: "#ffffff"
|
text: itemDelegate.value ?? ""
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
font.bold: false
|
font.bold: false
|
||||||
|
elide: Text.ElideMiddle
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Rectangle {
|
||||||
width: 120
|
width: root.style.squareControlSize.width
|
||||||
|
height: root.style.squareControlSize.height
|
||||||
|
|
||||||
text: "-"
|
color: toolTipArea.containsMouse ?
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||||
horizontalAlignment: Text.AlignRight
|
: root.style.background.hover
|
||||||
font.pointSize: 14
|
: "transparent"
|
||||||
color: "#ffffff"
|
|
||||||
font.bold: true
|
Text {
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: listView.model.remove(index)
|
|
||||||
|
text: StudioTheme.Constants.remove_medium
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: root.style.baseIconFontSize
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
color: row.textColor
|
||||||
|
renderType: Text.QtRendering
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
id: toolTipArea
|
||||||
|
tooltip: qsTr("This is a test.")
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.model.remove(itemDelegate.index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
highlight: Rectangle {
|
highlight: Rectangle {
|
||||||
color: "#2a5593"
|
color: root.style.interaction
|
||||||
width: 600
|
width: 600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,252 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int actionType
|
||||||
|
|
||||||
|
property int horizontalSpacing
|
||||||
|
property int columnWidth
|
||||||
|
|
||||||
|
property var statement
|
||||||
|
|
||||||
|
//implicitWidth: Math.max(16, container.childrenRect.width + container.childrenRect.x)
|
||||||
|
//implicitHeight: Math.max(16, container.childrenRect.height + container.childrenRect.y)
|
||||||
|
|
||||||
|
// Call Function
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.CallFunction
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
PopupLabel { text: qsTr("Item") ; tooltip: qsTr("The target item of the function.")}
|
||||||
|
PopupLabel { text: qsTr("Method") ; tooltip: qsTr("The name of the function.")}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.CallFunction
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: functionId
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
|
||||||
|
model: root.statement.function.id.model ?? 0
|
||||||
|
|
||||||
|
onActivated: backend.okStatement.function.id.activateIndex(functionId.currentIndex)
|
||||||
|
property int currentTypeIndex: backend.okStatement.function.id.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: functionId.currentIndex = functionId.currentTypeIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: functionName
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
model: root.statement.function.name.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.function.name.activateIndex(functionName.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.function.name.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: functionName.currentIndex = functionName.currentTypeIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.Assign
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
PopupLabel { text: qsTr("From") ; tooltip: qsTr("The Property to assign from.")}
|
||||||
|
PopupLabel { text: qsTr("To"); tooltip: qsTr("The Property to assign to.") }
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.Assign
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: rhsAssignmentId
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
//from - rhs - id
|
||||||
|
|
||||||
|
model: root.statement.rhsAssignment.id.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.rhsAssignment.id.activateIndex(rhsAssignmentId.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.rhsAssignment.id.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: rhsAssignmentId.currentIndex = rhsAssignmentId.currentTypeIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: lhsAssignmentId
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
//to lhs - id
|
||||||
|
model: root.statement.lhs.id.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.lhs.id.activateIndex(lhsAssignmentId.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.lhs.id.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: lhsAssignmentId.currentIndex = lhsAssignmentId.currentTypeIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.Assign
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: rhsAssignmentName
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
//from - rhs - name
|
||||||
|
|
||||||
|
model: root.statement.rhsAssignment.name.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.rhsAssignment.name.activateIndex(rhsAssignmentName.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.rhsAssignment.name.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: rhsAssignmentName.currentIndex = rhsAssignmentName.currentTypeIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: lhsAssignmentName
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
//to lhs - name
|
||||||
|
model: root.statement.lhs.name.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.lhs.name.activateIndex(lhsAssignmentName.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.lhs.name.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: lhsAssignmentName.currentIndex = lhsAssignmentName.currentTypeIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change State
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.ChangeState
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
PopupLabel { text: qsTr("State Group"); tooltip: qsTr("The State Group.") }
|
||||||
|
PopupLabel { text: qsTr("State"); tooltip: qsTr("The State .") }
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.ChangeState
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: stateGroups
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
model: root.statement.stateTargets.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.stateTargets.activateIndex(stateGroups.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.stateTargets.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: stateGroups.currentIndex = stateGroups.currentTypeIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: states
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
|
||||||
|
model: root.statement.states.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.states.activateIndex(states.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.states.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: states.currentIndex = states.currentTypeIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Property
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
PopupLabel { text: qsTr("Item"); tooltip: qsTr("The Item.")}
|
||||||
|
PopupLabel { text: qsTr("Property"); tooltip: qsTr("The property of the item.")}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: lhsPropertyId
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
|
||||||
|
model: root.statement.lhs.id.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.lhs.id.activateIndex(lhsPropertyId.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.lhs.id.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: lhsPropertyId.currentIndex = lhsPropertyId.currentTypeIndex
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
|
id: lhsPropertyName
|
||||||
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
|
width: root.columnWidth
|
||||||
|
model: root.statement.lhs.name.model ?? 0
|
||||||
|
|
||||||
|
onActivated: root.statement.lhs.name.activateIndex(lhsPropertyName.currentIndex)
|
||||||
|
property int currentTypeIndex: root.statement.lhs.name.currentIndex ?? 0
|
||||||
|
onCurrentTypeIndexChanged: lhsPropertyName.currentIndex = lhsPropertyName.currentTypeIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupLabel {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
||||||
|
text: qsTr("Value")
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: setPropertyArgument
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
||||||
|
width: root.width
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
|
||||||
|
text: root.statement.stringArgument.text ?? ""
|
||||||
|
onEditingFinished: {
|
||||||
|
root.statement.stringArgument.activateText(setPropertyArgument.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print Message
|
||||||
|
PopupLabel {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.PrintMessage
|
||||||
|
text: qsTr("Message")
|
||||||
|
tooltip: qsTr("The message that is printed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: messageString
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.PrintMessage
|
||||||
|
width: root.width
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
text: root.statement.stringArgument.text ?? ""
|
||||||
|
onEditingFinished: {
|
||||||
|
root.statement.stringArgument.activateText(messageString.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom
|
||||||
|
PopupLabel {
|
||||||
|
visible: root.actionType === ConnectionModelStatementDelegate.Custom
|
||||||
|
text: qsTr("Custom Connections can only be edited with the binding editor")
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: 30
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,303 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls as Controls
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import ConnectionsEditorEditorBackend
|
||||||
|
|
||||||
|
Controls.Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
|
||||||
|
|
||||||
|
property var listModel: ConnectionsEditorEditorBackend.connectionModel.delegate.propertyListProxyModel
|
||||||
|
property var treeModel: ConnectionsEditorEditorBackend.connectionModel.delegate.propertyTreeModel
|
||||||
|
|
||||||
|
signal select(var value)
|
||||||
|
signal entered(var value)
|
||||||
|
signal exited(var value)
|
||||||
|
|
||||||
|
property alias searchActive: search.activeFocus
|
||||||
|
property bool showOperators: false
|
||||||
|
property alias operatorModel: repeater.model
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
search.clear()
|
||||||
|
stack.pop(null, Controls.StackView.Immediate)
|
||||||
|
root.listModel.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
closePolicy: Controls.Popup.CloseOnEscape | Controls.Popup.CloseOnPressOutsideParent
|
||||||
|
padding: 0
|
||||||
|
focus: search.activeFocus
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: root.width
|
||||||
|
color: root.style.background.idle
|
||||||
|
border {
|
||||||
|
color: root.style.border.idle
|
||||||
|
width: root.style.borderWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Column {
|
||||||
|
StudioControls.SearchBox {
|
||||||
|
id: search
|
||||||
|
width: parent.width
|
||||||
|
visible: !root.showOperators
|
||||||
|
|
||||||
|
onSearchChanged: function(value) {
|
||||||
|
root.treeModel.setFilter(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls.StackView {
|
||||||
|
id: stack
|
||||||
|
visible: !root.showOperators
|
||||||
|
width: parent.width
|
||||||
|
height: currentItem?.implicitHeight
|
||||||
|
clip: true
|
||||||
|
initialItem: mainView
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: mainView
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Rectangle {
|
||||||
|
width: stack.width
|
||||||
|
height: 30
|
||||||
|
visible: root.listModel.parentName !== ""
|
||||||
|
color: backMouseArea.containsMouse ? "#4DBFFF" : "transparent"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: backMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
stack.pop(Controls.StackView.Immediate)
|
||||||
|
root.listModel.goUp() //treeModel.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: chevronLeft
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: root.style.baseIconFontSize
|
||||||
|
color: backMouseArea.containsMouse ? "#111111" : "white" // TODO colors
|
||||||
|
text: StudioTheme.Constants.back_medium
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: root.listModel.parentName
|
||||||
|
color: backMouseArea.containsMouse ? "#111111" : "white" // TODO colors
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: stack.width - 8
|
||||||
|
height: 1
|
||||||
|
visible: root.listModel.parentName !== ""
|
||||||
|
color: "#3C3C3C"
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listView
|
||||||
|
visible: search.empty
|
||||||
|
width: stack.width
|
||||||
|
implicitHeight: Math.min(180, childrenRect.height)
|
||||||
|
clip: true
|
||||||
|
model: root.listModel
|
||||||
|
|
||||||
|
HoverHandler { id: listViewHoverHandler }
|
||||||
|
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||||
|
id: listScrollBar
|
||||||
|
parent: listView
|
||||||
|
x: listView.width - listScrollBar.width
|
||||||
|
y: 0
|
||||||
|
height: listView.availableHeight
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
show: (listViewHoverHandler.hovered || listView.focus || listScrollBar.inUse)
|
||||||
|
&& listScrollBar.isNeeded
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: MyListViewDelegate {
|
||||||
|
id: listViewDelegate
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
required property string propertyName
|
||||||
|
required property int childCount
|
||||||
|
required property string expression
|
||||||
|
|
||||||
|
text: listViewDelegate.propertyName
|
||||||
|
implicitWidth: listView.width
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (!listViewDelegate.childCount) {
|
||||||
|
root.select(listViewDelegate.expression)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.push(mainView, Controls.StackView.Immediate)
|
||||||
|
|
||||||
|
ListView.view.model.goInto(listViewDelegate.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (listViewDelegate.childCount)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (listViewDelegate.hovered)
|
||||||
|
root.entered(listViewDelegate.expression)
|
||||||
|
else
|
||||||
|
root.exited(listViewDelegate.expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TreeView {
|
||||||
|
id: treeView
|
||||||
|
visible: !search.empty
|
||||||
|
width: stack.width
|
||||||
|
implicitHeight: Math.min(180, childrenRect.height)
|
||||||
|
clip: true
|
||||||
|
model: root.treeModel
|
||||||
|
|
||||||
|
HoverHandler { id: treeViewHoverHandler }
|
||||||
|
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||||
|
id: treeScrollBar
|
||||||
|
parent: treeView
|
||||||
|
x: treeView.width - treeScrollBar.width
|
||||||
|
y: 0
|
||||||
|
height: treeView.availableHeight
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
|
||||||
|
show: (treeViewHoverHandler.hovered || treeView.focus || treeScrollBar.inUse)
|
||||||
|
&& treeScrollBar.isNeeded
|
||||||
|
}
|
||||||
|
|
||||||
|
onLayoutChanged: function() {
|
||||||
|
treeView.expand(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
rowHeightProvider: function(row) {
|
||||||
|
return (row <= 0) ? 0 : -1
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: MyTreeViewDelegate {
|
||||||
|
id: treeViewDelegate
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
required property string propertyName
|
||||||
|
required property int childCount
|
||||||
|
required property string expression
|
||||||
|
|
||||||
|
text: treeViewDelegate.propertyName
|
||||||
|
implicitWidth: treeView.width
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (!treeViewDelegate.childCount)
|
||||||
|
root.select(treeViewDelegate.expression)
|
||||||
|
else
|
||||||
|
treeView.toggleExpanded(treeViewDelegate.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
onHoveredChanged: {
|
||||||
|
if (treeViewDelegate.childCount)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (treeViewDelegate.hovered)
|
||||||
|
root.entered(treeViewDelegate.expression)
|
||||||
|
else
|
||||||
|
root.exited(treeViewDelegate.expression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
visible: root.showOperators
|
||||||
|
width: stack.width
|
||||||
|
height: flow.childrenRect.height + 2 * StudioTheme.Values.flowMargin
|
||||||
|
|
||||||
|
Flow {
|
||||||
|
id: flow
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: StudioTheme.Values.flowMargin
|
||||||
|
spacing: StudioTheme.Values.flowSpacing
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
required property string value
|
||||||
|
required property string tooltip
|
||||||
|
|
||||||
|
width: textItem.contentWidth + 2 * StudioTheme.Values.flowPillMargin
|
||||||
|
height: StudioTheme.Values.flowPillHeight
|
||||||
|
color: "#161616"
|
||||||
|
radius: StudioTheme.Values.flowPillRadius
|
||||||
|
border {
|
||||||
|
color: "white"
|
||||||
|
width: mouseArea.containsMouse ? 1 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
id: mouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
tooltip: delegate.tooltip
|
||||||
|
|
||||||
|
onClicked: root.select(delegate.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: textItem
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
text: delegate.name
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,79 +2,163 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Templates
|
import QtQuick.Templates as T
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
Button {
|
T.TabButton {
|
||||||
id: control
|
id: control
|
||||||
|
|
||||||
implicitWidth: Math.max(
|
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||||
buttonBackground ? buttonBackground.implicitWidth : 0,
|
|
||||||
textItem.implicitWidth + leftPadding + rightPadding)
|
|
||||||
implicitHeight: Math.max(
|
|
||||||
buttonBackground ? buttonBackground.implicitHeight : 0,
|
|
||||||
textItem.implicitHeight + topPadding + bottomPadding)
|
|
||||||
leftPadding: 4
|
|
||||||
rightPadding: 4
|
|
||||||
|
|
||||||
text: "My Button"
|
property alias tooltip: toolTipArea.tooltip
|
||||||
|
property alias buttonIcon: buttonIcon.text
|
||||||
|
|
||||||
background: buttonBackground
|
width: control.style.squareControlSize.width + buttonLabel.implicitWidth
|
||||||
Rectangle {
|
+ buttonLabel.leftPadding + buttonLabel.rightPadding
|
||||||
id: buttonBackground
|
height: control.style.squareControlSize.height
|
||||||
color: "#047eff"
|
|
||||||
implicitWidth: 100
|
contentItem: Row {
|
||||||
implicitHeight: 40
|
spacing: 0
|
||||||
opacity: enabled ? 1 : 0.3
|
|
||||||
radius: 12
|
|
||||||
border.color: "#047eff"
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: textItem
|
|
||||||
Text {
|
Text {
|
||||||
id: textItem
|
id: buttonIcon
|
||||||
text: control.text
|
width: control.style.squareControlSize.width
|
||||||
|
height: control.height
|
||||||
opacity: enabled ? 1.0 : 0.3
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
color: "#ffffff"
|
font.pixelSize: control.style.baseIconFontSize
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: buttonLabel
|
||||||
|
height: control.height
|
||||||
|
rightPadding: 4
|
||||||
|
font.pixelSize: control.style.baseFontSize
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text: control.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
id: controlBackground
|
||||||
|
color: control.style.background.idle
|
||||||
|
border.color: control.style.border.idle
|
||||||
|
border.width: control.style.borderWidth
|
||||||
|
radius: StudioTheme.Values.smallRadius //control.style.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
id: toolTipArea
|
||||||
|
anchors.fill: parent
|
||||||
|
// Without setting the acceptedButtons property the clicked event won't
|
||||||
|
// reach the AbstractButton, it will be consumed by the ToolTipArea
|
||||||
|
acceptedButtons: Qt.NoButton
|
||||||
|
}
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "normal"
|
name: "default"
|
||||||
when: !control.down && !control.checked
|
when: control.enabled && !control.hovered && !control.pressed && !control.checked
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: buttonBackground
|
target: controlBackground
|
||||||
visible: false
|
color: control.style.background.idle
|
||||||
color: "#00000000"
|
border.color: control.style.border.idle
|
||||||
border.color: "#047eff"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textItem
|
target: buttonIcon
|
||||||
color: "#ffffff"
|
color: control.style.icon.idle
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonLabel
|
||||||
|
color: control.style.icon.idle
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "down"
|
name: "hover"
|
||||||
when: control.down && !control.checked
|
when: control.enabled && control.hovered && !control.pressed && !control.checked
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textItem
|
target: controlBackground
|
||||||
color: "#ffffff"
|
color: control.style.background.hover
|
||||||
|
border.color: control.style.border.hover
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: buttonBackground
|
target: buttonIcon
|
||||||
color: "#047eff"
|
color: control.style.icon.hover
|
||||||
border.color: "#00000000"
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonLabel
|
||||||
|
color: control.style.icon.hover
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "down1"
|
name: "hoverCheck"
|
||||||
when: control.checked
|
when: control.enabled && control.hovered && !control.pressed && control.checked
|
||||||
extend: "down"
|
PropertyChanges {
|
||||||
|
target: controlBackground
|
||||||
|
color: control.style.interactionHover
|
||||||
|
border.color: control.style.interactionHover
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonIcon
|
||||||
|
color: control.style.text.selectedText
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonLabel
|
||||||
|
color: control.style.text.selectedText
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "pressed"
|
||||||
|
when: control.enabled && control.hovered && control.pressed
|
||||||
|
PropertyChanges {
|
||||||
|
target: controlBackground
|
||||||
|
color: control.style.interaction
|
||||||
|
border.color: control.style.interaction
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonIcon
|
||||||
|
color: control.style.icon.interaction
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonLabel
|
||||||
|
color: control.style.icon.interaction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "check"
|
||||||
|
when: control.enabled && !control.pressed && control.checked
|
||||||
|
extend: "hoverCheck"
|
||||||
|
PropertyChanges {
|
||||||
|
target: controlBackground
|
||||||
|
color: control.style.interaction
|
||||||
|
border.color: control.style.interaction
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "pressedButNotHovered"
|
||||||
|
when: control.enabled && !control.hovered && control.pressed
|
||||||
|
extend: "hover"
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "disable"
|
||||||
|
when: !control.enabled
|
||||||
|
PropertyChanges {
|
||||||
|
target: controlBackground
|
||||||
|
color: control.style.background.disabled
|
||||||
|
border.color: control.style.border.disabled
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonIcon
|
||||||
|
color: control.style.icon.disabled
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: buttonLabel
|
||||||
|
color: control.style.icon.disabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ StudioControls.Menu {
|
|||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Add an instance")
|
text: qsTr("Add an instance")
|
||||||
enabled: root.targetAvailable
|
enabled: root.targetAvailable && ContentLibraryBackend.rootView.hasActive3DScene
|
||||||
onTriggered: ContentLibraryBackend.effectsModel.addInstance(root.targetItem)
|
onTriggered: ContentLibraryBackend.effectsModel.addInstance(root.targetItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
[
|
||||||
{
|
{
|
||||||
"ContextMenuArea": {
|
"ContextMenuArea": {
|
||||||
"size": "28x28",
|
"size": "28x28",
|
||||||
@@ -183,4 +184,101 @@
|
|||||||
"iconName": "visibilityOn"
|
"iconName": "visibilityOn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ToolbarArea": {
|
||||||
|
"size": "32x32",
|
||||||
|
"Off": {
|
||||||
|
"Disabled": { "color": "DStoolbarIcon_blocked" },
|
||||||
|
"Hovered": { "color": "DSiconColor" },
|
||||||
|
"Normal": { "color": "DSiconColor" },
|
||||||
|
"Selected": { "color": "DStextSelectedTextColor" }
|
||||||
|
},
|
||||||
|
"On": {
|
||||||
|
"Disabled": { "color": "DStoolbarIcon_blocked" },
|
||||||
|
"Hovered": { "color": "DStextSelectedTextColor" },
|
||||||
|
"Normal": { "color": "DStextSelectedTextColor" },
|
||||||
|
"Selected": { "color": "DStextSelectedTextColor" }
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"AlignCameraToViewIcon": {
|
||||||
|
"iconName": "alignToCam_medium"
|
||||||
|
},
|
||||||
|
"AlignViewToCameraIcon": {
|
||||||
|
"iconName": "alignToView_medium"
|
||||||
|
},
|
||||||
|
"CameraIcon": {
|
||||||
|
"Off": {
|
||||||
|
"iconName": "orthCam_small"
|
||||||
|
},
|
||||||
|
"On": {
|
||||||
|
"iconName": "perspectiveCam_small"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EditColorIcon": {
|
||||||
|
"iconName": "colorSelection_medium"
|
||||||
|
},
|
||||||
|
"EditLightIcon": {
|
||||||
|
"Off": {
|
||||||
|
"iconName": "editLightOff_medium"
|
||||||
|
},
|
||||||
|
"On": {
|
||||||
|
"iconName": "editLightOn_medium"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"FitToViewIcon": {
|
||||||
|
"iconName": "fitToView_medium"
|
||||||
|
},
|
||||||
|
"LocalOrientIcon": {
|
||||||
|
"iconName": "localOrient_medium"
|
||||||
|
},
|
||||||
|
"MoveToolIcon": {
|
||||||
|
"iconName": "move_medium"
|
||||||
|
},
|
||||||
|
"ParticlesAnimationIcon": {
|
||||||
|
"iconName": "particleAnimation_medium"
|
||||||
|
},
|
||||||
|
"ParticlesPlayIcon": {
|
||||||
|
"Off": {
|
||||||
|
"iconName": "playOutline_medium"
|
||||||
|
},
|
||||||
|
"On": {
|
||||||
|
"iconName": "pause"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ParticlesRestartIcon": {
|
||||||
|
"iconName": "restartParticles_medium"
|
||||||
|
},
|
||||||
|
"ResetViewIcon": {
|
||||||
|
"iconName": "reload_medium"
|
||||||
|
},
|
||||||
|
"RotateToolIcon": {
|
||||||
|
"iconName": "roatate_medium"
|
||||||
|
},
|
||||||
|
"ScaleToolIcon": {
|
||||||
|
"iconName": "scale_medium"
|
||||||
|
},
|
||||||
|
"SnappingIcon": {
|
||||||
|
"iconName": "snapping_medium"
|
||||||
|
},
|
||||||
|
"SnappingConfIcon": {
|
||||||
|
"iconName": "snapping_conf_medium"
|
||||||
|
},
|
||||||
|
"ToggleGroupIcon": {
|
||||||
|
"Off": {
|
||||||
|
"iconName": "selectOutline_medium"
|
||||||
|
},
|
||||||
|
"On": {
|
||||||
|
"iconName": "selectFill_medium"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"VisibilityIcon": {
|
||||||
|
"Off": {
|
||||||
|
"iconName": "invisible_medium"
|
||||||
|
},
|
||||||
|
"On": {
|
||||||
|
"iconName": "visible_medium"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
@@ -0,0 +1,242 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int toolTipDelay: 1000
|
||||||
|
|
||||||
|
width: 230
|
||||||
|
height: 270
|
||||||
|
color: StudioTheme.Values.themePanelBackground
|
||||||
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
|
border.width: StudioTheme.Values.border
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: rootView
|
||||||
|
|
||||||
|
// Spinboxes lose the initial binding if the value changes so we need these connections
|
||||||
|
onPosIntChanged: posIntSpin.realValue = rootView.posInt
|
||||||
|
onRotIntChanged: rotIntSpin.realValue = rootView.rotInt
|
||||||
|
onScaleIntChanged: scaleIntSpin.realValue = rootView.scaleInt
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
height: 32
|
||||||
|
Layout.topMargin: 8
|
||||||
|
Layout.rightMargin: 8
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 16
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
radius: 5
|
||||||
|
Layout.fillHeight: false
|
||||||
|
color: StudioTheme.Values.themePanelBackground
|
||||||
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
|
border.width: StudioTheme.Values.border
|
||||||
|
|
||||||
|
HelperWidgets.IconIndicator {
|
||||||
|
anchors.fill: parent
|
||||||
|
icon: StudioTheme.Constants.snapping_conf_medium
|
||||||
|
pixelSize: StudioTheme.Values.myIconFontSize * 1.4
|
||||||
|
iconColor: StudioTheme.Values.themeLinkIndicatorColorHover
|
||||||
|
enabled: false
|
||||||
|
states: [] // Disable normal state based coloring
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: qsTr("Snap Configuration")
|
||||||
|
font.pixelSize: 12
|
||||||
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.bold: true
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
Layout.margins:10
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
rowSpacing: 5
|
||||||
|
columnSpacing: 5
|
||||||
|
rows: 5
|
||||||
|
columns: 3
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Interval")
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.row: 0
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
font.pixelSize: 12
|
||||||
|
font.bold: true
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
text: qsTr("Position")
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.minimumWidth: 100
|
||||||
|
checked: rootView.posEnabled
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Snap position.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onToggled: rootView.posEnabled = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.RealSpinBox {
|
||||||
|
id: posIntSpin
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
realFrom: 1
|
||||||
|
realTo: 10000
|
||||||
|
realValue: rootView.posInt
|
||||||
|
realStepSize: 1
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Snap interval for move gizmo.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onRealValueChanged: rootView.posInt = realValue
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
text: qsTr("Rotation")
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.minimumWidth: 100
|
||||||
|
checked: rootView.rotEnabled
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Snap rotation.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onToggled: rootView.rotEnabled = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.RealSpinBox {
|
||||||
|
id: rotIntSpin
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
realFrom: 1
|
||||||
|
realTo: 90
|
||||||
|
realValue: rootView.rotInt
|
||||||
|
realStepSize: 1
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Snap interval in degrees for rotation gizmo.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onRealValueChanged: rootView.rotInt = realValue
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
text: qsTr("Scale")
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.minimumWidth: 100
|
||||||
|
checked: rootView.scaleEnabled
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Snap scale.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onToggled: rootView.scaleEnabled = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.RealSpinBox {
|
||||||
|
id: scaleIntSpin
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
realFrom: 1
|
||||||
|
realTo: 100
|
||||||
|
realValue: rootView.scaleInt
|
||||||
|
realStepSize: 1
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Snap interval for scale gizmo in percentage of original scale.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onRealValueChanged: rootView.scaleInt = realValue
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
text: qsTr("Absolute Position")
|
||||||
|
Layout.fillWidth: false
|
||||||
|
Layout.leftMargin: 0
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.row: 4
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
checked: rootView.absolute
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
ToolTip.text: qsTr("Toggles if the position snaps to absolute values or relative to object position.")
|
||||||
|
ToolTip.delay: root.toolTipDelay
|
||||||
|
|
||||||
|
onToggled: rootView.absolute = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("deg")
|
||||||
|
font.pixelSize: 12
|
||||||
|
Layout.column: 2
|
||||||
|
Layout.row: 2
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("%")
|
||||||
|
font.pixelSize: 12
|
||||||
|
Layout.column: 2
|
||||||
|
Layout.row: 3
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
text: qsTr("Reset All")
|
||||||
|
Layout.bottomMargin: 8
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
onClicked: rootView.resetDefaults()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
HelperWidgets.Section {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// model properties
|
||||||
|
required property string nodeName
|
||||||
|
required property bool nodeEnabled
|
||||||
|
required property var nodeUniformsModel
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
caption: root.nodeName
|
||||||
|
category: "EffectMaker"
|
||||||
|
|
||||||
|
draggable: true
|
||||||
|
fillBackground: true
|
||||||
|
showCloseButton: true
|
||||||
|
closeButtonToolTip: qsTr("Remove")
|
||||||
|
|
||||||
|
onCloseButtonClicked: {
|
||||||
|
EffectMakerBackend.effectMakerModel.removeNode(root.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
showEyeButton: true
|
||||||
|
eyeEnabled: root.nodeEnabled
|
||||||
|
eyeButtonToolTip: qsTr("Enable/Disable Node")
|
||||||
|
|
||||||
|
onEyeButtonClicked: {
|
||||||
|
root.nodeEnabled = root.eyeEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.nodeUniformsModel
|
||||||
|
|
||||||
|
EffectCompositionNodeUniform {
|
||||||
|
width: root.width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
height: layout.implicitHeight
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (uniformType === "int")
|
||||||
|
valueLoader.source = "ValueInt.qml"
|
||||||
|
else if (uniformType === "vec2")
|
||||||
|
valueLoader.source = "ValueVec2.qml"
|
||||||
|
else if (uniformType === "vec3")
|
||||||
|
valueLoader.source = "ValueVec3.qml"
|
||||||
|
else if (uniformType === "vec4")
|
||||||
|
valueLoader.source = "ValueVec4.qml"
|
||||||
|
else if (uniformType === "bool")
|
||||||
|
valueLoader.source = "ValueBool.qml"
|
||||||
|
else if (uniformType === "color")
|
||||||
|
valueLoader.source = "ValueColor.qml"
|
||||||
|
else if (uniformType === "image")
|
||||||
|
valueLoader.source = "ValueImage.qml"
|
||||||
|
else if (uniformType === "define")
|
||||||
|
valueLoader.source = "ValueDefine.qml"
|
||||||
|
else
|
||||||
|
valueLoader.source = "ValueFloat.qml"
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: layout
|
||||||
|
|
||||||
|
spacing: 20
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: uniformName
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
Layout.maximumWidth: 140
|
||||||
|
Layout.minimumWidth: 140
|
||||||
|
Layout.preferredWidth: 140
|
||||||
|
|
||||||
|
HelperWidgets.ToolTipArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
tooltip: uniformDescription
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: valueLoader
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,152 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var draggedSec: null
|
||||||
|
property var secsY: []
|
||||||
|
property int moveFromIdx: 0
|
||||||
|
property int moveToIdx: 0
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: col
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
EffectMakerTopBar {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectMakerPreview {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.toolbarHeight
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
|
EffectNodesComboBox {
|
||||||
|
mainRoot: root
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.code
|
||||||
|
tooltip: qsTr("Open Shader in Code Editor")
|
||||||
|
|
||||||
|
onClicked: {} // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ScrollView {
|
||||||
|
id: scrollView
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - y
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: scrollView.width
|
||||||
|
spacing: 1
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: repeater
|
||||||
|
|
||||||
|
width: root.width
|
||||||
|
model: EffectMakerBackend.effectMakerModel
|
||||||
|
|
||||||
|
onCountChanged: {
|
||||||
|
HelperWidgets.Controller.setCount("EffectMaker", repeater.count)
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: EffectCompositionNode {
|
||||||
|
width: root.width
|
||||||
|
|
||||||
|
Behavior on y {
|
||||||
|
PropertyAnimation {
|
||||||
|
duration: 300
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onStartDrag: (section) => {
|
||||||
|
root.draggedSec = section
|
||||||
|
root.moveFromIdx = index
|
||||||
|
|
||||||
|
highlightBorder = true
|
||||||
|
|
||||||
|
root.secsY = []
|
||||||
|
for (let i = 0; i < repeater.count; ++i)
|
||||||
|
root.secsY[i] = repeater.itemAt(i).y
|
||||||
|
}
|
||||||
|
|
||||||
|
onStopDrag: {
|
||||||
|
if (root.moveFromIdx === root.moveToIdx)
|
||||||
|
root.draggedSec.y = root.secsY[root.moveFromIdx]
|
||||||
|
else
|
||||||
|
EffectMakerBackend.effectMakerModel.moveNode(root.moveFromIdx, root.moveToIdx)
|
||||||
|
|
||||||
|
highlightBorder = false
|
||||||
|
root.draggedSec = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // Repeater
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: root.draggedSec
|
||||||
|
interval: 50
|
||||||
|
repeat: true
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root.moveToIdx = root.moveFromIdx
|
||||||
|
for (let i = 0; i < repeater.count; ++i) {
|
||||||
|
let currItem = repeater.itemAt(i)
|
||||||
|
if (i > root.moveFromIdx) {
|
||||||
|
if (root.draggedSec.y > currItem.y + (currItem.height - root.draggedSec.height) * .5) {
|
||||||
|
currItem.y = root.secsY[i] - root.draggedSec.height
|
||||||
|
root.moveToIdx = i
|
||||||
|
} else {
|
||||||
|
currItem.y = root.secsY[i]
|
||||||
|
}
|
||||||
|
} else if (i < root.moveFromIdx) {
|
||||||
|
if (root.draggedSec.y < currItem.y + (currItem.height - root.draggedSec.height) * .5) {
|
||||||
|
currItem.y = root.secsY[i] + root.draggedSec.height
|
||||||
|
root.moveToIdx = Math.min(root.moveToIdx, i)
|
||||||
|
} else {
|
||||||
|
currItem.y = root.secsY[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // Timer
|
||||||
|
} // Column
|
||||||
|
} // ScrollView
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: emptyText
|
||||||
|
|
||||||
|
text: qsTr("Add an effect node to start")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
|
|
||||||
|
x: scrollView.x + (scrollView.width - emptyText.width) * .5
|
||||||
|
y: scrollView.y + scrollView.height * .5
|
||||||
|
|
||||||
|
visible: EffectMakerBackend.effectMakerModel.isEmpty
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,127 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Rectangle { // toolbar
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.toolbarHeight
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 5
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
enabled: previewImage.scale > .4
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.zoomOut_medium
|
||||||
|
tooltip: qsTr("Zoom out")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
previewImage.scale -= .2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
enabled: previewImage.scale < 2
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.zoomIn_medium
|
||||||
|
tooltip: qsTr("Zoom In")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
previewImage.scale += .2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
enabled: previewImage.scale !== 1
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.fitAll_medium
|
||||||
|
tooltip: qsTr("Zoom Fit")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
previewImage.scale = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Text {
|
||||||
|
text: "0.000s"
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "0000000"
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.toStartFrame_medium
|
||||||
|
tooltip: qsTr("Restart Animation")
|
||||||
|
|
||||||
|
onClicked: {} // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.topToolbar_runProject
|
||||||
|
tooltip: qsTr("Play Animation")
|
||||||
|
|
||||||
|
onClicked: {} // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { // preview image
|
||||||
|
id: previewImageBg
|
||||||
|
|
||||||
|
color: "#dddddd"
|
||||||
|
width: parent.width
|
||||||
|
height: 200
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: previewImage
|
||||||
|
|
||||||
|
anchors.margins: 5
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
smooth: true
|
||||||
|
|
||||||
|
source: "images/qt_logo.png" // TODO: update image
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 200
|
||||||
|
easing.type: Easing.OutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.toolbarHeight
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
|
HelperWidgets.Button {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
x: 5
|
||||||
|
|
||||||
|
text: qsTr("Save in Library")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.AbstractButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
style: StudioTheme.Values.viewBarButtonStyle
|
||||||
|
buttonIcon: StudioTheme.Constants.help
|
||||||
|
tooltip: qsTr("How to use Effect Maker:
|
||||||
|
1. Click \"+ Add Effect\" to add effect node
|
||||||
|
2. Adjust the effect nodes properties
|
||||||
|
3. Change the order of the effects, if you like
|
||||||
|
4. See the preview
|
||||||
|
5. Save in the library, if you wish to reuse the effect later") // TODO: revise with doc engineer
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,55 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: 140
|
||||||
|
height: 32
|
||||||
|
|
||||||
|
color: mouseArea.containsMouse ? StudioTheme.Values.themeControlBackgroundInteraction
|
||||||
|
: "transparent"
|
||||||
|
|
||||||
|
signal addEffectNode(var nodeQenPath)
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
root.addEffectNode(modelData.nodeQenPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
id: nodeIcon
|
||||||
|
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
source: modelData.nodeIcon
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: modelData.nodeName
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pointSize: StudioTheme.Values.smallFontSize
|
||||||
|
anchors.verticalCenter: nodeIcon.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,113 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
StudioControls.ComboBox {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
x: 5
|
||||||
|
width: parent.width - 50
|
||||||
|
|
||||||
|
model: [qsTr("+ Add Effect")]
|
||||||
|
|
||||||
|
// hide default popup
|
||||||
|
popup.width: 0
|
||||||
|
popup.height: 0
|
||||||
|
|
||||||
|
required property Item mainRoot
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.popup
|
||||||
|
|
||||||
|
function onAboutToShow() {
|
||||||
|
var a = mainRoot.mapToGlobal(0, 0)
|
||||||
|
var b = root.mapToItem(mainRoot, 0, 0)
|
||||||
|
|
||||||
|
effectNodesWindow.x = a.x + b.x + root.width - effectNodesWindow.width
|
||||||
|
effectNodesWindow.y = a.y + b.y + root.height - 1
|
||||||
|
|
||||||
|
effectNodesWindow.show()
|
||||||
|
effectNodesWindow.requestActivate()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAboutToHide() {
|
||||||
|
effectNodesWindow.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: effectNodesWindow
|
||||||
|
|
||||||
|
width: row.width + 2 // 2: scrollView left and right 1px margins
|
||||||
|
height: Math.min(800, Math.min(row.height + 2, Screen.height - y - 40)) // 40: some bottom margin to cover OS bottom toolbar
|
||||||
|
flags: Qt.Popup | Qt.FramelessWindowHint
|
||||||
|
|
||||||
|
onActiveChanged: {
|
||||||
|
if (!active && !root.hover)
|
||||||
|
root.popup.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: StudioTheme.Values.themePanelBackground
|
||||||
|
border.color: StudioTheme.Values.themeInteraction
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
HelperWidgets.ScrollView {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 1
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: row
|
||||||
|
|
||||||
|
onWidthChanged: {
|
||||||
|
// Needed to update on first window showing, as row.width only gets
|
||||||
|
// correct value after the window is shown, so first showing is off
|
||||||
|
|
||||||
|
var a = mainRoot.mapToGlobal(0, 0)
|
||||||
|
var b = root.mapToItem(mainRoot, 0, 0)
|
||||||
|
|
||||||
|
effectNodesWindow.x = a.x + b.x + root.width - row.width
|
||||||
|
}
|
||||||
|
|
||||||
|
padding: 10
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: EffectMakerBackend.effectMakerNodesModel
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: categoryName
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pointSize: StudioTheme.Values.baseFontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: 1; height: 5 } // spacer
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: categoryNodes
|
||||||
|
|
||||||
|
EffectNode {
|
||||||
|
onAddEffectNode: (nodeQenPath) => {
|
||||||
|
EffectMakerBackend.rootView.addEffectNode(modelData.nodeQenPath)
|
||||||
|
root.popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
checked: uniformValue
|
||||||
|
onToggled: uniformValue = checked
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: itemPane
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
HelperWidgets.ColorEditor {
|
||||||
|
backendValue: uniformBackendValue
|
||||||
|
|
||||||
|
showExtendedFunctionButton: false
|
||||||
|
|
||||||
|
onValueChanged: uniformValue = convertColorToString(color)
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: textField
|
||||||
|
|
||||||
|
width: parent.width - 20
|
||||||
|
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
|
||||||
|
text: uniformValue
|
||||||
|
|
||||||
|
onEditingFinished: uniformValue = text
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user