Merge remote-tracking branch 'origin/qds/dev'

add QWidget include in src/plugins/qmldesigner/libs/designercore/model/model.cpp

prepare src/plugins/lua/CMakeLists.txt if lua plugin is not built

Necessary change in:
src/plugins/qmldesigner/components/toolbar/messagemodel.h

Because Utils::Id is a friend of qHash now, QtCreator API
removed uniqueIdentifier().

std::unordered_map<quintptr, ProjectExplorer::TaskCategory>
->
QHash<Utils::Id, ProjectExplorer::TaskCategory> m_categories = {};

other resolved Conflicts were in:
	cmake/QtCreatorAPI.cmake
	cmake/QtCreatorAPIInternal.cmake
	share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl
	share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json
	src/plugins/effectcomposer/effectcomposerview.cpp
	src/plugins/effectcomposer/effectcomposerwidget.cpp
	src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp
	src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
	src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp
	src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
	src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
	src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
	src/plugins/qmldesigner/designmodecontext.cpp
	src/plugins/qmldesigner/designmodewidget.cpp
	src/plugins/qmldesigner/qmldesignerplugin.cpp
	src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp
	src/plugins/qmlprojectmanager/qmlprojectmanager.qbs
	src/plugins/studiowelcome/examplecheckout.h

Change-Id: Ia6c204460baf4de886e45666d859ca048d578bcb
This commit is contained in:
Tim Jenssen
2024-09-25 14:19:15 +02:00
831 changed files with 13010 additions and 8303 deletions

View File

@@ -11,7 +11,7 @@ env:
MACOS_DEPLOYMENT_TARGET: 11.0 MACOS_DEPLOYMENT_TARGET: 11.0
CLANG_VERSION: 19.1.0 CLANG_VERSION: 19.1.0
ELFUTILS_VERSION: 0.175 ELFUTILS_VERSION: 0.175
CMAKE_VERSION: 3.21.1 CMAKE_VERSION: 3.30.3
NINJA_VERSION: 1.10.2 NINJA_VERSION: 1.10.2
BUILD_TYPE: Release BUILD_TYPE: Release
CCACHE_VERSION: 4.9 CCACHE_VERSION: 4.9

View File

@@ -129,6 +129,9 @@ function(add_qtc_library name)
"CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN}
) )
check_library_dependencies(${_arg_DEPENDS})
check_library_dependencies(${_arg_PUBLIC_DEPENDS})
get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS}) get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS})
if (${_arg_UNPARSED_ARGUMENTS}) if (${_arg_UNPARSED_ARGUMENTS})
@@ -348,6 +351,9 @@ function(add_qtc_plugin target_name)
${ARGN} ${ARGN}
) )
check_library_dependencies(${_arg_DEPENDS})
check_library_dependencies(${_arg_PUBLIC_DEPENDS})
if (${_arg_UNPARSED_ARGUMENTS}) if (${_arg_UNPARSED_ARGUMENTS})
message(FATAL_ERROR "add_qtc_plugin had unparsed arguments") message(FATAL_ERROR "add_qtc_plugin had unparsed arguments")
endif() endif()
@@ -651,6 +657,9 @@ function(extend_qtc_plugin target_name)
return() return()
endif() endif()
check_library_dependencies(${_arg_DEPENDS})
check_library_dependencies(${_arg_PUBLIC_DEPENDS})
extend_qtc_target(${target_name} ${ARGN}) extend_qtc_target(${target_name} ${ARGN})
endfunction() endfunction()
@@ -660,6 +669,9 @@ function(extend_qtc_library target_name)
return() return()
endif() endif()
check_library_dependencies(${_arg_DEPENDS})
check_library_dependencies(${_arg_PUBLIC_DEPENDS})
extend_qtc_target(${target_name} ${ARGN}) extend_qtc_target(${target_name} ${ARGN})
endfunction() endfunction()

View File

@@ -356,6 +356,18 @@ function(add_qtc_depends target_name)
endforeach() endforeach()
endfunction() endfunction()
function(check_library_dependencies)
foreach(i ${ARGN})
if (NOT TARGET ${i})
continue()
endif()
get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME)
if (_class_name)
message(SEND_ERROR "${i} is a plugin, not a library!")
endif()
endforeach()
endfunction()
function(enable_pch target) function(enable_pch target)
if (BUILD_WITH_PCH) if (BUILD_WITH_PCH)
# Skip PCH for targets that do not use the expected visibility settings: # Skip PCH for targets that do not use the expected visibility settings:

View File

@@ -1,5 +1,7 @@
# Defines function add_translation_targets # Defines function add_translation_targets
include(${CMAKE_CURRENT_LIST_DIR}/Utils.cmake)
function(_extract_ts_data_from_targets outprefix) function(_extract_ts_data_from_targets outprefix)
set(_sources "") set(_sources "")
set(_includes "") set(_includes "")
@@ -18,9 +20,7 @@ function(_extract_ts_data_from_targets outprefix)
if (NOT _skip_translation) if (NOT _skip_translation)
if(_include_dirs) if(_include_dirs)
list(FILTER _include_dirs EXCLUDE REGEX "\\$<TARGET_PROPERTY") remove_generator_expressions(_include_dirs ${_include_dirs})
list(FILTER _include_dirs EXCLUDE REGEX "\\$<INSTALL_INTERFACE")
list(TRANSFORM _include_dirs REPLACE "\\$<BUILD_INTERFACE:([^>]+)>" "\\1")
list(APPEND _includes ${_include_dirs}) list(APPEND _includes ${_include_dirs})
endif() endif()

View File

@@ -100,4 +100,30 @@ function(configure_qml_designer Qt6_VERSION)
env_with_default("QTC_IS_SUPPORTED_PROJECTSTORAGE_QT" ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT ${QTC_IS_SUPPORTED_PROJECTSTORAGE_QT_DEFAULT}) env_with_default("QTC_IS_SUPPORTED_PROJECTSTORAGE_QT" ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT ${QTC_IS_SUPPORTED_PROJECTSTORAGE_QT_DEFAULT})
option(IS_SUPPORTED_PROJECTSTORAGE_QT "IS_SUPPORTED_PROJECTSTORAGE_QT" ${ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT}) option(IS_SUPPORTED_PROJECTSTORAGE_QT "IS_SUPPORTED_PROJECTSTORAGE_QT" ${ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT})
add_feature_info("IS_SUPPORTED_PROJECTSTORAGE_QT" ${IS_SUPPORTED_PROJECTSTORAGE_QT} "is ${IS_SUPPORTED_PROJECTSTORAGE_QT}") add_feature_info("IS_SUPPORTED_PROJECTSTORAGE_QT" ${IS_SUPPORTED_PROJECTSTORAGE_QT} "is ${IS_SUPPORTED_PROJECTSTORAGE_QT}")
# to enable define QML_DOM_MSVC2019_COMPAT if necessary, see QTBUG-127761
if(NOT DEFINED QT_BUILT_WITH_MSVC2019)
get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION)
execute_process(
COMMAND dumpbin /headers ${QT_QMAKE_EXECUTABLE} | findstr /c:"linker version"
OUTPUT_VARIABLE DUMPBIN_OUTPUT
)
string(FIND "${DUMPBIN_OUTPUT}" "14.2" QT_BUILT_WITH_MSVC2019)
if(QT_BUILT_WITH_MSVC2019 GREATER -1)
set(QT_BUILT_WITH_MSVC2019 TRUE CACHE BOOL "Qt was built with MSVC 2019")
else()
set(QT_BUILT_WITH_MSVC2019 FALSE CACHE BOOL "Qt was not built with MSVC 2019")
endif()
endif()
endfunction()
function(remove_generator_expressions out_var list)
set(result ${list})
list(FILTER result EXCLUDE REGEX "\\$<TARGET_PROPERTY")
list(FILTER result EXCLUDE REGEX "\\$<INSTALL_INTERFACE")
list(TRANSFORM result REPLACE "\\$<BUILD_INTERFACE:([^>]+)>" "\\1")
set(${out_var} ${result} PARENT_SCOPE)
endfunction() endfunction()

View File

