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
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++11
|
||||
Standard: c++17
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
|
@@ -36,8 +36,6 @@ qtc_link_with_qt()
|
||||
|
||||
option(WITH_TESTS "Build Tests" ${ENV_QTC_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(SHOW_BUILD_DATE "Show build date in about dialog" 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}
|
||||
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
|
||||
if (TARGET Qt6::Core5CompatPrivate)
|
||||
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
|
||||
features if they are available.
|
||||
|
||||
https://github.com/tcbrindle/span
|
||||
https://github.com/martinmoene/span-lite
|
||||
|
||||
QtCreator/src/libs/3rdparty/span
|
||||
|
||||
Copyright Tristan Brindle, 2018
|
||||
Copyright 2018-2021 Martin Moene
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(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)
|
||||
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"
|
||||
"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})
|
||||
@@ -198,7 +198,9 @@ function(add_qtc_library name)
|
||||
SOURCES_PREFIX ${_arg_SOURCES_PREFIX}
|
||||
SOURCES ${_arg_SOURCES}
|
||||
INCLUDES ${_arg_INCLUDES}
|
||||
SYSTEM_INCLUDES ${_arg_SYTEM_INCLUDES}
|
||||
PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES}
|
||||
PUBLIC_SYSTEM_INCLUDES ${_arg_PUBLIC_SYSTEM_INCLUDES}
|
||||
DEFINES ${default_defines_copy} ${_arg_DEFINES} ${TEST_DEFINES}
|
||||
PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES}
|
||||
DEPENDS ${_arg_DEPENDS} ${IMPLICIT_DEPENDS}
|
||||
@@ -322,7 +324,7 @@ function(add_qtc_plugin target_name)
|
||||
cmake_parse_arguments(_arg
|
||||
"SKIP_INSTALL;INTERNAL_ONLY;SKIP_TRANSLATION;EXPORT;SKIP_PCH"
|
||||
"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}
|
||||
)
|
||||
|
||||
@@ -465,7 +467,9 @@ function(add_qtc_plugin target_name)
|
||||
|
||||
extend_qtc_target(${target_name}
|
||||
INCLUDES ${_arg_INCLUDES}
|
||||
SYSTEM_INCLUDES ${_arg_SYSTEM_INCLUDES}
|
||||
PUBLIC_INCLUDES ${_arg_PUBLIC_INCLUDES}
|
||||
PUBLIC_SYSTEM_INCLUDES ${_arg_PUBLIC_SYSTEM_INCLUDES}
|
||||
DEFINES ${DEFAULT_DEFINES} ${_arg_DEFINES} ${TEST_DEFINES}
|
||||
PUBLIC_DEFINES ${_arg_PUBLIC_DEFINES}
|
||||
DEPENDS ${_arg_DEPENDS} ${_DEP_PLUGINS} ${IMPLICIT_DEPENDS}
|
||||
|
@@ -244,13 +244,13 @@ function(update_resource_files_list sources)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
function(set_public_includes target includes)
|
||||
function(set_public_includes target includes system)
|
||||
foreach(inc_dir IN LISTS includes)
|
||||
if (NOT IS_ABSOLUTE ${inc_dir})
|
||||
set(inc_dir "${CMAKE_CURRENT_SOURCE_DIR}/${inc_dir}")
|
||||
endif()
|
||||
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}>
|
||||
$<INSTALL_INTERFACE:${_IDE_HEADER_INSTALL_PATH}/${include_dir_relative_path}>
|
||||
)
|
||||
@@ -463,7 +463,7 @@ function(extend_qtc_target target_name)
|
||||
cmake_parse_arguments(_arg
|
||||
""
|
||||
"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}
|
||||
)
|
||||
|
||||
@@ -504,8 +504,10 @@ function(extend_qtc_target target_name)
|
||||
PUBLIC ${_arg_PUBLIC_DEFINES}
|
||||
)
|
||||
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)
|
||||
foreach(source IN LISTS _arg_SOURCES)
|
||||
|
@@ -35,6 +35,8 @@ macro.QMLD = "Qt Quick Designer"
|
||||
macro.QQV = "Qt QML Viewer"
|
||||
macro.QSDK = "Qt"
|
||||
macro.QUL = "Qt Quick Ultralite"
|
||||
macro.QOI = "Qt Online Installer"
|
||||
macro.QMT = "Qt Maintenance Tool"
|
||||
macro.qtcversion = $QTC_VERSION
|
||||
macro.param = "\\e"
|
||||
macro.raisedaster.HTML = "<sup>*</sup>"
|
||||
|
@@ -31,7 +31,7 @@
|
||||
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.
|
||||
|
||||
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
|
||||
\c {choco install conan} or \c {pip install conan} command.
|
||||
|
||||
|
@@ -169,7 +169,7 @@
|
||||
\section2 Debugging Tools for Windows
|
||||
|
||||
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
|
||||
installation packages.
|
||||
|
||||
|
@@ -102,21 +102,13 @@
|
||||
|
||||
\e{Windows}
|
||||
|
||||
Check whether \QC has been compiled with OpenGL/Desktop, or ANGLE as
|
||||
a backend. The official binaries are always built with ANGLE (a library that
|
||||
maps OpenGL ES API to DirectX).
|
||||
By default Qt Quick uses Direct3D 11. 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.
|
||||
|
||||
\list
|
||||
|
||||
\li ANGLE backend: This requires a Windows version newer than Windows XP.
|
||||
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
|
||||
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}
|
||||
for details.
|
||||
|
||||
\e{Unix}
|
||||
|
||||
|
@@ -83,7 +83,7 @@
|
||||
|
||||
The data is transmitted to the backend storage using an encrypted
|
||||
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
|
||||
|
||||
|
@@ -22,10 +22,10 @@
|
||||
\endlist
|
||||
|
||||
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
|
||||
\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.
|
||||
|
||||
You can connect embedded devices to the development PC to run, debug, and
|
||||
|
@@ -54,7 +54,7 @@
|
||||
\section2 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.
|
||||
|
||||
\section2 Specifying MCU Settings
|
||||
|
@@ -376,7 +376,7 @@
|
||||
the C++20 committee draft. It is compatible with C++11, but will use
|
||||
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}
|
||||
{Boost Software License, Version 1.0}.
|
||||
@@ -384,7 +384,7 @@
|
||||
|
||||
The source code can be found here:
|
||||
\list
|
||||
\li \l{https://github.com/tcbrindle/span}
|
||||
\li \l{https://github.com/martinmoene/span-lite}
|
||||
\li QtCreator/src/libs/3rdparty/span
|
||||
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/span}
|
||||
\endlist
|
||||
@@ -394,180 +394,6 @@
|
||||
Roberto Raggi <roberto.raggi@gmail.com>\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)}
|
||||
|
||||
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}
|
||||
\endlist
|
||||
|
||||
\li \b{three.js}
|
||||
|
||||
Copyright (C) 2010-2015 three.js authors
|
||||
|
||||
MIT License.
|
||||
|
||||
share/qtcreator/templates/wizards/projects/qmake/qtcanvas3dapplication
|
||||
|
||||
\li \b{OpenSSL}
|
||||
|
||||
The OpenSSL toolkit stays under a double license, i.e. both the conditions of
|
||||
|
@@ -34,13 +34,13 @@
|
||||
\section1 Checking Build and Run Settings
|
||||
|
||||
\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
|
||||
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
|
||||
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
|
||||
available in \QC. If it does not, you must add the kits yourself to tell
|
||||
\QC where everything is.
|
||||
|
@@ -46,8 +46,8 @@
|
||||
\row
|
||||
\li \b {\l{Building and Running an Example}}
|
||||
|
||||
To check that the \l{https://www.qt.io/download-qt-installer}
|
||||
{Qt Online Installer} created \l{glossary-buildandrun-kit}
|
||||
To check that \l{https://www.qt.io/download-qt-installer}
|
||||
{\QOI} created \l{glossary-buildandrun-kit}
|
||||
{build and run kits}, open an example application and run it.
|
||||
If you have not done so before, go to
|
||||
\l{Building and Running an Example}.
|
||||
|
@@ -19,10 +19,10 @@
|
||||
\endlist
|
||||
|
||||
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
|
||||
\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.
|
||||
|
||||
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
|
||||
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 >
|
||||
\uicontrol Kits > \uicontrol Compilers.
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
|
||||
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
|
||||
to a Qt that the system installed with some other package
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
\section1 Minimum Requirements
|
||||
|
@@ -14,8 +14,8 @@
|
||||
|
||||
\title Configuring Projects
|
||||
|
||||
When you install Qt for a target platform, such as Android or QNX, the
|
||||
\l{https://www.qt.io/download-qt-installer}{Qt Online Installer}
|
||||
When you install Qt for a target platform, such as Android or QNX,
|
||||
\l{https://www.qt.io/download-qt-installer}{\QOI}
|
||||
creates \l{glossary-buildandrun-kit}{kits} for the development
|
||||
targets.
|
||||
|
||||
|
@@ -83,8 +83,8 @@
|
||||
|
||||
\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
|
||||
\e Main.qml for editing. You can use the \l {Installing Qt}
|
||||
{Qt Maintenance Tool} to install Qt Virtual Keyboard.
|
||||
\e Main.qml for editing. You can use \l {Installing Qt}
|
||||
{\QMT} to install Qt Virtual Keyboard.
|
||||
|
||||
\li Select \uicontrol Next to open the \uicontrol {Kit Selection}
|
||||
dialog.
|
||||
|
@@ -119,6 +119,9 @@
|
||||
name of the main QML file in the Qt Quick UI project.
|
||||
\li Select \uicontrol Build > \uicontrol Run to build and run your
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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}.
|
||||
|
||||
\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
|
||||
|
||||
@@ -183,7 +198,7 @@
|
||||
|
||||
\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
|
||||
the \uicontrol {Clean Repository} dialog. Ignored files are deselected by
|
||||
default. Select the files to delete, and then select \uicontrol Delete.
|
||||
@@ -465,15 +480,6 @@
|
||||
\li Show the commit in the diff editor.
|
||||
\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
|
||||
|
||||
To work with remote repositories, select the commands in \uicontrol Tools >
|
||||
|
@@ -39,7 +39,7 @@
|
||||
\section1 Setting Up the Development Environment
|
||||
|
||||
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.
|
||||
|
||||
\section2 Setting Up Qt for WebAssembly
|
||||
@@ -47,7 +47,7 @@
|
||||
To set up Qt for WebAssembly:
|
||||
|
||||
\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}).
|
||||
\li Check out a known-good Emscripten version supported by the Qt for
|
||||
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
|
||||
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/}
|
||||
{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/}
|
||||
{released \QC version} or a \l{https://download.qt.io/snapshots/qtcreator/}
|
||||
{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
|
||||
more components.
|
||||
|
||||
\include qtquick-mcu-support.qdocinc mcu qtquick components
|
||||
|
||||
\section1 Merging Files with Templates
|
||||
|
||||
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
|
||||
|
||||
/*!
|
||||
\previouspage studio-on-mcus.html
|
||||
\previouspage studio-mcu-framework.html
|
||||
\page studio-compatibility-with-mcu-sdks.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
|
||||
\page studio-features-on-mcu-projects.html
|
||||
\nextpage studio-help.html
|
||||
\nextpage studio-projects-for-mcus.html
|
||||
|
||||
\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
|
||||
\page studio-on-mcus.html
|
||||
\nextpage studio-compatibility-with-mcu-sdks.html
|
||||
\nextpage studio-mcu-framework.html
|
||||
|
||||
\title \QDS on MCUs
|
||||
|
||||
\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).
|
||||
|
||||
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:
|
||||
\table
|
||||
\row
|
||||
\li \image qds-front-gs.png
|
||||
\li With \QDS, you can use subsets of components to create UIs
|
||||
for devices that are powered by microcontroller units (MCU). Use
|
||||
the \uicontrol {\QMCU} preset in the \QDS wizard to set up a new
|
||||
\QMCU project. Using the \uicontrol {\QMCU} preset creates an
|
||||
application that utilizes a subset of the default components that
|
||||
you can deploy, run, and debug on MCU boards.
|
||||
\endtable
|
||||
|
||||
\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
|
||||
\li \l {\QMCU Framework}
|
||||
|
||||
\section1 Developing applications for MCU devices with \QDS
|
||||
Provides an overview of the \QMCU framework.
|
||||
\li \l {\QDS Version Compatibility with \QMCU SDKs}
|
||||
|
||||
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.
|
||||
Lists how the \QDS versions match with particular \QMCU SDKs.
|
||||
\li \l {\QDS Features on MCU Projects}
|
||||
|
||||
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}.
|
||||
Specifies how the \QDS features are supported for developing MCU projects.
|
||||
\li \l {Creating Projects for MCUs}
|
||||
|
||||
\image qds-mcu-target-deployment.png
|
||||
Describes how to use the \QDS wizard and \uicontrol {\QMCU} preset
|
||||
to set up a new \QMCU project.
|
||||
\li \l {Creating UIs for MCUs}
|
||||
|
||||
\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}.
|
||||
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}
|
||||
|
||||
\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
|
||||
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
|
||||
*/
|
||||
|
@@ -170,6 +170,36 @@
|
||||
\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
|
||||
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
|
||||
\li \uicontrol Alias
|
||||
\li Exports the component generated from this layer as an alias in the
|
||||
|
@@ -21,7 +21,7 @@
|
||||
|
||||
\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.
|
||||
|
||||
\table
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
\QBPS is included in the
|
||||
\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:
|
||||
|
||||
\list
|
||||
|
@@ -187,8 +187,22 @@
|
||||
Components 1.0, you need the import statement
|
||||
\c {QtQuick.Studio.Components 1.0}. You can also import a module
|
||||
as an alias.
|
||||
\li In the \uicontrol {Properties} field, specify properties for
|
||||
the component. You can add and modify properties in \QDS.
|
||||
\li In the \uicontrol {Properties} field, 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.
|
||||
\li Select the \uicontrol {Clip Contents} check box to enable clipping
|
||||
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
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
\QBSK is included in the
|
||||
\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:
|
||||
|
||||
\list
|
||||
|
@@ -209,8 +209,22 @@
|
||||
\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 can also import a module as an alias.
|
||||
\li In the \uicontrol {Properties} field, specify properties for the
|
||||
component. You can add and modify properties in \QDS.
|
||||
\li In the \uicontrol {Properties} field, 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.
|
||||
\li Select the \uicontrol Alias check box to export the item generated
|
||||
from this layer as an alias in the parent component.
|
||||
\li Select the \uicontrol Clip check box to enable clipping in the
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
\QBXD is included in the
|
||||
\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:
|
||||
|
||||
\list
|
||||
|
@@ -114,15 +114,21 @@
|
||||
you need the import statement \c {QtQuick.Studio.Components 1.0}.
|
||||
You can also import a module as an alias.
|
||||
\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.
|
||||
Following are few examples of properties:
|
||||
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 In the \uicontrol {Snippet} field, specify component to be added as child under this
|
||||
component.
|
||||
Following example adds a Connection component:
|
||||
@@ -134,6 +140,7 @@
|
||||
\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.
|
||||
\li Select the \uicontrol Clip check box to enable clipping in the
|
||||
component generated from the layer. The generated component will clip
|
||||
its own painting, as well as the painting of its children, to its
|
||||
|
@@ -24,7 +24,7 @@
|
||||
\li \l {Installation}
|
||||
|
||||
\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}
|
||||
|
||||
Follow a set of hands-on tutorials that illustrate how to use the
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
/*!
|
||||
\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
|
||||
|
||||
\title Help
|
||||
|
@@ -8,15 +8,15 @@
|
||||
|
||||
\title Installation
|
||||
|
||||
You can install \QDS either using a stand-alone installation package or the
|
||||
Qt online installer. The installers copy all the modules and tools you need
|
||||
You can install \QDS either using a stand-alone installation package or \QOI.
|
||||
The installers copy all the modules and tools you need
|
||||
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
|
||||
systems. For more information, see \l{Supported Platforms}.
|
||||
|
||||
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
|
||||
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}.
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
\list 1
|
||||
\li Start the Qt online installer.
|
||||
\li Start \QOI.
|
||||
\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
|
||||
installer to complete the installation.
|
||||
\endlist
|
||||
|
@@ -51,7 +51,7 @@
|
||||
\li MCU
|
||||
\li Creates an application that uses a subset of default components
|
||||
(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
|
||||
\li {1,3} Mobile
|
||||
\li Scroll
|
||||
|
@@ -33,6 +33,7 @@
|
||||
\li \l{Open Documents}
|
||||
\li \l{Content Library}
|
||||
\li \l{Texture Editor}
|
||||
\li \l{Qt Insight}
|
||||
\endlist
|
||||
\li \l{Managing Workspaces}
|
||||
\li \l{Managing Sessions}
|
||||
@@ -254,8 +255,13 @@
|
||||
\li \l{Use external tools}
|
||||
\li \l{\QDS on MCUs}
|
||||
\list
|
||||
\li \l {\QMCU Framework}
|
||||
\li \l {\QDS Version Compatibility with \QMCU SDKs}
|
||||
\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
|
||||
\li \l Help
|
||||
|
@@ -183,7 +183,7 @@
|
||||
and drag the component along the axis.
|
||||
\li To move components on a plane, click the plane handle and drag the
|
||||
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.
|
||||
\endlist
|
||||
|
||||
@@ -221,6 +221,35 @@
|
||||
gray handle at the center of the component.
|
||||
\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
|
||||
|
||||
To align a camera to the \uicontrol{3D} view:
|
||||
@@ -375,6 +404,16 @@
|
||||
\li Toggle Edit Light On/Off
|
||||
\li \key U
|
||||
\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
|
||||
\li \inlineimage icons/align-camera-on.png
|
||||
\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
|
||||
\previouspage studio-content-library.html
|
||||
\nextpage creator-project-managing-workspaces.html
|
||||
\nextpage studio-qt-insight.html
|
||||
|
||||
\title Texture Editor
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
/*!
|
||||
\page creator-project-managing-workspaces.html
|
||||
\previouspage studio-texture-editor.html
|
||||
\previouspage studio-qt-insight.html
|
||||
\nextpage creator-project-managing-sessions.html
|
||||
|
||||
\title Managing Workspaces
|
||||
|
@@ -156,7 +156,7 @@ TreeViewDelegate {
|
||||
mouseArea.allowTooltip = true
|
||||
}
|
||||
|
||||
onPositionChanged: tooltipBackend.reposition()
|
||||
onPositionChanged: AssetsLibraryBackend.tooltipBackend.reposition()
|
||||
|
||||
onPressed: (mouse) => {
|
||||
mouseArea.forceActiveFocus()
|
||||
|
@@ -145,11 +145,11 @@ Item {
|
||||
Column {
|
||||
id: toolbarColumn
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 6
|
||||
anchors.bottomMargin: 6
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
spacing: 12
|
||||
anchors.topMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||
anchors.bottomMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||
anchors.leftMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||
anchors.rightMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||
spacing: StudioTheme.Values.toolbarColumnSpacing
|
||||
|
||||
StudioControls.SearchBox {
|
||||
id: searchBox
|
||||
@@ -260,10 +260,13 @@ Item {
|
||||
|
||||
AssetsView {
|
||||
id: assetsView
|
||||
assetsRoot: root
|
||||
contextMenu: contextMenu
|
||||
|
||||
width: parent.width
|
||||
height: parent.height - assetsView.y
|
||||
|
||||
assetsRoot: root
|
||||
contextMenu: contextMenu
|
||||
focus: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,11 @@ TreeView {
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
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 rootView: AssetsLibraryBackend.rootView
|
||||
property var tooltipBackend: AssetsLibraryBackend.tooltipBackend
|
||||
@@ -46,9 +51,18 @@ TreeView {
|
||||
return -1
|
||||
}
|
||||
|
||||
ScrollBar.vertical: HelperWidgets.VerticalScrollBar {
|
||||
HoverHandler { id: hoverHandler }
|
||||
|
||||
ScrollBar.vertical: HelperWidgets.ScrollBar {
|
||||
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
|
||||
@@ -348,22 +362,21 @@ TreeView {
|
||||
root.currentFilePath = filePath
|
||||
}
|
||||
|
||||
Keys.enabled: true
|
||||
|
||||
Keys.onUpPressed: {
|
||||
if (!root.currentFilePath)
|
||||
function moveSelection(amount)
|
||||
{
|
||||
if (!assetsModel.haveFiles || !amount)
|
||||
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 nextRow = row
|
||||
let nextIndex = index
|
||||
|
||||
do {
|
||||
if (nextRow <= root.firstRow)
|
||||
return // don't select hidden rows
|
||||
|
||||
nextRow--
|
||||
nextRow = nextRow + amount
|
||||
if ((amount < 0 && nextRow < root.firstRow) || (amount > 0 && nextRow > root.lastRow))
|
||||
return
|
||||
nextIndex = root.__modelIndex(nextRow)
|
||||
} while (assetsModel.isDirectory(nextIndex))
|
||||
|
||||
@@ -371,26 +384,14 @@ TreeView {
|
||||
root.positionViewAtRow(nextRow, TableView.Contain)
|
||||
}
|
||||
|
||||
Keys.enabled: true
|
||||
|
||||
Keys.onUpPressed: {
|
||||
moveSelection(-1)
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
if (!root.currentFilePath)
|
||||
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)
|
||||
moveSelection(1)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import QtQuick
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import HelperWidgets as HelperWidgets
|
||||
|
||||
PopupDialog {
|
||||
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 {
|
||||
id: form
|
||||
y: 32
|
||||
height: 160
|
||||
}
|
||||
}
|
||||
|
@@ -3,99 +3,77 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import StudioControls
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Rectangle {
|
||||
width: 400
|
||||
height: 800
|
||||
color: "#1b1b1b"
|
||||
Column {
|
||||
id: root
|
||||
|
||||
readonly property real horizontalSpacing: 10
|
||||
readonly property real verticalSpacing: 16
|
||||
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||
|
||||
property var backend
|
||||
|
||||
Text {
|
||||
id: text1
|
||||
x: 10
|
||||
y: 25
|
||||
color: "#ffffff"
|
||||
text: qsTr("Target")
|
||||
font.pixelSize: 15
|
||||
y: StudioTheme.Values.popupMargin
|
||||
width: parent.width
|
||||
spacing: root.verticalSpacing
|
||||
|
||||
Row {
|
||||
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.") }
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text111
|
||||
x: 80
|
||||
y: 25
|
||||
color: "red"
|
||||
text: backend.targetNode
|
||||
font.pixelSize: 15
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: sourceNode
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
|
||||
model: backend.sourceNode.model ?? []
|
||||
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
}
|
||||
|
||||
PopupLabel {
|
||||
width: root.columnWidth
|
||||
text: backend.targetNode
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
Text {
|
||||
id: text2
|
||||
x: 13
|
||||
y: 111
|
||||
color: "#ffffff"
|
||||
text: qsTr("Source Propety")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: sourceProperty
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
|
||||
TopLevelComboBox {
|
||||
id: sourceNode
|
||||
x: 135
|
||||
y: 98
|
||||
width: 156
|
||||
model: backend.sourceProperty.model ?? []
|
||||
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
onActivated: backend.sourceProperty.activateIndex(
|
||||
sourceProperty.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceProperty.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
}
|
||||
|
||||
model: backend.sourceNode.model ?? []
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: name
|
||||
width: root.columnWidth
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
|
||||
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
model: backend.property.model ?? []
|
||||
|
||||
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 13
|
||||
y: 88
|
||||
color: "#ffffff"
|
||||
text: qsTr("Source Node")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: sourceProperty
|
||||
x: 140
|
||||
y: 121
|
||||
width: 156
|
||||
|
||||
model: backend.sourceProperty.model ?? []
|
||||
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
onActivated: backend.sourceProperty.activateIndex(
|
||||
sourceProperty.currentIndex)
|
||||
property int currentTypeIndex: backend.sourceProperty.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text3
|
||||
x: 10
|
||||
y: 55
|
||||
color: "#ffffff"
|
||||
text: qsTr("Property")
|
||||
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.Controls
|
||||
import ConnectionsEditor
|
||||
import HelperWidgets 2.0 as HelperWidgets
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
import ConnectionsEditorEditorBackend
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
width: 606
|
||||
height: 160
|
||||
interactive: false
|
||||
id: root
|
||||
|
||||
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||
|
||||
property bool adsFocus: false
|
||||
|
||||
clip: true
|
||||
interactive: true
|
||||
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: {
|
||||
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: {
|
||||
listView.currentIndex = listView.model.currentIndex
|
||||
root.currentIndex = root.model.currentIndex
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
listView.currentIndex = listView.model.currentIndex
|
||||
dialog.backend.currentRow = listView.currentIndex
|
||||
root.currentIndex = root.model.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: [
|
||||
BindingsDialog {
|
||||
id: dialog
|
||||
visible: false
|
||||
backend: listView.model.delegate
|
||||
backend: root.model.delegate
|
||||
}
|
||||
]
|
||||
delegate: Item {
|
||||
|
||||
width: 600
|
||||
height: 18
|
||||
delegate: Rectangle {
|
||||
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 {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: {
|
||||
listView.model.currentIndex = index
|
||||
listView.currentIndex = index
|
||||
dialog.backend.currentRow = index
|
||||
root.model.currentIndex = itemDelegate.index
|
||||
root.currentIndex = itemDelegate.index
|
||||
dialog.popup(mouseArea)
|
||||
}
|
||||
|
||||
property int currentIndex: listView.currentIndex
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row1
|
||||
x: 0
|
||||
y: 0
|
||||
width: 600
|
||||
height: 16
|
||||
spacing: 10
|
||||
id: row
|
||||
|
||||
property color textColor: itemDelegate.ListView.isCurrentItem ? root.style.text.selectedText
|
||||
: root.style.icon.idle
|
||||
|
||||
height: itemDelegate.height
|
||||
spacing: root.rowSpacing
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
color: "#ffffff"
|
||||
text: target ?? ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: root.rowWidth + root.rowRest
|
||||
height: itemDelegate.height
|
||||
color: row.textColor
|
||||
text: itemDelegate.target ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
leftPadding: root.rowSpacing
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: targetProperty ?? ""
|
||||
color: "#ffffff"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: root.rowWidth
|
||||
height: itemDelegate.height
|
||||
text: itemDelegate.targetProperty ?? ""
|
||||
color: row.textColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: source ?? ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "#ffffff"
|
||||
width: root.rowWidth
|
||||
height: itemDelegate.height
|
||||
text: itemDelegate.source ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: row.textColor
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: sourceProperty ?? ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "#ffffff"
|
||||
width: root.rowWidth
|
||||
height: itemDelegate.height
|
||||
text: itemDelegate.sourceProperty ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: row.textColor
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
Rectangle {
|
||||
width: root.style.squareControlSize.width
|
||||
height: root.style.squareControlSize.height
|
||||
|
||||
text: "-"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pointSize: 14
|
||||
color: "#ffffff"
|
||||
font.bold: true
|
||||
MouseArea {
|
||||
color: toolTipArea.containsMouse ?
|
||||
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||
: root.style.background.hover
|
||||
: "transparent"
|
||||
|
||||
Text {
|
||||
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 {
|
||||
color: "#2a5593"
|
||||
color: root.style.interaction
|
||||
width: 600
|
||||
}
|
||||
}
|
||||
|
@@ -2,9 +2,44 @@
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import HelperWidgets 2.0 as HelperWidgets
|
||||
|
||||
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 {
|
||||
y: 32
|
||||
id: form
|
||||
}
|
||||
}
|
||||
|
@@ -1,242 +1,207 @@
|
||||
|
||||
// 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 StudioControls
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
|
||||
Rectangle {
|
||||
width: 400
|
||||
height: 800
|
||||
color: "#1b1b1b"
|
||||
Column {
|
||||
id: root
|
||||
|
||||
Text {
|
||||
id: text1
|
||||
x: 10
|
||||
y: 25
|
||||
color: "#ffffff"
|
||||
text: qsTr("Target:")
|
||||
font.pixelSize: 15
|
||||
readonly property real horizontalSpacing: 10
|
||||
readonly property real verticalSpacing: 16
|
||||
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||
|
||||
property var backend
|
||||
|
||||
y: StudioTheme.Values.popupMargin
|
||||
width: parent.width
|
||||
spacing: root.verticalSpacing
|
||||
|
||||
TapHandler {
|
||||
onTapped: root.forceActiveFocus()
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: target
|
||||
x: 95
|
||||
width: 210
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -367
|
||||
model: ["mySpinbox", "foo", "backendObject"]
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
PopupLabel { text: qsTr("Signal"); tooltip: qsTr("The name of the signal.") }
|
||||
PopupLabel { text: qsTr("Action"); tooltip: qsTr("The type of the action.") }
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text2
|
||||
x: 10
|
||||
y: 131
|
||||
color: "#ffffff"
|
||||
text: qsTr("Signal")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
TopLevelComboBox {
|
||||
id: signal
|
||||
x: 10
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -207
|
||||
model: ["onClicked", "onPressed", "onReleased"]
|
||||
}
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: signal
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
|
||||
TopLevelComboBox {
|
||||
id: action
|
||||
x: 207
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -207
|
||||
model: ["Call Function", "Assign", "ChnageState"]
|
||||
}
|
||||
model: backend.signal.name.model ?? 0
|
||||
|
||||
Text {
|
||||
id: text3
|
||||
x: 207
|
||||
y: 131
|
||||
color: "#ffffff"
|
||||
text: qsTr("Action")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
Item {
|
||||
id: functionGroup
|
||||
x: 0
|
||||
y: 276
|
||||
width: 400
|
||||
height: 176
|
||||
|
||||
Text {
|
||||
id: text4
|
||||
x: 17
|
||||
y: -11
|
||||
color: "#ffffff"
|
||||
text: qsTr("Target")
|
||||
font.pixelSize: 15
|
||||
onActivated: backend.signal.name.activateIndex(signal.currentIndex)
|
||||
property int currentTypeIndex: backend.signal.name.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: signal.currentIndex = signal.currentTypeIndex
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: functionTarget
|
||||
x: 10
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -48
|
||||
model: ["mySpinBox", "backendObject", "someButton"]
|
||||
}
|
||||
StudioControls.TopLevelComboBox {
|
||||
id: action
|
||||
style: StudioTheme.Values.connectionPopupControlStyle
|
||||
width: root.columnWidth
|
||||
textRole: "text"
|
||||
valueRole: "value"
|
||||
///model.getData(currentIndex, "role")
|
||||
property int indexFromBackend: indexOfValue(backend.actionType)
|
||||
onIndexFromBackendChanged: action.currentIndex = action.indexFromBackend
|
||||
onActivated: backend.changeActionType(action.currentValue)
|
||||
|
||||
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
|
||||
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") }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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)
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: stateGroup
|
||||
x: 10
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -12
|
||||
model: ["default", "State Group 01", "State Group 02"]
|
||||
onUpdate: function(index, value) {
|
||||
//console.log("update", index, value)
|
||||
backend.conditionListModel.updateToken(index, value)
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: stateName
|
||||
x: 209
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -12
|
||||
model: ["State 01", "State 02", "State 03"]
|
||||
onAdd: function(value) {
|
||||
//console.log("add", value)
|
||||
backend.conditionListModel.appendToken(value)
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text7
|
||||
x: 209
|
||||
y: -11
|
||||
color: "#ffffff"
|
||||
text: qsTr("State")
|
||||
font.pixelSize: 15
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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
|
||||
|
||||
TopLevelComboBox {
|
||||
id: valueTarget
|
||||
x: 10
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -12
|
||||
model: ["mySpinBox", "myButton", "backendObject"]
|
||||
}
|
||||
onClicked: backend.addElse()
|
||||
}
|
||||
|
||||
TopLevelComboBox {
|
||||
id: valueSource
|
||||
x: 209
|
||||
y: 7
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: -12
|
||||
model: ["mySpinBox", "myButton", "backendObject"]
|
||||
}
|
||||
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 {
|
||||
id: text9
|
||||
x: 209
|
||||
y: -11
|
||||
color: "#ffffff"
|
||||
text: qsTr("source")
|
||||
font.pixelSize: 15
|
||||
width: parent.width - 8 // twice the editor button margins
|
||||
anchors.centerIn: parent
|
||||
text: backend.source
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text10
|
||||
x: 17
|
||||
y: 76
|
||||
color: "#ffffff"
|
||||
text: qsTr("value")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
HelperWidgets.AbstractButton {
|
||||
id: editorButton
|
||||
|
||||
TopLevelComboBox {
|
||||
id: valueOut
|
||||
x: 10
|
||||
y: -2
|
||||
width: 156
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: 84
|
||||
model: ["width", "height", "opacity"]
|
||||
}
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 4
|
||||
|
||||
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
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.edit_medium
|
||||
tooltip: qsTr("Add something.")
|
||||
onClicked: console.log("OPEN EDITOR")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,113 +3,178 @@
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import ConnectionsEditor
|
||||
import HelperWidgets 2.0 as HelperWidgets
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
import ConnectionsEditorEditorBackend
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
width: 606
|
||||
height: 160
|
||||
interactive: false
|
||||
id: root
|
||||
|
||||
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||
|
||||
property bool adsFocus: false
|
||||
|
||||
clip: true
|
||||
interactive: true
|
||||
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: {
|
||||
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: {
|
||||
listView.currentIndex = listView.model.currentIndex
|
||||
root.currentIndex = root.model.currentIndex
|
||||
}
|
||||
|
||||
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: [
|
||||
ConnectionsDialog {
|
||||
id: dialog
|
||||
visible: false
|
||||
backend: root.model.delegate
|
||||
}
|
||||
]
|
||||
|
||||
delegate: Item {
|
||||
delegate: Rectangle {
|
||||
id: itemDelegate
|
||||
|
||||
width: 600
|
||||
height: 18
|
||||
required property int index
|
||||
|
||||
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 {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: {
|
||||
listView.model.currentIndex = index
|
||||
listView.currentIndex = index
|
||||
root.model.currentIndex = itemDelegate.index
|
||||
root.currentIndex = itemDelegate.index
|
||||
dialog.backend.currentRow = itemDelegate.index
|
||||
dialog.popup(mouseArea)
|
||||
}
|
||||
|
||||
property int currentIndex: listView.currentIndex
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row1
|
||||
x: 0
|
||||
y: 0
|
||||
width: 600
|
||||
height: 16
|
||||
spacing: 10
|
||||
id: row
|
||||
|
||||
property color textColor: itemDelegate.ListView.isCurrentItem ? root.style.text.selectedText
|
||||
: root.style.icon.idle
|
||||
|
||||
height: itemDelegate.height
|
||||
spacing: root.rowSpacing
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
color: "#ffffff"
|
||||
text: target
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: root.rowWidth + root.rowRest
|
||||
height: itemDelegate.height
|
||||
color: row.textColor
|
||||
text: itemDelegate.target
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
leftPadding: root.rowSpacing
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: signal
|
||||
color: "#ffffff"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: root.rowWidth
|
||||
height: itemDelegate.height
|
||||
text: itemDelegate.signal
|
||||
color: row.textColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
|
||||
text: action
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "#ffffff"
|
||||
width: root.rowWidth
|
||||
height: itemDelegate.height
|
||||
text: itemDelegate.action
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: row.textColor
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
Rectangle {
|
||||
width: root.style.squareControlSize.width
|
||||
height: root.style.squareControlSize.height
|
||||
|
||||
text: "-"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pointSize: 14
|
||||
color: "#ffffff"
|
||||
font.bold: true
|
||||
MouseArea {
|
||||
color: toolTipArea.containsMouse ?
|
||||
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||
: root.style.background.hover
|
||||
: "transparent"
|
||||
|
||||
Text {
|
||||
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 {
|
||||
color: "#2a5593"
|
||||
width: 600
|
||||
color: root.style.interaction
|
||||
}
|
||||
}
|
||||
|
@@ -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,114 +4,129 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import ConnectionsEditor
|
||||
import HelperWidgets 2.0 as HelperWidgets
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import HelperWidgets as HelperWidgets
|
||||
import StudioControls as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
import ConnectionsEditorEditorBackend
|
||||
|
||||
Rectangle {
|
||||
width: 640
|
||||
height: 1080
|
||||
color: "#232222"
|
||||
id: root
|
||||
|
||||
Rectangle {
|
||||
id: rectangle
|
||||
x: 10
|
||||
y: 10
|
||||
width: 620
|
||||
height: 97
|
||||
color: "#333333"
|
||||
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 {
|
||||
id: rectangle1
|
||||
x: 10
|
||||
y: 10
|
||||
width: 600
|
||||
height: 34
|
||||
color: "#00ffffff"
|
||||
border.width: 1
|
||||
id: toolbar
|
||||
width: parent.width
|
||||
height: StudioTheme.Values.doubleToolbarHeight
|
||||
color: StudioTheme.Values.themeToolbarBackground
|
||||
|
||||
Text {
|
||||
id: text1
|
||||
x: 10
|
||||
y: 10
|
||||
color: "#b5b2b2"
|
||||
text: qsTr("Search")
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
x: 10
|
||||
y: 50
|
||||
TabCheckButton {
|
||||
id: connections
|
||||
text: "Connections"
|
||||
checked: true
|
||||
autoExclusive: true
|
||||
checkable: true
|
||||
}
|
||||
|
||||
TabCheckButton {
|
||||
id: bindings
|
||||
text: "Bindings"
|
||||
autoExclusive: true
|
||||
checkable: true
|
||||
}
|
||||
|
||||
TabCheckButton {
|
||||
id: properties
|
||||
text: "Properties"
|
||||
autoExclusive: true
|
||||
checkable: true
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text2
|
||||
x: 577
|
||||
y: 58
|
||||
color: "#ffffff"
|
||||
text: qsTr("+")
|
||||
font.pixelSize: 18
|
||||
font.bold: true
|
||||
MouseArea {
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
print(ConnectionsEditorEditorBackend.dynamicPropertiesModel.delegate)
|
||||
print(ConnectionsEditorEditorBackend.dynamicPropertiesModel.delegate.type)
|
||||
print(ConnectionsEditorEditorBackend.dynamicPropertiesModel.delegate.type.model)
|
||||
anchors.topMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||
anchors.bottomMargin: StudioTheme.Values.toolbarVerticalMargin
|
||||
anchors.leftMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||
anchors.rightMargin: StudioTheme.Values.toolbarHorizontalMargin
|
||||
spacing: StudioTheme.Values.toolbarColumnSpacing
|
||||
|
||||
if (connections.checked)
|
||||
ConnectionsEditorEditorBackend.connectionModel.add()
|
||||
else if (bindings.checked)
|
||||
ConnectionsEditorEditorBackend.bindingModel.add()
|
||||
else if (properties.checked)
|
||||
ConnectionsEditorEditorBackend.dynamicPropertiesModel.add()
|
||||
StudioControls.SearchBox {
|
||||
id: searchBox
|
||||
width: parent.width
|
||||
style: StudioTheme.Values.searchControlStyle
|
||||
|
||||
onSearchChanged: function(searchText) {}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row
|
||||
width: parent.width
|
||||
height: StudioTheme.Values.toolbarHeight
|
||||
spacing: 6
|
||||
|
||||
TabCheckButton {
|
||||
id: connections
|
||||
buttonIcon: StudioTheme.Constants.connections_medium
|
||||
text: qsTr("Connections")
|
||||
tooltip: qsTr("This is a tooltip.")
|
||||
checked: true
|
||||
autoExclusive: true
|
||||
checkable: true
|
||||
}
|
||||
|
||||
TabCheckButton {
|
||||
id: bindings
|
||||
buttonIcon: StudioTheme.Constants.binding_medium
|
||||
text: qsTr("Bindings")
|
||||
tooltip: qsTr("This is a tooltip.")
|
||||
autoExclusive: true
|
||||
checkable: true
|
||||
}
|
||||
|
||||
TabCheckButton {
|
||||
id: properties
|
||||
buttonIcon: StudioTheme.Constants.properties_medium
|
||||
text: qsTr("Properties")
|
||||
tooltip: qsTr("This is a tooltip.")
|
||||
autoExclusive: true
|
||||
checkable: true
|
||||
}
|
||||
|
||||
Item {
|
||||
id: spacer
|
||||
width: row.width - connections.width - bindings.width
|
||||
- properties.width - addButton.width - row.spacing * 4
|
||||
height: 1
|
||||
}
|
||||
|
||||
HelperWidgets.AbstractButton {
|
||||
id: addButton
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.add_medium
|
||||
tooltip: qsTr("Add something.")
|
||||
onClicked: {
|
||||
if (connections.checked)
|
||||
ConnectionsEditorEditorBackend.connectionModel.add()
|
||||
else if (bindings.checked)
|
||||
ConnectionsEditorEditorBackend.bindingModel.add()
|
||||
else if (properties.checked)
|
||||
ConnectionsEditorEditorBackend.dynamicPropertiesModel.add()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConnectionsListView {
|
||||
visible: connections.checked
|
||||
x: 17
|
||||
y: 124
|
||||
model: ConnectionsEditorEditorBackend.connectionModel
|
||||
}
|
||||
ConnectionsListView {
|
||||
visible: connections.checked
|
||||
width: parent.width
|
||||
height: parent.height - toolbar.height - column.spacing
|
||||
model: ConnectionsEditorEditorBackend.connectionModel
|
||||
adsFocus: root.adsFocus
|
||||
}
|
||||
|
||||
BindingsListView {
|
||||
visible: bindings.checked
|
||||
x: 17
|
||||
y: 124
|
||||
model: ConnectionsEditorEditorBackend.bindingModel
|
||||
}
|
||||
BindingsListView {
|
||||
visible: bindings.checked
|
||||
width: parent.width
|
||||
height: parent.height - toolbar.height - column.spacing
|
||||
model: ConnectionsEditorEditorBackend.bindingModel
|
||||
adsFocus: root.adsFocus
|
||||
}
|
||||
|
||||
PropertiesListView {
|
||||
visible: properties.checked
|
||||
x: 17
|
||||
y: 124
|
||||
model: ConnectionsEditorEditorBackend.dynamicPropertiesModel
|
||||
PropertiesListView {
|
||||
visible: properties.checked
|
||||
width: parent.width
|
||||
height: parent.height - toolbar.height - column.spacing
|
||||
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.Controls
|
||||
import HelperWidgets 2.0 as HelperWidgets
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import ConnectionsEditorEditorBackend
|
||||
|
||||
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
|
||||
flags: Qt.FramelessWindowHint || Qt.Dialog
|
||||
flags: Qt.FramelessWindowHint | Qt.Dialog
|
||||
color: StudioTheme.Values.themePopoutBackground
|
||||
|
||||
color: Qt.transparent
|
||||
|
||||
property int bw: 5
|
||||
|
||||
function popup(item) {
|
||||
print("popup " + item)
|
||||
var padding = 12
|
||||
var p = item.mapToGlobal(0, 0)
|
||||
dialog.x = p.x - dialog.width - padding
|
||||
if (dialog.x < 0)
|
||||
dialog.x = p.x + item.width + padding
|
||||
dialog.y = p.y
|
||||
dialog.show()
|
||||
dialog.raise()
|
||||
function ensureVerticalPosition() {
|
||||
if ((window.y + window.height) > (Screen.height - window.style.dialogScreenMargin)) {
|
||||
window.y = (Screen.height - window.height - window.style.dialogScreenMargin)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangle1
|
||||
color: "#d7d7d7"
|
||||
border.color: "#232323"
|
||||
onHeightChanged: window.ensureVerticalPosition()
|
||||
|
||||
function popup(item) {
|
||||
var padding = 12
|
||||
var p = item.mapToGlobal(0, 0)
|
||||
window.x = p.x - window.width - padding
|
||||
if (window.x < 0)
|
||||
window.x = p.x + item.width + padding
|
||||
window.y = p.y
|
||||
|
||||
window.ensureVerticalPosition()
|
||||
|
||||
window.show()
|
||||
window.raise()
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
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 {
|
||||
grabPermissions: TapHandler.CanTakeOverFromAnything
|
||||
onActiveChanged: if (active) { window.startSystemMove(); }
|
||||
id: dragHandler
|
||||
|
||||
target: null
|
||||
grabPermissions: PointerHandler.CanTakeOverFromAnything
|
||||
onActiveChanged: {
|
||||
if (dragHandler.active)
|
||||
window.startSystemMove() // QTBUG-102488
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangle2
|
||||
x: 329
|
||||
width: 16
|
||||
height: 16
|
||||
color: "#ffffff"
|
||||
radius: 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 6
|
||||
Row {
|
||||
id: row
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: StudioTheme.Values.popupMargin
|
||||
anchors.rightMargin: StudioTheme.Values.popupMargin
|
||||
spacing: 0
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import QtQuick
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import HelperWidgets as HelperWidgets
|
||||
|
||||
PopupDialog {
|
||||
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 {
|
||||
id: form
|
||||
y: 32
|
||||
height: 180
|
||||
}
|
||||
}
|
||||
|
@@ -1,76 +1,73 @@
|
||||
// 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 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick
|
||||
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
|
||||
|
||||
Text {
|
||||
id: text1
|
||||
x: 10
|
||||
y: 25
|
||||
color: "#ffffff"
|
||||
text: qsTr("Type:")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
y: StudioTheme.Values.popupMargin
|
||||
width: parent.width
|
||||
spacing: root.verticalSpacing
|
||||
|
||||
PopupLabel {
|
||||
text: qsTr("Type")
|
||||
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 ?? []
|
||||
onActivated: backend.type.activateIndex(target.currentIndex)
|
||||
onActivated: backend.type.activateIndex(type.currentIndex)
|
||||
property int currentTypeIndex: backend.type.currentIndex ?? 0
|
||||
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
||||
onCurrentTypeIndexChanged: type.currentIndex = type.currentTypeIndex
|
||||
}
|
||||
|
||||
Text {
|
||||
id: text2
|
||||
x: 10
|
||||
y: 131
|
||||
color: "#ffffff"
|
||||
text: qsTr("Name")
|
||||
font.pixelSize: 15
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
|
||||
PopupLabel { text: qsTr("Name") ; tooltip: qsTr("The name of the property.")}
|
||||
PopupLabel { text: qsTr("Value"); tooltip: qsTr("The value of the property.") }
|
||||
}
|
||||
|
||||
TextInput {
|
||||
id: name
|
||||
x: 70
|
||||
y: 131
|
||||
color: "white"
|
||||
width: 156
|
||||
text: backend.name.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.name.activateText(name.text)
|
||||
Row {
|
||||
spacing: root.horizontalSpacing
|
||||
StudioControls.TextField {
|
||||
id: name
|
||||
|
||||
width: root.columnWidth
|
||||
actionIndicatorVisible: false
|
||||
translationIndicatorVisible: false
|
||||
|
||||
text: backend.name.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.name.activateText(name.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
StudioControls.TextField {
|
||||
id: value
|
||||
|
||||
Text {
|
||||
x: 10
|
||||
y: 81
|
||||
color: "#ffffff"
|
||||
text: qsTr("Value")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
width: root.columnWidth
|
||||
actionIndicatorVisible: false
|
||||
translationIndicatorVisible: false
|
||||
|
||||
TextInput {
|
||||
id: value
|
||||
color: "red"
|
||||
x: 70
|
||||
y: 81
|
||||
width: 156
|
||||
text: backend.value.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.value.activateText(value.text)
|
||||
|
||||
text: backend.value.text ?? ""
|
||||
onEditingFinished: {
|
||||
backend.value.activateText(value.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,126 +3,191 @@
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import ConnectionsEditor
|
||||
import HelperWidgets 2.0 as HelperWidgets
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme as StudioTheme
|
||||
import ConnectionsEditorEditorBackend
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
width: 606
|
||||
height: 160
|
||||
interactive: false
|
||||
id: root
|
||||
|
||||
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||
|
||||
property bool adsFocus: false
|
||||
|
||||
clip: true
|
||||
interactive: true
|
||||
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: {
|
||||
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: {
|
||||
listView.currentIndex = listView.model.currentIndex
|
||||
root.currentIndex = root.model.currentIndex
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
listView.currentIndex = listView.model.currentIndex
|
||||
dialog.backend.currentRow = listView.currentIndex
|
||||
root.currentIndex = root.model.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: [
|
||||
PropertiesDialog {
|
||||
id: dialog
|
||||
visible: false
|
||||
backend: listView.model.delegate
|
||||
backend: root.model.delegate
|
||||
}
|
||||
]
|
||||
|
||||
delegate: Item {
|
||||
delegate: Rectangle {
|
||||
id: itemDelegate
|
||||
|
||||
width: 600
|
||||
height: 18
|
||||
required property int index
|
||||
|
||||
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 {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
property int currentIndex: listView.currentIndex
|
||||
property int currentIndex: root.currentIndex
|
||||
|
||||
Connections {
|
||||
target: mouseArea
|
||||
function onClicked() {
|
||||
listView.model.currentIndex = index
|
||||
listView.currentIndex = index
|
||||
dialog.backend.currentRow = index
|
||||
root.model.currentIndex = itemDelegate.index
|
||||
root.currentIndex = itemDelegate.index
|
||||
dialog.popup(mouseArea)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row1
|
||||
x: 0
|
||||
y: 0
|
||||
width: 600
|
||||
height: 16
|
||||
spacing: 10
|
||||
id: row
|
||||
|
||||
height: itemDelegate.height
|
||||
spacing: root.rowSpacing
|
||||
|
||||
property color textColor: itemDelegate.ListView.isCurrentItem ? root.style.text.selectedText
|
||||
: root.style.icon.idle
|
||||
Text {
|
||||
width: 120
|
||||
color: "#ffffff"
|
||||
text: target ?? ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: root.rowWidth + root.rowRest
|
||||
height: itemDelegate.height
|
||||
color: row.textColor
|
||||
text: itemDelegate.target ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
leftPadding: root.rowSpacing
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: name ?? ""
|
||||
color: "#ffffff"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: root.rowWidth
|
||||
height: itemDelegate.height
|
||||
color: row.textColor
|
||||
text: itemDelegate.name ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: type ?? ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "#ffffff"
|
||||
width: root.rowWidth + root.rowRest
|
||||
height: itemDelegate.height
|
||||
color: row.textColor
|
||||
text: itemDelegate.type ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
text: value ?? ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: "#ffffff"
|
||||
width: root.rowWidth + root.rowRest
|
||||
height: itemDelegate.height
|
||||
color: row.textColor
|
||||
text: itemDelegate.value ?? ""
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.bold: false
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
Text {
|
||||
width: 120
|
||||
Rectangle {
|
||||
width: root.style.squareControlSize.width
|
||||
height: root.style.squareControlSize.height
|
||||
|
||||
text: "-"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
font.pointSize: 14
|
||||
color: "#ffffff"
|
||||
font.bold: true
|
||||
MouseArea {
|
||||
color: toolTipArea.containsMouse ?
|
||||
itemDelegate.ListView.isCurrentItem ? root.style.interactionHover
|
||||
: root.style.background.hover
|
||||
: "transparent"
|
||||
|
||||
Text {
|
||||
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 {
|
||||
color: "#2a5593"
|
||||
color: root.style.interaction
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
implicitWidth: Math.max(
|
||||
buttonBackground ? buttonBackground.implicitWidth : 0,
|
||||
textItem.implicitWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(
|
||||
buttonBackground ? buttonBackground.implicitHeight : 0,
|
||||
textItem.implicitHeight + topPadding + bottomPadding)
|
||||
leftPadding: 4
|
||||
rightPadding: 4
|
||||
property StudioTheme.ControlStyle style: StudioTheme.Values.viewBarButtonStyle
|
||||
|
||||
text: "My Button"
|
||||
property alias tooltip: toolTipArea.tooltip
|
||||
property alias buttonIcon: buttonIcon.text
|
||||
|
||||
background: buttonBackground
|
||||
Rectangle {
|
||||
id: buttonBackground
|
||||
color: "#047eff"
|
||||
implicitWidth: 100
|
||||
implicitHeight: 40
|
||||
opacity: enabled ? 1 : 0.3
|
||||
radius: 12
|
||||
border.color: "#047eff"
|
||||
width: control.style.squareControlSize.width + buttonLabel.implicitWidth
|
||||
+ buttonLabel.leftPadding + buttonLabel.rightPadding
|
||||
height: control.style.squareControlSize.height
|
||||
|
||||
contentItem: Row {
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
id: buttonIcon
|
||||
width: control.style.squareControlSize.width
|
||||
height: control.height
|
||||
font.family: StudioTheme.Constants.iconFont.family
|
||||
font.pixelSize: control.style.baseIconFontSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: textItem
|
||||
Text {
|
||||
id: textItem
|
||||
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
|
||||
}
|
||||
|
||||
opacity: enabled ? 1.0 : 0.3
|
||||
color: "#ffffff"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
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: [
|
||||
State {
|
||||
name: "normal"
|
||||
when: !control.down && !control.checked
|
||||
|
||||
name: "default"
|
||||
when: control.enabled && !control.hovered && !control.pressed && !control.checked
|
||||
PropertyChanges {
|
||||
target: buttonBackground
|
||||
visible: false
|
||||
color: "#00000000"
|
||||
border.color: "#047eff"
|
||||
target: controlBackground
|
||||
color: control.style.background.idle
|
||||
border.color: control.style.border.idle
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: textItem
|
||||
color: "#ffffff"
|
||||
target: buttonIcon
|
||||
color: control.style.icon.idle
|
||||
}
|
||||
PropertyChanges {
|
||||
target: buttonLabel
|
||||
color: control.style.icon.idle
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "down"
|
||||
when: control.down && !control.checked
|
||||
name: "hover"
|
||||
when: control.enabled && control.hovered && !control.pressed && !control.checked
|
||||
PropertyChanges {
|
||||
target: textItem
|
||||
color: "#ffffff"
|
||||
target: controlBackground
|
||||
color: control.style.background.hover
|
||||
border.color: control.style.border.hover
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: buttonBackground
|
||||
color: "#047eff"
|
||||
border.color: "#00000000"
|
||||
target: buttonIcon
|
||||
color: control.style.icon.hover
|
||||
}
|
||||
PropertyChanges {
|
||||
target: buttonLabel
|
||||
color: control.style.icon.hover
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "down1"
|
||||
when: control.checked
|
||||
extend: "down"
|
||||
name: "hoverCheck"
|
||||
when: control.enabled && control.hovered && !control.pressed && control.checked
|
||||
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 {
|
||||
text: qsTr("Add an instance")
|
||||
enabled: root.targetAvailable
|
||||
enabled: root.targetAvailable && ContentLibraryBackend.rootView.hasActive3DScene
|
||||
onTriggered: ContentLibraryBackend.effectsModel.addInstance(root.targetItem)
|
||||
}
|
||||
|
||||
|
@@ -1,186 +1,284 @@
|
||||
{
|
||||
"ContextMenuArea": {
|
||||
"size": "28x28",
|
||||
"Off": {
|
||||
"Disabled": { "color": "DStextColorDisabled" },
|
||||
"Hovered": { "color": "DSpanelBackground" },
|
||||
"Normal": { "color": "DStextColor" },
|
||||
"Selected": { "color": "DStextSelectedTextColor" }
|
||||
[
|
||||
{
|
||||
"ContextMenuArea": {
|
||||
"size": "28x28",
|
||||
"Off": {
|
||||
"Disabled": { "color": "DStextColorDisabled" },
|
||||
"Hovered": { "color": "DSpanelBackground" },
|
||||
"Normal": { "color": "DStextColor" },
|
||||
"Selected": { "color": "DStextSelectedTextColor" }
|
||||
},
|
||||
"On": {
|
||||
"Disabled": { "color": "DStextColorDisabled" },
|
||||
"Hovered": { "color": "DSsubPanelBackground" },
|
||||
"Normal": { "color": "DStextColor" },
|
||||
"Selected": { "color": "DStextSelectedTextColor" }
|
||||
}
|
||||
},
|
||||
"On": {
|
||||
"Disabled": { "color": "DStextColorDisabled" },
|
||||
"Hovered": { "color": "DSsubPanelBackground" },
|
||||
"Normal": { "color": "DStextColor" },
|
||||
"Selected": { "color": "DStextSelectedTextColor" }
|
||||
"AddMouseAreaIcon": {
|
||||
"iconName": "mouseArea_small"
|
||||
},
|
||||
"AlignCameraToViewIcon": {
|
||||
"iconName": "alignToCamera_small"
|
||||
},
|
||||
"AlignViewToCameraIcon": {
|
||||
"iconName": "alignToObject_small"
|
||||
},
|
||||
"AnchorsIcon": {
|
||||
"iconName": "anchors_small"
|
||||
},
|
||||
"AnnotationIcon": {
|
||||
"iconName": "annotations_small"
|
||||
},
|
||||
"ArrangeIcon": {
|
||||
"iconName": "arrange_small"
|
||||
},
|
||||
"BackspaceIcon": {
|
||||
"iconName": "backspace_small"
|
||||
},
|
||||
"CameraIcon": {
|
||||
"iconName": "camera_small"
|
||||
},
|
||||
"CameraOrthographicIcon": {
|
||||
"iconName": "orthCam_small"
|
||||
},
|
||||
"CameraPerspectiveIcon": {
|
||||
"iconName": "perspectiveCam_small"
|
||||
},
|
||||
"ConnectionsIcon": {
|
||||
"iconName": "connection_small"
|
||||
},
|
||||
"CopyIcon": {
|
||||
"iconName": "copy_small"
|
||||
},
|
||||
"CreateIcon": {
|
||||
"iconName": "create_small"
|
||||
},
|
||||
"DeleteIcon": {
|
||||
"iconName": "delete_small"
|
||||
},
|
||||
"DuplicateIcon": {
|
||||
"iconName": "duplicate_small"
|
||||
},
|
||||
"EditComponentIcon": {
|
||||
"iconName": "editComponent_small"
|
||||
},
|
||||
"EditIcon": {
|
||||
"iconName": "edit_small"
|
||||
},
|
||||
"EnterComponentIcon": {
|
||||
"iconName": "editComponent_small"
|
||||
},
|
||||
"EventListIcon": {
|
||||
"iconName": "events_small"
|
||||
},
|
||||
"FitSelectedIcon": {
|
||||
"iconName": "fitSelected_small"
|
||||
},
|
||||
"GroupSelectionIcon": {
|
||||
"iconName": "group_small"
|
||||
},
|
||||
"ImportedModelsIcon": {
|
||||
"iconName": "importedModels_small"
|
||||
},
|
||||
"LayoutsIcon": {
|
||||
"iconName": "layouts_small"
|
||||
},
|
||||
"LightIcon": {
|
||||
"Off": {
|
||||
"iconName": "editLightOff_medium"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "editLightOn_medium"
|
||||
}
|
||||
},
|
||||
"LightDirectionalIcon": {
|
||||
"iconName": "directionalLight_small"
|
||||
},
|
||||
"LightPointIcon": {
|
||||
"iconName": "pointLight_small"
|
||||
},
|
||||
"LightSpotIcon": {
|
||||
"iconName": "spotLight_small"
|
||||
},
|
||||
"MakeComponentIcon": {
|
||||
"iconName": "createComponent_small"
|
||||
},
|
||||
"MaterialIcon": {
|
||||
"iconName": "material_medium"
|
||||
},
|
||||
"MergeWithTemplateIcon": {
|
||||
"iconName": "merge_small"
|
||||
},
|
||||
"MinimalDownArrowIcon" : {
|
||||
"iconName": "upDownSquare2"
|
||||
},
|
||||
"ModelConeIcon": {
|
||||
"iconName": "cone_small"
|
||||
},
|
||||
"ModelCubeIcon": {
|
||||
"iconName": "cube_small"
|
||||
},
|
||||
"ModelCylinderIcon": {
|
||||
"iconName": "cylinder_small"
|
||||
},
|
||||
"ModelPlaneIcon": {
|
||||
"iconName": "plane_small"
|
||||
},
|
||||
"ModelSphereIcon": {
|
||||
"iconName": "sphere_small"
|
||||
},
|
||||
"ParentIcon": {
|
||||
"iconName": "selectParent_small"
|
||||
},
|
||||
"PasteIcon": {
|
||||
"iconName": "paste_small"
|
||||
},
|
||||
"PositionsersIcon": {
|
||||
"iconName": "positioners_small"
|
||||
},
|
||||
"PrimitivesIcon": {
|
||||
"iconName": "cube_small"
|
||||
},
|
||||
"ResetViewIcon": {
|
||||
"iconName": "reload_medium"
|
||||
},
|
||||
"SelecionIcon": {
|
||||
"iconName": "selection_small"
|
||||
},
|
||||
"ShowBoundsIcon": {
|
||||
"Off": {
|
||||
"iconName": "visibilityOff"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "visibilityOn"
|
||||
}
|
||||
},
|
||||
"SnappingIcon": {
|
||||
"iconName": "snapping_small"
|
||||
},
|
||||
"SimpleCheckIcon": {
|
||||
"Off": {
|
||||
"iconName": "transparent"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "tickMark_small"
|
||||
}
|
||||
},
|
||||
"TimelineIcon": {
|
||||
"iconName": "timeline_small"
|
||||
},
|
||||
"ToggleGroupIcon": {
|
||||
"Off": {
|
||||
"iconName": "selectOutline_medium"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "selectFill_medium"
|
||||
}
|
||||
},
|
||||
"VisibilityIcon": {
|
||||
"Off": {
|
||||
"iconName": "visibilityOff"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "visibilityOn"
|
||||
}
|
||||
}
|
||||
},
|
||||
"AddMouseAreaIcon": {
|
||||
"iconName": "mouseArea_small"
|
||||
},
|
||||
"AlignCameraToViewIcon": {
|
||||
"iconName": "alignToCamera_small"
|
||||
},
|
||||
"AlignViewToCameraIcon": {
|
||||
"iconName": "alignToObject_small"
|
||||
},
|
||||
"AnchorsIcon": {
|
||||
"iconName": "anchors_small"
|
||||
},
|
||||
"AnnotationIcon": {
|
||||
"iconName": "annotations_small"
|
||||
},
|
||||
"ArrangeIcon": {
|
||||
"iconName": "arrange_small"
|
||||
},
|
||||
"BackspaceIcon": {
|
||||
"iconName": "backspace_small"
|
||||
},
|
||||
"CameraIcon": {
|
||||
"iconName": "camera_small"
|
||||
},
|
||||
"CameraOrthographicIcon": {
|
||||
"iconName": "orthCam_small"
|
||||
},
|
||||
"CameraPerspectiveIcon": {
|
||||
"iconName": "perspectiveCam_small"
|
||||
},
|
||||
"ConnectionsIcon": {
|
||||
"iconName": "connection_small"
|
||||
},
|
||||
"CopyIcon": {
|
||||
"iconName": "copy_small"
|
||||
},
|
||||
"CreateIcon": {
|
||||
"iconName": "create_small"
|
||||
},
|
||||
"DeleteIcon": {
|
||||
"iconName": "delete_small"
|
||||
},
|
||||
"DuplicateIcon": {
|
||||
"iconName": "duplicate_small"
|
||||
},
|
||||
"EditComponentIcon": {
|
||||
"iconName": "editComponent_small"
|
||||
},
|
||||
"EditIcon": {
|
||||
"iconName": "edit_small"
|
||||
},
|
||||
"EnterComponentIcon": {
|
||||
"iconName": "editComponent_small"
|
||||
},
|
||||
"EventListIcon": {
|
||||
"iconName": "events_small"
|
||||
},
|
||||
"FitSelectedIcon": {
|
||||
"iconName": "fitSelected_small"
|
||||
},
|
||||
"GroupSelectionIcon": {
|
||||
"iconName": "group_small"
|
||||
},
|
||||
"ImportedModelsIcon": {
|
||||
"iconName": "importedModels_small"
|
||||
},
|
||||
"LayoutsIcon": {
|
||||
"iconName": "layouts_small"
|
||||
},
|
||||
"LightIcon": {
|
||||
"Off": {
|
||||
"iconName": "editLightOff_medium"
|
||||
{
|
||||
"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" }
|
||||
}
|
||||
},
|
||||
"On": {
|
||||
"iconName": "editLightOn_medium"
|
||||
}
|
||||
},
|
||||
"LightDirectionalIcon": {
|
||||
"iconName": "directionalLight_small"
|
||||
},
|
||||
"LightPointIcon": {
|
||||
"iconName": "pointLight_small"
|
||||
},
|
||||
"LightSpotIcon": {
|
||||
"iconName": "spotLight_small"
|
||||
},
|
||||
"MakeComponentIcon": {
|
||||
"iconName": "createComponent_small"
|
||||
},
|
||||
"MaterialIcon": {
|
||||
"iconName": "material_medium"
|
||||
},
|
||||
"MergeWithTemplateIcon": {
|
||||
"iconName": "merge_small"
|
||||
},
|
||||
"MinimalDownArrowIcon" : {
|
||||
"iconName": "upDownSquare2"
|
||||
},
|
||||
"ModelConeIcon": {
|
||||
"iconName": "cone_small"
|
||||
},
|
||||
"ModelCubeIcon": {
|
||||
"iconName": "cube_small"
|
||||
},
|
||||
"ModelCylinderIcon": {
|
||||
"iconName": "cylinder_small"
|
||||
},
|
||||
"ModelPlaneIcon": {
|
||||
"iconName": "plane_small"
|
||||
},
|
||||
"ModelSphereIcon": {
|
||||
"iconName": "sphere_small"
|
||||
},
|
||||
"ParentIcon": {
|
||||
"iconName": "selectParent_small"
|
||||
},
|
||||
"PasteIcon": {
|
||||
"iconName": "paste_small"
|
||||
},
|
||||
"PositionsersIcon": {
|
||||
"iconName": "positioners_small"
|
||||
},
|
||||
"PrimitivesIcon": {
|
||||
"iconName": "cube_small"
|
||||
},
|
||||
"ResetViewIcon": {
|
||||
"iconName": "reload_medium"
|
||||
},
|
||||
"SelecionIcon": {
|
||||
"iconName": "selection_small"
|
||||
},
|
||||
"ShowBoundsIcon": {
|
||||
"Off": {
|
||||
"iconName": "visibilityOff"
|
||||
"AlignCameraToViewIcon": {
|
||||
"iconName": "alignToCam_medium"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "visibilityOn"
|
||||
}
|
||||
},
|
||||
"SnappingIcon": {
|
||||
"iconName": "snapping_small"
|
||||
},
|
||||
"SimpleCheckIcon": {
|
||||
"Off": {
|
||||
"iconName": "transparent"
|
||||
"AlignViewToCameraIcon": {
|
||||
"iconName": "alignToView_medium"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "tickMark_small"
|
||||
}
|
||||
},
|
||||
"TimelineIcon": {
|
||||
"iconName": "timeline_small"
|
||||
},
|
||||
"ToggleGroupIcon": {
|
||||
"Off": {
|
||||
"iconName": "selectOutline_medium"
|
||||
"CameraIcon": {
|
||||
"Off": {
|
||||
"iconName": "orthCam_small"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "perspectiveCam_small"
|
||||
}
|
||||
},
|
||||
"On": {
|
||||
"iconName": "selectFill_medium"
|
||||
}
|
||||
},
|
||||
"VisibilityIcon": {
|
||||
"Off": {
|
||||
"iconName": "visibilityOff"
|
||||
"EditColorIcon": {
|
||||
"iconName": "colorSelection_medium"
|
||||
},
|
||||
"On": {
|
||||
"iconName": "visibilityOn"
|
||||
"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