@@ -1,6 +1,6 @@
set(IDE_VERSION "4.6.0") # The IDE version. set(IDE_VERSION "4.7.0") # The IDE version.
set(IDE_VERSION_COMPAT "4.6.0") # The IDE Compatibility version. set(IDE_VERSION_COMPAT "4.7.0") # The IDE Compatibility version.
set(IDE_VERSION_DISPLAY "4.6") # The IDE display version. set(IDE_VERSION_DISPLAY "4.7") # The IDE display version.
set(IDE_COPYRIGHT_YEAR "2024") # The IDE current copyright year. set(IDE_COPYRIGHT_YEAR "2024") # The IDE current copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
@@ -30,6 +30,7 @@ set(DESIGNSTUDIO_PLUGINS
Designer Designer
DiffEditor DiffEditor
EffectComposer EffectComposer
FakeVim
Help Help
Insight Insight
LanguageClient LanguageClient

View File

@@ -1,5 +1,7 @@
# Generate documentation # Generate documentation
include(Utils)
option(BUILD_DEVELOPER_DOCS "Include developer documentation" OFF) option(BUILD_DEVELOPER_DOCS "Include developer documentation" OFF)
add_feature_info("Include developer documentation" BUILD_DEVELOPER_DOCS "") add_feature_info("Include developer documentation" BUILD_DEVELOPER_DOCS "")
@@ -15,6 +17,7 @@ function(_find_all_includes _ret_includes _ret_framework_paths)
string(FIND "${_include}" "/src/libs/" _in_libs) string(FIND "${_include}" "/src/libs/" _in_libs)
string(FIND "${_include}" "${CMAKE_BINARY_DIR}" _in_build) string(FIND "${_include}" "${CMAKE_BINARY_DIR}" _in_build)
if(_in_plugins LESS 0 AND _in_libs LESS 0 AND _in_build LESS 0) if(_in_plugins LESS 0 AND _in_libs LESS 0 AND _in_build LESS 0)
remove_generator_expressions(_include ${_include})
list(APPEND _all_includes ${_include}) list(APPEND _all_includes ${_include})
endif() endif()
endforeach() endforeach()

View File

@@ -144,10 +144,10 @@
\list \list
\li \l{Qt::}{qsTr()} \li \l{Qt::}{qsTr()}
\li \l{Qt::}{qsTranslate()} \li \l{Qt::}{qsTranslate()}
\li \l{Qt::}{qsTranslateNoOp()} \li \l{Qt::}{QT_TRANSLATE_NOOP()}
\li \l{Qt::}{qsTrId()} \li \l{Qt::}{qsTrId()}
\li \l{Qt::}{qsTrIdNoOp()} \li \l{Qt::}{QT_TRID_NOOP()}
\li \l{Qt::}{qsTrNoOp()} \li \l{Qt::}{QT_TR_NOOP()}
\endlist \endlist
\note Do not mix translation methods in a UI file. \note Do not mix translation methods in a UI file.

View File

@@ -1,5 +1,5 @@
project = $IDE_ID project = $IDE_ID
description = "$IDE_DISPLAY_NAME Manual" description = "$IDE_DISPLAY_NAME Documentation"
url = https://doc.qt.io/qtdesignstudio url = https://doc.qt.io/qtdesignstudio
version = $QTC_VERSION version = $QTC_VERSION
@@ -103,14 +103,14 @@ qhp.projects = qtdesignstudio
qhp.qtdesignstudio.file = qtdesignstudio.qhp qhp.qtdesignstudio.file = qtdesignstudio.qhp
qhp.qtdesignstudio.namespace = org.qt-project.$IDE_ID.$QTC_VERSION_TAG qhp.qtdesignstudio.namespace = org.qt-project.$IDE_ID.$QTC_VERSION_TAG
qhp.qtdesignstudio.virtualFolder = doc qhp.qtdesignstudio.virtualFolder = doc
qhp.qtdesignstudio.indexTitle = $IDE_DISPLAY_NAME Manual $QTC_VERSION qhp.qtdesignstudio.indexTitle = $IDE_DISPLAY_NAME Documentation $QTC_VERSION
qhp.qtdesignstudio.filterAttributes = $IDE_ID $QTC_VERSION qhp.qtdesignstudio.filterAttributes = $IDE_ID $QTC_VERSION
qhp.qtdesignstudio.customFilters.qtdesignstudio.name = $IDE_DISPLAY_NAME $QTC_VERSION qhp.qtdesignstudio.customFilters.qtdesignstudio.name = $IDE_DISPLAY_NAME $QTC_VERSION
qhp.qtdesignstudio.customFilters.qtdesignstudio.filterAttributes = $IDE_ID $QTC_VERSION qhp.qtdesignstudio.customFilters.qtdesignstudio.filterAttributes = $IDE_ID $QTC_VERSION
qhp.qtdesignstudio.indexRoot = qhp.qtdesignstudio.indexRoot =
qhp.qtdesignstudio.subprojects = manual qhp.qtdesignstudio.subprojects = manual
qhp.qtdesignstudio.subprojects.manual.title = $IDE_DISPLAY_NAME Manual qhp.qtdesignstudio.subprojects.manual.title = $IDE_DISPLAY_NAME Documentation
qhp.qtdesignstudio.subprojects.manual.indexTitle = All Topics qhp.qtdesignstudio.subprojects.manual.indexTitle = All Topics
qhp.qtdesignstudio.subprojects.manual.type = manual qhp.qtdesignstudio.subprojects.manual.type = manual
@@ -120,10 +120,10 @@ macro.see = "\\sa"
macro.function = "\\fn" macro.function = "\\fn"
macro.QMLD = "Qt Design Studio" macro.QMLD = "Qt Design Studio"
navigation.landingpage = "$IDE_DISPLAY_NAME Manual" navigation.landingpage = "$IDE_DISPLAY_NAME Documentation"
# Auto-generate navigation linking based on "All Topics": # Auto-generate navigation linking based on "All Topics":
navigation.toctitles = "All Topics" navigation.toctitles = "All Topics"
navigation.toctitles.inclusive = false navigation.toctitles.inclusive = false
buildversion = "$IDE_DISPLAY_NAME Manual $QTC_VERSION" buildversion = "$IDE_DISPLAY_NAME Documentation $QTC_VERSION"

View File

@@ -0,0 +1,74 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page effect-composer-example.html
\ingroup studioexamples
\title Effect Composer Example
\brief Illustrates how to work with the Effect Composer effects.
\image effect-composer-example.webp {The Effect Composer example project}
The \e {Effect Composer Example} illustrates how to work with the \uicontrol {Effect Composer}
effects. Use the example project to experiment with effects and get familiar with
\uicontrol {Effect Composer}. To learn more, see \l {Effect Composer}.
The example consists of a 3D model and four \uicontrol {Effect Composer} effects. You can show
and hide the effects from the scene with buttons. To modify the effect properties, select an
effect and then use the sliders. To visualize the effects better, rotate the 3D model by
dragging it and zoom it with the mouse wheel.
The example project has a scalable design. When you resize the window to fit your screen, some
components will adjust automatically.
\section1 Running the Example
To run the example in \QDS, go to the \uicontrol Welcome screen and select the example
from the \uicontrol Examples tab.
\section1 The Effects
The following table introduces the effects in this example.
\table
\header
\li Effect Name
\li Description
\row
\li \uicontrol {Displace}
\li A displace effect, the pixels move according to a displacement map.
\row
\li \uicontrol {Glow} and \uicontrol {Swirl}
\li A combination of two effects, a soft glowing effect and a swirl distortion effect.
\row
\li \uicontrol {Noise}
\li An animated effect with RGB noise.
\row
\li \uicontrol {Rain} and \uicontrol {Thunder}
\li A weather effect, a combination of a rain effect and a thunder effect.
\endtable
\section1 The Structure of the Example
In addition to the effects, the example project also includes the following components:
\list
\li A \l {3D} scene
\list
\li \l {Importing 3D Assets}{A 3D model}
\li \l {Lights}{A directional light}
\li \l {Cameras}{A scene camera}
\li \l {OrbitCameraController}
\endlist
\li \l {Text} components
\li \l {Rectangle} components
\li \l {Shapes#Border}{Border} components
\li \l {Creating Buttons}{Custom Buttons}
\li \l {Creating Custom Components}{Custom Sliders}
\endlist
The example project also uses \uicontrol States and \uicontrol Transitions. To learn more, see
\l {Working with States} and \l {Transitions}.
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -27,14 +27,19 @@
\e CMakeLists.txt file as the project file. This enables you to share \e CMakeLists.txt file as the project file. This enables you to share
your project as a fully working C++ application with developers. your project as a fully working C++ application with developers.
To export a \QDS project for Qt Creator, you need: You can also enable \QDS projects for Python development. When enabled,
\QDS creates a Python folder within the project folder with the file
\e {main.py}. Use this file to start the development in Python for the UI
made with \QDS.
\list \section1 Exporting a \QDS Project for C++ Development
\li Qt Creator 13.0 or above.
\li \QDS 4.5 or above.
\endlist
\section1 Exporting a \QDS Project To export a \QDS project for Qt Creator, you need:
\list
\li Qt Creator 13.0 or above.
\li \QDS 4.5 or above.
\endlist
\list 1 \list 1
\li \l {Creating a Project} {Create} or open your \QDS project with \QDS 4.5 or above. \li \l {Creating a Project} {Create} or open your \QDS project with \QDS 4.5 or above.
@@ -44,14 +49,14 @@
used in your Qt Creator. used in your Qt Creator.
\li Go to \uicontrol {File} > \uicontrol {Export Project} \li Go to \uicontrol {File} > \uicontrol {Export Project}
> \uicontrol {Enable Automatic CMake Generation}. This creates a > \uicontrol {Enable CMake Generator}. This creates a
\e {CMakeLists.txt} file in your project folder. \e {CMakeLists.txt} file in your project folder.
\note Enabling this option tracks the changes made to the project in Qt Creator \note Enabling this option tracks the changes made to the project in \QDS
and automatically updates in \QDS. The connection works unless you and automatically updates in Qt Creator. The connection works unless you
deactivate the option. deactivate the option.
\image studio-project-export.webp "Exporting Qt Design Studio project" \image studio-project-export-cmake.webp "Exporting Qt Design Studio project to CMake"
\endlist \endlist
\section1 Opening the \QDS Project in Qt Creator \section1 Opening the \QDS Project in Qt Creator
@@ -76,4 +81,81 @@
\image qtcreator-qt-design-studio-project.webp "Qt Design studio projects in Qt Creator after successful import" \image qtcreator-qt-design-studio-project.webp "Qt Design studio projects in Qt Creator after successful import"
\li To run the project, select \uicontrol Run. \li To run the project, select \uicontrol Run.
\endlist \endlist
\note \QDS 4.4 and earlier versions have a project structure where
different explicit import paths such as \e imports or \e asset_imports
reference assets such as images or mesh files separately in their own
scope. So, linking them from one module to another does not work in the
generated CMake-based C++ application. Such cross-modular references are
not considered good practice. Since \QDS 4.5, this issue has been solved.
All the import assets are now bundled in the same folder, so the CMake
generation works properly.
\section1 Exporting a \QDS Project for Python Development
\list 1
\li \l {Creating a Project} {Create} a project with \QDS 4.5 or above.
Then open your \QDS project with \QDS 4.6 or above.
\note You cannot export a project created with \QDS 4.4 or an
earlier version of \QDS for Python development.
\li Go to \uicontrol {File} > \uicontrol {Export Project}
> \uicontrol {Enable Python Generator}. This creates a
Python folder in your project folder. You can find the
\e {main.py} file in the Python folder. This file is
necessary for working in Python.
\note Do not modify the contents of the \e {autogen} folder inside
the Python folder manually; they are overwritten with each
change you make in the project.
\image studio-project-export-python.webp "Exporting Qt Design Studio project to Python"
\endlist
\section1 Opening the \QDS Project with Python
After your project have the Python folder and the \e {main.py} file
available, you can start setting up your Python environment for developing
with \QDS projects.
\table
\row
\li {2,1} \image studio-project-export-python-folder.webp "The generated Python folder in the Qt Design Studio project"
\li {2,2} \image studio-project-export-python-file.webp "The generated Python file in the Qt Design Studio project"
\endtable
\list 1
\li If you don't have Python installed on your computer, install it.
The latest version of Python is available
\l {https://www.python.org/downloads/} {here}.
\li Next, follow the steps from this document to
\l {https://doc.qt.io/qtforpython-6/quickstart.html} {install PySide6}.
You need this for working with Qt in Python.
\note You need Python version between 3.8 and 3.13 to install
PySide6.
\li After installing PySide6, install \QDS packages for PySide6. Stay
in the virtual environment that was accessed for installing
PySide6. From there, execute the command in the command prompt.
\code
pip install PySide6_DS
\endcode
\li Go to your project folder in the command prompt.
\code
cd path/to/your/project/folder
\endcode
\li Finally, run the command below in the command prompt to open the
\e {main.py} file from your project.
\code
python Python\main.py
\endcode
\endlist
Your \QDS project now runs in Python. Use Python to add more
functionalities to the project. Go to \l {Qt for Python} to learn more
about developing Qt projects using Python.
*/ */

View File

@@ -46,5 +46,4 @@
To preview the design on a device, see \l {Previewing on Devices}. To preview the design on a device, see \l {Previewing on Devices}.
\endif
*/ */

View File

@@ -37,5 +37,8 @@
\row \row
\li 4.5 \li 4.5
\li 6.7.0 (with additional Quick3D features) \li 6.7.0 (with additional Quick3D features)
\row
\li 4.6
\li 6.8.0
\endtable \endtable
*/ */

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\previouspage qt-using-effect-maker-effects.html
\page sharing-assets.html
\nextpage qtquick-motion-design.html
\sa {Content Library}
\title Sharing Assets
With \QDS Bundle files (\e{.qdsbundle}), you can import and export 3D components (such as
cameras, lights, and models) and materials easily.
\section1 Exporting Bundles
To export a 3D component or material as a bundle, do one of the following:
\list
\li In the \uicontrol 3D or \uicontrol Navigator view, right-click a 3D component and select
\uicontrol {Export Component}.
\li In the \uicontrol {Material Browser} view, right-click a material and select
\uicontrol {Export Material}.
\endlist
\section1 Importing Bundles
To import a 3D component or material bundle, do one of the following:
\list
\li In the \uicontrol {3D}, \uicontrol {2D}, or \uicontrol {Navigator} view, right-click
and select \uicontrol {Import Component}. If you use this method to import a bundle of 3D
components, the 3D components are added to the 3D scene.
\li In \uicontrol {Content Library} > \uicontrol {User Assets}, right-click and select
\uicontrol {Import Bundle}. If you use this method to import a bundle of 3D
components, the 3D components are added to \uicontrol {User Assets}.
\endlist
*/

View File

@@ -191,6 +191,7 @@
\endlist \endlist
\li \l{Exporting Components} \li \l{Exporting Components}
\li \l{Using Qt Quick Effect Maker Effects} \li \l{Using Qt Quick Effect Maker Effects}
\li \l{Sharing Assets}
\endlist \endlist
\endlist \endlist
\li \l{Motion Design} \li \l{Motion Design}

View File

@@ -1,104 +1,98 @@
// Copyright (C) 2021 The Qt Company Ltd. // Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*! /*!
\page index.html \page index.html
\nextpage studio-getting-started.html \nextpage studio-getting-started.html
\title Qt Design Studio Manual \keyword {Qt Design Studio Manual}
\title Qt Design Studio Documentation
Define the look and feel of the UI from wireframe to final implementation \raw HTML
with preset UI components. Import UI design files from 2D and 3D tools to <style>
\QDS, which can turn them into code for developers. \QDS prototyping .main-navigation table { table-layout: fixed; }
features bring your designs to life and simulate and validate interactions .main-navigation table tr:first-child { text-align: center; background: none; }
and dynamic behavior. You can test, preview, and fine-tune your designs to </style>
pixel-perfection live on the desktop or target device. \endraw
View \l{All Topics}{all topics} or select a topic from below. \div {class="main-navigation"}
\table borderless 100%
\row
\li \inlineimage icons/installation.png
\li \inlineimage icons/getting-started.png
\li \inlineimage icons/tutorials.png
\row
\li \b {INSTALLATION}
\table \QDS is available with \e commercial, \e evaluation, and \e educational licenses
\row on Windows, \macOs, and Linux.
\li \inlineimage qds-front-gs.png
\li \inlineimage qds-front-ui.png
\li \inlineimage qds-studio-3d-scenes.png
\li \inlineimage qds-studio-animation.png
\row
\li \b {\l{Getting Started}}
\list
\li \l{Installing \QDS}
\li \l{Tutorials}
\li \l{User Interface}
\li \l{Creating Projects}
\li \l{Use Cases}
\li \l{Concepts and Terms}
\li \l{Best Practices}
\li \l{Examples}
\endlist
\li \b {\l{Wireframing}}
\list
\li \l{Designing Application Flows}
\li \l{Using Components}
\li \l{Specifying Component Properties}
\li \l{Scalable Layouts}
\li \l{Annotating Designs}
\endlist
\li \b {\l{Prototyping}}
\list
\li \l{Creating UI Logic}
\li \l{Effects}
\li \l{Simulating Complex Experiences}
\li \l{Dynamic Behaviors}
\li \l{Validating with Target Hardware}
\li \l{Asset Creation with Other Tools}
\endlist
\li \b {\l{Motion Design}}
\list
\li \l{Introduction to Animation Techniques}
\li \l{Creating Timeline Animations}
\li \l{Editing Easing Curves}
\li \l{Production Quality}
\li \l{Optimizing Designs}
\endlist
\row
\li \inlineimage qds-front-preview.png
\li \inlineimage qds-front-advanced.png
\li \inlineimage qds-front-projects.png
\li \inlineimage qds-front-help.png
\row
\li \b {\l{Implementing Applications}}
\list
\li \l{Designer-Developer Workflow}
\li \l{Code}{Coding}
\li \l{Debugging and Profiling}
\endlist
\li \b {\l{Advanced Designer Topics}}
\list
\li \l{UI Files}
\li \l {Manage Data Collection}
\li \l{Packaging Applications}
\endlist
\li \b {\l{Developer Topics}}
\list
\li \l{Using Git}
\li \l{Converting Qt 5 Projects into Qt 6 Projects}
\li \l{Converting UI Projects to Applications}
\li \l{Use external tools}{Using External Tools}
\li \l{\QDS on MCUs}
\endlist
\li \b {\l Help}
\list
\li \l{Get help}{Getting Help}
\li \l{Supported Platforms}
\endlist
\row
\li {4,1} \note To report bugs and suggestions to the
\l{https://bugreports.qt.io/}{Qt Project Bug Tracker},
select \uicontrol {Help > Report Bug} in \QDS.
To copy and paste detailed information about your system to the
bug report, select \uicontrol Help >
\uicontrol {System Information}.
For credits and a list of third-party libraries, see \l {Installing \QDS}
\l {Acknowledgements}. \li \b {GETTING STARTED}
Learn about the \QDS features, UI and how to get started with
your first project.
\l{Getting Started}
\li \b {TUTORIALS}
Follow the tutorials to learn how to create \QDS applications.
\l{Tutorials}
\endtable \endtable
\enddiv
\section1 About
\QDS transforms your designs into a fully functional user interface. It's no longer a
click-through mockup. Test, preview, and fine-tune your designs to pixel-perfection,
live on target devices.
A single unified framework, one common language, fewer feedback loops, and faster iterations,
\QDS closes the gap between designers and developers.
\b {LEARN MORE}
\raw HTML
<style>
.link-list table { table-layout: fixed; }
.link-list table, .link-list table tr:first-child { background: none; border: none; }
</style>
\endraw
\div {class="link-list"}
\table 100%
\row
\li \inlineimage icons/demo-32x32.png
\li \inlineimage icons/build-32x32.png
\li \inlineimage icons/settings-32x32.png
\row
\li Key Concepts
\list
\li \l{Introduction to Animation Techniques}{Animation Techniques}
\li \l{Asset Creation with Other Tools}{Creating Assets with Other Tools}
\li \l{Creating UI Logic}
\li \l{Using Components}{Components}
\li \l{Designer-Developer Workflow}
\li \l{Qt Design Studio on MCUs}
\endlist
\li Best Practices
\list
\li \l{Converting Qt 5 Projects into Qt 6 Projects}
\li \l{Converting UI Projects to Applications}
\li \l{Creating Glow and Bloom Effects}
\li \l{Creating Optimized 3D Scenes}
\li \l{Optimizing Designs}
\li \l{Production Quality}{Achieving Production Quality}
\endlist
\li Online Courses
\list
\li \l{https://qurious.qt.io/enrollments/197683855/details}{Getting Started}
\li \l{https://qurious.qt.io/catalog/courses/3910783}{Creating Your First App}
\li \l{https://qurious.qt.io/enrollments/154647839/details}{Introduction to 2D UI Design}
\li \l{https://qurious.qt.io/enrollments/167005403/details}{Introduction to 3D Design}
\li \l{https://qurious.qt.io/catalog/courses/3910791}{Using Qt Bridge for Figma}
\endlist
\endtable
\enddiv
*/ */

View File

@@ -89,11 +89,14 @@
camera: camera:
\list \list
\li To pan, press \key Alt (or \key Option on \macos) and use the \li To pan, do one of the following and drag anywhere in the view to pan:
wheel button to drag anywhere in the \uicontrol 3D view to \list
slide the view around. Alternatively, press and hold \key \li Press and hold \key Alt (or \key Option on \macos) and
{right mouse button} and \key {left mouse button} and drag \key {middle mouse button}.
anywhere in the view to pan. \li Press and hold \key {right mouse button}, and then press and hold
\key {left mouse button}.
\li Press and hold \key Shift and \key {left mouse button}.
\endlist
\li To orbit, press \key Alt and and drag anywhere in the \li To orbit, press \key Alt and and drag anywhere in the
\uicontrol 3D view to rotate the view. \uicontrol 3D view to rotate the view.
\li To zoom, use the mouse wheel or press \key Alt and right-click \li To zoom, use the mouse wheel or press \key Alt and right-click
@@ -179,6 +182,30 @@
\li Set a value multiplier for the speed slider. \li Set a value multiplier for the speed slider.
\endlist \endlist
\section1 Toggling Camera View
In the 3D view, you can show a small window displaying the camera view.
\image 3d-view-camera-view.webp
To toggle this view,
select \inlineimage icons/visibilityon.png
and then one of the options:
\table
\row
\li \uicontrol {Hide Camera View}
\li Never shows the camera view.
\row
\li \uicontrol {Show Selected Camera View}
\li Shows the camera view of the selected camera. If no camera is selected, the camera
view is hidden.
\row
\li \uicontrol {Always Show Camera View}
\li Always shows the camera view of the camera that was selected last, even if no camera
is currently selected.
\endtable
\section1 Using Global and Local Orientation \section1 Using Global and Local Orientation
In \uicontrol 3D view, you view the scene in global or local orientation In \uicontrol 3D view, you view the scene in global or local orientation

View File

@@ -43,9 +43,8 @@
\image studio-effect-composer-assets.webp "Effect Composer and the Assets view" \image studio-effect-composer-assets.webp "Effect Composer and the Assets view"
The saved custom effects appear in the \uicontrol {Assets} view. Double-click a The saved custom effects appear in the \uicontrol {Assets} view. To delete a custom effect,
custom effect in \uicontrol Assets to view and edit it in \uicontrol {Effect Composer}. right-click it in the \uicontrol {Assets} view, and then
To delete a custom effect, right-click it in the \uicontrol {Assets} view, and then
select \uicontrol {Delete File}. select \uicontrol {Delete File}.
\section1 Assigning a Custom Effect to a Component \section1 Assigning a Custom Effect to a Component
@@ -63,6 +62,18 @@
\note To assign an effect to a component, you need to save it first. \note To assign an effect to a component, you need to save it first.
\section1 Editing Effects
To open an effect in the \uicontrol {Effect Composer} to edit it, do one of the following:
\list
\li In the \uicontrol Assets view, double-click the effect.
\li In the \uicontrol Navigator or \uicontrol Assets view, right-click and select
\uicontrol {Edit in Effect Composer}.
\li Drag the effect from the \uicontrol Navigator or \uicontrol Assets view to the
\uicontrol {Effect Composer} view.
\endlist
\section1 Stacking Effects \section1 Stacking Effects
To compose complex custom effects, add multiple effects to your stack in To compose complex custom effects, add multiple effects to your stack in

View File

@@ -21,6 +21,11 @@
have added an asset from \uicontrol {Content Library}, you can use it in have added an asset from \uicontrol {Content Library}, you can use it in
your project. your project.
You can also add assets to the \uicontrol {Content Library} > \uicontrol {User Assets}.
Assets added to \uicontrol {User Assets} are always available in \uicontrol {Content Library}
regardless of what project you are working on.
\image content-library.webp \image content-library.webp
\section1 Adding a Material to Your Project \section1 Adding a Material to Your Project
@@ -28,7 +33,7 @@
You can use materials on 3D models. You can use materials on 3D models.
To add a material from the \uicontrol {Content Library} view to your To add a material from the \uicontrol {Content Library} view to your
project, do one of the following: project, download the material and then do one of the following:
\list \list
\li Select the \inlineimage icons/plus.png \li Select the \inlineimage icons/plus.png
@@ -79,4 +84,60 @@
\uicontrol Navigator view. \uicontrol Navigator view.
\endlist \endlist
\section1 User Assets
\image user-assets.webp
Add assets to \uicontrol {User Assets} to access them in any project.
You can add 3D objects (such as 3D models, cameras, and lights), materials, and images to
\uicontrol {User Assets}.
\section2 Adding an Asset to User Assets
Add assets to \uicontrol{User Assets} in the following ways:
\list
\li In the \uicontrol {Assets} view, right-click an asset and select
\uicontrol {Add to Content Library}.
\li In the \uicontrol {3D} view, right-click an asset and select
\uicontrol {Add to Content Library}.
\li In the \uicontrol {Navigator} view, right-click an asset and select
\uicontrol {Add to Content Library}.
\li In the \uicontrol {Material Browser} view, right-click a material and select
\uicontrol {Add to Content Library}.
\endlist
\section2 Using Assets from User Assets
\section3 Adding a Material
Add a material to your project in the following ways:
\list
\li Right-click the material and select \uicontrol {Add an instance to project}. This
adds the material to the \uicontrol {Material Browser} view.
\li Drag a material to a 3D model in the \uicontrol 3D or \uicontrol Navigator view.
\endlist
\section3 Adding a 3D component
Add a 3D component to your project in the following ways:
\list
\li Drag the 3D component to the \uicontrol 3D or \uicontrol Navigator view.
\li Right-click the 3D component and select \uicontrol {Add an instance to project}.
\endlist
\section3 Adding a Texture
Add a texture to your project in the following ways:
\list
\li Right-click a texture and select \uicontrol {Add image}, \uicontrol{Add texture}, or
\uicontrol {Add light probe}.
\li Drag a texture to a 3D model in the \uicontrol 3D, \uicontrol {2D}, or
\uicontrol {Navigator} view to add it as a texture to that 3D model.
\li Drag a texture to the \uicontrol Assets view.
\endlist
*/ */

View File

@@ -335,6 +335,7 @@
"Path": "src/libs/3rdparty/span", "Path": "src/libs/3rdparty/span",
"Description": "A single-header implementation of C++20's std::span, conforming to the C++20 committee draft.", "Description": "A single-header implementation of C++20's std::span, conforming to the C++20 committee draft.",
"Homepage": "https://github.com/martinmoene/span-lite", "Homepage": "https://github.com/martinmoene/span-lite",
"Version": "00afc28",
"License": "Boost Software License 1.0", "License": "Boost Software License 1.0",
"LicenseFile": "src/libs/3rdparty/span/LICENSE_1_0.txt", "LicenseFile": "src/libs/3rdparty/span/LICENSE_1_0.txt",
"Copyright": "Copyright 2018-2021 Martin Moene" "Copyright": "Copyright 2018-2021 Martin Moene"

View File

@@ -101,20 +101,8 @@ TreeViewDelegate {
: "transparent" : "transparent"
} }
border.width: StudioTheme.Values.border border.width: StudioTheme.Values.border
border.color: { border.color: root.assetsView.selectedAssets[root.__itemPath] ? StudioTheme.Values.themeInteraction
if (root.__isDirectory && (root.isHighlighted || root.hasChildWithDropHover)) : "transparent"
return StudioTheme.Values.themeInteraction
if (!root.__isDirectory && root.assetsView.selectedAssets[root.__itemPath])
return StudioTheme.Values.themeInteraction
if (mouseArea.containsMouse)
return StudioTheme.Values.themeSectionHeadBackground
return root.__isDirectory
? StudioTheme.Values.themeSectionHeadBackground
: "transparent"
}
} }
contentItem: Text { contentItem: Text {
@@ -158,26 +146,31 @@ TreeViewDelegate {
mouseArea.allowTooltip = false mouseArea.allowTooltip = false
AssetsLibraryBackend.tooltipBackend.hideTooltip() AssetsLibraryBackend.tooltipBackend.hideTooltip()
if (root.__isDirectory)
return
var ctrlDown = mouse.modifiers & Qt.ControlModifier var ctrlDown = mouse.modifiers & Qt.ControlModifier
if (mouse.button === Qt.LeftButton) {
if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown)
root.assetsView.clearSelectedAssets()
root.currFileSelected = ctrlDown ? !root.assetsView.isAssetSelected(root.__itemPath) : true
root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected)
if (root.currFileSelected) { if (mouse.button === Qt.LeftButton) {
let selectedPaths = root.assetsView.selectedPathsAsList() if (root.__isDirectory) {
AssetsLibraryBackend.rootView.startDragAsset(selectedPaths, mapToGlobal(mouse.x, mouse.y)) // ensure only one directory can be selected
} root.assetsView.clearSelectedAssets()
} else { root.currFileSelected = true
if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown) } else {
root.assetsView.clearSelectedAssets() if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown)
root.currFileSelected = root.assetsView.isAssetSelected(root.__itemPath) || !ctrlDown root.assetsView.clearSelectedAssets()
root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected) root.currFileSelected = ctrlDown ? !root.assetsView.isAssetSelected(root.__itemPath) : true
} }
root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected)
if (root.currFileSelected) {
let selectedPaths = root.assetsView.selectedPathsAsList()
AssetsLibraryBackend.rootView.startDragAsset(selectedPaths, mapToGlobal(mouse.x, mouse.y))
}
} else {
if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown)
root.assetsView.clearSelectedAssets()
root.currFileSelected = root.assetsView.isAssetSelected(root.__itemPath) || !ctrlDown
root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected)
}
} }
onReleased: (mouse) => { onReleased: (mouse) => {
@@ -288,7 +281,7 @@ TreeViewDelegate {
function __toggleExpandCurrentRow() { function __toggleExpandCurrentRow() {
if (!root.__isDirectory) if (!root.__isDirectory)
return return
let index = root.assetsView.__modelIndex(root.__currentRow) let index = root.assetsView.__modelIndex(root.__currentRow)
// if the user manually clicked on a directory, then this is definitely not a // if the user manually clicked on a directory, then this is definitely not a
@@ -315,7 +308,7 @@ TreeViewDelegate {
id: thumbnailImage id: thumbnailImage
visible: !root.__isDirectory visible: !root.__isDirectory
y: StudioTheme.Values.border y: StudioTheme.Values.border
x: bg.x x: bg.x + StudioTheme.Values.border
width: 48 width: 48
height: 48 height: 48
cache: false cache: false
@@ -336,4 +329,51 @@ TreeViewDelegate {
assetTooltip.refresh() assetTooltip.refresh()
} }
} }
DropArea {
id: dropArea
anchors.fill: parent
anchors.bottomMargin: -assetsView.rowSpacing
function updateParentHighlight(highlight) {
let index = root.assetsView.__modelIndex(root.__currentRow)
let parentItem = assetsView.__getDelegateParentForIndex(index)
if (parentItem)
parentItem.isHighlighted = highlight
// highlights the root folder canvas area when dragging over child
if (root.depth === 1 && !root.__isDirectory)
root.assetsRoot.highlightCanvas = highlight
}
onEntered: (drag) => {
root.assetsRoot.updateDropExtFiles(drag)
drag.accepted |= drag.formats[0] === "application/vnd.qtdesignstudio.assets"
&& !root.assetsModel.isSameOrDescendantPath(drag.urls[0], root.__itemPath)
if (root.__isDirectory)
root.isHighlighted = drag.accepted
else
dropArea.updateParentHighlight(drag.accepted)
}
onDropped: (drag) => {
if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") {
root.rootView.invokeAssetsDrop(drag.urls, root.getDirPath())
} else {
root.rootView.emitExtFilesDrop(root.assetsRoot.dropSimpleExtFiles,
root.assetsRoot.dropComplexExtFiles,
root.getDirPath())
}
root.isHighlighted = false
dropArea.updateParentHighlight(false)
}
onExited: {
root.isHighlighted = false
dropArea.updateParentHighlight(false)
}
}
} }

View File

@@ -21,6 +21,7 @@ Item {
readonly property int qtVersion: rootView.qtVersion() readonly property int qtVersion: rootView.qtVersion()
property bool __searchBoxEmpty: true property bool __searchBoxEmpty: true
property bool highlightCanvas: false
AssetsContextMenu { AssetsContextMenu {
id: contextMenu id: contextMenu
@@ -58,14 +59,21 @@ Item {
height: parent.height - y height: parent.height - y
onEntered: (drag) => { onEntered: (drag) => {
root.updateDropExtFiles(drag) if (drag.formats[0] === "application/vnd.qtdesignstudio.assets")
drag.accepted = drag.urls.length > 0
else
root.updateDropExtFiles(drag)
} }
onDropped: (drag) => { onDropped: (drag) => {
drag.accept() drag.accept()
rootView.handleExtFilesDrop(root.dropSimpleExtFiles, if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") {
root.dropComplexExtFiles, root.rootView.handleAssetsDrop(drag.urls, assetsModel.rootPath())
assetsModel.rootPath()) } else {
root.rootView.handleExtFilesDrop(root.dropSimpleExtFiles,
root.dropComplexExtFiles,
assetsModel.rootPath())
}
} }
Canvas { // marker for the drop area Canvas { // marker for the drop area
@@ -73,8 +81,7 @@ Item {
y: 5 y: 5
width: parent.width width: parent.width
height: parent.height - y height: parent.height - y
visible: dropArea.containsDrag && root.dropSimpleExtFiles.length > 0 visible: dropArea.containsDrag || root.highlightCanvas
onWidthChanged: dropCanvas.requestPaint() onWidthChanged: dropCanvas.requestPaint()
onHeightChanged: dropCanvas.requestPaint() onHeightChanged: dropCanvas.requestPaint()

View File

@@ -120,6 +120,16 @@ StudioControls.Menu {
height: visible ? StudioTheme.Values.border : 0 height: visible ? StudioTheme.Values.border : 0
} }
StudioControls.MenuItem {
id: editInEffectComposerItem
text: qsTr("Edit in Effect Composer")
visible: root.__fileIndex && root.__selectedAssetPathsList.length === 1
&& root.assetsModel.allFilePathsAreComposedEffects(root.__selectedAssetPathsList)
&& root.rootView.canCreateEffects()
height: editInEffectComposerItem.visible ? editInEffectComposerItem.implicitHeight : 0
onTriggered: AssetsLibraryBackend.rootView.openEffectComposer(root.__selectedAssetPathsList[0])
}
StudioControls.MenuItem { StudioControls.MenuItem {
id: addTexturesItem id: addTexturesItem
text: qsTr("Add Texture") text: qsTr("Add Texture")

View File

@@ -83,9 +83,7 @@ TreeView {
interval: 200 interval: 200
repeat: false repeat: false
onTriggered: { onTriggered: root.updateRows()
root.updateRows()
}
} }
Connections { Connections {
@@ -278,36 +276,6 @@ TreeView {
return "" return ""
} }
function startDropHoverOver(row)
{
let index = root.__modelIndex(row)
if (assetsModel.isDirectory(index)) {
let item = root.__getDelegateItemForIndex(index)
if (item)
item.isHighlighted = true
return
}
let parentItem = root.__getDelegateParentForIndex(index)
if (parentItem)
parentItem.hasChildWithDropHover = true
}
function endDropHover(row)
{
let index = root.__modelIndex(row)
if (assetsModel.isDirectory(index)) {
let item = root.__getDelegateItemForIndex(index)
if (item)
item.isHighlighted = false
return
}
let parentItem = root.__getDelegateParentForIndex(index)
if (parentItem)
parentItem.hasChildWithDropHover = false
}
function isAssetSelected(itemPath) function isAssetSelected(itemPath)
{ {
return root.selectedAssets[itemPath] ? true : false return root.selectedAssets[itemPath] ? true : false
@@ -331,12 +299,6 @@ TreeView {
return root.itemAtCell(parentCell) return root.itemAtCell(parentCell)
} }
function __getDelegateItemForIndex(index)
{
let cell = root.cellAtIndex(index)
return root.itemAtCell(cell)
}
function __modelIndex(row) function __modelIndex(row)
{ {
// The modelIndex() function exists since 6.3. In Qt 6.3, this modelIndex() function was a // The modelIndex() function exists since 6.3. In Qt 6.3, this modelIndex() function was a
@@ -405,77 +367,6 @@ TreeView {
onClosed: confirmDeleteFiles.files = [] onClosed: confirmDeleteFiles.files = []
} }
DropArea {
id: dropArea
enabled: true
anchors.fill: parent
property bool __isHoveringDrop: false
property int __rowHoveringOver: -1
function __rowAndItem(drag)
{
let pos = dropArea.mapToItem(root, drag.x, drag.y)
let cell = root.cellAtPos(pos.x, pos.y, true)
let item = root.itemAtCell(cell)
return [cell.y, item]
}
onEntered: (drag) => {
root.assetsRoot.updateDropExtFiles(drag)
let [row, item] = dropArea.__rowAndItem(drag)
dropArea.__isHoveringDrop = drag.accepted && root.assetsRoot.dropSimpleExtFiles.length > 0
if (item && dropArea.__isHoveringDrop)
root.startDropHoverOver(row)
dropArea.__rowHoveringOver = row
}
onDropped: (drag) => {
let [row, item] = dropArea.__rowAndItem(drag)
if (item) {
drag.accept()
root.endDropHover(row)
let dirPath = item.getDirPath()
rootView.emitExtFilesDrop(root.assetsRoot.dropSimpleExtFiles,
root.assetsRoot.dropComplexExtFiles,
dirPath)
}
dropArea.__isHoveringDrop = false
dropArea.__rowHoveringOver = -1
}
onPositionChanged: (drag) => {
let [row, item] = dropArea.__rowAndItem(drag)
if (dropArea.__rowHoveringOver !== row && dropArea.__rowHoveringOver > -1) {
root.endDropHover(dropArea.__rowHoveringOver)
if (item)
root.startDropHoverOver(row)
}
dropArea.__rowHoveringOver = row
}
onExited: {
if (!dropArea.__isHoveringDrop || dropArea.__rowHoveringOver === -1)
return
root.endDropHover(dropArea.__rowHoveringOver)
dropArea.__isHoveringDrop = false
dropArea.__rowHoveringOver = -1
}
}
delegate: AssetDelegate { delegate: AssetDelegate {
assetsView: root assetsView: root
assetsRoot: root.assetsRoot assetsRoot: root.assetsRoot

View File

@@ -120,7 +120,7 @@ Column {
buttonIcon: qsTr("Add Condition") buttonIcon: qsTr("Add Condition")
tooltip: qsTr("Sets a logical condition for the selected <b>Signal</b>. It works with the properties of the <b>Target</b> component.") tooltip: qsTr("Sets a logical condition for the selected <b>Signal</b>. It works with the properties of the <b>Target</b> component.")
iconSize: StudioTheme.Values.baseFontSize iconSize: StudioTheme.Values.baseFontSize
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && !backend.hasCondition visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && !backend.hasCondition
@@ -133,7 +133,7 @@ Column {
buttonIcon: qsTr("Remove Condition") buttonIcon: qsTr("Remove Condition")
tooltip: qsTr("Removes the logical condition for the <b>Target</b> component.") tooltip: qsTr("Removes the logical condition for the <b>Target</b> component.")
iconSize: StudioTheme.Values.baseFontSize iconSize: StudioTheme.Values.baseFontSize
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition
@@ -184,7 +184,7 @@ Column {
buttonIcon: qsTr("Add Else Statement") buttonIcon: qsTr("Add Else Statement")
tooltip: qsTr("Sets an alternate condition for the previously defined logical condition.") tooltip: qsTr("Sets an alternate condition for the previously defined logical condition.")
iconSize: StudioTheme.Values.baseFontSize iconSize: StudioTheme.Values.baseFontSize
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
&& backend.hasCondition && !backend.hasElse && backend.hasCondition && !backend.hasElse
@@ -198,7 +198,7 @@ Column {
buttonIcon: qsTr("Remove Else Statement") buttonIcon: qsTr("Remove Else Statement")
tooltip: qsTr("Removes the alternate logical condition for the previously defined logical condition.") tooltip: qsTr("Removes the alternate logical condition for the previously defined logical condition.")
iconSize: StudioTheme.Values.baseFontSize iconSize: StudioTheme.Values.baseFontSize
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
&& backend.hasCondition && backend.hasElse && backend.hasCondition && backend.hasElse

View File

@@ -17,6 +17,14 @@ Item {
// and set the ads focus on it. // and set the ads focus on it.
objectName: "__mainSrollView" objectName: "__mainSrollView"
enum TabIndex {
MaterialsTab,
TexturesTab,
EnvironmentsTab,
EffectsTab,
UserAssetsTab
}
// Called also from C++ to close context menu on focus out // Called also from C++ to close context menu on focus out
function closeContextMenu() { function closeContextMenu() {
materialsView.closeContextMenu() materialsView.closeContextMenu()
@@ -67,6 +75,13 @@ Item {
root.numColumns = numColumns root.numColumns = numColumns
} }
Connections {
target: ContentLibraryBackend.rootView
function onRequestTab(tabIndex) {
tabBar.currIndex = tabIndex
}
}
Column { Column {
id: col id: col
anchors.fill: parent anchors.fill: parent
@@ -90,12 +105,22 @@ Item {
width: parent.width width: parent.width
style: StudioTheme.Values.searchControlStyle style: StudioTheme.Values.searchControlStyle
enabled: { enabled: {
if (tabBar.currIndex === 0) { // Materials tab switch (tabBar.currIndex) {
ContentLibraryBackend.materialsModel.matBundleExists case ContentLibrary.TabIndex.MaterialsTab:
&& ContentLibraryBackend.rootView.hasMaterialLibrary return ContentLibraryBackend.materialsModel.hasRequiredQuick3DImport
&& ContentLibraryBackend.materialsModel.hasRequiredQuick3DImport && ContentLibraryBackend.rootView.hasMaterialLibrary
} else { // Textures / Environments tabs && ContentLibraryBackend.materialsModel.bundleExists
ContentLibraryBackend.texturesModel.texBundleExists case ContentLibrary.TabIndex.TexturesTab:
case ContentLibrary.TabIndex.EnvironmentsTab:
return ContentLibraryBackend.texturesModel.bundleExists
case ContentLibrary.TabIndex.EffectsTab:
return ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport
&& ContentLibraryBackend.effectsModel.bundleExists
case ContentLibrary.TabIndex.UserAssetsTab:
return ContentLibraryBackend.rootView.hasQuick3DImport
&& !ContentLibraryBackend.userModel.isEmpty
default:
return false
} }
} }
@@ -240,14 +265,16 @@ Item {
onUnimport: (bundleItem) => { onUnimport: (bundleItem) => {
confirmUnimportDialog.targetBundleItem = bundleItem confirmUnimportDialog.targetBundleItem = bundleItem
confirmUnimportDialog.targetBundleLabel = "material" confirmUnimportDialog.targetBundleLabel = bundleItem.bundleId === "MaterialBundle"
? qsTr("material") : qsTr("item")
confirmUnimportDialog.targetBundleModel = ContentLibraryBackend.userModel confirmUnimportDialog.targetBundleModel = ContentLibraryBackend.userModel
confirmUnimportDialog.open() confirmUnimportDialog.open()
} }
onRemoveFromContentLib: (bundleItem) => { onRemoveFromContentLib: (bundleItem) => {
confirmDeleteDialog.targetBundleItem = bundleItem confirmDeleteDialog.targetBundleItem = bundleItem
confirmDeleteDialog.targetBundleLabel = "material" confirmDeleteDialog.targetBundleLabel = bundleItem.bundleId === "MaterialBundle"
? qsTr("material") : qsTr("item")
confirmDeleteDialog.open() confirmDeleteDialog.open()
} }

View File

@@ -112,12 +112,12 @@ HelperWidgets.ScrollView {
qsTr("<b>Content Library</b> effects are not supported in Qt5 projects.") qsTr("<b>Content Library</b> effects are not supported in Qt5 projects.")
else if (!ContentLibraryBackend.rootView.hasQuick3DImport) else if (!ContentLibraryBackend.rootView.hasQuick3DImport)
qsTr("To use <b>Content Library</b>, first add the QtQuick3D module in the <b>Components</b> view.") qsTr("To use <b>Content Library</b>, first add the QtQuick3D module in the <b>Components</b> view.")
else if (!ContentLibraryBackend.effectsModel.bundleExists)
qsTr("No effects available.")
else if (!ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport) else if (!ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport)
qsTr("To use <b>Content Library</b>, version 6.4 or later of the QtQuick3D module is required.") qsTr("To use <b>Content Library</b>, version 6.4 or later of the QtQuick3D module is required.")
else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) else if (!ContentLibraryBackend.rootView.hasMaterialLibrary)
qsTr("<b>Content Library</b> is disabled inside a non-visual component.") qsTr("<b>Content Library</b> is disabled inside a non-visual component.")
else if (!ContentLibraryBackend.effectsModel.bundleExists)
qsTr("No effects available.")
else if (!searchBox.isEmpty()) else if (!searchBox.isEmpty())
qsTr("No match found.") qsTr("No match found.")
else else

View File

@@ -121,8 +121,8 @@ HelperWidgets.ScrollView {
qsTr("To use <b>Content Library</b>, version 6.3 or later of the QtQuick3D module is required.") qsTr("To use <b>Content Library</b>, version 6.3 or later of the QtQuick3D module is required.")
else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) else if (!ContentLibraryBackend.rootView.hasMaterialLibrary)
qsTr("<b>Content Library</b> is disabled inside a non-visual component.") qsTr("<b>Content Library</b> is disabled inside a non-visual component.")
else if (!root.materialsModel.matBundleExists) else if (!root.materialsModel.bundleExists)
qsTr("No materials available. Make sure you have internet connection.") qsTr("No materials available. Make sure you have an internet connection.")
else if (!searchBox.isEmpty()) else if (!searchBox.isEmpty())
qsTr("No match found.") qsTr("No match found.")
else else

View File

@@ -109,8 +109,8 @@ HelperWidgets.ScrollView {
Text { Text {
id: infoText id: infoText
text: { text: {
if (!root.model.texBundleExists) if (!root.model.bundleExists)
qsTr("No textures available. Make sure you have internet connection.") qsTr("No textures available. Make sure you have an internet connection.")
else if (!searchBox.isEmpty()) else if (!searchBox.isEmpty())
qsTr("No match found.") qsTr("No match found.")
else else

View File

@@ -10,11 +10,9 @@ import StudioControls as StudioControls
import StudioTheme as StudioTheme import StudioTheme as StudioTheme
import EffectComposerBackend import EffectComposerBackend
ColumnLayout { Item {
id: root id: root
spacing: 1
readonly property var backendModel: EffectComposerBackend.effectComposerModel readonly property var backendModel: EffectComposerBackend.effectComposerModel
property var draggedSec: null property var draggedSec: null
@@ -36,281 +34,26 @@ ColumnLayout {
// Invoked from C++ side before resetting the model to store current expanded state of nodes // Invoked from C++ side before resetting the model to store current expanded state of nodes
function storeExpandStates() { function storeExpandStates() {
expandStates = new Map() root.expandStates = new Map()
for (let i = 0; i < repeater.count; ++i) { for (let i = 0; i < repeater.count; ++i) {
var curItem = repeater.itemAt(i) var curItem = repeater.itemAt(i)
expandStates.set(curItem.caption, curItem.expanded) root.expandStates.set(curItem.caption, curItem.expanded)
} }
} }
// Invoked after model has been reset to restore expanded state for nodes // Invoked after model has been reset to restore expanded state for nodes
function restoreExpandStates() { function restoreExpandStates() {
if (expandStates) { if (root.expandStates) {
for (let i = 0; i < repeater.count; ++i) { for (let i = 0; i < repeater.count; ++i) {
var curItem = repeater.itemAt(i) var curItem = repeater.itemAt(i)
if (expandStates.has(curItem.caption)) if (root.expandStates.has(curItem.caption))
curItem.expanded = expandStates.get(curItem.caption) curItem.expanded = root.expandStates.get(curItem.caption)
} }
expandStates = null root.expandStates = null
} }
} }
Connections {
target: root.backendModel
function onIsEmptyChanged() {
if (root.backendModel.isEmpty)
saveAsDialog.close()
}
}
SaveAsDialog {
id: saveAsDialog
anchors.centerIn: parent
}
SaveChangesDialog {
id: saveChangesDialog
anchors.centerIn: parent
onSave: {
if (root.backendModel.currentComposition === "") {
// if current composition is unsaved, show save as dialog and clear afterwards
saveAsDialog.clearOnClose = true
saveAsDialog.open()
} else {
root.onSaveChangesCallback()
}
}
onDiscard: {
root.onSaveChangesCallback()
}
}
ConfirmClearAllDialog {
id: confirmClearAllDialog
anchors.centerIn: parent
}
EffectComposerTopBar {
Layout.fillWidth: true
onAddClicked: {
root.onSaveChangesCallback = () => { root.backendModel.clear(true) }
if (root.backendModel.hasUnsavedChanges)
saveChangesDialog.open()
else
root.backendModel.clear(true)
}
onSaveClicked: {
let name = root.backendModel.currentComposition
if (name === "")
saveAsDialog.open()
else
root.backendModel.saveComposition(name)
}
onSaveAsClicked: saveAsDialog.open()
onAssignToSelectedClicked: {
root.backendModel.assignToSelected()
}
}
SplitView {
id: splitView
Layout.fillWidth: true
Layout.fillHeight: true
orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical
handle: Rectangle {
implicitWidth: splitView.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : splitView.width
implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : StudioTheme.Values.splitterThickness
color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction
: (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover
: "transparent")
}
EffectComposerPreview {
mainRoot: root
SplitView.minimumWidth: 250
SplitView.minimumHeight: 200
SplitView.preferredWidth: 300
SplitView.preferredHeight: 300
Layout.fillWidth: true
Layout.fillHeight: true
FrameAnimation {
id: previewFrameTimer
running: true
paused: !previewAnimationRunning
}
}
Column {
spacing: 1
SplitView.minimumWidth: 250
SplitView.minimumHeight: 100
Component.onCompleted: HelperWidgets.Controller.mainScrollView = scrollView
Rectangle {
width: parent.width
height: StudioTheme.Values.toolbarHeight
color: StudioTheme.Values.themeToolbarBackground
EffectNodesComboBox {
id: nodesComboBox
mainRoot: root
anchors.verticalCenter: parent.verticalCenter
x: 5
width: parent.width - 50
}
HelperWidgets.AbstractButton {
anchors.right: parent.right
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
style: StudioTheme.Values.viewBarButtonStyle
buttonIcon: StudioTheme.Constants.clearList_medium
tooltip: qsTr("Remove all effect nodes.")
enabled: root.backendModel ? !root.backendModel.isEmpty : false
onClicked: {
if (root.backendModel.hasUnsavedChanges)
confirmClearAllDialog.open()
else
root.backendModel.clear()
}
}
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.")
visible: false // TODO: to be implemented
onClicked: {} // TODO
}
}
Item {
width: parent.width
height: parent.height - y
HelperWidgets.ScrollView {
id: scrollView
readonly property int dragScrollMargin: 50
anchors.fill: parent
clip: true
interactive: !HelperWidgets.Controller.contextMenuOpened
onContentHeightChanged: {
// Expand states are stored before full model reset.
// Content height change indicates the model has been updated after full
// reset, so we restore expand states if any are stored.
root.restoreExpandStates()
// If content height change was because a recent node addition, we want to
// scroll to the end of the content so the newly added item is visible.
if (nodesComboBox.nodeJustAdded && scrollView.contentItem.height > scrollView.height) {
let lastItemH = repeater.itemAt(repeater.count - 1).height
scrollView.contentY = scrollView.contentItem.height - lastItemH
nodesComboBox.nodeJustAdded = false
}
}
Column {
id: nodesCol
width: scrollView.width
spacing: 1
Repeater {
id: repeater
width: parent.width
model: root.backendModel
onCountChanged: {
HelperWidgets.Controller.setCount("EffectComposer", repeater.count)
}
delegate: EffectCompositionNode {
width: parent.width
modelIndex: index
property bool wasExpanded: false
Behavior on y {
id: dragAnimation
PropertyAnimation {
duration: 300
easing.type: Easing.InOutQuad
}
}
onStartDrag: (section) => {
root.draggedSec = section
root.moveFromIdx = index
// We only need to animate non-dragged sections
dragAnimation.enabled = false
wasExpanded = expanded
expanded = false
highlightBorder = true
root.secsY = []
}
onStopDrag: {
if (root.secsY.length !== 0) {
if (root.moveFromIdx === root.moveToIdx)
root.draggedSec.y = root.secsY[root.moveFromIdx]
else
root.backendModel.moveNode(root.moveFromIdx, root.moveToIdx)
}
highlightBorder = false
root.draggedSec = null
expanded = wasExpanded
dragAnimation.enabled = true
}
}
} // Repeater
} // Column
} // ScrollView
Text {
text: root.backendModel ? root.backendModel.isEnabled
? qsTr("Add an effect node to start")
: qsTr("Effect Composer is disabled on MCU projects")
: ""
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.baseFontSize
anchors.centerIn: parent
visible: root.backendModel ? root.backendModel.isEmpty : false
}
} // Item
} // Column
} // SplitView
function handleDragMove() { function handleDragMove() {
dragTimer.stop() dragTimer.stop()
if (root.secsY.length === 0) { if (root.secsY.length === 0) {
@@ -362,6 +105,43 @@ ColumnLayout {
} }
} }
Connections {
target: root.backendModel
function onIsEmptyChanged() {
if (root.backendModel.isEmpty)
saveAsDialog.close()
}
}
SaveAsDialog {
id: saveAsDialog
anchors.centerIn: parent
}
SaveChangesDialog {
id: saveChangesDialog
anchors.centerIn: parent
onSave: {
if (root.backendModel.currentComposition === "") {
// if current composition is unsaved, show save as dialog and clear afterwards
saveAsDialog.clearOnClose = true
saveAsDialog.open()
} else {
root.onSaveChangesCallback()
}
}
onDiscard: {
root.onSaveChangesCallback()
}
}
ConfirmClearAllDialog {
id: confirmClearAllDialog
anchors.centerIn: parent
}
Connections { Connections {
id: dragConnection id: dragConnection
target: root.draggedSec target: root.draggedSec
@@ -382,5 +162,256 @@ ColumnLayout {
root.draggedSec.y = targetY root.draggedSec.y = targetY
root.handleDragMove() root.handleDragMove()
} }
} // Timer }
ColumnLayout {
anchors.fill: parent
spacing: 1
EffectComposerTopBar {
Layout.fillWidth: true
onAddClicked: {
root.onSaveChangesCallback = () => { root.backendModel.clear(true) }
if (root.backendModel.hasUnsavedChanges)
saveChangesDialog.open()
else
root.backendModel.clear(true)
}
onSaveClicked: {
let name = root.backendModel.currentComposition
if (name === "")
saveAsDialog.open()
else
root.backendModel.saveComposition(name)
}
onSaveAsClicked: saveAsDialog.open()
onAssignToSelectedClicked: {
root.backendModel.assignToSelected()
}
}
SplitView {
id: splitView
Layout.fillWidth: true
Layout.fillHeight: true
orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical
handle: Rectangle {
implicitWidth: splitView.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : splitView.width
implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : StudioTheme.Values.splitterThickness
color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction
: (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover
: "transparent")
}
EffectComposerPreview {
mainRoot: root
SplitView.minimumWidth: 250
SplitView.minimumHeight: 200
SplitView.preferredWidth: 300
SplitView.preferredHeight: 300
Layout.fillWidth: true
Layout.fillHeight: true
FrameAnimation {
id: previewFrameTimer
running: true
paused: !root.previewAnimationRunning
}
}
Column {
spacing: 1
SplitView.minimumWidth: 250
SplitView.minimumHeight: 100
Component.onCompleted: HelperWidgets.Controller.mainScrollView = scrollView
Rectangle {
width: parent.width
height: StudioTheme.Values.toolbarHeight
color: StudioTheme.Values.themeToolbarBackground
EffectNodesComboBox {
id: nodesComboBox
mainRoot: root
anchors.verticalCenter: parent.verticalCenter
x: 5
width: parent.width - 50
}
HelperWidgets.AbstractButton {
anchors.right: parent.right
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
style: StudioTheme.Values.viewBarButtonStyle
buttonIcon: StudioTheme.Constants.clearList_medium
tooltip: qsTr("Remove all effect nodes.")
enabled: root.backendModel ? !root.backendModel.isEmpty : false
onClicked: {
if (root.backendModel.hasUnsavedChanges)
confirmClearAllDialog.open()
else
root.backendModel.clear()
}
}
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.")
visible: false // TODO: to be implemented
onClicked: {} // TODO
}
}
Item {
width: parent.width
height: parent.height - y
HelperWidgets.ScrollView {
id: scrollView
readonly property int dragScrollMargin: 50
anchors.fill: parent
clip: true
interactive: !HelperWidgets.Controller.contextMenuOpened
onContentHeightChanged: {
// Expand states are stored before full model reset.
// Content height change indicates the model has been updated after full
// reset, so we restore expand states if any are stored.
root.restoreExpandStates()
// If content height change was because a recent node addition, we want to
// scroll to the end of the content so the newly added item is visible.
if (nodesComboBox.nodeJustAdded && scrollView.contentItem.height > scrollView.height) {
let lastItemH = repeater.itemAt(repeater.count - 1).height
scrollView.contentY = scrollView.contentItem.height - lastItemH
nodesComboBox.nodeJustAdded = false
}
}
Column {
id: nodesCol
width: scrollView.width
spacing: 1
Repeater {
id: repeater
width: parent.width
model: root.backendModel
onCountChanged: {
HelperWidgets.Controller.setCount("EffectComposer", repeater.count)
}
delegate: EffectCompositionNode {
width: parent.width
modelIndex: index
property bool wasExpanded: false
Behavior on y {
id: dragAnimation
PropertyAnimation {
duration: 300
easing.type: Easing.InOutQuad
}
}
onStartDrag: (section) => {
root.draggedSec = section
root.moveFromIdx = index
// We only need to animate non-dragged sections
dragAnimation.enabled = false
wasExpanded = expanded
expanded = false
highlightBorder = true
root.secsY = []
}
onStopDrag: {
if (root.secsY.length !== 0) {
if (root.moveFromIdx === root.moveToIdx)
root.draggedSec.y = root.secsY[root.moveFromIdx]
else
root.backendModel.moveNode(root.moveFromIdx, root.moveToIdx)
}
highlightBorder = false
root.draggedSec = null
expanded = wasExpanded
dragAnimation.enabled = true
}
}
} // Repeater
} // Column
} // ScrollView
Text {
text: root.backendModel ? root.backendModel.isEnabled
? qsTr("Add an effect node to start")
: qsTr("Effect Composer is disabled on MCU projects")
: ""
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.baseFontSize
anchors.centerIn: parent
visible: root.backendModel ? root.backendModel.isEmpty : false
}
} // Item
} // Column
} // SplitView
} // ColumnLayout
DropArea {
id: dropArea
anchors.fill: parent
onEntered: (drag) => {
let accepted = false
if (drag.formats[0] === "application/vnd.qtdesignstudio.assets" && drag.hasUrls) {
accepted = EffectComposerBackend.rootView.isEffectAsset(drag.urls[0])
} else if (drag.formats[0] === "application/vnd.qtdesignstudio.modelnode.list") {
accepted = EffectComposerBackend.rootView.isEffectNode(
drag.getDataAsArrayBuffer("application/vnd.qtdesignstudio.modelnode.list"))
}
drag.accepted = accepted
}
onDropped: (drop) => {
if (drop.formats[0] === "application/vnd.qtdesignstudio.assets" && drop.hasUrls) {
EffectComposerBackend.rootView.dropAsset(drop.urls[0])
} else if (drop.formats[0] === "application/vnd.qtdesignstudio.modelnode.list") {
EffectComposerBackend.rootView.dropNode(
drop.getDataAsArrayBuffer("application/vnd.qtdesignstudio.modelnode.list"))
}
drop.accept()
}
}
} }

View File

@@ -10,16 +10,17 @@ import MaterialBrowserBackend
StudioControls.Menu { StudioControls.Menu {
id: root id: root
property var targetTexture: null property int textureInternalId: -1
property int copiedTextureInternalId: -1
property var materialBrowserTexturesModel: MaterialBrowserBackend.materialBrowserTexturesModel property var materialBrowserTexturesModel: MaterialBrowserBackend.materialBrowserTexturesModel
function popupMenu(targetTexture = null) function popupMenu(targetTexture = null)
{ {
this.targetTexture = targetTexture root.textureInternalId = targetTexture ? targetTexture.textureInternalId : -1
materialBrowserTexturesModel.updateSceneEnvState() materialBrowserTexturesModel.updateSceneEnvState()
materialBrowserTexturesModel.updateModelSelectionState() materialBrowserTexturesModel.updateModelSelectionState()
popup() popup()
} }
@@ -27,33 +28,33 @@ StudioControls.Menu {
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Apply to selected model") text: qsTr("Apply to selected model")
enabled: root.targetTexture && materialBrowserTexturesModel.hasSingleModelSelection enabled: root.textureInternalId >= 0 && materialBrowserTexturesModel.hasSingleModelSelection
onTriggered: materialBrowserTexturesModel.applyToSelectedModel(root.targetTexture.textureInternalId) onTriggered: materialBrowserTexturesModel.applyToSelectedModel(root.textureInternalId)
} }
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Apply to selected material") text: qsTr("Apply to selected material")
enabled: root.targetTexture && MaterialBrowserBackend.materialBrowserModel.selectedIndex >= 0 enabled: root.textureInternalId >= 0 && MaterialBrowserBackend.materialBrowserModel.selectedIndex >= 0
onTriggered: materialBrowserTexturesModel.applyToSelectedMaterial(root.targetTexture.textureInternalId) onTriggered: materialBrowserTexturesModel.applyToSelectedMaterial(root.textureInternalId)
} }
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Apply as light probe") text: qsTr("Apply as light probe")
enabled: root.targetTexture && materialBrowserTexturesModel.hasSceneEnv enabled: root.textureInternalId >= 0 && materialBrowserTexturesModel.hasSceneEnv
onTriggered: materialBrowserTexturesModel.applyAsLightProbe(root.targetTexture.textureInternalId) onTriggered: materialBrowserTexturesModel.applyAsLightProbe(root.textureInternalId)
} }
StudioControls.MenuSeparator {} StudioControls.MenuSeparator {}
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Duplicate") text: qsTr("Duplicate")
enabled: root.targetTexture enabled: root.textureInternalId >= 0
onTriggered: materialBrowserTexturesModel.duplicateTexture(materialBrowserTexturesModel.selectedIndex) onTriggered: materialBrowserTexturesModel.duplicateTexture(materialBrowserTexturesModel.selectedIndex)
} }
StudioControls.MenuItem { StudioControls.MenuItem {
text: qsTr("Delete") text: qsTr("Delete")
enabled: root.targetTexture enabled: root.textureInternalId >= 0
onTriggered: materialBrowserTexturesModel.deleteTexture(materialBrowserTexturesModel.selectedIndex) onTriggered: materialBrowserTexturesModel.deleteTexture(materialBrowserTexturesModel.selectedIndex)
} }

View File

@@ -0,0 +1,63 @@
// Copyright (C) 2024 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
StudioControls.PopupDialog {
id: colorPopup
property QtObject loaderItem: loader.item
property color originalColor
required property color currentColor
signal activateColor(color : color)
width: 260
onOriginalColorChanged: loader.updateOriginalColor()
onClosing: loader.active = false
function open(showItem) {
loader.ensureActive()
colorPopup.show(showItem)
loader.updateOriginalColor()
}
Loader {
id: loader
function ensureActive() {
if (!loader.active)
loader.active = true
}
function updateOriginalColor() {
if (loader.status === Loader.Ready)
loader.item.originalColor = colorPopup.originalColor
}
sourceComponent: StudioControls.ColorEditorPopup {
width: colorPopup.contentWidth
visible: colorPopup.visible
onActivateColor: (color) => {
colorPopup.activateColor(color)
}
}
Binding {
target: loader.item
property: "color"
value: colorPopup.currentColor
when: loader.status === Loader.Ready
}
onLoaded: {
loader.updateOriginalColor()
colorPopup.titleBar = loader.item.titleBarContent
}
}
}

View File

@@ -134,12 +134,16 @@ Item {
onPreviewEnvChanged: root.previewEnvChanged(previewEnv) onPreviewEnvChanged: root.previewEnvChanged(previewEnv)
onPreviewModelChanged: root.previewModelChanged(previewModel) onPreviewModelChanged: root.previewModelChanged(previewModel)
previewEnv: root.__previewEnv
previewModel: root.__previewModel
pinned: settings.dockMode pinned: settings.dockMode
showPinButton: !leftSideView.visible showPinButton: !leftSideView.visible
onPinnedChanged: settings.dockMode = previewItem.pinned onPinnedChanged: settings.dockMode = previewItem.pinned
Binding {
previewItem.previewEnv: root.__previewEnv
previewItem.previewModel: root.__previewModel
delayed: true
}
Connections { Connections {
target: root target: root

View File

@@ -45,6 +45,8 @@ Rectangle {
image.source = "image://materialEditor/preview" image.source = "image://materialEditor/preview"
} }
onPreviewEnvChanged: envMenu.updateEnvParams(root.previewEnv)
Image { Image {
id: image id: image
@@ -107,6 +109,7 @@ Rectangle {
StudioControls.Menu { StudioControls.Menu {
id: modelMenu id: modelMenu
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
ListModel { ListModel {
@@ -146,40 +149,111 @@ Rectangle {
StudioControls.Menu { StudioControls.Menu {
id: envMenu id: envMenu
property string previewEnvName
property string previewEnvValue
signal envParametersChanged()
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
ListModel { Component.onCompleted: envMenu.updateEnvParams(root.previewEnv)
id: envMenuModel
ListElement { function updateEnvParams(str: string) {
envName: qsTr("Basic") let eqFound = str.lastIndexOf("=")
envStr: "Basic" let newEnvName = (eqFound > 0) ? str.substr(0, eqFound) : str
} let newEnvValue = (eqFound > 0) ? str.substr(eqFound + 1, str.length - eqFound) : ""
ListElement {
envName: qsTr("Color") if (envMenu.previewEnvName !== newEnvName
envStr: "Color" || envMenu.previewEnvValue !== newEnvValue) {
} envMenu.previewEnvName = newEnvName
ListElement { envMenu.previewEnvValue = newEnvValue
envName: qsTr("Studio") envMenu.envParametersChanged()
envStr: "SkyBox=preview_studio"
}
ListElement {
envName: qsTr("Landscape")
envStr: "SkyBox=preview_landscape"
} }
} }
Repeater { EnvMenuItem {
model: envMenuModel envName: qsTr("Basic")
StudioControls.MenuItemWithIcon { envStr: "Basic"
text: envName }
onClicked: {
// Force property change notifications to keep check mark when reselected EnvMenuItem {
root.previewEnv = "" id: colorItem
root.previewEnv = envStr
property color color
property bool colorIsValid: false
envName: qsTr("Color")
envStr: "Color"
checked: false
Component.onCompleted: update()
onColorIsValidChanged: updatePopupOriginalColor()
onClicked: {
colorItem.updatePopupOriginalColor()
colorPopup.open(colorItem)
}
onColorChanged: {
colorItem.envStr = colorItem.checked
? "Color=" + color.toString()
: "Color"
colorItem.commit()
}
function updatePopupOriginalColor() {
if (colorItem.colorIsValid)
colorPopup.originalColor = colorItem.color
}
function update() {
colorItem.checked = envMenu.previewEnvName === "Color"
if (colorItem.checked && envMenu.previewEnvValue) {
colorItem.color = envMenu.previewEnvValue
colorItem.colorIsValid = true
} else {
colorItem.colorIsValid = false
}
}
Connections {
target: envMenu
function onEnvParametersChanged() {
colorItem.update();
} }
checkable: true
checked: root.previewEnv === envStr
} }
} }
EnvMenuItem {
envName: qsTr("Studio")
envStr: "SkyBox=preview_studio"
}
EnvMenuItem {
envName: qsTr("Landscape")
envStr: "SkyBox=preview_landscape"
}
}
ColorEditorPopup {
id: colorPopup
currentColor: colorItem.color
onActivateColor: (color) => colorItem.color = color
}
component EnvMenuItem: StudioControls.MenuItemWithIcon {
required property string envName
property string envStr
function commit() {
root.previewEnv = envStr
}
text: envName
onClicked: commit()
checkable: false
checked: root.previewEnv === envStr
} }
} }

View File

@@ -321,7 +321,7 @@ Item {
visible: true visible: true
buttonIcon: qsTr("Cancel") buttonIcon: qsTr("Cancel")
iconSize: DialogValues.defaultPixelSize iconSize: DialogValues.defaultPixelSize
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
onClicked: { onClicked: {
BackendApi.reject(); BackendApi.reject();
@@ -337,7 +337,7 @@ Item {
buttonIcon: qsTr("Create") buttonIcon: qsTr("Create")
iconSize: DialogValues.defaultPixelSize iconSize: DialogValues.defaultPixelSize
enabled: BackendApi.fieldsValid enabled: BackendApi.fieldsValid
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
onClicked: { onClicked: {
BackendApi.accept(); BackendApi.accept();

View File

@@ -121,7 +121,7 @@ Item {
iconSize: 20 iconSize: 20
visible: true visible: true
buttonIcon: "…" buttonIcon: "…"
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
onClicked: { onClicked: {
var newLocation = BackendApi.chooseProjectLocation() var newLocation = BackendApi.chooseProjectLocation()
@@ -439,8 +439,9 @@ Item {
id: savePresetButton id: savePresetButton
width: StudioTheme.Values.singleControlColumnWidth width: StudioTheme.Values.singleControlColumnWidth
buttonIcon: qsTr("Save Custom Preset") buttonIcon: qsTr("Save Custom Preset")
iconFont: StudioTheme.Constants.font
iconSize: DialogValues.defaultPixelSize iconSize: DialogValues.defaultPixelSize
iconFontFamily: StudioTheme.Constants.font.family
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -337,7 +337,6 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Warning") text: qsTr("Warning")
visible: root.warningVisible visible: root.warningVisible
font.weight: Font.Bold
} }
SecondColumnLayout { SecondColumnLayout {
@@ -354,7 +353,7 @@ Section {
Layout.fillWidth: true Layout.fillWidth: true
font.family: StudioTheme.Constants.font.family font.family: StudioTheme.Constants.font.family
font.pixelSize: StudioTheme.Values.myFontSize font.pixelSize: StudioTheme.Values.myFontSize
color: StudioTheme.Values.themeTextColor color: StudioTheme.Values.themeAmberLight
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: qsTr("- The selection contains the root component.") text: qsTr("- The selection contains the root component.")
} }
@@ -365,7 +364,7 @@ Section {
Layout.fillWidth: true Layout.fillWidth: true
font.family: StudioTheme.Constants.font.family font.family: StudioTheme.Constants.font.family
font.pixelSize: StudioTheme.Values.myFontSize font.pixelSize: StudioTheme.Values.myFontSize
color: StudioTheme.Values.themeTextColor color: StudioTheme.Values.themeAmberLight
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: qsTr("- The selection contains a non-visual component.") text: qsTr("- The selection contains a non-visual component.")
} }
@@ -376,7 +375,7 @@ Section {
Layout.fillWidth: true Layout.fillWidth: true
font.family: StudioTheme.Constants.font.family font.family: StudioTheme.Constants.font.family
font.pixelSize: StudioTheme.Values.myFontSize font.pixelSize: StudioTheme.Values.myFontSize
color: StudioTheme.Values.themeTextColor color: StudioTheme.Values.themeAmberLight
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: qsTr("- A component in the selection uses anchors.") text: qsTr("- A component in the selection uses anchors.")
} }

View File

@@ -62,7 +62,7 @@ Section {
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
width: StudioTheme.Values.singleControlColumnWidth width: StudioTheme.Values.singleControlColumnWidth
buttonIcon: root.hasDesignerEffect ? qsTr("Remove Effects") : qsTr("Add Effects") buttonIcon: root.hasDesignerEffect ? qsTr("Remove Effects") : qsTr("Add Effects")
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
tooltip: qsTr("Adds visual effects on the component.") tooltip: qsTr("Adds visual effects on the component.")
onClicked: { onClicked: {
if (root.hasDesignerEffect) { if (root.hasDesignerEffect) {
@@ -535,7 +535,7 @@ Section {
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
width: StudioTheme.Values.singleControlColumnWidth width: StudioTheme.Values.singleControlColumnWidth
buttonIcon: qsTr("Add Shadow Effect") buttonIcon: qsTr("Add Shadow Effect")
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
tooltip: qsTr("Adds <b>Drop Shadow</b> or <b>Inner Shadow</b> effects to a component.") tooltip: qsTr("Adds <b>Drop Shadow</b> or <b>Inner Shadow</b> effects to a component.")
onClicked: { onClicked: {
modelNodeBackend.createModelNode(root.effectNode, modelNodeBackend.createModelNode(root.effectNode,

View File

@@ -39,7 +39,7 @@ SecondColumnLayout {
property bool shapeGradients: false property bool shapeGradients: false
//for now, gradients on MCUs are limited to Basic and Shape Linear Gradient: // Gradients on MCUs are limited to Basic and Shape Linear Gradient.
property bool mcuGradients: false property bool mcuGradients: false
property color originalColor property color originalColor
@@ -91,9 +91,9 @@ SecondColumnLayout {
if (colorEditor.backendValue !== undefined) { if (colorEditor.backendValue !== undefined) {
if (colorEditor.isVector3D) if (colorEditor.isVector3D)
colorEditor.backendValue.value = Qt.vector3d( colorEditor.backendValue.value = Qt.vector3d(colorEditor.color.r,
colorEditor.color.r, colorEditor.color.g, colorEditor.color.g,
colorEditor.color.b) colorEditor.color.b)
else else
colorEditor.backendValue.value = colorEditor.color colorEditor.backendValue.value = colorEditor.color
} }
@@ -223,10 +223,8 @@ SecondColumnLayout {
function open() { function open() {
popupDialog.ensureLoader() popupDialog.ensureLoader()
popupDialog.show(preview) popupDialog.show(preview)
popupDialog.loaderItem.aboutToBeShown() // need it for now
popupDialog.loaderItem.aboutToBeShown() //need it for now
} }
function determineActiveColorMode() { function determineActiveColorMode() {

View File

@@ -12,10 +12,9 @@ import QtQuickDesignerColorPalette
Column { Column {
id: root id: root
// There seems to be an issue on Windows and MacOS with ColorPickers // There seems to be an issue on Windows and macOS with ColorPickers canvas not being painted
// Canvases not being painted on initialization // on initialization, because ColorEditorPopup is invisible at init time, so we use this signal
// because ColorEditorPopup is invisible at init time, // to explicitly pass visibility status.
// so we use this signal to explicitly pass visibility status
signal aboutToBeShown signal aboutToBeShown
property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive
@@ -23,7 +22,7 @@ Column {
property bool supportGradient: false property bool supportGradient: false
property bool shapeGradients: false property bool shapeGradients: false
//for now, gradients on MCUs are limited to Basic and Shape Linear Gradient: // Gradients on MCUs are limited to Basic and Shape Linear Gradient.
property bool mcuGradients: false property bool mcuGradients: false
property alias gradientLine: gradientLine property alias gradientLine: gradientLine
@@ -188,7 +187,7 @@ Column {
icon: StudioTheme.Constants.eyeDropper icon: StudioTheme.Constants.eyeDropper
pixelSize: StudioTheme.Values.myIconFontSize * 1.4 pixelSize: StudioTheme.Values.myIconFontSize * 1.4
tooltip: qsTr("Eye Dropper") tooltip: qsTr("Eye Dropper")
onClicked: ColorPaletteBackend.eyeDropper() onClicked: ColorPaletteBackend.invokeEyeDropper()
} }
} }

View File

@@ -28,7 +28,7 @@ Column {
AbstractButton { AbstractButton {
implicitWidth: 180 implicitWidth: 180
buttonIcon: qsTr("Edit Component") buttonIcon: qsTr("Edit Component")
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
onClicked: goIntoComponent() onClicked: goIntoComponent()
} }

View File

@@ -246,7 +246,7 @@ Section {
width: StudioTheme.Values.singleControlColumnWidth width: StudioTheme.Values.singleControlColumnWidth
visible: !annotationEditor.hasAuxData visible: !annotationEditor.hasAuxData
buttonIcon: qsTr("Add Annotation") buttonIcon: qsTr("Add Annotation")
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
tooltip: qsTr("Adds a note with a title to explain the component.") tooltip: qsTr("Adds a note with a title to explain the component.")
onClicked: annotationEditor.showWidget() onClicked: annotationEditor.showWidget()
onHoveredChanged: annotationEditor.checkAux() onHoveredChanged: annotationEditor.checkAux()

View File

@@ -732,7 +732,7 @@ Section {
id: acceptButton id: acceptButton
buttonIcon: qsTr("Add Property") buttonIcon: qsTr("Add Property")
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
width: cePopup.width / 3 width: cePopup.width / 3
enabled: textField.acceptableInput enabled: textField.acceptableInput

View File

@@ -8,7 +8,7 @@ import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme import StudioTheme 1.0 as StudioTheme
Section { Section {
id: fontSection id: root
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
caption: qsTr("Font") caption: qsTr("Font")
@@ -16,19 +16,20 @@ Section {
property string fontName: "font" property string fontName: "font"
property bool showStyle: false property bool showStyle: false
property bool showHinting: true
function getBackendValue(name) { function getBackendValue(name) {
return backendValues[fontSection.fontName + "_" + name] return backendValues[root.fontName + "_" + name]
} }
property variant fontFamily: getBackendValue("family") property variant fontFamily: root.getBackendValue("family")
property variant pointSize: getBackendValue("pointSize") property variant pointSize: root.getBackendValue("pointSize")
property variant pixelSize: getBackendValue("pixelSize") property variant pixelSize: root.getBackendValue("pixelSize")
property variant boldStyle: getBackendValue("bold") property variant boldStyle: root.getBackendValue("bold")
property variant italicStyle: getBackendValue("italic") property variant italicStyle: root.getBackendValue("italic")
property variant underlineStyle: getBackendValue("underline") property variant underlineStyle: root.getBackendValue("underline")
property variant strikeoutStyle: getBackendValue("strikeout") property variant strikeoutStyle: root.getBackendValue("strikeout")
onPointSizeChanged: sizeWidget.setPointPixelSize() onPointSizeChanged: sizeWidget.setPointPixelSize()
onPixelSizeChanged: sizeWidget.setPointPixelSize() onPixelSizeChanged: sizeWidget.setPointPixelSize()
@@ -42,11 +43,13 @@ Section {
SecondColumnLayout { SecondColumnLayout {
FontComboBox { FontComboBox {
id: fontComboBox id: fontComboBox
property string familyName: backendValue.value
backendValue: fontSection.fontFamily property string familyName: fontComboBox.backendValue.value
backendValue: root.fontFamily
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: fontComboBox.implicitWidth
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -59,8 +62,8 @@ Section {
SecondColumnLayout { SecondColumnLayout {
id: sizeWidget id: sizeWidget
property bool selectionFlag: selectionChanged
property bool selectionFlag: selectionChanged
property bool pixelSize: sizeType.currentText === "px" property bool pixelSize: sizeType.currentText === "px"
property bool isSetup property bool isSetup
@@ -68,7 +71,7 @@ Section {
sizeWidget.isSetup = true sizeWidget.isSetup = true
sizeType.currentIndex = 1 sizeType.currentIndex = 1
if (fontSection.pixelSize.isInModel) if (root.pixelSize.isInModel)
sizeType.currentIndex = 0 sizeType.currentIndex = 0
sizeWidget.isSetup = false sizeWidget.isSetup = false
@@ -77,31 +80,33 @@ Section {
onSelectionFlagChanged: sizeWidget.setPointPixelSize() onSelectionFlagChanged: sizeWidget.setPointPixelSize()
Item { Item {
id: sizeSpinBoxItem
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: sizeSpinBoxItem.implicitWidth
height: sizeSpinBox.height height: sizeSpinBoxPoint.height
SpinBox { SpinBox {
id: sizeSpinBox id: sizeSpinBoxPoint
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: sizeSpinBoxPoint.implicitWidth
minimumValue: 0 minimumValue: 0
visible: !sizeWidget.pixelSize visible: !sizeWidget.pixelSize
z: !sizeWidget.pixelSize ? 1 : 0 z: !sizeWidget.pixelSize ? 1 : 0
maximumValue: 400 maximumValue: 400
backendValue: pointSize backendValue: root.pointSize
} }
SpinBox { SpinBox {
id: sizeSpinBoxPixel
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: sizeSpinBoxPixel.implicitWidth
minimumValue: 0 minimumValue: 0
visible: sizeWidget.pixelSize visible: sizeWidget.pixelSize
z: sizeWidget.pixelSize ? 1 : 0 z: sizeWidget.pixelSize ? 1 : 0
maximumValue: 400 maximumValue: 400
backendValue: pixelSize backendValue: root.pixelSize
} }
} }
@@ -113,7 +118,7 @@ Section {
StudioControls.ComboBox { StudioControls.ComboBox {
id: sizeType id: sizeType
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
width: implicitWidth width: sizeType.implicitWidth
model: ["px", "pt"] model: ["px", "pt"]
actionIndicatorVisible: false actionIndicatorVisible: false
@@ -122,10 +127,10 @@ Section {
return return
if (sizeType.currentText === "px") { if (sizeType.currentText === "px") {
pointSize.resetValue() root.pointSize.resetValue()
pixelSize.value = 8 root.pixelSize.value = 8
} else { } else {
pixelSize.resetValue() root.pixelSize.resetValue()
} }
} }
} }
@@ -136,35 +141,36 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Emphasis") text: qsTr("Emphasis")
tooltip: qsTr("Sets the text to bold, italic, underlined, or strikethrough.") tooltip: qsTr("Sets the text to bold, italic, underlined, or strikethrough.")
blockedByTemplate: !fontSection.boldStyle.isAvailable blockedByTemplate: !root.boldStyle.isAvailable
&& !fontSection.italicStyle.isAvailable && !root.italicStyle.isAvailable
&& !fontSection.underlineStyle.isAvailable && !root.underlineStyle.isAvailable
&& !fontSection.strikeoutStyle.isAvailable && !root.strikeoutStyle.isAvailable
} }
FontStyleButtons { FontStyleButtons {
bold: fontSection.boldStyle bold: root.boldStyle
italic: fontSection.italicStyle italic: root.italicStyle
underline: fontSection.underlineStyle underline: root.underlineStyle
strikeout: fontSection.strikeoutStyle strikeout: root.strikeoutStyle
enabled: !styleNameComboBox.styleSet enabled: !styleNameComboBox.styleSet
} }
PropertyLabel { PropertyLabel {
text: qsTr("Capitalization") text: qsTr("Capitalization")
tooltip: qsTr("Sets capitalization rules for the text.") tooltip: qsTr("Sets capitalization rules for the text.")
blockedByTemplate: !getBackendValue("capitalization").isAvailable blockedByTemplate: !root.getBackendValue("capitalization").isAvailable
} }
SecondColumnLayout { SecondColumnLayout {
ComboBox { ComboBox {
id: capitalizationComboBox
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: capitalizationComboBox.implicitWidth
backendValue: getBackendValue("capitalization") backendValue: root.getBackendValue("capitalization")
scope: "Font" scope: "Font"
model: ["MixedCase", "AllUppercase", "AllLowercase", "SmallCaps", "Capitalize"] model: ["MixedCase", "AllUppercase", "AllLowercase", "SmallCaps", "Capitalize"]
enabled: backendValue.isAvailable enabled: capitalizationComboBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -178,10 +184,11 @@ Section {
SecondColumnLayout { SecondColumnLayout {
ComboBox { ComboBox {
id: weightComboBox
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: weightComboBox.implicitWidth
backendValue: getBackendValue("weight") backendValue: root.getBackendValue("weight")
model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"] model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"]
scope: "Font" scope: "Font"
enabled: !styleNameComboBox.styleSet enabled: !styleNameComboBox.styleSet
@@ -199,38 +206,41 @@ Section {
SecondColumnLayout { SecondColumnLayout {
ComboBox { ComboBox {
id: styleNameComboBox id: styleNameComboBox
property bool styleSet: backendValue.isInModel property bool styleSet: backendValue.isInModel
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: styleNameComboBox.implicitWidth
backendValue: getBackendValue("styleName") backendValue: root.getBackendValue("styleName")
model: styleNamesForFamily(fontComboBox.familyName) model: styleNamesForFamily(fontComboBox.familyName)
valueType: ComboBox.String valueType: ComboBox.String
enabled: backendValue.isAvailable enabled: styleNameComboBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
} }
PropertyLabel { PropertyLabel {
visible: fontSection.showStyle visible: root.showStyle
text: qsTr("Style") text: qsTr("Style")
tooltip: qsTr("Sets the font style.") tooltip: qsTr("Sets the font style.")
blockedByTemplate: !styleComboBox.enabled blockedByTemplate: !styleComboBox.enabled
} }
SecondColumnLayout { SecondColumnLayout {
visible: fontSection.showStyle visible: root.showStyle
ComboBox { ComboBox {
id: styleComboBox id: styleComboBox
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: styleComboBox.implicitWidth
backendValue: (backendValues.style === undefined) ? dummyBackendValue backendValue: (backendValues.style === undefined) ? dummyBackendValue
: backendValues.style : backendValues.style
scope: "Text" scope: "Text"
model: ["Normal", "Outline", "Raised", "Sunken"] model: ["Normal", "Outline", "Raised", "Sunken"]
enabled: backendValue.isAvailable enabled: styleComboBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -239,30 +249,34 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Style color") text: qsTr("Style color")
tooltip: qsTr("Sets the color for the font style.") tooltip: qsTr("Sets the color for the font style.")
visible: fontSection.showStyle && backendValues.styleColor.isAvailable visible: root.showStyle && backendValues.styleColor.isAvailable
} }
ColorEditor { ColorEditor {
visible: fontSection.showStyle && backendValues.styleColor.isAvailable visible: root.showStyle && backendValues.styleColor.isAvailable
backendValue: backendValues.styleColor backendValue: backendValues.styleColor
supportGradient: false supportGradient: false
} }
PropertyLabel { PropertyLabel {
visible: root.showHinting
text: qsTr("Hinting") text: qsTr("Hinting")
tooltip: qsTr("Sets how to interpolate the text to render it more clearly when scaled.") tooltip: qsTr("Sets how to interpolate the text to render it more clearly when scaled.")
blockedByTemplate: !getBackendValue("hintingPreference").isAvailable blockedByTemplate: !root.getBackendValue("hintingPreference").isAvailable
} }
SecondColumnLayout { SecondColumnLayout {
visible: root.showHinting
ComboBox { ComboBox {
id: hintingPreferenceComboBox
implicitWidth: StudioTheme.Values.singleControlColumnWidth implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
width: implicitWidth width: hintingPreferenceComboBox.implicitWidth
backendValue: getBackendValue("hintingPreference") backendValue: root.getBackendValue("hintingPreference")
scope: "Font" scope: "Font"
model: ["PreferDefaultHinting", "PreferNoHinting", "PreferVerticalHinting", "PreferFullHinting"] model: ["PreferDefaultHinting", "PreferNoHinting", "PreferVerticalHinting", "PreferFullHinting"]
enabled: backendValue.isAvailable enabled: hintingPreferenceComboBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -271,19 +285,20 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Letter spacing") text: qsTr("Letter spacing")
tooltip: qsTr("Sets the letter spacing for the text.") tooltip: qsTr("Sets the letter spacing for the text.")
blockedByTemplate: !getBackendValue("letterSpacing").isAvailable blockedByTemplate: !root.getBackendValue("letterSpacing").isAvailable
} }
SecondColumnLayout { SecondColumnLayout {
SpinBox { SpinBox {
id: letterSpacingSpinBox
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
backendValue: getBackendValue("letterSpacing") backendValue: root.getBackendValue("letterSpacing")
decimals: 2 decimals: 2
minimumValue: -500 minimumValue: -500
maximumValue: 500 maximumValue: 500
stepSize: 0.1 stepSize: 0.1
enabled: backendValue.isAvailable enabled: letterSpacingSpinBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -292,19 +307,20 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Word spacing") text: qsTr("Word spacing")
tooltip: qsTr("Sets the word spacing for the text.") tooltip: qsTr("Sets the word spacing for the text.")
blockedByTemplate: !getBackendValue("wordSpacing").isAvailable blockedByTemplate: !root.getBackendValue("wordSpacing").isAvailable
} }
SecondColumnLayout { SecondColumnLayout {
SpinBox { SpinBox {
id: wordSpacingSpinBox
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
backendValue: getBackendValue("wordSpacing") backendValue: root.getBackendValue("wordSpacing")
decimals: 2 decimals: 2
minimumValue: -500 minimumValue: -500
maximumValue: 500 maximumValue: 500
stepSize: 0.1 stepSize: 0.1
enabled: backendValue.isAvailable enabled: wordSpacingSpinBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -313,16 +329,17 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Auto kerning") text: qsTr("Auto kerning")
tooltip: qsTr("Resolves the gap between texts if turned true.") tooltip: qsTr("Resolves the gap between texts if turned true.")
blockedByTemplate: !getBackendValue("kerning").isAvailable blockedByTemplate: !root.getBackendValue("kerning").isAvailable
} }
SecondColumnLayout { SecondColumnLayout {
CheckBox { CheckBox {
text: backendValue.valueToString id: kerningCheckBox
text: kerningCheckBox.backendValue.valueToString
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
backendValue: getBackendValue("kerning") backendValue: root.getBackendValue("kerning")
enabled: backendValue.isAvailable enabled: kerningCheckBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}
@@ -331,16 +348,17 @@ Section {
PropertyLabel { PropertyLabel {
text: qsTr("Prefer shaping") text: qsTr("Prefer shaping")
tooltip: qsTr("Toggles the disables font-specific special features.") tooltip: qsTr("Toggles the disables font-specific special features.")
blockedByTemplate: !getBackendValue("preferShaping").isAvailable blockedByTemplate: !root.getBackendValue("preferShaping").isAvailable
} }
SecondColumnLayout { SecondColumnLayout {
CheckBox { CheckBox {
text: backendValue.valueToString id: preferShapingCheckBox
text: preferShapingCheckBox.backendValue.valueToString
implicitWidth: StudioTheme.Values.twoControlColumnWidth implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth + StudioTheme.Values.actionIndicatorWidth
backendValue: getBackendValue("preferShaping") backendValue: root.getBackendValue("preferShaping")
enabled: backendValue.isAvailable enabled: preferShapingCheckBox.backendValue.isAvailable
} }
ExpandingSpacer {} ExpandingSpacer {}

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
import QtQuick import QtQuick
import HelperWidgets 2.0 as HelperWidgets import HelperWidgets as HelperWidgets
HelperWidgets.ComboBox { HelperWidgets.ComboBox {
id: comboBox id: comboBox
@@ -15,7 +15,10 @@ HelperWidgets.ComboBox {
valueRole: "id" valueRole: "id"
textRole: (comboBox.typeFilter === "QtQuick3D.Texture") ? "idAndName" : "id" textRole: (comboBox.typeFilter === "QtQuick3D.Texture") ? "idAndName" : "id"
validator: RegularExpressionValidator { regularExpression: /(^$|^[a-z_]\w*)/ } validator: RegularExpressionValidator {
regularExpression: (comboBox.textRole !== "id") ? /^(\w+\s)*\w+\s\[[a-z_]\w*\]/
: /(^$|^[a-z_]\w*)/
}
HelperWidgets.ItemFilterModel { HelperWidgets.ItemFilterModel {
id: itemFilterModel id: itemFilterModel
@@ -89,8 +92,8 @@ HelperWidgets.ComboBox {
comboBox.backendValue.resetValue() comboBox.backendValue.resetValue()
} else { } else {
let valueData = (comboBox.valueRole === "") let valueData = (comboBox.valueRole === "")
? comboBox.editText ? comboBox.editText
: itemFilterModel.modelItemData(comboBox.currentIndex - 1)[comboBox.valueRole] : comboBox.model[comboBox.currentIndex][comboBox.valueRole]
if (comboBox.backendValue.expression !== valueData) if (comboBox.backendValue.expression !== valueData)
comboBox.backendValue.expression = valueData comboBox.backendValue.expression = valueData
@@ -98,28 +101,29 @@ HelperWidgets.ComboBox {
comboBox.dirty = false comboBox.dirty = false
} }
Repeater { QtObject {
id: optionsList id: optionsList
property var localModel: [] property var model
function updateModel() { function updateModel() {
optionsList.localModel = [] let localModel = []
if (comboBox.textRole !== "" && comboBox.valueRole !== "") { if (comboBox.textRole !== "") {
let defaultItem = {} let defaultItem = {}
defaultItem[comboBox.textRole] = comboBox.defaultItem defaultItem[comboBox.textRole] = comboBox.defaultItem
defaultItem[comboBox.valueRole] = "" if (comboBox.valueRole !== "" && comboBox.textRole !== comboBox.valueRole)
optionsList.localModel.push(defaultItem) defaultItem[comboBox.valueRole] = ""
localModel.push(defaultItem)
} else { } else {
optionsList.localModel.push(comboBox.defaultItem) localModel.push(comboBox.defaultItem)
} }
let rows = itemFilterModel.rowCount() let rows = itemFilterModel.rowCount()
for (let i = 0; i < rows; ++i) for (let i = 0; i < rows; ++i)
optionsList.localModel.push(itemFilterModel.modelItemData(i)) localModel.push(itemFilterModel.modelItemData(i))
optionsList.model = optionsList.localModel // trigger on change handler optionsList.model = localModel // trigger on change handler
} }
} }
} }

View File

@@ -3,7 +3,7 @@
import QtQuick import QtQuick
import QtQuick.Templates as T import QtQuick.Templates as T
import StudioTheme 1.0 as StudioTheme import StudioTheme as StudioTheme
T.AbstractButton { T.AbstractButton {
id: control id: control
@@ -16,8 +16,10 @@ T.AbstractButton {
property alias buttonIcon: buttonIcon.text property alias buttonIcon: buttonIcon.text
property alias iconColor: buttonIcon.color property alias iconColor: buttonIcon.color
property alias iconFont: buttonIcon.font.family
property alias iconSize: buttonIcon.font.pixelSize property string iconFontFamily: StudioTheme.Constants.iconFont.family
property int iconSize: control.style.baseIconFontSize
property alias iconItalic: buttonIcon.font.italic property alias iconItalic: buttonIcon.font.italic
property alias iconBold: buttonIcon.font.bold property alias iconBold: buttonIcon.font.bold
property alias iconRotation: buttonIcon.rotation property alias iconRotation: buttonIcon.rotation
@@ -58,8 +60,10 @@ T.AbstractButton {
T.Label { T.Label {
id: buttonIcon id: buttonIcon
color: control.style.icon.idle color: control.style.icon.idle
font.family: StudioTheme.Constants.iconFont.family font {
font.pixelSize: control.style.baseIconFontSize family: control.iconFontFamily
pixelSize: control.iconSize
}
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
anchors.fill: parent anchors.fill: parent
@@ -111,6 +115,34 @@ T.AbstractButton {
} }
} }
function highlight() {
// Only run the highlight animation if not running already and if default state is active
if (highlightAnimation.running || control.state !== "default")
return
highlightAnimation.start()
}
component MyColorAnimation: ColorAnimation {
target: buttonBackground
property: "color"
duration: 750
}
SequentialAnimation {
id: highlightAnimation
running: false
MyColorAnimation { to: StudioTheme.Values.themeConnectionEditorButtonBorder_hover }
MyColorAnimation { to: control.style.background.idle }
MyColorAnimation { to: StudioTheme.Values.themeConnectionEditorButtonBorder_hover }
MyColorAnimation { to: control.style.background.idle }
MyColorAnimation { to: StudioTheme.Values.themeConnectionEditorButtonBorder_hover }
MyColorAnimation { to: control.style.background.idle }
}
onStateChanged: highlightAnimation.stop()
states: [ states: [
State { State {
name: "default" name: "default"

View File

@@ -69,6 +69,8 @@ Item {
property QtObject loaderItem: loader.item property QtObject loaderItem: loader.item
keepOpen: loader.item?.eyeDropperActive ?? false
width: 260 width: 260
function ensureLoader() { function ensureLoader() {
@@ -91,6 +93,7 @@ Item {
id: popup id: popup
width: popupDialog.contentWidth width: popupDialog.contentWidth
visible: popupDialog.visible visible: popupDialog.visible
parentWindow: popupDialog.window
onActivateColor: function(color) { onActivateColor: function(color) {
colorBackend.activateColor(color) colorBackend.activateColor(color)

View File

@@ -131,23 +131,23 @@ T.ComboBox {
delegate: ItemDelegate { delegate: ItemDelegate {
id: itemDelegate id: itemDelegate
required property var model
required property int index
width: comboBoxPopup.width - comboBoxPopup.leftPadding - comboBoxPopup.rightPadding width: comboBoxPopup.width - comboBoxPopup.leftPadding - comboBoxPopup.rightPadding
height: control.style.controlSize.height - 2 * control.style.borderWidth height: control.style.controlSize.height - 2 * control.style.borderWidth
padding: 0 padding: 0
enabled: model.enabled === undefined ? true : model.enabled enabled: itemDelegate.model["enabled"] === undefined ? true : itemDelegate.model["enabled"]
contentItem: Text { contentItem: Text {
leftPadding: 8 leftPadding: 8
rightPadding: verticalScrollBar.style.scrollBarThicknessHover rightPadding: verticalScrollBar.style.scrollBarThicknessHover
text: control.textRole ? (Array.isArray(control.model) text: itemDelegate.model[control.textRole]
? modelData[control.textRole]
: model[control.textRole])
: modelData
color: { color: {
if (!itemDelegate.enabled) if (!itemDelegate.enabled)
return control.style.text.disabled return control.style.text.disabled
if (control.currentIndex === index) if (control.currentIndex === itemDelegate.index)
return control.style.text.selectedText return control.style.text.selectedText
return control.style.text.idle return control.style.text.idle
@@ -158,10 +158,7 @@ T.ComboBox {
ToolTipArea { ToolTipArea {
anchors.fill: parent anchors.fill: parent
text: control.tooltipRole ? (Array.isArray(control.model) text: control.tooltipRole ? itemDelegate.model[control.tooltipRole] : ""
? modelData[control.tooltipRole]
: model[control.tooltipRole])
: ""
enabled: text enabled: text
onClicked: itemDelegate.clicked() onClicked: itemDelegate.clicked()
onDoubleClicked: itemDelegate.doubleClicked() onDoubleClicked: itemDelegate.doubleClicked()

View File

@@ -45,7 +45,7 @@ QtObject {
window.raise() window.raise()
} }
function show(target: Item) { function show(target: Item): void {
var originGlobal = target.mapToGlobal(0, 0) var originGlobal = target.mapToGlobal(0, 0)
root.__itemGlobal = Qt.rect(originGlobal.x, originGlobal.y, target.width, target.height) root.__itemGlobal = Qt.rect(originGlobal.x, originGlobal.y, target.width, target.height)
//root.chevronVisible = true //root.chevronVisible = true
@@ -154,7 +154,7 @@ QtObject {
return true return true
} }
function getRegions(source: rect, target: rect) { function getRegions(source: rect, target: rect): var {
var edges = {} var edges = {}
// Overlaps or Inside // Overlaps or Inside
@@ -229,7 +229,7 @@ QtObject {
return edges return edges
} }
function popoverGeometry(edge: int, anchor: point, region: rect) { function popoverGeometry(edge: int, anchor: point, region: rect): rect {
if (edge === Qt.TopEdge) { if (edge === Qt.TopEdge) {
let height = Math.min(window.height, region.height) let height = Math.min(window.height, region.height)
return Qt.rect(Math.max(region.x, return Qt.rect(Math.max(region.x,

View File

@@ -3,7 +3,8 @@
import QtQuick import QtQuick
import QtQuick.Templates as T import QtQuick.Templates as T
import StudioTheme 1.0 as StudioTheme import StudioTheme as StudioTheme
import StudioQuickUtils
T.SpinBox { T.SpinBox {
id: control id: control
@@ -71,6 +72,8 @@ T.SpinBox {
signal dragging signal dragging
signal indicatorPressed signal indicatorPressed
locale: Utils.locale
// Use custom wheel handling due to bugs // Use custom wheel handling due to bugs
property bool __wheelEnabled: false property bool __wheelEnabled: false
wheelEnabled: false wheelEnabled: false
@@ -97,7 +100,7 @@ T.SpinBox {
DoubleValidator { DoubleValidator {
id: doubleValidator id: doubleValidator
locale: control.locale.name locale: control.locale
notation: DoubleValidator.StandardNotation notation: DoubleValidator.StandardNotation
decimals: control.decimals decimals: control.decimals
bottom: Math.min(control.realFrom, control.realTo) bottom: Math.min(control.realFrom, control.realTo)
@@ -106,7 +109,7 @@ T.SpinBox {
IntValidator { IntValidator {
id: intValidator id: intValidator
locale: control.locale.name locale: control.locale
bottom: Math.round(Math.min(control.realFrom, control.realTo)) bottom: Math.round(Math.min(control.realFrom, control.realTo))
top: Math.round(Math.max(control.realFrom, control.realTo)) top: Math.round(Math.max(control.realFrom, control.realTo))
} }

View File

@@ -3,7 +3,8 @@
import QtQuick import QtQuick
import QtQuick.Templates as T import QtQuick.Templates as T
import StudioTheme 1.0 as StudioTheme import StudioTheme as StudioTheme
import StudioQuickUtils
T.SpinBox { T.SpinBox {
id: control id: control
@@ -54,6 +55,8 @@ T.SpinBox {
signal dragEnded signal dragEnded
signal dragging signal dragging
locale: Utils.locale
// Use custom wheel handling due to bugs // Use custom wheel handling due to bugs
property bool __wheelEnabled: false property bool __wheelEnabled: false
wheelEnabled: false wheelEnabled: false
@@ -76,7 +79,7 @@ T.SpinBox {
DoubleValidator { DoubleValidator {
id: doubleValidator id: doubleValidator
locale: control.locale.name locale: control.locale
notation: DoubleValidator.StandardNotation notation: DoubleValidator.StandardNotation
decimals: control.decimals decimals: control.decimals
bottom: Math.min(control.from, control.to) / control.factor bottom: Math.min(control.from, control.to) / control.factor
@@ -85,7 +88,7 @@ T.SpinBox {
IntValidator { IntValidator {
id: intValidator id: intValidator
locale: control.locale.name locale: control.locale
bottom: Math.min(control.from, control.to) bottom: Math.min(control.from, control.to)
top: Math.max(control.from, control.to) top: Math.max(control.from, control.to)
} }

View File

@@ -156,6 +156,9 @@ T.ComboBox {
delegate: ItemDelegate { delegate: ItemDelegate {
id: itemDelegate id: itemDelegate
required property var model
required property int index
onClicked: { onClicked: {
// Necessary to keep the transient parent open otherwise it will change the focus // Necessary to keep the transient parent open otherwise it will change the focus
// to the main window "Utils::AppMainWindowClassWindow" and closes the transient // to the main window "Utils::AppMainWindowClassWindow" and closes the transient
@@ -169,15 +172,12 @@ T.ComboBox {
width: control.width width: control.width
height: control.style.controlSize.height height: control.style.controlSize.height
padding: 0 padding: 0
enabled: model.enabled === undefined ? true : model.enabled enabled: itemDelegate.model["enabled"] === undefined ? true : itemDelegate.model["enabled"]
contentItem: Text { contentItem: Text {
leftPadding: 8 leftPadding: 8
rightPadding: verticalScrollBar.style.scrollBarThicknessHover rightPadding: verticalScrollBar.style.scrollBarThicknessHover
text: control.textRole ? (Array.isArray(control.model) text: itemDelegate.model[control.textRole]
? modelData[control.textRole]
: model[control.textRole])
: modelData
color: { color: {
if (!itemDelegate.enabled) if (!itemDelegate.enabled)
return control.style.text.disabled return control.style.text.disabled

View File

@@ -12,9 +12,13 @@ import QtQuickDesignerColorPalette
Column { Column {
id: root id: root
property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive
property color color property color color
property color originalColor property color originalColor
property Window parentWindow: null
readonly property real twoColumnWidth: (colorColumn.width - StudioTheme.Values.controlGap) * 0.5 readonly property real twoColumnWidth: (colorColumn.width - StudioTheme.Values.controlGap) * 0.5
readonly property real fourColumnWidth: (colorColumn.width - (3 * StudioTheme.Values.controlGap)) * 0.25 readonly property real fourColumnWidth: (colorColumn.width - (3 * StudioTheme.Values.controlGap)) * 0.25
@@ -42,7 +46,7 @@ Column {
icon: StudioTheme.Constants.eyeDropper icon: StudioTheme.Constants.eyeDropper
pixelSize: StudioTheme.Values.myIconFontSize * 1.4 pixelSize: StudioTheme.Values.myIconFontSize * 1.4
toolTip: qsTr("Eye Dropper") toolTip: qsTr("Eye Dropper")
onClicked: ColorPaletteBackend.eyeDropper() onClicked: ColorPaletteBackend.invokeEyeDropper()
} }
} }

View File

@@ -156,242 +156,245 @@ QtObject {
readonly property string edit_medium: "\u00AF" readonly property string edit_medium: "\u00AF"
readonly property string edit_small: "\u00B0" readonly property string edit_small: "\u00B0"
readonly property string effects: "\u00B1" readonly property string effects: "\u00B1"
readonly property string events_small: "\u00B2" readonly property string error_medium: "\u00B2"
readonly property string export_medium: "\u00B3" readonly property string events_small: "\u00B3"
readonly property string eyeDropper: "\u00B4" readonly property string export_medium: "\u00B4"
readonly property string favorite: "\u00B5" readonly property string eyeDropper: "\u00B5"
readonly property string fitAll_medium: "\u00B6" readonly property string favorite: "\u00B6"
readonly property string fitSelected_small: "\u00B7" readonly property string fitAll_medium: "\u00B7"
readonly property string fitSelection_medium: "\u00B8" readonly property string fitSelected_small: "\u00B8"
readonly property string fitToView_medium: "\u00B9" readonly property string fitSelection_medium: "\u00B9"
readonly property string flowAction: "\u00BA" readonly property string fitToView_medium: "\u00BA"
readonly property string flowTransition: "\u00BB" readonly property string flowAction: "\u00BB"
readonly property string fontStyleBold: "\u00BC" readonly property string flowTransition: "\u00BC"
readonly property string fontStyleItalic: "\u00BD" readonly property string fontStyleBold: "\u00BD"
readonly property string fontStyleStrikethrough: "\u00BE" readonly property string fontStyleItalic: "\u00BE"
readonly property string fontStyleUnderline: "\u00BF" readonly property string fontStyleStrikethrough: "\u00BF"
readonly property string forward_medium: "\u00C0" readonly property string fontStyleUnderline: "\u00C0"
readonly property string globalOrient_medium: "\u00C1" readonly property string forward_medium: "\u00C1"
readonly property string gradient: "\u00C2" readonly property string globalOrient_medium: "\u00C2"
readonly property string gridView: "\u00C3" readonly property string gradient: "\u00C3"
readonly property string grid_medium: "\u00C4" readonly property string gridView: "\u00C4"
readonly property string group_small: "\u00C5" readonly property string grid_medium: "\u00C5"
readonly property string help: "\u00C6" readonly property string group_small: "\u00C6"
readonly property string home_large: "\u00C7" readonly property string help: "\u00C7"
readonly property string idAliasOff: "\u00C8" readonly property string home_large: "\u00C8"
readonly property string idAliasOn: "\u00C9" readonly property string idAliasOff: "\u00C9"
readonly property string import_medium: "\u00CA" readonly property string idAliasOn: "\u00CA"
readonly property string imported: "\u00CB" readonly property string import_medium: "\u00CB"
readonly property string importedModels_small: "\u00CC" readonly property string imported: "\u00CC"
readonly property string infinity: "\u00CD" readonly property string importedModels_small: "\u00CD"
readonly property string invisible_medium: "\u00CE" readonly property string infinity: "\u00CE"
readonly property string invisible_small: "\u00CF" readonly property string invisible_medium: "\u00CF"
readonly property string jumpToCode_medium: "\u00D0" readonly property string invisible_small: "\u00D0"
readonly property string jumpToCode_small: "\u00D1" readonly property string jumpToCode_medium: "\u00D1"
readonly property string keyframe: "\u00D2" readonly property string jumpToCode_small: "\u00D2"
readonly property string languageList_medium: "\u00D3" readonly property string keyframe: "\u00D3"
readonly property string layouts_small: "\u00D4" readonly property string languageList_medium: "\u00D4"
readonly property string lights_small: "\u00D5" readonly property string layouts_small: "\u00D5"
readonly property string linear_medium: "\u00D6" readonly property string lights_small: "\u00D6"
readonly property string linkTriangle: "\u00D7" readonly property string linear_medium: "\u00D7"
readonly property string linked: "\u00D8" readonly property string linkTriangle: "\u00D8"
readonly property string listView: "\u00D9" readonly property string linked: "\u00D9"
readonly property string listView_medium: "\u00DA" readonly property string listView: "\u00DA"
readonly property string list_medium: "\u00DB" readonly property string listView_medium: "\u00DB"
readonly property string localOrient_medium: "\u00DC" readonly property string list_medium: "\u00DC"
readonly property string lockOff: "\u00DD" readonly property string localOrient_medium: "\u00DD"
readonly property string lockOn: "\u00DE" readonly property string lockOff: "\u00DE"
readonly property string loopPlayback_medium: "\u00DF" readonly property string lockOn: "\u00DF"
readonly property string materialBrowser_medium: "\u00E0" readonly property string loopPlayback_medium: "\u00E0"
readonly property string materialPreviewEnvironment: "\u00E1" readonly property string materialBrowser_medium: "\u00E1"
readonly property string materialPreviewModel: "\u00E2" readonly property string materialPreviewEnvironment: "\u00E2"
readonly property string material_medium: "\u00E3" readonly property string materialPreviewModel: "\u00E3"
readonly property string maxBar_small: "\u00E4" readonly property string material_medium: "\u00E4"
readonly property string mergeCells: "\u00E5" readonly property string maxBar_small: "\u00E5"
readonly property string merge_small: "\u00E6" readonly property string mergeCells: "\u00E6"
readonly property string minus: "\u00E7" readonly property string merge_small: "\u00E7"
readonly property string mirror: "\u00E8" readonly property string minus: "\u00E8"
readonly property string more_medium: "\u00E9" readonly property string mirror: "\u00E9"
readonly property string mouseArea_small: "\u00EA" readonly property string more_medium: "\u00EA"
readonly property string moveDown_medium: "\u00EB" readonly property string mouseArea_small: "\u00EB"
readonly property string moveInwards_medium: "\u00EC" readonly property string moveDown_medium: "\u00EC"
readonly property string moveUp_medium: "\u00ED" readonly property string moveInwards_medium: "\u00ED"
readonly property string moveUpwards_medium: "\u00EE" readonly property string moveUp_medium: "\u00EE"
readonly property string move_medium: "\u00EF" readonly property string moveUpwards_medium: "\u00EF"
readonly property string newMaterial: "\u00F0" readonly property string move_medium: "\u00F0"
readonly property string nextFile_large: "\u00F1" readonly property string newMaterial: "\u00F1"
readonly property string normalBar_small: "\u00F2" readonly property string nextFile_large: "\u00F2"
readonly property string openLink: "\u00F3" readonly property string normalBar_small: "\u00F3"
readonly property string openMaterialBrowser: "\u00F4" readonly property string openLink: "\u00F4"
readonly property string orientation: "\u00F5" readonly property string openMaterialBrowser: "\u00F5"
readonly property string orthCam_medium: "\u00F6" readonly property string orientation: "\u00F6"
readonly property string orthCam_small: "\u00F7" readonly property string orthCam_medium: "\u00F7"
readonly property string paddingEdge: "\u00F8" readonly property string orthCam_small: "\u00F8"
readonly property string paddingFrame: "\u00F9" readonly property string paddingEdge: "\u00F9"
readonly property string particleAnimation_medium: "\u00FA" readonly property string paddingFrame: "\u00FA"
readonly property string pasteStyle: "\u00FB" readonly property string particleAnimation_medium: "\u00FB"
readonly property string paste_small: "\u00FC" readonly property string pasteStyle: "\u00FC"
readonly property string pause: "\u00FD" readonly property string paste_small: "\u00FD"
readonly property string pause_medium: "\u00FE" readonly property string pause: "\u00FE"
readonly property string perspectiveCam_medium: "\u00FF" readonly property string pause_medium: "\u00FF"
readonly property string perspectiveCam_small: "\u0100" readonly property string perspectiveCam_medium: "\u0100"
readonly property string pin: "\u0101" readonly property string perspectiveCam_small: "\u0101"
readonly property string plane_medium: "\u0102" readonly property string pin: "\u0102"
readonly property string plane_small: "\u0103" readonly property string plane_medium: "\u0103"
readonly property string play: "\u0104" readonly property string plane_small: "\u0104"
readonly property string playFill_medium: "\u0105" readonly property string play: "\u0105"
readonly property string playOutline_medium: "\u0106" readonly property string playFill_medium: "\u0106"
readonly property string plus: "\u0107" readonly property string playOutline_medium: "\u0107"
readonly property string pointLight_small: "\u0108" readonly property string plus: "\u0108"
readonly property string positioners_small: "\u0109" readonly property string pointLight_small: "\u0109"
readonly property string previewEnv_medium: "\u010A" readonly property string positioners_small: "\u010A"
readonly property string previousFile_large: "\u010B" readonly property string previewEnv_medium: "\u010B"
readonly property string promote: "\u010C" readonly property string previousFile_large: "\u010C"
readonly property string properties_medium: "\u010D" readonly property string promote: "\u010D"
readonly property string readOnly: "\u010E" readonly property string properties_medium: "\u010E"
readonly property string recent_medium: "\u010F" readonly property string readOnly: "\u010F"
readonly property string recordFill_medium: "\u0110" readonly property string recent_medium: "\u0110"
readonly property string recordOutline_medium: "\u0111" readonly property string recordFill_medium: "\u0111"
readonly property string redo: "\u0112" readonly property string recordOutline_medium: "\u0112"
readonly property string reload_medium: "\u0113" readonly property string redo: "\u0113"
readonly property string remove_medium: "\u0114" readonly property string reload_medium: "\u0114"
readonly property string remove_small: "\u0115" readonly property string remove_medium: "\u0115"
readonly property string rename_small: "\u0116" readonly property string remove_small: "\u0116"
readonly property string replace_small: "\u0117" readonly property string rename_small: "\u0117"
readonly property string resetView_small: "\u0118" readonly property string replace_small: "\u0118"
readonly property string restartParticles_medium: "\u0119" readonly property string resetView_small: "\u0119"
readonly property string reverseOrder_medium: "\u011A" readonly property string restartParticles_medium: "\u011A"
readonly property string roatate_medium: "\u011B" readonly property string reverseOrder_medium: "\u011B"
readonly property string rotationFill: "\u011C" readonly property string roatate_medium: "\u011C"
readonly property string rotationOutline: "\u011D" readonly property string rotationFill: "\u011D"
readonly property string runProjFill_large: "\u011E" readonly property string rotationOutline: "\u011E"
readonly property string runProjOutline_large: "\u011F" readonly property string runProjFill_large: "\u011F"
readonly property string s_anchors: "\u0120" readonly property string runProjOutline_large: "\u0120"
readonly property string s_annotations: "\u0121" readonly property string s_anchors: "\u0121"
readonly property string s_arrange: "\u0122" readonly property string s_annotations: "\u0122"
readonly property string s_boundingBox: "\u0123" readonly property string s_arrange: "\u0123"
readonly property string s_component: "\u0124" readonly property string s_boundingBox: "\u0124"
readonly property string s_connections: "\u0125" readonly property string s_component: "\u0125"
readonly property string s_edit: "\u0126" readonly property string s_connections: "\u0126"
readonly property string s_enterComponent: "\u0127" readonly property string s_edit: "\u0127"
readonly property string s_eventList: "\u0128" readonly property string s_enterComponent: "\u0128"
readonly property string s_group: "\u0129" readonly property string s_eventList: "\u0129"
readonly property string s_layouts: "\u012A" readonly property string s_group: "\u012A"
readonly property string s_merging: "\u012B" readonly property string s_layouts: "\u012B"
readonly property string s_mouseArea: "\u012C" readonly property string s_merging: "\u012C"
readonly property string s_positioners: "\u012D" readonly property string s_mouseArea: "\u012D"
readonly property string s_selection: "\u012E" readonly property string s_positioners: "\u012E"
readonly property string s_snapping: "\u012F" readonly property string s_selection: "\u012F"
readonly property string s_timeline: "\u0130" readonly property string s_snapping: "\u0130"
readonly property string s_visibility: "\u0131" readonly property string s_timeline: "\u0131"
readonly property string saveAs_medium: "\u0132" readonly property string s_visibility: "\u0132"
readonly property string saveLogs_medium: "\u0133" readonly property string saveAs_medium: "\u0133"
readonly property string save_medium: "\u0134" readonly property string saveLogs_medium: "\u0134"
readonly property string scale_medium: "\u0135" readonly property string save_medium: "\u0135"
readonly property string search: "\u0136" readonly property string scale_medium: "\u0136"
readonly property string search_small: "\u0137" readonly property string search: "\u0137"
readonly property string sectionToggle: "\u0138" readonly property string search_small: "\u0138"
readonly property string selectFill_medium: "\u0139" readonly property string sectionToggle: "\u0139"
readonly property string selectOutline_medium: "\u013A" readonly property string selectFill_medium: "\u013A"
readonly property string selectParent_small: "\u013B" readonly property string selectOutline_medium: "\u013B"
readonly property string selection_small: "\u013C" readonly property string selectParent_small: "\u013C"
readonly property string settings_medium: "\u013D" readonly property string selection_small: "\u013D"
readonly property string signal_small: "\u013E" readonly property string settings_medium: "\u013E"
readonly property string snapping_conf_medium: "\u013F" readonly property string signal_small: "\u013F"
readonly property string snapping_medium: "\u0140" readonly property string snapping_conf_medium: "\u0140"
readonly property string snapping_small: "\u0141" readonly property string snapping_medium: "\u0141"
readonly property string sortascending_medium: "\u0142" readonly property string snapping_small: "\u0142"
readonly property string sortdescending_medium: "\u0143" readonly property string sortascending_medium: "\u0143"
readonly property string sphere_medium: "\u0144" readonly property string sortdescending_medium: "\u0144"
readonly property string sphere_small: "\u0145" readonly property string sphere_medium: "\u0145"
readonly property string splitColumns: "\u0146" readonly property string sphere_small: "\u0146"
readonly property string splitRows: "\u0147" readonly property string splitColumns: "\u0147"
readonly property string splitScreen_medium: "\u0148" readonly property string splitRows: "\u0148"
readonly property string spotLight_small: "\u0149" readonly property string splitScreen_medium: "\u0149"
readonly property string stackedContainer_small: "\u014A" readonly property string spotLight_small: "\u014A"
readonly property string startNode: "\u014B" readonly property string stackedContainer_small: "\u014B"
readonly property string step_medium: "\u014C" readonly property string startNode: "\u014C"
readonly property string stop_medium: "\u014D" readonly property string step_medium: "\u014D"
readonly property string tableView_medium: "\u014E" readonly property string stop_medium: "\u014E"
readonly property string testIcon: "\u014F" readonly property string tableView_medium: "\u014F"
readonly property string textAlignBottom: "\u0150" readonly property string testIcon: "\u0150"
readonly property string textAlignCenter: "\u0151" readonly property string textAlignBottom: "\u0151"
readonly property string textAlignJustified: "\u0152" readonly property string textAlignCenter: "\u0152"
readonly property string textAlignLeft: "\u0153" readonly property string textAlignJustified: "\u0153"
readonly property string textAlignMiddle: "\u0154" readonly property string textAlignLeft: "\u0154"
readonly property string textAlignRight: "\u0155" readonly property string textAlignMiddle: "\u0155"
readonly property string textAlignTop: "\u0156" readonly property string textAlignRight: "\u0156"
readonly property string textBulletList: "\u0157" readonly property string textAlignTop: "\u0157"
readonly property string textFullJustification: "\u0158" readonly property string textBulletList: "\u0158"
readonly property string textNumberedList: "\u0159" readonly property string textFullJustification: "\u0159"
readonly property string textures_medium: "\u015A" readonly property string textNumberedList: "\u015A"
readonly property string tickIcon: "\u015B" readonly property string textures_medium: "\u015B"
readonly property string tickMark_small: "\u015C" readonly property string tickIcon: "\u015C"
readonly property string timeline_small: "\u015D" readonly property string tickMark_small: "\u015D"
readonly property string toEndFrame_medium: "\u015E" readonly property string timeline_small: "\u015E"
readonly property string toNextFrame_medium: "\u015F" readonly property string toEndFrame_medium: "\u015F"
readonly property string toPrevFrame_medium: "\u0160" readonly property string toNextFrame_medium: "\u0160"
readonly property string toStartFrame_medium: "\u0161" readonly property string toPrevFrame_medium: "\u0161"
readonly property string topToolbar_annotations: "\u0162" readonly property string toStartFrame_medium: "\u0162"
readonly property string topToolbar_closeFile: "\u0163" readonly property string topToolbar_annotations: "\u0163"
readonly property string topToolbar_designMode: "\u0164" readonly property string topToolbar_closeFile: "\u0164"
readonly property string topToolbar_enterComponent: "\u0165" readonly property string topToolbar_designMode: "\u0165"
readonly property string topToolbar_home: "\u0166" readonly property string topToolbar_enterComponent: "\u0166"
readonly property string topToolbar_makeComponent: "\u0167" readonly property string topToolbar_home: "\u0167"
readonly property string topToolbar_navFile: "\u0168" readonly property string topToolbar_makeComponent: "\u0168"
readonly property string topToolbar_runProject: "\u0169" readonly property string topToolbar_navFile: "\u0169"
readonly property string translationCreateFiles: "\u016A" readonly property string topToolbar_runProject: "\u016A"
readonly property string translationCreateReport: "\u016B" readonly property string translationCreateFiles: "\u016B"
readonly property string translationExport: "\u016C" readonly property string translationCreateReport: "\u016C"
readonly property string translationImport: "\u016D" readonly property string translationExport: "\u016D"
readonly property string translationSelectLanguages: "\u016E" readonly property string translationImport: "\u016E"
readonly property string translationTest: "\u016F" readonly property string translationSelectLanguages: "\u016F"
readonly property string transparent: "\u0170" readonly property string translationTest: "\u0170"
readonly property string triState: "\u0171" readonly property string transparent: "\u0171"
readonly property string triangleArcA: "\u0172" readonly property string trash_medium: "\u0172"
readonly property string triangleArcB: "\u0173" readonly property string triState: "\u0173"
readonly property string triangleCornerA: "\u0174" readonly property string triangleArcA: "\u0174"
readonly property string triangleCornerB: "\u0175" readonly property string triangleArcB: "\u0175"
readonly property string unLinked: "\u0176" readonly property string triangleCornerA: "\u0176"
readonly property string undo: "\u0177" readonly property string triangleCornerB: "\u0177"
readonly property string unify_medium: "\u0178" readonly property string unLinked: "\u0178"
readonly property string unpin: "\u0179" readonly property string undo: "\u0179"
readonly property string upDownIcon: "\u017A" readonly property string unify_medium: "\u017A"
readonly property string upDownSquare2: "\u017B" readonly property string unpin: "\u017B"
readonly property string updateAvailable_medium: "\u017C" readonly property string upDownIcon: "\u017C"
readonly property string updateContent_medium: "\u017D" readonly property string upDownSquare2: "\u017D"
readonly property string visibilityOff: "\u017E" readonly property string updateAvailable_medium: "\u017E"
readonly property string visibilityOn: "\u017F" readonly property string updateContent_medium: "\u017F"
readonly property string visible_medium: "\u0180" readonly property string visibilityOff: "\u0180"
readonly property string visible_small: "\u0181" readonly property string visibilityOn: "\u0181"
readonly property string warning_medium: "\u0182" readonly property string visible_medium: "\u0182"
readonly property string wildcard: "\u0183" readonly property string visible_small: "\u0183"
readonly property string wizardsAutomotive: "\u0184" readonly property string warning2_medium: "\u0184"
readonly property string wizardsDesktop: "\u0185" readonly property string warning_medium: "\u0185"
readonly property string wizardsGeneric: "\u0186" readonly property string wildcard: "\u0186"
readonly property string wizardsMcuEmpty: "\u0187" readonly property string wizardsAutomotive: "\u0187"
readonly property string wizardsMcuGraph: "\u0188" readonly property string wizardsDesktop: "\u0188"
readonly property string wizardsMobile: "\u0189" readonly property string wizardsGeneric: "\u0189"
readonly property string wizardsUnknown: "\u018A" readonly property string wizardsMcuEmpty: "\u018A"
readonly property string zoomAll: "\u018B" readonly property string wizardsMcuGraph: "\u018B"
readonly property string zoomIn: "\u018C" readonly property string wizardsMobile: "\u018C"
readonly property string zoomIn_medium: "\u018D" readonly property string wizardsUnknown: "\u018D"
readonly property string zoomOut: "\u018E" readonly property string zoomAll: "\u018E"
readonly property string zoomOut_medium: "\u018F" readonly property string zoomIn: "\u018F"
readonly property string zoomSelection: "\u0190" readonly property string zoomIn_medium: "\u0190"
readonly property string zoomOut: "\u0191"
readonly property string zoomOut_medium: "\u0192"
readonly property string zoomSelection: "\u0193"
readonly property font iconFont: Qt.font({ readonly property font iconFont: Qt.font({
"family": controlIcons.name, family: controlIcons.name,
"pixelSize": 12 pixelSize: 12
}) })
readonly property font font: Qt.font({ readonly property font font: Qt.font({
"family": "Arial", family: Qt.application.font.family,
"pointSize": Qt.application.font.pixelSize pointSize: Qt.application.font.pixelSize
}) })
readonly property font largeFont: Qt.font({ readonly property font largeFont: Qt.font({
"family": "Arial", family: "Arial",
"pointSize": Qt.application.font.pixelSize * 1.6 pointSize: Qt.application.font.pixelSize * 1.6
}) })
} }

View File

@@ -168,7 +168,7 @@ Item {
height: stateBackground.controlHeight height: stateBackground.controlHeight
checkedInverted: true checkedInverted: true
buttonIcon: qsTr("Default") buttonIcon: qsTr("Default")
iconFont: StudioTheme.Constants.font iconFontFamily: StudioTheme.Constants.font.family
tooltip: qsTr("Set State as default") tooltip: qsTr("Set State as default")
onClicked: { onClicked: {
root.defaultClicked() root.defaultClicked()

View File

@@ -0,0 +1,142 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import StudioControls as StudioControls
import StudioTheme as StudioTheme
import ToolBar
StudioControls.PopupDialog {
id: root
width: 800
property Item targetItem
property alias warningCount: issuesPanel.warningCount
property alias errorCount: issuesPanel.errorCount
property alias unreadOutput: outputPanel.unreadMessages
readonly property bool issuesVisible: issuesPanel.visible && root.visible
readonly property bool outputVisible: outputPanel.visible && root.visible
function toggleShowIssuesPanel() {
if (!root.visible) {
outputPanel.visible = false
issuesPanel.visible = true
root.show(root.targetItem)
} else {
if (issuesPanel.visible) {
root.close()
} else {
outputPanel.visible = false
issuesPanel.visible = true
}
}
}
function toggleShowOutputPanel() {
if (!root.visible) {
issuesPanel.visible = false
outputPanel.visible = true
root.show(root.targetItem)
} else {
if (outputPanel.visible) {
root.close()
} else {
issuesPanel.visible = false
outputPanel.visible = true
}
}
}
onClosing: {
issuesPanel.visible = false
outputPanel.visible = false
}
titleBar: RowLayout {
id: toolBar
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 0
anchors.rightMargin: 10
RowLayout {
id: leftAlignedButtons
Layout.alignment: Qt.AlignLeft
TabBarButton {
id: issuesButton
style: StudioTheme.Values.statusbarButtonStyle
text: qsTr("Issues")
checked: issuesPanel.visible
checkedInverted: true
onClicked: {
if (!issuesPanel.visible) {
outputPanel.visible = false
issuesPanel.visible = true
}
}
}
TabBarButton {
id: outputButton
style: StudioTheme.Values.statusbarButtonStyle
text: qsTr("Output")
checked: outputPanel.visible
checkedInverted: true
onClicked: {
if (!outputPanel.visible) {
issuesPanel.visible = false
outputPanel.visible = true
}
}
}
}
RowLayout {
id: rightAlignedButtons
Layout.alignment: Qt.AlignRight
StudioControls.IconIndicator {
id: clearButton
icon: StudioTheme.Constants.trash_medium
pixelSize: StudioTheme.Values.myIconFontSize * 1.4
toolTip: qsTr("Clear")
onClicked: {
if (issuesPanel.visible)
issuesPanel.clearIssues()
else
outputPanel.clearOutput()
}
}
}
}
Item {
id: panels
width: parent.width
height: 500
IssuesPanel {
id: issuesPanel
visible: false
anchors.fill: panels
}
OutputPanel {
id: outputPanel
visible: false
anchors.fill: panels
}
}
}

View File

@@ -0,0 +1,96 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import StudioControls as StudioControls
import StudioTheme as StudioTheme
import OutputPane
ScrollView {
id: root
signal showCodeViewSignal
property int warningCount: messageModel.warningCount
property int errorCount: messageModel.errorCount
function clearIssues() { messageModel.resetModel() }
ScrollBar.vertical: StudioControls.TransientScrollBar {
id: verticalScrollBar
style: StudioTheme.Values.viewStyle
parent: root
x: root.width - verticalScrollBar.width
y: 0
height: root.availableHeight
orientation: Qt.Vertical
show: (root.hovered || root.focus) && verticalScrollBar.isNeeded
}
ColumnLayout {
Repeater {
id: listView
model: MessageModel { id: messageModel }
delegate: Row {
id: row
required property int index
required property string message
required property string location
required property string type
width: root.width
spacing: 10
Text {
id: labelIcon
font.family: StudioTheme.Constants.iconFont.family
font.pixelSize: StudioTheme.Values.baseIconFontSize
color: (type == "Warning") ? StudioTheme.Values.themeAmberLight
: StudioTheme.Values.themeRedLight
text: (type == "Warning") ? StudioTheme.Constants.warning2_medium
: StudioTheme.Constants.error_medium
width: 18
height: 18
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Text {
id: labelLocation
text: location
color: "#57b9fc"
font.pixelSize: StudioTheme.Values.baseFontSize
verticalAlignment: Text.AlignVCenter
font.underline: mouseArea.containsMouse
height: 18
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: mouseArea.containsMouse ? Qt.PointingHandCursor
: Qt.ArrowCursor
}
}
Text {
id: labelInfo
color: (type == "Warning") ? StudioTheme.Values.themeAmberLight
: StudioTheme.Values.themeRedLight
text: message
font.pixelSize: StudioTheme.Values.baseFontSize
verticalAlignment: Text.AlignTop
wrapMode: Text.WordWrap
width: row.width - labelIcon.width - labelLocation.width - row.spacing * 2
}
}
}
}
}

View File

@@ -3,12 +3,13 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
import "../toolbar"
import HelperWidgets 2.0
import ToolBar 1.0 import StudioControls as StudioControls
import StudioTheme as StudioTheme
import "../toolbar"
import HelperWidgets
import ToolBar
Item { Item {
id: toolbarContainer id: toolbarContainer
@@ -25,8 +26,10 @@ Item {
anchors.fill: parent anchors.fill: parent
Row { Row {
anchors.fill: parent anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 3 anchors.topMargin: 3
anchors.left: parent.left
anchors.leftMargin: 4 anchors.leftMargin: 4
spacing: 29 spacing: 29
@@ -50,6 +53,7 @@ Item {
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
ToolTipArea { ToolTipArea {
anchors.fill: parent anchors.fill: parent
tooltip: qsTr("Choose a predefined kit for the runtime configuration of the project.") tooltip: qsTr("Choose a predefined kit for the runtime configuration of the project.")
@@ -77,6 +81,7 @@ Item {
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
ToolTipArea { ToolTipArea {
anchors.fill: parent anchors.fill: parent
tooltip: qsTr("Choose a style for the Qt Quick Controls of the project.") tooltip: qsTr("Choose a style for the Qt Quick Controls of the project.")
@@ -95,5 +100,62 @@ Item {
onCurrentStyleIndexChanged: styles.currentIndex = backend.currentStyle onCurrentStyleIndexChanged: styles.currentIndex = backend.currentStyle
} }
} }
Row {
id: buttonRow
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.topMargin: 3
anchors.right: parent.right
anchors.rightMargin: 4
spacing: 10
NotificationButton {
id: issuesNotification
style: StudioTheme.Values.statusbarButtonStyle
warningCount: popupPanel.warningCount
errorCount: popupPanel.errorCount
checkable: true
checkedInverted: true
checked: popupPanel.issuesVisible
width: 136
enabled: backend.projectOpened
tooltip: qsTr("Show issues.")
onClicked: popupPanel.toggleShowIssuesPanel()
}
ToolbarButton {
id: outputButton
style: StudioTheme.Values.statusbarButtonStyle
buttonIcon: StudioTheme.Constants.import_medium
iconRotation: -90
checkable: true
checkedInverted: true
checked: popupPanel.outputVisible
enabled: backend.projectOpened
tooltip: qsTr("Show application output.")
onClicked: popupPanel.toggleShowOutputPanel()
Connections {
target: popupPanel
function onUnreadOutputChanged() {
if (popupPanel.unreadOutput)
outputButton.highlight()
}
}
}
}
}
IssuesOutputPanel {
id: popupPanel
targetItem: buttonRow
edge: Qt.TopEdge
keepOpen: true
} }
} }

View File

@@ -0,0 +1,244 @@
// Copyright (C) 2024 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.Templates as T
import StudioTheme as StudioTheme
import HelperWidgets
T.AbstractButton {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property bool globalHover: false
property bool hover: control.hovered
property bool press: control.pressed
property alias backgroundVisible: buttonBackground.visible
property alias backgroundRadius: buttonBackground.radius
// Inverts the checked style
property bool checkedInverted: false
property int warningCount: 0
property int errorCount: 0
property bool hasWarnings: control.warningCount > 0
property bool hasErrors: control.errorCount > 0
property alias tooltip: toolTipArea.tooltip
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
}
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
width: control.style.squareControlSize.width
height: control.style.squareControlSize.height
z: control.checked ? 10 : 3
activeFocusOnTab: false
background: Rectangle {
id: buttonBackground
color: control.style.background.idle
border.color: control.style.border.idle
border.width: control.style.borderWidth
radius: control.style.radius
}
component CustomLabel : T.Label {
id: customLabel
color: control.style.icon.idle
font.pixelSize: control.style.baseIconFontSize
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
property bool active: false
property color activeColor: "red"
states: [
State {
name: "default"
when: control.enabled && !control.press && !control.checked && !control.hover
PropertyChanges {
target: customLabel
color: customLabel.active ? customLabel.activeColor : control.style.icon.idle
}
},
State {
name: "hover"
when: control.enabled && !control.press && !control.checked && control.hover
PropertyChanges {
target: customLabel
color: customLabel.active ? customLabel.activeColor : control.style.icon.hover
}
},
State {
name: "press"
when: control.enabled && control.press
PropertyChanges {
target: customLabel
color: control.style.icon.interaction
}
},
State {
name: "check"
when: control.enabled && !control.press && control.checked
PropertyChanges {
target: customLabel
color: control.checkedInverted ? control.style.text.selectedText // TODO rather something in icon
: control.style.icon.selected
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: customLabel
color: control.style.icon.disabled
}
}
]
}
indicator: Item {
x: 0
y: 0
width: control.width
height: control.height
Row {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
spacing: 8
CustomLabel {
height: control.height
font.pixelSize: StudioTheme.Values.baseFontSize
text: control.warningCount
active: control.hasWarnings
activeColor: StudioTheme.Values.themeAmberLight
}
CustomLabel {
height: control.height
text: StudioTheme.Constants.warning2_medium
font.family: StudioTheme.Constants.iconFont.family
active: control.hasWarnings
activeColor: StudioTheme.Values.themeAmberLight
}
CustomLabel {
height: control.height
text: StudioTheme.Constants.error_medium
font.family: StudioTheme.Constants.iconFont.family
active: control.hasErrors
activeColor: StudioTheme.Values.themeRedLight
}
CustomLabel {
height: control.height
font.pixelSize: StudioTheme.Values.baseFontSize
text: control.errorCount
active: control.hasErrors
activeColor: StudioTheme.Values.themeRedLight
}
}
}
states: [
State {
name: "default"
when: control.enabled && !control.globalHover && !control.hover
&& !control.press && !control.checked
PropertyChanges {
target: buttonBackground
color: control.style.background.idle
border.color: control.style.border.idle
}
PropertyChanges {
target: control
z: 3
}
},
State {
name: "globalHover"
when: control.globalHover && !control.hover && !control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.background.idle
border.color: control.style.border.idle
}
},
State {
name: "hover"
when: !control.checked && control.hover && !control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.background.hover
border.color: control.style.border.hover
}
PropertyChanges {
target: control
z: 100
}
},
State {
name: "hoverCheck"
when: control.checked && control.hover && !control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.checkedInverted ? control.style.interactionHover
: control.style.background.hover
border.color: control.checkedInverted ? control.style.interactionHover
: control.style.border.hover
}
PropertyChanges {
target: control
z: 100
}
},
State {
name: "press"
when: control.hover && control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.interaction
border.color: control.style.interaction
}
PropertyChanges {
target: control
z: 100
}
},
State {
name: "check"
when: control.enabled && !control.press && control.checked
PropertyChanges {
target: buttonBackground
color: control.checkedInverted ? control.style.interaction
: control.style.background.idle
border.color: control.checkedInverted ? control.style.interaction
: control.style.border.idle
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.background.disabled
border.color: control.style.border.disabled
}
}
]
}

View File

@@ -0,0 +1,103 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import StudioControls as StudioControls
import StudioTheme as StudioTheme
import OutputPane
ScrollView {
id: root
property int unreadMessages: 0
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
function clearOutput() {
parentListModel.resetModel()
root.markMessagesRead()
}
onVisibleChanged: {
if (root.visible === true)
root.markMessagesRead()
}
function markMessagesRead() { root.unreadMessages = 0 }
clip: true
ScrollBar.vertical: StudioControls.TransientScrollBar {
id: verticalScrollBar
style: StudioTheme.Values.viewStyle
parent: root
x: root.width - verticalScrollBar.width
y: 0
height: root.availableHeight
orientation: Qt.Vertical
show: (root.hovered || root.focus) && verticalScrollBar.isNeeded
}
Column {
Repeater {
id: parentList
model: AppOutputParentModel {
id: parentListModel
historyColor: "grey"
messageColor: "#007b7b"
errorColor: "#ff6666"
onMessageAdded: {
if (!root.visible)
root.unreadMessages++
}
}
delegate: ColumnLayout {
id: parentDelegate
spacing: 0
required property int index
required property string run
required property color blockColor
Text {
id: timeStampText
text: parentDelegate.run
color: parentDelegate.blockColor
}
Repeater {
id: childList
model: AppOutputChildModel {
id: childListModel
parentModel: parentListModel
row: parentDelegate.index
}
onItemAdded: verticalScrollBar.position = 1.0 // Scroll to bottom
delegate: Column {
id: childDelegate
required property string message
required property color messageColor
Text {
wrapMode: Text.WordWrap
text: childDelegate.message
color: childDelegate.messageColor
width: root.width
}
}
}
}
}
}
}

View File

@@ -0,0 +1,167 @@
// Copyright (C) 2024 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.Templates as T
import StudioTheme as StudioTheme
T.AbstractButton {
id: control
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
property bool hover: control.hovered
property bool press: control.pressed
// Inverts the checked style
property bool checkedInverted: false
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
width: 100
height: control.style.squareControlSize.height
activeFocusOnTab: false
background: Rectangle {
id: buttonBackground
color: control.style.background.idle
border.color: control.style.border.idle
border.width: control.style.borderWidth
radius: control.style.radius
}
indicator: T.Label {
id: buttonIcon
text: control.text
color: control.style.icon.idle
font.pixelSize: control.style.baseFontSize
width: control.width
height: control.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
states: [
State {
name: "default"
when: control.enabled && !control.press && !control.checked && !control.hover
PropertyChanges {
target: buttonIcon
color: control.style.icon.idle
}
},
State {
name: "hover"
when: control.enabled && !control.press && !control.checked && control.hover
PropertyChanges {
target: buttonIcon
color: control.style.icon.hover
}
},
State {
name: "press"
when: control.enabled && control.press
PropertyChanges {
target: buttonIcon
color: control.style.icon.interaction
}
},
State {
name: "check"
when: control.enabled && !control.press && control.checked
PropertyChanges {
target: buttonIcon
color: control.checkedInverted ? control.style.text.selectedText // TODO rather something in icon
: control.style.icon.selected
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: buttonIcon
color: control.style.icon.disabled
}
}
]
}
states: [
State {
name: "default"
when: control.enabled && !control.hover
&& !control.press && !control.checked
PropertyChanges {
target: buttonBackground
color: control.style.background.idle
border.color: control.style.border.idle
}
PropertyChanges {
target: control
z: 3
}
},
State {
name: "hover"
when: !control.checked && control.hover && !control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.background.hover
border.color: control.style.border.hover
}
PropertyChanges {
target: control
z: 100
}
},
State {
name: "hoverCheck"
when: control.checked && control.hover && !control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.checkedInverted ? control.style.interactionHover
: control.style.background.hover
border.color: control.checkedInverted ? control.style.interactionHover
: control.style.border.hover
}
PropertyChanges {
target: control
z: 100
}
},
State {
name: "press"
when: control.hover && control.press && control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.interaction
border.color: control.style.interaction
}
PropertyChanges {
target: control
z: 100
}
},
State {
name: "check"
when: control.enabled && !control.press && control.checked
PropertyChanges {
target: buttonBackground
color: control.checkedInverted ? control.style.interaction
: control.style.background.idle
border.color: control.checkedInverted ? control.style.interaction
: control.style.border.idle
}
},
State {
name: "disable"
when: !control.enabled
PropertyChanges {
target: buttonBackground
color: control.style.background.disabled
border.color: control.style.border.disabled
}
}
]
}

View File

@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls
Button { Button {
id: control id: control

View File

@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls
CheckBox { CheckBox {
id: control id: control

View File

@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls
Dial { Dial {
id: control id: control

View File

@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls
Slider { Slider {
id: control id: control

View File

@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls
SpinBox { SpinBox {
id: control id: control

View File

@@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
import QtQuick.Controls 2.15 import QtQuick.Controls
Switch { Switch {
id: control id: control

View File

@@ -5,14 +5,14 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
@if %{UseQtQuickControls2} @if %{UseQtQuickControls2}
import QtQuick.Controls 2.15 import QtQuick.Controls
@endif @endif
@if %{UseImport} @if %{UseImport}
import %{ApplicationImport} import %{ApplicationImport}
@endif @endif
import FlowView 1.0 import FlowView
FlowItem { FlowItem {
@if %{UseImport} @if %{UseImport}

View File

@@ -5,11 +5,11 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
@if %{UseImport} @if %{UseImport}
import %{ApplicationImport} import %{ApplicationImport}
@endif @endif
import FlowView 1.0 import FlowView
FlowView { FlowView {
@if %{UseImport} @if %{UseImport}

View File

@@ -1,4 +1,4 @@
import QtQuick 2.15 import QtQuick
ListModel { ListModel {
ListElement { ListElement {

View File

@@ -1,6 +1,6 @@
import QtQuick 2.15 import QtQuick
import QtQuick.Layouts 1.15 import QtQuick.Layouts
import QtQuick.Controls 2.15 import QtQuick.Controls
import %{ApplicationImport} import %{ApplicationImport}
Pane { Pane {

View File

@@ -1,6 +1,6 @@
import QtQuick 2.15 import QtQuick
@if %{UseQtQuickControls2} @if %{UseQtQuickControls2}
import QtQuick.Controls 2.15 import QtQuick.Controls
@endif @endif
@if %{UseImport} @if %{UseImport}
import %{ApplicationImport} import %{ApplicationImport}

View File

@@ -3,7 +3,7 @@
"supportedProjectTypes": [ ], "supportedProjectTypes": [ ],
"id": "B.QtStudio.Qml.2", "id": "B.QtStudio.Qml.2",
"category": "B.StudioQtQuickFiles", "category": "B.StudioQtQuickFiles",
"trDescription": "Creates a component file (.qml) with boilerplate code, starting with \"import QtQuick 2.15\".", "trDescription": "Creates a component file (.qml) with boilerplate code, starting with \"import QtQuick\".",
"trDisplayName": "Qt Quick File", "trDisplayName": "Qt Quick File",
"trDisplayCategory": "Qt Quick Files", "trDisplayCategory": "Qt Quick Files",
"icon": "file_qml.png", "icon": "file_qml.png",

View File

@@ -1,4 +1,4 @@
import QtQuick 2.15 import QtQuick
ListModel { ListModel {
ListElement { ListElement {

View File

@@ -1,4 +1,4 @@
import QtQuick 2.15 import QtQuick
Item { Item {
id: delegate id: delegate

View File

@@ -5,7 +5,7 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
GridView { GridView {
width: 420 width: 420

View File

@@ -5,7 +5,7 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
Item { Item {
id: delegate id: delegate

View File

@@ -5,7 +5,7 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
ListView { ListView {
id: view id: view

View File

@@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
@if %{UseQtQuickControls2} @if %{UseQtQuickControls2}
import QtQuick.Controls 2.15 import QtQuick.Controls
@endif @endif
@if %{UseImport} @if %{UseImport}
import %{ApplicationImport} import %{ApplicationImport}

View File

@@ -3,7 +3,7 @@
"supportedProjectTypes": [ ], "supportedProjectTypes": [ ],
"id": "Q.QtStudio.QmlUI.2", "id": "Q.QtStudio.QmlUI.2",
"category": "B.StudioQtQuickFiles", "category": "B.StudioQtQuickFiles",
"trDescription": "Creates a UI file (.ui.qml) with boilerplate code, starting with \"import QtQuick 2.15\".", "trDescription": "Creates a UI file (.ui.qml) with boilerplate code, starting with \"import QtQuick\".",
"trDisplayName": "Qt Quick UI File", "trDisplayName": "Qt Quick UI File",
"trDisplayCategory": "Qt Quick Files", "trDisplayCategory": "Qt Quick Files",
"icon": "file_ui.png", "icon": "file_ui.png",

View File

@@ -1,4 +1,4 @@
import QtQuick 2.15 import QtQuick
%{FormClass} { %{FormClass} {
button.onClicked: console.log("Button Pressed") button.onClicked: console.log("Button Pressed")

View File

@@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick 2.15 import QtQuick
@if %{UseQtQuickControls2} @if %{UseQtQuickControls2}
import QtQuick.Controls 2.15 import QtQuick.Controls
@endif @endif
@if %{UseImport} @if %{UseImport}
import %{ApplicationImport} import %{ApplicationImport}

View File

@@ -1,6 +1,6 @@
import QtQuick 2.15 import QtQuick
import QtQuick.Layouts 1.15 import QtQuick.Layouts
import QtQuick.Controls 2.15 import QtQuick.Controls
import %{ApplicationImport} import %{ApplicationImport}
Item { Item {

View File

@@ -1,6 +1,6 @@
import QtQuick 2.15 import QtQuick
import QtQuick.Layouts 1.15 import QtQuick.Layouts
import QtQuick.Controls 2.15 import QtQuick.Controls
import %{ApplicationImport} import %{ApplicationImport}
Item { Item {

View File

@@ -5,11 +5,11 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick %{QtQuickVersion} import QtQuick
import QtQuick.Controls %{QtQuickVersion} import QtQuick.Controls
import QtQuick3D %{QtQuick3DVersion} import QtQuick3D
import QtQuick3D.Effects %{QtQuick3DVersion} import QtQuick3D.Effects
import %{ImportModuleName} %{ImportModuleVersion} import %{ImportModuleName}
Rectangle { Rectangle {
width: Constants.width width: Constants.width

View File

@@ -1,10 +1,7 @@
import QtQuick %{QtQuickVersion} import QtQuick
@if !%{IsQt6Project}
import QtQuick.Window %{QtQuickVersion}
@endif
import %{ApplicationImport} import %{ApplicationImport}
@if %{UseVirtualKeyboard} @if %{UseVirtualKeyboard}
import QtQuick.VirtualKeyboard %{QtQuickVersion} import QtQuick.VirtualKeyboard
@endif @endif
Window { Window {

View File

@@ -18,7 +18,6 @@
{ "key": "ProjectPluginName", "value": "%{ProjectName}plugin" }, { "key": "ProjectPluginName", "value": "%{ProjectName}plugin" },
{ "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" }, { "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" },
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" }, { "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" },
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
{ "key": "AssetDir", "value": "Generated" }, { "key": "AssetDir", "value": "Generated" },
{ "key": "ContentDir", "value": "%{ProjectName}Content" }, { "key": "ContentDir", "value": "%{ProjectName}Content" },
{ "key": "ImportModuleName", "value": "%{ProjectName}" }, { "key": "ImportModuleName", "value": "%{ProjectName}" },
@@ -28,13 +27,12 @@
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
{ "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyle", "value": "Basic" },
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, { "key": "ApplicationImport", "value": "%{ImportModuleName}" },
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
{ "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" },
{ "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" }, { "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" }
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
], ],
"pages": "pages":
@@ -345,10 +343,6 @@
"source": "../shared-plugin/name/Constants.qml.tpl", "source": "../shared-plugin/name/Constants.qml.tpl",
"target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml"
}, },
{
"source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl",
"target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml"
},
{ {
"source": "../shared-plugin/name/EventListModel.qml.tpl", "source": "../shared-plugin/name/EventListModel.qml.tpl",
"target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml"

View File

@@ -5,12 +5,12 @@ this file manually, you might introduce QML code that is not supported by Qt Des
Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
*/ */
import QtQuick %{QtQuickVersion} import QtQuick
import QtQuick.Controls %{QtQuickVersion} import QtQuick.Controls
import QtQuick3D %{QtQuick3DVersion} import QtQuick3D
import QtQuick3D.Effects %{QtQuick3DVersion} import QtQuick3D.Effects
import QtQuick3D.Helpers %{QtQuick3DVersion} import QtQuick3D.Helpers
import %{ImportModuleName} %{ImportModuleVersion} import %{ImportModuleName}
Rectangle { Rectangle {
width: Constants.width width: Constants.width

View File

@@ -1,10 +1,7 @@
import QtQuick %{QtQuickVersion} import QtQuick
@if !%{IsQt6Project}
import QtQuick.Window %{QtQuickVersion}
@endif
import %{ApplicationImport} import %{ApplicationImport}
@if %{UseVirtualKeyboard} @if %{UseVirtualKeyboard}
import QtQuick.VirtualKeyboard %{QtQuickVersion} import QtQuick.VirtualKeyboard
@endif @endif
Window { Window {

View File

@@ -18,7 +18,6 @@
{ "key": "ProjectPluginName", "value": "%{ProjectName}plugin" }, { "key": "ProjectPluginName", "value": "%{ProjectName}plugin" },
{ "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" }, { "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" },
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" }, { "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" },
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
{ "key": "AssetDir", "value": "Generated" }, { "key": "AssetDir", "value": "Generated" },
{ "key": "ContentDir", "value": "%{ProjectName}Content" }, { "key": "ContentDir", "value": "%{ProjectName}Content" },
{ "key": "ImportModuleName", "value": "%{ProjectName}" }, { "key": "ImportModuleName", "value": "%{ProjectName}" },
@@ -28,13 +27,12 @@
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
{ "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyle", "value": "Basic" },
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, { "key": "ApplicationImport", "value": "%{ImportModuleName}" },
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
{ "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" },
{ "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" }, { "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" }
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
], ],
"pages": "pages":
@@ -321,10 +319,6 @@
"source": "../shared-plugin/name/Constants.qml.tpl", "source": "../shared-plugin/name/Constants.qml.tpl",
"target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml"
}, },
{
"source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl",
"target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml"
},
{ {
"source": "../shared-plugin/name/EventListModel.qml.tpl", "source": "../shared-plugin/name/EventListModel.qml.tpl",
"target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml"

Some files were not shown because too many files have changed in this diff Show More