diff --git a/doc/qtcreator/src/editors/creator-locator.qdoc b/doc/qtcreator/src/editors/creator-locator.qdoc index d649442309e..f3e82ea396c 100644 --- a/doc/qtcreator/src/editors/creator-locator.qdoc +++ b/doc/qtcreator/src/editors/creator-locator.qdoc @@ -230,9 +230,10 @@ \endlist - If locator does not find some files, you can add them to the \c DISTFILES - variable in the \c .pro file to include them into the distribution tarball - of your project and thus make them known to \QC as well. + \if defined(qtcreator) + If locator does not find some files, see \l{Specifying Project Contents} + for how to make them known to the locator. + \endif \section1 Configuring Locator Filters diff --git a/doc/qtcreator/src/editors/creator-only/creator-beautifier.qdoc b/doc/qtcreator/src/editors/creator-only/creator-beautifier.qdoc index 011ada3307c..dca905d6120 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-beautifier.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-beautifier.qdoc @@ -121,8 +121,7 @@ \li Select \uicontrol {Use file *.astylerc defined in project files} or \uicontrol {Use file uncrustify.cfg defined in project files}, - to use the configuration file - \l{Displaying Additional File Types in Projects View} + to use the configuration file \l{Specifying Project Contents} {defined in the project file} as the configuration file for the selected tool. diff --git a/doc/qtcreator/src/editors/creator-search.qdoc b/doc/qtcreator/src/editors/creator-search.qdoc index e68c1725ca0..12054b72d87 100644 --- a/doc/qtcreator/src/editors/creator-search.qdoc +++ b/doc/qtcreator/src/editors/creator-search.qdoc @@ -142,6 +142,12 @@ \image qtcreator-search-allprojects.png + \if defined(qtcreator) + If you cannot find some files, see + \l{Specifying Project Contents} for how + to declare them as a part of the project. + \endif + \li \uicontrol {Current Project} searches from the project you are currently editing. diff --git a/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc b/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc index db241e9c60d..d1880588a00 100644 --- a/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc +++ b/doc/qtcreator/src/linux-mobile/creator-deployment-embedded-linux.qdoc @@ -56,6 +56,7 @@ \section1 Adding Missing Files The process to add files to deploy depends on the build system you use. + For more information, see \l{Specifying Project Contents}. \section2 CMake Builds diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc index a3ad3bb15dd..c89efd5a465 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc @@ -239,21 +239,33 @@ \include creator-python-project.qdocinc python project wizards - \section1 Displaying Additional File Types in Projects View + \section1 Specifying Project Contents + + A project can contain files that should be: + + \list + \li Compiled or otherwise handled by the build + \li Installed + \li Not installed, but included in a source package created with + \c {make dist} + \li Not installed, nor be part of a source package, but still be known + to \QC + \endlist \QC displays all files that are declared to be part of the project by the project files in the \l Projects view. The files are sorted into categories by file type (.cpp, .h, .qrc, and so on). To display additional files, edit - the project file. + the project file. Alternatively, you can see all the files in a project + directory in the \l {File System} view. - Alternatively, you can see all the files in a project in the - \l {File System} view. + Declaring files as a part of the project also makes them visible to the + \l{Searching with the Locator}{locator} and \l{Advanced Search} + {project-wide search}. \section2 CMake Projects - When using CMake, you can specify additional files to display in the - \uicontrol Projects view by either adding them as sources or installing - them. + When using CMake, you can specify additional files for a project by either + adding them as sources or installing them. In the CMakeLists.txt file, define the files as values of the \l{CMake: target_sources command}{target_sources} command using @@ -273,11 +285,17 @@ \section2 qmake Projects - When using qmake, add filenames as values of the \c {DISTFILES} variable - in the .pro file. You can also use wildcards. + Use the following variables in the .pro file: - For example, the following value specifies that text files are part of the - project: + \list + \li \c SOURCES and \c HEADERS for files to compile + \li \c INSTALLS for files to install + \li \c DISTFILES for files to include in a source package + \li \c OTHER_FILES for files to manage with \QC without + installing them or including them in source packages + \endlist + + For example, the following value includes text files in the source package: \badcode diff --git a/doc/qtcreator/src/user-interface/creator-projects-view.qdoc b/doc/qtcreator/src/user-interface/creator-projects-view.qdoc index 94acded57c3..be9ba3530d8 100644 --- a/doc/qtcreator/src/user-interface/creator-projects-view.qdoc +++ b/doc/qtcreator/src/user-interface/creator-projects-view.qdoc @@ -155,6 +155,9 @@ allows to specify exactly where a new file should be placed in the build system. + If you cannot see some files, they might not be declared as part of the + project. For more information, see \l{Specifying Project Contents}. + If the project is under version control, information from the version control system might be displayed in brackets after the project name. This is currently implemented for Git (the branch name or a tag is diff --git a/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc b/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc new file mode 100644 index 00000000000..b3dd7681e74 --- /dev/null +++ b/doc/qtdesignstudio/examples/doc/StateTransitions.qdoc @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Studio documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \page state-transition-animations.html + \ingroup gstutorials + \sa States, {Transition Editor}, {Adding States} + + \title Animated State Transitions + \brief Illustrates how to create animated state transitions. + + \image animated-state-transitions.jpg + + The \e{Animated State Transitions} tutorial illustrates how you can animate + the transition between \l{Adding States}{states}. + + The starting point of this tutorial is the Car Demo project, you can + download it from + \l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/animated-state-transition/Start/CarDemo} + {here}. + + You can download the completed project from + \l{https://git.qt.io/public-demos/qtdesign-studio/-/tree/master/tutorial%20projects/animated-state-transition/Completed/CarDemo} + {here}. + + This tutorial requires that you know the basics of \QDS, see + \l{Getting Started}. + + \section1 Tutorial Assets + + All assets you need for this tutorial are included in the Car Demo project. + + \section1 Creating States + + First, you create the different states. In this tutorial, you create four + different states with different views of the car in the scene: + \list + \li Side view + \li Front view + \li Back view + \li Interior view + \endlist + + To create the first state: + \list 1 + \li In the \l States view, select \inlineimage icons/plus.png + . + \li Change the name of the new state to \e{side}. + \endlist + + For the \e side state, you do not need to make any changes to the car model + because it is already in side view position. + + Next, create the rest of the states and change the rotation of the car. For + the \e interior state, you also change the position of the camera: + \list 1 + \li Create a new state and change the name to \e{front}. + \li In \l{Navigator}, select \e car_final and in + \l{Properties}, set \uicontrol Transform > \uicontrol Rotation > + \uicontrol Y to 0. + \li Create a new state and change the name to \e{back}. + \li In \uicontrol{Navigator}, select \e car_final and in + \uicontrol{Properties}, set \uicontrol Transform > \uicontrol Rotation > + \uicontrol Y to 180. + \li Create a new state and change the name to \e{interior}. + \li In \uicontrol{Navigator}, select \e camera1 and in + \uicontrol{Properties}, set \uicontrol Transform > \uicontrol Translation + > \uicontrol Z to 20. + \endlist + + \image animated-state-transitions-states.png + + \section1 Creating State Transitions + + With the states created, you need a way to move between the states in the + UI. In this tutorial, you create buttons arranged in a column to do this. + + \note Ensure that you have the base state selected before you add the + buttons. + + To add the buttons: + + \list 1 + \li From \l{Components}, drag \uicontrol Column to \e rectangle in + \uicontrol{Navigator}. + \li In \uicontrol{Navigator}, select \e column and in + \uicontrol{Properties}, set: + \list + \li \uicontrol Size > \uicontrol H to 200. + \li \uicontrol Spacing to 10. + \endlist + \li In \uicontrol{Properties}, go to the \uicontrol Layout tab. + \li Select \uicontrol Anchors > \uicontrol{Bottom} and set: + \list + \li \uicontrol Target to parent. + \li \uicontrol Margin to 10. + \endlist + \li Select \uicontrol Anchors > \uicontrol{Left} and set: + \list + \li \uicontrol Target to parent. + \li \uicontrol Margin to 10. + \endlist + \li From \uicontrol {Components}, drag \uicontrol Button to \e column in + \uicontrol {Navigator}. + \li In \uicontrol {Navigator}, select \e button and set \uicontrol ID to + \e {button_side}. + \li On the \uicontrol Button tab, set \uicontrol Text to \e {Side}. + \li Repeat step 6 to 8 three times to create a total of four buttons. Set + the ID for the three last buttons to \e{button_front}, \e{button_back}, + and \e {button_interior}. Change the text on the buttons accordingly. + \endlist + + \image state-transition-navigator-buttons.png + + Now, you add the actions to the buttons. Actions determine what happens + when you select a button in the application. In this tutorial, you use + the buttons to switch between the different states. + + To add actions: + + \list 1 + \li Go to the \uicontrol Connections view. + \li In \uicontrol{Navigator}, select \e button_side and in + \uicontrol {Connections}, select \inlineimage icons/plus.png + . + This creates a new connection with \e button_side as the target. + \li Set \uicontrol{Signal Handler} to \uicontrol onClicked. + \li Set \uicontrol Actions to \e {Change state to side}. + \li Repeat steps 2 to 4 for the next three buttons and set them to go to + their corresponding states. + \endlist + + \image state-transition-connections.png + + Now you can preview and try the transitions to see how the UI moves between + the states when you select the buttons. + + To preview, select \key Alt + \key{P}. + + \section1 Animating State Transitions + + The final step of this tutorial is to create animations between the states: + + \list 1 + \li Go to \l{Transition Editor}. + \li Select \inlineimage icons/plus.png + . + \li In the upper right corner of \uicontrol {Transition Editor}, change + the number 2000 to 1000. + This sets the length of the animation in milliseconds. + \li Drag the left end of the timebar for \e car_final to the 0 mark in + the timeline, and then drag the right end to the 1000 mark. + \li Repeat the above step for \e {camera1}. + \endlist + + \image state-transition-transitions.png + + This adds the transition and sets the animation durations to 1 second + (1000 ms). By default, all properties that have changed between the states + are added to the transition and therefor animated. In + this case, the properties are Y rotation for the car model and Z position + for the camera. + + \section1 Previewing + + Now you are done. To preview and try the transitions animations, + select \key Alt + \key{P}. + +*/ diff --git a/doc/qtdesignstudio/examples/doc/images/animated-state-transitions-states.png b/doc/qtdesignstudio/examples/doc/images/animated-state-transitions-states.png new file mode 100644 index 00000000000..71d775e1cb3 Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/animated-state-transitions-states.png differ diff --git a/doc/qtdesignstudio/examples/doc/images/animated-state-transitions.jpg b/doc/qtdesignstudio/examples/doc/images/animated-state-transitions.jpg new file mode 100644 index 00000000000..06d2d71b754 Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/animated-state-transitions.jpg differ diff --git a/doc/qtdesignstudio/examples/doc/images/state-transition-connections.png b/doc/qtdesignstudio/examples/doc/images/state-transition-connections.png new file mode 100644 index 00000000000..c4c429378d4 Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/state-transition-connections.png differ diff --git a/doc/qtdesignstudio/examples/doc/images/state-transition-navigator-buttons.png b/doc/qtdesignstudio/examples/doc/images/state-transition-navigator-buttons.png new file mode 100644 index 00000000000..d8add7b9922 Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/state-transition-navigator-buttons.png differ diff --git a/doc/qtdesignstudio/examples/doc/images/state-transition-transitions.png b/doc/qtdesignstudio/examples/doc/images/state-transition-transitions.png new file mode 100644 index 00000000000..84a4bb37acb Binary files /dev/null and b/doc/qtdesignstudio/examples/doc/images/state-transition-transitions.png differ diff --git a/doc/qtdesignstudio/images/studio-import-3d.png b/doc/qtdesignstudio/images/studio-import-3d.png index 6f960a875a9..106bba5bb57 100644 Binary files a/doc/qtdesignstudio/images/studio-import-3d.png and b/doc/qtdesignstudio/images/studio-import-3d.png differ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc index 0450253af83..0fd20c0467a 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc @@ -103,7 +103,7 @@ want to import assets. \li Select the \uicontrol {Merge QML} check box if you have imported the assets before and want to merge the changes into existing QML files - instead of overwriting the existing files. + instead of overwriting the existing files. See \l {Merging QML Files}. \li Select \uicontrol Import to import the QML files and assets. This might take a little while for complex projects. \endlist @@ -128,6 +128,25 @@ \uicontrol {Asset Import} dialog while importing, fix the issues in design tool and export the assets again. + \section2 Merging QML Files + When you re-import a QML component, the changes done in \QDS are preserved. + The QML item changes in the existing QML component are copied to the corresponding + QML item in the new component. + + The following rules are observed while merging QML components. + \list + \li While importing, a unique identifier (UUID) is added for each QML item in the + component. The UUID is used to find the corresponding QML item in the existing + component. + \li New item properties in the existing component are added to the corresponding + item in the new component. + \li When a QML property is set in both old and new QML item, the property in the + new item remains unchanged. This rule does not apply to binding properties. In case + of bindings, changes done in \QDS are preserved. + \li New child items are added to the corresponding item in the new component. + \li QML items for which a corresponding QML item is not found in the existing component, + are added under the root item of the new component. + \endlist \include qtbridge-tutorial-links.qdocinc qtsketchbridge tutorials */ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc index 2a8087faa3f..476b32321d2 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc @@ -34,53 +34,10 @@ \title Importing 3D Assets - You can download \QB from the \l{https://marketplace.qt.io/}{Qt Marketplace}. - It enables you to import files you created using 3D graphics applications - and stored in several widely-used formats, such as .blend, .dae, .fbx, .glb, - .gltf, .obj, .uia, or .uip. For a list of formats supported by each + In \QDS, you can import 3D assets in formats such as .stl, .dae, .fbx, .glb, + .gltf, .obj, .uia, and .uip. For a list of formats supported by each \l{Qt Quick 3D} version, see the module documentation. - For more information about exporting 3D graphics, see - \l{Exporting 3D Assets}. - - \image studio-import-3d.png - - To import 3D assets to \QDS projects: - - \list 1 - \li Drag-and-drop an external file containing the 3D asset from, - for example, File Explorer (on Windows), to \uicontrol {3D Editor}. - \li In the \uicontrol {3D Scene Options} tab, select options for - importing the file. - \li Select \uicontrol Import to import the 3D graphics file. - \li When the import is done, select \uicontrol Close. - \endlist - - The 3D asset you dragged-and-dropped to \uicontrol {3D Editor} has now - been added to your scene, and you can see it in the \uicontrol {3D Editor} - view and in \uicontrol Navigator. It is also available in - \uicontrol Components > \uicontrol {My 3D Components}. - - Alternatively, you can initiate the import dialog from the - \uicontrol Assets view: - - \list 1 - \li In the \l{Design Views}{Design mode}, select - \uicontrol Assets > \inlineimage icons/plus.png - . - \li Select \uicontrol {3D Assets} in the dropdown menu to filter 3D - graphics files. - \li Select a file to import, and then select \uicontrol Open. - \li In the \uicontrol {3D Scene Options} tab, select options for - importing the file. - \li Select \uicontrol Import to import the 3D graphics file. - \li When the import is done, select \uicontrol Close. - \endlist - - The 3D asset now appears in \uicontrol Components > - \uicontrol {My 3D Components}. You can add it to the scene by - drag-and-dropping it to \uicontrol {3D Editor}. - During the import, you can optimize the files for \QDS. You can remove components from meshes to reduce the cache size, find and fix issues in the files, optimize graphs and meshes, and so on. The available options @@ -88,7 +45,45 @@ or with other 3D graphics tools. See the tooltips in the options dialog for more information about a particular option. - The 3D asset you added to the project now appears in - \uicontrol Components > \uicontrol {My 3D Components}. You can add it to - your UI by dragging-and-dropping it to \l {3D Editor}. + For more information about exporting 3D graphics, see + \l{Exporting 3D Assets}. + + \image studio-import-3d.png + + \section1 Importing a 3D Asset + + To import a 3D asset to a \QDS project: + + \list 1 + \li Drag-and-drop an external file containing the 3D asset from, + for example, File Explorer (on Windows), to \uicontrol {3D Editor}. + \li In the \uicontrol {3D Scene Options} tab, select options for + importing the file. + \note To see all options, select \uicontrol{Show All Options}. + \li Select \uicontrol Import to import the 3D asset. + \endlist + + The 3D asset is now added to your scene, and you can see it in the + \uicontrol {3D Editor} view and in \uicontrol Navigator. It is also + available in \uicontrol Components > \uicontrol {My 3D Components}. + + Alternatively, you can initiate the import dialog from the + \uicontrol Assets view: + + \list 1 + \li Select \l Assets > \inlineimage icons/plus.png + . + \li Select \uicontrol {3D Assets} in the dropdown menu to filter 3D + graphics files. + \li Select a file to import, and then select \uicontrol Open. + \li In the \uicontrol {3D Scene Options} tab, select options for + importing the file. + \note To see all options, select \uicontrol{Show All Options}. + \li Select \uicontrol Import to import the 3D asset. + \endlist + + The 3D asset now appears in \uicontrol Components > + \uicontrol {My 3D Components}. You can add it to the scene by + drag-and-dropping it to \uicontrol {3D Editor}. + */ diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index a6c50c4632d..6f7c271f7fe 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -2388,15 +2388,26 @@ void EditorManagerPrivate::handleContextChange(const QList &context) if ((editor = qobject_cast(c))) break; if (editor && editor != d->m_currentEditor) { + d->m_scheduledCurrentEditor = editor; // Delay actually setting the current editor to after the current event queue has been handled // Without doing this, e.g. clicking into projects tree or locator would always open editors // in the main window. That is because clicking anywhere in the main window (even over e.g. // the locator line edit) first activates the window and sets focus to its focus widget. // Only afterwards the focus is shifted to the widget that received the click. - d->m_scheduledCurrentEditor = editor; - QTimer::singleShot(QApplication::doubleClickInterval() + 10, - d, - &EditorManagerPrivate::setCurrentEditorFromContextChange); + + // 1) During this event handling, focus landed in the editor. + // 2) During the following event handling, focus might change to the project tree. + // So, delay setting the current editor by two events. + // If focus changes to e.g. the project tree in (2), then m_scheduledCurrentEditor is set to + // nullptr, and the setCurrentEditorFromContextChange call becomes a no-op. + QMetaObject::invokeMethod( + d, + [] { + QMetaObject::invokeMethod(d, + &EditorManagerPrivate::setCurrentEditorFromContextChange, + Qt::QueuedConnection); + }, + Qt::QueuedConnection); } else { updateActions(); } diff --git a/src/plugins/coreplugin/locator/executefilter.cpp b/src/plugins/coreplugin/locator/executefilter.cpp index 91f0ae9b1f6..5b5a4a9ae25 100644 --- a/src/plugins/coreplugin/locator/executefilter.cpp +++ b/src/plugins/coreplugin/locator/executefilter.cpp @@ -27,10 +27,13 @@ #include #include +#include #include #include #include +#include +#include #include using namespace Core; @@ -90,11 +93,15 @@ void ExecuteFilter::accept(const LocatorFilterEntry &selection, auto p = const_cast(this); const QString value = selection.displayName.trimmed(); + const int index = m_commandHistory.indexOf(value); if (index != -1 && index != 0) p->m_commandHistory.removeAt(index); if (index != 0) p->m_commandHistory.prepend(value); + static const int maxHistory = 100; + while (p->m_commandHistory.size() > maxHistory) + p->m_commandHistory.removeLast(); bool found; QString workingDirectory = Utils::globalMacroExpander()->value("CurrentDocument:Path", &found); @@ -203,6 +210,20 @@ void ExecuteFilter::removeProcess() m_process = nullptr; } +const char historyKey[] = "history"; + +void ExecuteFilter::saveState(QJsonObject &object) const +{ + if (!m_commandHistory.isEmpty()) + object.insert(historyKey, QJsonArray::fromStringList(m_commandHistory)); +} + +void ExecuteFilter::restoreState(const QJsonObject &object) +{ + m_commandHistory = Utils::transform(object.value(historyKey).toArray().toVariantList(), + &QVariant::toString); +} + QString ExecuteFilter::headCommand() const { if (m_taskQueue.isEmpty()) diff --git a/src/plugins/coreplugin/locator/executefilter.h b/src/plugins/coreplugin/locator/executefilter.h index 6b5b84aaf8f..588bdad6ecd 100644 --- a/src/plugins/coreplugin/locator/executefilter.h +++ b/src/plugins/coreplugin/locator/executefilter.h @@ -65,6 +65,9 @@ private: void createProcess(); void removeProcess(); + void saveState(QJsonObject &object) const final; + void restoreState(const QJsonObject &object) final; + QString headCommand() const; QQueue m_taskQueue; diff --git a/src/plugins/cppeditor/projectpart.cpp b/src/plugins/cppeditor/projectpart.cpp index 1d827648fcb..b51c28d64ce 100644 --- a/src/plugins/cppeditor/projectpart.cpp +++ b/src/plugins/cppeditor/projectpart.cpp @@ -129,6 +129,11 @@ static ToolChain::MacroInspectionReport getToolchainMacros( return report; } +static QStringList getIncludedFiles(const RawProjectPart &rpp, const RawProjectPartFlags &flags) +{ + return !rpp.includedFiles.isEmpty() ? rpp.includedFiles : flags.includedFiles; +} + ProjectPart::ProjectPart(const Utils::FilePath &topLevelProject, const RawProjectPart &rpp, const QString &displayName, @@ -148,7 +153,7 @@ ProjectPart::ProjectPart(const Utils::FilePath &topLevelProject, languageExtensions(languageExtensions | flags.languageExtensions), qtVersion(rpp.qtVersion), files(files), - includedFiles(rpp.includedFiles), + includedFiles(getIncludedFiles(rpp, flags)), precompiledHeaders(rpp.precompiledHeaders), headerPaths(getHeaderPaths(rpp, flags, tcInfo)), projectMacros(getProjectMacros(rpp)), diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp index f4ebb0ecf06..5de8df42cef 100644 --- a/src/plugins/languageclient/languageclientoutline.cpp +++ b/src/plugins/languageclient/languageclientoutline.cpp @@ -31,6 +31,7 @@ #include #include #include +#include > #include #include #include @@ -345,13 +346,18 @@ OutlineComboBox::OutlineComboBox(Client *client, TextEditor::BaseTextEditor *edi setMaxVisibleItems(40); setContextMenuPolicy(Qt::ActionsContextMenu); - auto sortAction = new QAction(tr("Sort Alphabetically"), this); + const QString sortActionText + = QCoreApplication::translate("TextEditor::Internal::OutlineWidgetStack", + "Sort Alphabetically"); + auto sortAction = new QAction(sortActionText, this); sortAction->setCheckable(true); sortAction->setChecked(sorted); addAction(sortAction); - connect(client->documentSymbolCache(), &DocumentSymbolCache::gotSymbols, - this, &OutlineComboBox::updateModel); + connect(client->documentSymbolCache(), + &DocumentSymbolCache::gotSymbols, + this, + &OutlineComboBox::updateModel); connect(client, &Client::documentUpdated, this, &OutlineComboBox::documentUpdated); connect(m_editorWidget, &TextEditor::TextEditorWidget::cursorPositionChanged, this, &OutlineComboBox::updateEntry); diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index e1adf657ad2..2382103d910 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -83,7 +83,10 @@ int ProjectModel::rowCount(const QModelIndex &) const QVariant ProjectModel::data(const QModelIndex &index, int role) const { - QPair data = ProjectExplorerPlugin::recentProjects().at(index.row()); + const QList > recentProjects = ProjectExplorerPlugin::recentProjects(); + if (recentProjects.count() <= index.row()) + return {}; + QPair data = recentProjects.at(index.row()); switch (role) { case Qt::DisplayRole: return data.second; diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index e208c7a3d9e..be6f82eda8e 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -537,6 +537,7 @@ extend_qtc_plugin(QmlDesigner curveeditorview.cpp curveeditorview.h animationcurve.cpp animationcurve.h curveeditor.cpp curveeditor.h + curveeditortoolbar.cpp curveeditortoolbar.h curveeditormodel.cpp curveeditormodel.h curveeditorstyle.h curvesegment.cpp curvesegment.h diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp index c004055197d..217e0e0eb76 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp @@ -25,6 +25,7 @@ #include "curveeditor.h" #include "curveeditormodel.h" +#include "curveeditortoolbar.h" #include "detail/curveitem.h" #include "detail/graphicsview.h" #include "detail/treeview.h" @@ -40,9 +41,17 @@ namespace QmlDesigner { CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent) : QWidget(parent) + , m_infoText(nullptr) + , m_toolbar(new CurveEditorToolBar(model, this)) , m_tree(new TreeView(model, this)) , m_view(new GraphicsView(model, this)) { + const QString labelText = tr( + "This file does not contain a timeline.

" + "To create an animation, add a timeline by clicking the + button in the \"Timeline\" view." + ); + m_infoText = new QLabel(labelText); + auto *splitter = new QSplitter; splitter->addWidget(m_tree); splitter->addWidget(m_view); @@ -53,17 +62,63 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent) area->setWidgetResizable(true); auto *box = new QVBoxLayout; - box->addWidget(createToolBar(model)); + box->addWidget(m_infoText); + box->addWidget(m_toolbar); box->addWidget(area); setLayout(box); + connect(m_toolbar, &CurveEditorToolBar::defaultClicked, [this]() { + m_view->setDefaultInterpolation(); + }); + + connect(m_toolbar, &CurveEditorToolBar::unifyClicked, [this]() { + m_view->toggleUnified(); + }); + + connect(m_toolbar, &CurveEditorToolBar::interpolationClicked, [this](Keyframe::Interpolation ipol) { + m_view->setInterpolation(ipol); + }); + + connect(m_toolbar, &CurveEditorToolBar::startFrameChanged, [this, model](int frame) { + model->setMinimumTime(frame); + m_view->viewport()->update(); + }); + + connect(m_toolbar, &CurveEditorToolBar::endFrameChanged, [this, model](int frame) { + model->setMaximumTime(frame); + m_view->viewport()->update(); + }); + + connect( + m_toolbar, &CurveEditorToolBar::currentFrameChanged, + model, &CurveEditorModel::commitCurrentFrame); + + connect( + m_view, &GraphicsView::currentFrameChanged, + m_toolbar, &CurveEditorToolBar::setCurrentFrame); + connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked); connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::setPinned); - connect(m_tree->selectionModel(), - &SelectionModel::curvesSelected, - m_view, - &GraphicsView::updateSelection); + connect( + m_tree->selectionModel(), &SelectionModel::curvesSelected, + m_view, &GraphicsView::updateSelection); + + auto updateTimeline = [this, model](bool validTimeline) { + if (validTimeline) { + m_toolbar->updateBoundsSilent(model->minimumTime(), model->maximumTime()); + m_toolbar->show(); + m_tree->show(); + m_view->show(); + m_infoText->hide(); + } else { + m_toolbar->hide(); + m_tree->hide(); + m_view->hide(); + m_infoText->show(); + } + }; + connect(model, &CurveEditorModel::timelineChanged, this, updateTimeline); } bool CurveEditor::dragging() const @@ -98,104 +153,4 @@ void CurveEditor::hideEvent(QHideEvent *event) QWidget::hideEvent(event); } -QToolBar *CurveEditor::createToolBar(CurveEditorModel *model) -{ - auto *bar = new QToolBar; - bar->setFloatable(false); - - QAction *tangentLinearAction = bar->addAction( - QIcon(":/curveeditor/images/tangetToolsLinearIcon.png"), "Linear"); - QAction *tangentStepAction = bar->addAction(QIcon( - ":/curveeditor/images/tangetToolsStepIcon.png"), - "Step"); - QAction *tangentSplineAction = bar->addAction( - QIcon(":/curveeditor/images/tangetToolsSplineIcon.png"), "Spline"); - - QAction *tangentDefaultAction = bar->addAction(tr("Set Default")); - QAction *tangentUnifyAction = bar->addAction(tr("Unify")); - - auto setLinearInterpolation = [this]() { - m_view->setInterpolation(Keyframe::Interpolation::Linear); - }; - auto setStepInterpolation = [this]() { - m_view->setInterpolation(Keyframe::Interpolation::Step); - }; - auto setSplineInterpolation = [this]() { - m_view->setInterpolation(Keyframe::Interpolation::Bezier); - }; - - auto toggleUnifyKeyframe = [this]() { m_view->toggleUnified(); }; - - connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation); - connect(tangentStepAction, &QAction::triggered, setStepInterpolation); - connect(tangentSplineAction, &QAction::triggered, setSplineInterpolation); - connect(tangentUnifyAction, &QAction::triggered, toggleUnifyKeyframe); - - Q_UNUSED(tangentLinearAction); - Q_UNUSED(tangentSplineAction); - Q_UNUSED(tangentStepAction); - Q_UNUSED(tangentDefaultAction); - - auto *durationBox = new QHBoxLayout; - auto *startSpin = new QSpinBox; - auto *endSpin = new QSpinBox; - - startSpin->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); - startSpin->setValue(model->minimumTime()); - - auto updateStartFrame = [this, model](int frame) { - model->setMinimumTime(frame); - m_view->viewport()->update(); - }; - connect(startSpin, QOverload::of(&QSpinBox::valueChanged), updateStartFrame); - - endSpin->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); - endSpin->setValue(model->maximumTime()); - - auto updateEndFrame = [this, model](int frame) { - model->setMaximumTime(frame); - m_view->viewport()->update(); - }; - connect(endSpin, QOverload::of(&QSpinBox::valueChanged), updateEndFrame); - - auto setStartSlot = [startSpin](int frame) { startSpin->setValue(frame); }; - connect(model, &CurveEditorModel::commitStartFrame, setStartSlot); - - auto setEndSlot = [endSpin](int frame) { endSpin->setValue(frame); }; - connect(model, &CurveEditorModel::commitEndFrame, setEndSlot); - - durationBox->addWidget(new QLabel(tr("Start Frame"))); - durationBox->addWidget(startSpin); - durationBox->addWidget(new QLabel(tr("End Frame"))); - durationBox->addWidget(endSpin); - - auto *durationWidget = new QWidget; - durationWidget->setLayout(durationBox); - bar->addWidget(durationWidget); - - auto *cfspin = new QSpinBox; - cfspin->setMinimum(0); - cfspin->setMaximum(std::numeric_limits::max()); - - auto intSignal = static_cast(&QSpinBox::valueChanged); - connect(cfspin, intSignal, [model](int val) { emit model->commitCurrentFrame(val); }); - connect(m_view, &GraphicsView::currentFrameChanged, [cfspin](int val, bool notify) { - if (notify) { - cfspin->setValue(val); - } else { - const QSignalBlocker blocker(cfspin); - cfspin->setValue(val); - } - }); - - auto *positionBox = new QHBoxLayout; - positionBox->addWidget(new QLabel(tr("Current Frame"))); - positionBox->addWidget(cfspin); - auto *positionWidget = new QWidget; - positionWidget->setLayout(positionBox); - bar->addWidget(positionWidget); - - return bar; -} - } // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h index e297e31a9bc..9d1a6f68f94 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h @@ -27,10 +27,12 @@ #include #include +#include namespace QmlDesigner { class CurveEditorModel; +class CurveEditorToolBar; class GraphicsView; class TreeView; @@ -57,7 +59,9 @@ protected: void hideEvent(QHideEvent *event) override; private: - QToolBar *createToolBar(CurveEditorModel *model); + QLabel *m_infoText; + + CurveEditorToolBar *m_toolbar; TreeView *m_tree; diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp index d357d555f7a..43776718174 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp @@ -43,6 +43,7 @@ namespace QmlDesigner { CurveEditorModel::CurveEditorModel(QObject *parent) : TreeModel(parent) + , m_hasTimeline(false) , m_minTime(CurveEditorStyle::defaultTimeMin) , m_maxTime(CurveEditorStyle::defaultTimeMax) {} @@ -98,15 +99,19 @@ CurveEditorStyle CurveEditorModel::style() const void CurveEditorModel::setTimeline(const QmlDesigner::QmlTimeline &timeline) { - m_minTime = timeline.startKeyframe(); - m_maxTime = timeline.endKeyframe(); - std::vector items; - for (auto &&target : timeline.allTargets()) { - if (TreeItem *item = createTopLevelItem(timeline, target)) - items.push_back(item); - } + m_hasTimeline = timeline.isValid(); - reset(items); + if (m_hasTimeline) { + m_minTime = timeline.startKeyframe(); + m_maxTime = timeline.endKeyframe(); + std::vector items; + for (auto &&target : timeline.allTargets()) { + if (TreeItem *item = createTopLevelItem(timeline, target)) + items.push_back(item); + } + reset(items); + } + emit timelineChanged(m_hasTimeline); } void CurveEditorModel::setCurrentFrame(int frame) diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h index 71fca7de039..041642aa610 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.h @@ -54,6 +54,8 @@ signals: void commitEndFrame(int frame); + void timelineChanged(bool valid); + void curveChanged(TreeItem *item); public: @@ -92,6 +94,8 @@ private: AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group); + bool m_hasTimeline = false; + double m_minTime = 0.; double m_maxTime = 0.; diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp new file mode 100644 index 00000000000..b7bbf370511 --- /dev/null +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Tooling +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "curveeditortoolbar.h" +#include "curveeditormodel.h" + +#include +#include +#include +#include + +namespace QmlDesigner { + +ValidatableSpinBox::ValidatableSpinBox(std::function validator, QWidget* parent) + : QSpinBox(parent) + , m_validator(validator) +{ } + +QValidator::State ValidatableSpinBox::validate(QString &text, int &pos) const +{ + auto result = QSpinBox::validate(text, pos); + if (result==QValidator::Acceptable) { + if (int val = text.toInt(); m_validator(val)) + return result; + + result = QValidator::Intermediate; + } + return result; +} + + +CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent) + : QToolBar(parent) + , m_startSpin(nullptr) + , m_endSpin(nullptr) + , m_currentSpin(new QSpinBox) + +{ + setFloatable(false); + + QAction *tangentLinearAction = addAction( + QIcon(":/curveeditor/images/tangetToolsLinearIcon.png"), "Linear"); + QAction *tangentStepAction = addAction( + QIcon(":/curveeditor/images/tangetToolsStepIcon.png"), "Step"); + QAction *tangentSplineAction = addAction( + QIcon(":/curveeditor/images/tangetToolsSplineIcon.png"), "Spline"); + + QAction *tangentDefaultAction = addAction(tr("Set Default")); + QAction *tangentUnifyAction = addAction(tr("Unify")); + + auto setLinearInterpolation = [this]() { + emit interpolationClicked(Keyframe::Interpolation::Linear); + }; + auto setStepInterpolation = [this]() { + emit interpolationClicked(Keyframe::Interpolation::Step); + }; + auto setSplineInterpolation = [this]() { + emit interpolationClicked(Keyframe::Interpolation::Bezier); + }; + auto setDefaultKeyframe = [this]() { + emit defaultClicked(); + }; + auto toggleUnifyKeyframe = [this]() { + emit unifyClicked(); + }; + + connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation); + connect(tangentStepAction, &QAction::triggered, setStepInterpolation); + connect(tangentSplineAction, &QAction::triggered, setSplineInterpolation); + connect(tangentDefaultAction, &QAction::triggered, setDefaultKeyframe); + connect(tangentUnifyAction, &QAction::triggered, toggleUnifyKeyframe); + + auto validateStart = [this](int val) -> bool { + if (m_endSpin==nullptr) + return false; + return m_endSpin->value() > val; + }; + m_startSpin = new ValidatableSpinBox(validateStart); + m_startSpin->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); + m_startSpin->setValue(model->minimumTime()); + + connect( + m_startSpin, QOverload::of(&QSpinBox::valueChanged), + this, &CurveEditorToolBar::startFrameChanged); + + connect( + model, &CurveEditorModel::commitStartFrame, + [this](int frame) { m_startSpin->setValue(frame); }); + + auto validateEnd = [this](int val) -> bool { + if (m_startSpin==nullptr) + return false; + return m_startSpin->value() < val; + }; + m_endSpin = new ValidatableSpinBox(validateEnd); + m_endSpin->setRange(std::numeric_limits::lowest(), std::numeric_limits::max()); + m_endSpin->setValue(model->maximumTime()); + + connect( + m_endSpin, QOverload::of(&QSpinBox::valueChanged), + this, &CurveEditorToolBar::endFrameChanged); + + connect( + model, &CurveEditorModel::commitEndFrame, + [this](int frame) { m_endSpin->setValue(frame); }); + + m_currentSpin->setMinimum(0); + m_currentSpin->setMaximum(std::numeric_limits::max()); + + connect( + m_currentSpin, QOverload::of(&QSpinBox::valueChanged), + this, &CurveEditorToolBar::currentFrameChanged); + + auto *durationBox = new QHBoxLayout; + durationBox->addWidget(new QLabel(tr("Start Frame"))); + durationBox->addWidget(m_startSpin); + durationBox->addWidget(new QLabel(tr("End Frame"))); + durationBox->addWidget(m_endSpin); + + auto *durationWidget = new QWidget; + durationWidget->setLayout(durationBox); + addWidget(durationWidget); + + auto *positionBox = new QHBoxLayout; + positionBox->addWidget(new QLabel(tr("Current Frame"))); + positionBox->addWidget(m_currentSpin); + + auto *positionWidget = new QWidget; + positionWidget->setLayout(positionBox); + addWidget(positionWidget); +} + +void CurveEditorToolBar::setCurrentFrame(int current, bool notify) +{ + if (notify) { + m_currentSpin->setValue(current); + } else { + QSignalBlocker blocker(m_currentSpin); + m_currentSpin->setValue(current); + } +} + +void CurveEditorToolBar::updateBoundsSilent(int start, int end) +{ + QSignalBlocker startBlocker(m_startSpin); + m_startSpin->setValue(start); + + QSignalBlocker endBlocker(m_endSpin); + m_endSpin->setValue(end); +} + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h new file mode 100644 index 00000000000..25271245c6e --- /dev/null +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditortoolbar.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Tooling +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +#include "keyframe.h" + +namespace QmlDesigner { + +class CurveEditorModel; + +class ValidatableSpinBox : public QSpinBox +{ + Q_OBJECT +public: + ValidatableSpinBox(std::function validator, QWidget* parent=nullptr); +protected: + QValidator::State validate(QString &text, int &pos) const override; +private: + std::function m_validator; +}; + + +class CurveEditorToolBar : public QToolBar +{ + Q_OBJECT + +signals: + void defaultClicked(); + + void unifyClicked(); + + void interpolationClicked(Keyframe::Interpolation interpol); + + void startFrameChanged(int start); + + void endFrameChanged(int end); + + void currentFrameChanged(int current); + +public: + CurveEditorToolBar(CurveEditorModel *model, QWidget* parent = nullptr); + + void setCurrentFrame(int current, bool notify); + + void updateBoundsSilent(int start, int end); + +private: + ValidatableSpinBox *m_startSpin; + ValidatableSpinBox *m_endSpin; + QSpinBox *m_currentSpin; +}; + +} // End namespace QmlDesigner. diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index 3d0f9a0e10b..cceecbb0b8e 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -395,11 +395,7 @@ void CurveEditorView::commitEndFrame(int frame) void CurveEditorView::init() { - QmlTimeline timeline = activeTimeline(); - if (timeline.isValid()) { - m_model->setTimeline(timeline); - } - + m_model->setTimeline(activeTimeline()); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp index ef8cf9f2f29..0b7ab9d391d 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp @@ -457,6 +457,18 @@ void CurveItem::setInterpolation(Keyframe::Interpolation interpolation) emit curveChanged(id(), curve()); } +void CurveItem::setDefaultInterpolation() +{ + if (m_keyframes.empty()) + return; + + for (auto *frame : qAsConst(m_keyframes)) { + if (frame->selected()) + frame->setDefaultInterpolation(); + } + emit curveChanged(id(), curve()); +} + void CurveItem::toggleUnified() { if (m_keyframes.empty()) diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h index f6857f7c065..5a2f363df7f 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.h @@ -125,6 +125,8 @@ public: void setInterpolation(Keyframe::Interpolation interpolation); + void setDefaultInterpolation(); + void toggleUnified(); void connect(GraphicsScene *scene); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp index 9198a4d9e57..9eda7f8934b 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.cpp @@ -208,6 +208,11 @@ SelectableItem *GraphicsScene::intersect(const QPointF &pos) const return nullptr; } +void GraphicsScene::setDirty(bool dirty) +{ + m_dirty = dirty; +} + void GraphicsScene::reset() { m_curves.clear(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h index cd42ffbd4da..2e6bc3b080d 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsscene.h @@ -88,6 +88,8 @@ public: SelectableItem *intersect(const QPointF &pos) const; + void setDirty(bool dirty); + void reset(); void deleteSelectedKeyframes(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp index 89084bc98bf..5b4e6e3cfbc 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp @@ -334,6 +334,18 @@ void GraphicsView::setInterpolation(Keyframe::Interpolation interpol) viewport()->update(); } +void GraphicsView::setDefaultInterpolation() +{ + const auto selectedCurves = m_scene->selectedCurves(); + for (auto *curve : selectedCurves) + curve->setDefaultInterpolation(); + + m_scene->setDirty(true); + + applyZoom(m_zoomX, m_zoomY); + viewport()->update(); +} + void GraphicsView::toggleUnified() { const auto selectedCurves = m_scene->selectedCurves(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h index 22b474d1bb7..917a8e7e2c4 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.h @@ -112,6 +112,8 @@ public: void setInterpolation(Keyframe::Interpolation interpol); + void setDefaultInterpolation(); + void toggleUnified(); protected: diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp index 025f5eb6eda..ef0a886d523 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.cpp @@ -239,6 +239,18 @@ void KeyframeItem::setKeyframe(const Keyframe &keyframe) setPos(m_transform.map(m_frame.position())); } +void KeyframeItem::setDefaultInterpolation() +{ + if (!m_left || !m_right) + return; + + m_frame.setDefaultInterpolation(); + + setKeyframe(m_frame); + + emit redrawCurve(); +} + void KeyframeItem::toggleUnified() { if (!m_left || !m_right) diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h index c0d33640278..3e566c84b74 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h +++ b/src/plugins/qmldesigner/components/curveeditor/detail/keyframeitem.h @@ -90,6 +90,8 @@ public: void setKeyframe(const Keyframe &keyframe); + void setDefaultInterpolation(); + void toggleUnified(); void setActivated(bool active, HandleItem::Slot slot); diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp index 02b2adc6366..085c230335c 100644 --- a/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.cpp @@ -25,6 +25,8 @@ #include "keyframe.h" +#include + #include namespace QmlDesigner { @@ -152,6 +154,15 @@ void Keyframe::setPosition(const QPointF &pos) m_position = pos; } +void Keyframe::setDefaultInterpolation() +{ + auto leftToRight = QLineF(m_leftHandle, m_rightHandle); + leftToRight.translate(m_position - leftToRight.center()); + + m_leftHandle = leftToRight.p1(); + m_rightHandle = leftToRight.p2(); +} + void Keyframe::setUnified(bool unified) { m_unified = unified; diff --git a/src/plugins/qmldesigner/components/curveeditor/keyframe.h b/src/plugins/qmldesigner/components/curveeditor/keyframe.h index d16e7d7a011..fd3c2cb88bc 100644 --- a/src/plugins/qmldesigner/components/curveeditor/keyframe.h +++ b/src/plugins/qmldesigner/components/curveeditor/keyframe.h @@ -28,6 +28,8 @@ #include #include +#include + namespace QmlDesigner { class Keyframe @@ -65,6 +67,8 @@ public: Interpolation interpolation() const; + void setDefaultInterpolation(); + void setUnified(bool unified); void setPosition(const QPointF &pos); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 4befc1cc678..218ca908121 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -23,23 +23,24 @@ ** ****************************************************************************/ +#include "designmodewidget.h" +#include "edit3dactions.h" +#include "edit3dcanvas.h" #include "edit3dview.h" #include "edit3dwidget.h" -#include "edit3dcanvas.h" -#include "edit3dactions.h" -#include "designmodewidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -216,6 +217,8 @@ void Edit3DView::modelAttached(Model *model) void Edit3DView::modelAboutToBeDetached(Model *model) { + QTC_ASSERT(edit3DWidget()->canvas(), return); + // Hide the canvas when model is detached (i.e. changing documents) m_canvasCache.insert(model, edit3DWidget()->canvas()->renderImage()); edit3DWidget()->showCanvas(false); diff --git a/src/plugins/qmldesigner/designercore/model/propertyparser.cpp b/src/plugins/qmldesigner/designercore/model/propertyparser.cpp index 3c7b498a929..eab05e0adc4 100644 --- a/src/plugins/qmldesigner/designercore/model/propertyparser.cpp +++ b/src/plugins/qmldesigner/designercore/model/propertyparser.cpp @@ -242,9 +242,21 @@ QVariant read(int variantType, const QString &str) bool conversionOk = true; switch (variantType) { case QMetaType::QVariant: { + + if (str == "true") + return true; + + if (str == "false") + return false; + auto tmp = QVariant(str); - value = QVariant(tmp); conversionOk = tmp.isValid(); + value = QVariant(tmp); + + if (tmp.canConvert(QMetaType::Double)) + value.convert(QMetaType::Double); + else if (tmp.canConvert(QMetaType::QColor)) + value.convert(QMetaType::QColor); break; } case QMetaType::QPoint: diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index 6332b6a9993..6d556ea0d4b 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -828,6 +828,8 @@ Project { "curveeditor/curveeditor.qrc", "curveeditor/curveeditormodel.cpp", "curveeditor/curveeditormodel.h", + "curveeditor/curveeditortoolbar.cpp", + "curveeditor/curveeditortoolbar.h", "curveeditor/curveeditorstyle.h", "curveeditor/curvesegment.cpp", "curveeditor/curvesegment.h", diff --git a/src/plugins/studiowelcome/qml/splashscreen/ColorOverlayEffect.qml b/src/plugins/studiowelcome/qml/splashscreen/ColorOverlayEffect.qml new file mode 100644 index 00000000000..6b670051624 --- /dev/null +++ b/src/plugins/studiowelcome/qml/splashscreen/ColorOverlayEffect.qml @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Designer Components. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import Qt5Compat.GraphicalEffects + +ColorOverlay { + id: colorOverlay + color: "#80fff000" +} diff --git a/src/plugins/studiowelcome/qml/splashscreen/EllipseItem.qml b/src/plugins/studiowelcome/qml/splashscreen/EllipseItem.qml new file mode 100644 index 00000000000..2ce07cab318 --- /dev/null +++ b/src/plugins/studiowelcome/qml/splashscreen/EllipseItem.qml @@ -0,0 +1,201 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Studio Components. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.10 +import QtQuick.Shapes 1.0 + +/*! + \qmltype EllipseItem + \inqmlmodule QtQuick.Studio.Components + \since QtQuick.Studio.Components 1.0 + \inherits Shape + + \brief A filled ellipse with an optional border. +*/ + +Shape { + id: root + width: 200 + height: 150 + +/*! + The gradient of the rectangle fill color. + + By default, no gradient is enabled and the value is null. In this case, the + fill uses a solid color based on the value of \l fillColor. + + When set, \l fillColor is ignored and filling is done using one of the + \l ShapeGradient subtypes. + + \note The \l Gradient type cannot be used here. Rather, prefer using one of + the advanced subtypes, like \l LinearGradient. +*/ + property alias gradient: path.fillGradient + +/*! + The style of the rectangle border. + + \value ShapePath.SolidLine + A solid line. This is the default value. + \value ShapePath.DashLine + Dashes separated by a few pixels. + The \l dashPattern property specifies the dash pattern. + + \sa Qt::PenStyle +*/ + property alias strokeStyle: path.strokeStyle + +/*! + The width of the border of the rectangle. + + The default value is 4. + + A width of 1 creates a thin line. For no line, use a negative value or a + transparent color. + + \note The width of the rectangle's border does not affect the geometry of + the rectangle itself or its position relative to other items if anchors are + used. + + The border is rendered within the rectangle's boundaries. +*/ + property alias strokeWidth: path.strokeWidth + +/*! + The color used to draw the border of the rectangle. + + When set to \c transparent, no line is drawn. + + The default value is \c red. + + \sa QColor +*/ + property alias strokeColor: path.strokeColor + +/*! + The dash pattern of the rectangle border specified as the dashes and the + gaps between them. + + The dash pattern is specified in units of the pen's width. That is, a dash + with the length 5 and width 10 is 50 pixels long. + + The default value is (4, 2), meaning a dash of 4 * \l strokeWidth pixels + followed by a space of 2 * \l strokeWidth pixels. + + \sa QPen::setDashPattern() +*/ + property alias dashPattern: path.dashPattern + +/*! + The rectangle fill color. + + A gradient for the fill can be specified by using \l gradient. If both a + color and a gradient are specified, the gradient is used. + + When set to \c transparent, no filling occurs. + + The default value is \c white. +*/ + property alias fillColor: path.fillColor + +/*! + The starting point of the dash pattern for the rectangle border. + + The offset is measured in terms of the units used to specify the dash + pattern. For example, a pattern where each stroke is four units long, + followed by a gap of two units, will begin with the stroke when drawn + as a line. However, if the dash offset is set to 4.0, any line drawn + will begin with the gap. Values of the offset up to 4.0 will cause part + of the stroke to be drawn first, and values of the offset between 4.0 and + 6.0 will cause the line to begin with part of the gap. + + The default value is 0. + + \sa QPen::setDashOffset() +*/ + property alias dashOffset: path.dashOffset + + layer.enabled: root.antialiasing + layer.smooth: root.antialiasing + layer.samples: root.antialiasing ? 4 : 0 + +/*! + The border is rendered within the rectangle's boundaries, outside of them, + or on top of them. +*/ + property int borderMode: 0 + + property real borderOffset: { + if (root.borderMode === 0) + return root.strokeWidth * 0.5 + if (root.borderMode === 1) + return 0 + + return -root.strokeWidth * 0.5 + } + + Item { + anchors.fill: parent + anchors.margins: { + if (root.borderMode === 0) + return 0 + if (root.borderMode === 1) + return -root.strokeWidth * 0.5 + + return -root.strokeWidth + } + } + + ShapePath { + id: path + + joinStyle: ShapePath.MiterJoin + strokeWidth: 4 + strokeColor: "red" + startX: root.width * 0.5 + startY: root.borderOffset + + PathArc { + x: path.startX + y: root.height - root.borderOffset + radiusX: root.width * 0.5 - root.borderOffset + radiusY: root.height * 0.5 - root.borderOffset + useLargeArc: true + } + + PathArc { + x: path.startX + y: path.startY + radiusX: root.width * 0.5 - root.borderOffset + radiusY: root.height * 0.5 - root.borderOffset + useLargeArc: true + } + + } +} diff --git a/src/plugins/studiowelcome/qml/splashscreen/FastBlurEffect.qml b/src/plugins/studiowelcome/qml/splashscreen/FastBlurEffect.qml new file mode 100644 index 00000000000..353fd1ddcac --- /dev/null +++ b/src/plugins/studiowelcome/qml/splashscreen/FastBlurEffect.qml @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Designer Components. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.8 +import Qt5Compat.GraphicalEffects + +FastBlur { + id: fastBlur + radius: 20 +} diff --git a/src/plugins/studiowelcome/qml/splashscreen/MyEllipse.qml b/src/plugins/studiowelcome/qml/splashscreen/MyEllipse.qml new file mode 100644 index 00000000000..b1195826ba1 --- /dev/null +++ b/src/plugins/studiowelcome/qml/splashscreen/MyEllipse.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import StudioFonts 1.0 +import projectmodel 1.0 +import usagestatistics 1.0 + +EllipseItem { + id: ellipse + width: 529 + height: 391 + opacity: 0.495 + layer.enabled: true + layer.effect: FastBlurEffect { + id: fastBlur + radius: 66 + transparentBorder: true + cached: true + } + fillColor: "#878787" + strokeColor: "#00ff0000" +} diff --git a/src/plugins/studiowelcome/qml/splashscreen/PushButton.ui.qml b/src/plugins/studiowelcome/qml/splashscreen/PushButton.ui.qml new file mode 100644 index 00000000000..968fdb18289 --- /dev/null +++ b/src/plugins/studiowelcome/qml/splashscreen/PushButton.ui.qml @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ +import QtQuick 2.15 +import QtQuick.Templates 2.15 + +Button { + id: control + + implicitWidth: Math.max( + buttonBackground ? buttonBackground.implicitWidth : 0, + textItem.implicitWidth + leftPadding + rightPadding) + implicitHeight: Math.max( + buttonBackground ? buttonBackground.implicitHeight : 0, + textItem.implicitHeight + topPadding + bottomPadding) + leftPadding: 4 + rightPadding: 4 + + text: "My Button" + property alias fontpixelSize: textItem.font.pixelSize + property bool forceHover: false + state: "normal" + + background: buttonBackground + Rectangle { + id: buttonBackground + color: "#00000000" + implicitWidth: 100 + implicitHeight: 40 + opacity: enabled ? 1 : 0.3 + radius: 2 + border.color: "#047eff" + anchors.fill: parent + } + + contentItem: textItem + + Text { + id: textItem + text: control.text + font.pixelSize: 18 + + opacity: enabled ? 1.0 : 0.3 + color: "#ffffff" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + rightPadding: 5 + leftPadding: 5 + } + + states: [ + State { + name: "normal" + when: !control.down && !control.hovered && !control.forceHover + + PropertyChanges { + target: buttonBackground + color: "#323232" + border.color: "#868686" + } + + PropertyChanges { + target: textItem + color: "#ffffff" + } + }, + State { + name: "hover" + when: (control.hovered || control.forceHover) && !control.down + PropertyChanges { + target: textItem + color: "#ffffff" + } + + PropertyChanges { + target: buttonBackground + color: "#474747" + border.color: "#adadad" + } + }, + State { + name: "activeQds" + when: control.down + PropertyChanges { + target: textItem + color: "#111111" + } + + PropertyChanges { + target: buttonBackground + color: "#2e769e" + border.color: "#2e769e" + } + } + ] +} diff --git a/src/plugins/studiowelcome/qml/splashscreen/RectangleItem.qml b/src/plugins/studiowelcome/qml/splashscreen/RectangleItem.qml new file mode 100644 index 00000000000..b2bd1d1ae84 --- /dev/null +++ b/src/plugins/studiowelcome/qml/splashscreen/RectangleItem.qml @@ -0,0 +1,418 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Quick Studio Components. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.10 +import QtQuick.Shapes 1.0 + +/*! + \qmltype RectangleItem + \inqmlmodule QtQuick.Studio.Components + \since QtQuick.Studio.Components 1.0 + \inherits Shape + + \brief A filled rectangle with an optional border. + + Rectangle items are used to fill areas with solid color or gradients and + to provide a rectangular border. + + Each Rectangle item is painted using either a solid fill color, specified + using the \l fillColor property, or a gradient, defined using one of the + \l ShapeGradient subtypes and set using the \l gradient property. + If both a color and a gradient are specified, the gradient is used. + + An optional border can be added to a rectangle with its own color and + thickness by setting the \l strokeColor and \l strokeWidth properties. + Setting the color to \c transparent creates a border without a fill color. + + Rounded rectangles can be drawn using the \l radius property. The radius + can also be specified separately for each corner. Because this introduces + curved edges to the corners of a rectangle, it may be appropriate to set + the \c antialiasing property that is inherited from \l Item to improve the + appearance of the rectangle. + + \section2 Example Usage + + You can use the Rectangle component in \QDS to create different kinds of + rectangles. + + \image studio-rectangle.png + + The QML code looks as follows: + + \code + RectangleItem { + id: rectangle + gradient: RadialGradient { + focalRadius: 0 + centerY: 38.5 + focalY: 38.5 + centerX: 51.5 + centerRadius: 38.5 + GradientStop { + position: 0 + color: "#ffffff" + } + + GradientStop { + position: 1 + color: "#000000" + } + focalX: 51.5 + } + bottomRightRadius: 0 + topLeftRadius: 0 + strokeColor: "gray" + } + + RectangleItem { + id: rectangle1 + gradient: LinearGradient { + y1: 0 + y2: 77 + x2: 103 + x1: 0 + GradientStop { + position: 0 + color: "#ffffff" + } + + GradientStop { + position: 1 + color: "#000000" + } + } + topRightRadius: 0 + bottomLeftRadius: 0 + strokeColor: "#808080" + } + + RectangleItem { + id: rectangle2 + topLeftRadius: 0 + bottomRightRadius: 0 + fillColor: "#d3d3d3" + strokeColor: "#808080" + } + + RectangleItem { + id: rectangle3 + fillColor: "#000000" + gradient: LinearGradient { + y1: 0 + y2: 77 + x2: 103 + x1: 0 + GradientStop { + position: 0 + color: "#000000" + } + + GradientStop { + position: 1 + color: "#fdf9f9" + } + } + topRightRadius: 0 + bottomLeftRadius: 0 + strokeColor: "#808080" + } + \endcode +*/ + +Shape { + id: root + width: 200 + height: 150 + +/*! + The radius used to draw rounded corners. + + The default value is 10. + + If radius is non-zero, the corners will be rounded, otherwise they will + be sharp. The radius can also be specified separately for each corner by + using the \l bottomLeftRadius, \l bottomRightRadius, \l topLeftRadius, and + \l topRightRadius properties. +*/ + property int radius: 10 + +/*! + The radius of the top left rectangle corner. +*/ + property int topLeftRadius: root.radius + +/*! + The radius of the bottom left rectangle corner. +*/ + property int bottomLeftRadius: root.radius + +/*! + The radius of the top right rectangle corner. +*/ + property int topRightRadius: root.radius + +/*! + The radius of the bottom right rectangle corner. +*/ + property int bottomRightRadius: root.radius + +/*! + The gradient of the rectangle fill color. + + By default, no gradient is enabled and the value is null. In this case, the + fill uses a solid color based on the value of \l fillColor. + + When set, \l fillColor is ignored and filling is done using one of the + \l ShapeGradient subtypes. + + \note The \l Gradient type cannot be used here. Rather, prefer using one of + the advanced subtypes, like \l LinearGradient. +*/ + property alias gradient: path.fillGradient + +/*! + The style of the rectangle border. + + \value ShapePath.SolidLine + A solid line. This is the default value. + \value ShapePath.DashLine + Dashes separated by a few pixels. + The \l dashPattern property specifies the dash pattern. + + \sa Qt::PenStyle +*/ + property alias strokeStyle: path.strokeStyle + +/*! + The width of the border of the rectangle. + + The default value is 4. + + A width of 1 creates a thin line. For no line, use a negative value or a + transparent color. + + \note The width of the rectangle's border does not affect the geometry of + the rectangle itself or its position relative to other items if anchors are + used. + + The border is rendered within the rectangle's boundaries. +*/ + property alias strokeWidth: path.strokeWidth + +/*! + The color used to draw the border of the rectangle. + + When set to \c transparent, no line is drawn. + + The default value is \c red. + + \sa QColor +*/ + property alias strokeColor: path.strokeColor + +/*! + The dash pattern of the rectangle border specified as the dashes and the + gaps between them. + + The dash pattern is specified in units of the pen's width. That is, a dash + with the length 5 and width 10 is 50 pixels long. + + The default value is (4, 2), meaning a dash of 4 * \l strokeWidth pixels + followed by a space of 2 * \l strokeWidth pixels. + + \sa QPen::setDashPattern() +*/ + property alias dashPattern: path.dashPattern + + + property alias joinStyle: path.joinStyle + +/*! + The rectangle fill color. + + A gradient for the fill can be specified by using \l gradient. If both a + color and a gradient are specified, the gradient is used. + + When set to \c transparent, no filling occurs. + + The default value is \c white. +*/ + property alias fillColor: path.fillColor + +/*! + The starting point of the dash pattern for the rectangle border. + + The offset is measured in terms of the units used to specify the dash + pattern. For example, a pattern where each stroke is four units long, + followed by a gap of two units, will begin with the stroke when drawn + as a line. However, if the dash offset is set to 4.0, any line drawn + will begin with the gap. Values of the offset up to 4.0 will cause part + of the stroke to be drawn first, and values of the offset between 4.0 and + 6.0 will cause the line to begin with part of the gap. + + The default value is 0. + + \sa QPen::setDashOffset() +*/ + property alias dashOffset: path.dashOffset + +/*! + Whether the border corner is beveled. +*/ + property bool bevel: false + +/*! + The bevel of the top left border corner. + + \sa bevel +*/ + property bool topLeftBevel: root.bevel + +/*! + The bevel of the top right border corner. + + \sa bevel +*/ + property bool topRightBevel: root.bevel + +/*! + The bevel of the bottom right border corner. + + \sa bevel +*/ + property bool bottomRightBevel: root.bevel + +/*! + The bevel of the bottom left border corner. + + \sa bevel +*/ + property bool bottomLeftBevel: root.bevel + + layer.enabled: root.antialiasing + layer.smooth: root.antialiasing + layer.samples: root.antialiasing ? 4 : 0 + +/*! + The border is rendered within the rectangle's boundaries, outside of them, + or on top of them. +*/ + property int borderMode: 0 + + property real borderOffset: { + if (root.borderMode === 0) + return root.strokeWidth * 0.5 + if (root.borderMode === 1) + return 0 + + return -root.strokeWidth * 0.5 + } + + Item { + anchors.fill: parent + anchors.margins: { + if (root.borderMode === 0) + return 0 + if (root.borderMode === 1) + return -root.strokeWidth * 0.5 + + return -root.strokeWidth + } + } + + ShapePath { + id: path + + property int __maxRadius: Math.floor(Math.min(root.width, root.height) / 2) + property int __topLeftRadius: Math.min(root.topLeftRadius, path.__maxRadius) + property int __topRightRadius: Math.min(root.topRightRadius, path.__maxRadius) + property int __bottomRightRadius: Math.min(root.bottomRightRadius, path.__maxRadius) + property int __bottomLeftRadius: Math.min(root.bottomLeftRadius, path.__maxRadius) + + joinStyle: ShapePath.MiterJoin + + strokeWidth: 4 + strokeColor: "red" + + startX: path.__topLeftRadius + root.borderOffset + startY: root.borderOffset + + PathLine { + x: root.width - path.__topRightRadius - root.borderOffset + y: root.borderOffset + } + + PathArc { + x: root.width - root.borderOffset + y: path.__topRightRadius + root.borderOffset + + radiusX: root.topRightBevel ? 50000 : path.__topRightRadius + radiusY: root.topRightBevel ? 50000 : path.__topRightRadius + } + + PathLine { + x: root.width - root.borderOffset + y: root.height - path.__bottomRightRadius - root.borderOffset + } + + PathArc { + x: root.width - path.__bottomRightRadius - root.borderOffset + y: root.height - root.borderOffset + + radiusX: root.bottomRightBevel ? 50000 : path.__bottomRightRadius + radiusY: root.bottomRightBevel ? 50000 : path.__bottomRightRadius + } + + PathLine { + x: path.__bottomLeftRadius + root.borderOffset + y: root.height - root.borderOffset + } + + PathArc { + x: root.borderOffset + y: root.height - path.__bottomLeftRadius - root.borderOffset + + radiusX: root.bottomLeftBevel ? 50000 : path.__bottomLeftRadius + radiusY: root.bottomLeftBevel ? 50000 : path.__bottomLeftRadius + } + + PathLine { + x: root.borderOffset + y: path.__topLeftRadius + root.borderOffset + } + + PathArc { + x: path.__topLeftRadius + root.borderOffset + y: root.borderOffset + + radiusX: root.topLeftBevel ? 50000 : path.__topLeftRadius + radiusY: root.topLeftBevel ? 50000 : path.__topLeftRadius + } + } +} diff --git a/src/plugins/studiowelcome/qml/splashscreen/Splash_Image25d.qml b/src/plugins/studiowelcome/qml/splashscreen/Splash_Image25d.qml index f0ae6c2d8b0..38054b52f9a 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Splash_Image25d.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Splash_Image25d.qml @@ -22,7 +22,6 @@ ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ - import QtQuick 2.3 Rectangle { @@ -30,6 +29,7 @@ Rectangle { width: 460 height: 480 color: "transparent" + scale: 1.2 layer.enabled: true layer.textureSize: Qt.size(width * 2, height * 2) @@ -40,21 +40,27 @@ Rectangle { anchors.centerIn: parent width: 460 height: 480 + visible: true + anchors.verticalCenterOffset: -1 + anchors.horizontalCenterOffset: 14 + clip: true layer.enabled: true layer.textureSize: Qt.size(width * 2, height * 2) layer.smooth: true Splash_Image2d_png { - x: 25 - y: 15 - antialiasing: false - scale: 1.4 - transform: Matrix4x4 { - matrix: Qt.matrix4x4(1.12606, 0.06371, 0, 0, 0.26038, 0.90592, - 0, 0, 0.00000, 0.0000, 1.0, 0, - 0.00121, -0.00009, 0.0, 1) + x: -22 + y: -33 + width: 461 + height: 427 + layer.enabled: true + layer.effect: ColorOverlayEffect { + id: colorOverlay + visible: true + color: "#41cd52" } + scale: 1 } } } diff --git a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml index 24fba429eaa..153436278ee 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml @@ -22,23 +22,30 @@ ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ - import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import StudioFonts 1.0 import projectmodel 1.0 import usagestatistics 1.0 +import QtQuick.Shapes 1.0 Rectangle { id: welcome_splash anchors.fill: parent + clip: true gradient: Gradient { orientation: Gradient.Horizontal - GradientStop { position: 0.0; color: "#1d212a" } - GradientStop { position: 1.0; color: "#232c56" } + GradientStop { + position: 0.0 + color: "#1d212a" + } + GradientStop { + position: 1.0 + color: "#232c56" + } } signal goNext @@ -47,52 +54,118 @@ Rectangle { property bool doNotShowAgain: true property bool loadingPlugins: true + + width: 600 + height: 720 + visible: true color: "#1d212a" + Rectangle { + id: qtGreen + color: "#515151" + anchors.fill: parent + anchors.rightMargin: 0 + anchors.bottomMargin: 0 + anchors.leftMargin: 0 + anchors.topMargin: 0 + } + + RectangleItem { + id: background + opacity: 0.825 + anchors.fill: parent + gradient: LinearGradient { + x1: 0 + stops: [ + GradientStop { + position: 0 + color: "#29323c" + }, + GradientStop { + position: 1 + color: "#485563" + } + ] + x2: 640 + y2: 800 + y1: 0 + } + topRightRadius: 0 + anchors.topMargin: 0 + bottomLeftRadius: 0 + borderMode: 1 + fillColor: "#2d2d2d" + bottomRightRadius: 0 + topLeftRadius: 0 + topRightBevel: true + bottomLeftBevel: true + strokeColor: "#00ff0000" + } + + RectangleItem { + id: topBar + opacity: 0.239 + anchors.fill: parent + anchors.bottomMargin: 550 + strokeColor: "#00ff0000" + bottomRightRadius: 0 + topRightBevel: true + fillColor: "#2d2d2d" + bottomLeftRadius: 0 + topRightRadius: 0 + borderMode: 1 + anchors.topMargin: 0 + topLeftRadius: 0 + bottomLeftBevel: true + } + + RectangleItem { + id: bottomBar + opacity: 0.534 + visible: true + anchors.fill: parent + anchors.rightMargin: 0 + anchors.leftMargin: 0 + strokeColor: "#00ff0000" + anchors.bottomMargin: 0 + bottomRightRadius: 0 + bottomLeftRadius: 0 + fillColor: "#2d2d2d" + topRightBevel: true + topRightRadius: 0 + borderMode: 1 + anchors.topMargin: 539 + topLeftRadius: 0 + bottomLeftBevel: true + } + + MyEllipse { + id: ellipse + x: 0 + y: 204 + width: 640 + height: 391 + opacity: 0.05 + } + Image { id: logo anchors.top: parent.top - anchors.left: parent.left anchors.margins: 10 - width: 66 * 2 - height: 50 * 2 smooth: true source: "welcome_windows/logo.png" - } - - - Text { - id: qt_design_studio_text - anchors.top: logo.top - anchors.left: logo.right - anchors.leftMargin: 10 - color: "#25709a" - text: qsTr("Qt Design Studio") - font.pixelSize: 36 - font.family: StudioFonts.titilliumWeb_light - } - - Text { - id: qt_design_studio_version_text - anchors.left: qt_design_studio_text.right - anchors.baseline: qt_design_studio_text.baseline - anchors.leftMargin: 10 - color: "#25709a" - text: usageStatisticModel.version - - font.family: StudioFonts.titilliumWeb_light - font.pixelSize: 36 + anchors.topMargin: 10 + anchors.horizontalCenter: parent.horizontalCenter } Text { id: license_variant_text - anchors.left: qt_design_studio_text.left - anchors.top: qt_design_studio_text.bottom - anchors.leftMargin: 5 + anchors.top: designStudioVersion.bottom color: "#ffffff" font.family: StudioFonts.titilliumWeb_light font.pixelSize: 20 + anchors.horizontalCenter: parent.horizontalCenter text: { if (projectModel.communityVersion) @@ -111,56 +184,94 @@ Rectangle { } } - Dof_Effect { - id: dof_effect - anchors.top: qt_design_studio_text.bottom - anchors.horizontalCenter: welcome_splash.horizontalCenter - width: 442 - height: 480 - maskBlurSamples: 64 - maskBlurRadius: 32 - - Splash_Image25d { - id: animated_artwork - width: dof_effect.width - height: dof_effect.height - clip: true - } + //DOF seems to do nothing, we should probably just remove it. + Splash_Image25d { + id: animated_artwork + width: 628 + height: 377 + anchors.top: license_variant_text.bottom + anchors.horizontalCenterOffset: 0 + scale: 1.1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 50 + clip: true } Text { id: help_us_text anchors.left: welcome_splash.left anchors.right: parent.right - anchors.leftMargin: 10 - anchors.top: dof_effect.bottom - anchors.topMargin: 10 + anchors.leftMargin: 20 + anchors.top: bottomBar.top color: "#FFFFFF" - text: qsTr("Before we let you move on to your wonderful designs, help us make Qt Design Studio even better by letting us know how you're using it.") - + text: qsTr("Before we let you move on to your wonderful designs, help us make Qt Design Studio even better by letting us know how you're using it. To do this, we would like to turn on automatic collection of pseudonymized Analytics and Crash Report Data.") font.family: StudioFonts.titilliumWeb_light - font.pixelSize: 18 + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter wrapMode: Text.WordWrap - anchors.rightMargin: 10 + anchors.topMargin: 25 + anchors.rightMargin: 20 } - ColumnLayout { - id: columnLayout + RowLayout { + anchors.right: parent.right + anchors.bottom: welcome_splash.bottom + anchors.rightMargin: 20 + anchors.bottomMargin: 20 + spacing: 20 + + PushButton { + text: qsTr("Turn Off") + fontpixelSize: 14 + onClicked: { + usageStatisticModel.setTelemetryEnabled(false) + usageStatisticModel.setCrashReporterEnabled(false) + welcome_splash.closeClicked() + } + } + + PushButton { + text: qsTr("Turn On") + forceHover: false + fontpixelSize: 14 + onClicked: { + usageStatisticModel.setTelemetryEnabled(true) + usageStatisticModel.setCrashReporterEnabled(true) + welcome_splash.closeClicked() + } + } + } + + PushButton { + y: 430 + text: qsTr("Learn More") anchors.left: parent.left - anchors.top: help_us_text.bottom - anchors.leftMargin: 10 - anchors.topMargin: 20 - spacing: 3 + anchors.bottom: parent.bottom + fontpixelSize: 14 + anchors.bottomMargin: 20 + anchors.leftMargin: 20 + onClicked: Qt.openUrlExternally( + "https://www.qt.io/terms-conditions/telemetry-privacy") + } + + Row { + y: 690 + visible: false + anchors.horizontalCenter: parent.horizontalCenter + spacing: 20 + layoutDirection: Qt.LeftToRight CheckBox { - visible: false + visible: true id: usageStatisticCheckBox text: qsTr("Send Usage Statistics") checked: usageStatisticModel.usageStatisticEnabled padding: 0 spacing: 12 - onCheckedChanged: usageStatisticModel.setTelemetryEnabled(usageStatisticCheckBox.checked) + onCheckedChanged: usageStatisticModel.setTelemetryEnabled( + usageStatisticCheckBox.checked) contentItem: Text { text: usageStatisticCheckBox.text @@ -171,15 +282,17 @@ Rectangle { } CheckBox { - visible: false + visible: true id: crashReportCheckBox text: qsTr("Send Crash Reports") spacing: 12 checked: usageStatisticModel.crashReporterEnabled onCheckedChanged: { - usageStatisticModel.setCrashReporterEnabled(crashReportCheckBox.checked) - welcome_splash.onPluginInitialized(true, crashReportCheckBox.checked) + usageStatisticModel.setCrashReporterEnabled( + crashReportCheckBox.checked) + welcome_splash.onPluginInitialized(true, + crashReportCheckBox.checked) } contentItem: Text { @@ -192,39 +305,39 @@ Rectangle { } } - RowLayout { - anchors.right: parent.right - anchors.bottom: welcome_splash.bottom - anchors.rightMargin: 10 - anchors.bottomMargin: 10 - spacing: 20 + Row { + id: designStudioVersion + anchors.top: logo.bottom + anchors.topMargin: 5 + spacing: 10 + anchors.horizontalCenter: parent.horizontalCenter - CustomButton { - text: qsTr("Don't send") - onClicked: { - usageStatisticModel.setTelemetryEnabled(false) - usageStatisticModel.setCrashReporterEnabled(false) - welcome_splash.closeClicked() - } + Text { + id: qt_design_studio_text + height: 45 + color: "#ffffff" + text: qsTr("Qt Design Studio") + font.pixelSize: 36 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: StudioFonts.titilliumWeb_light } - CustomButton { - text: qsTr("Send analytics data") - onClicked: { - usageStatisticModel.setTelemetryEnabled(true) - usageStatisticModel.setCrashReporterEnabled(true) - welcome_splash.closeClicked() - } + Text { + id: qt_design_studio_version_text + height: 45 + color: "#fbfbfb" + text: usageStatisticModel.version + font.family: StudioFonts.titilliumWeb_light + font.pixelSize: 36 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter } } - - CustomButton { - y: 430 - text: qsTr("Learn More") - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.bottomMargin: 10 - anchors.leftMargin: 10 - onClicked: Qt.openUrlExternally("https://www.qt.io/terms-conditions/telemetry-privacy") - } } + +/*##^## +Designer { + D{i:0;height:720;width:600}D{i:22} +} +##^##*/ diff --git a/src/plugins/studiowelcome/qml/splashscreen/main.qml b/src/plugins/studiowelcome/qml/splashscreen/main.qml index 9ada7e7504f..b60e4668cb0 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/main.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/main.qml @@ -27,7 +27,7 @@ import QtQuick 2.0 Item { id: root - width: 720 + width: 600 height: 720 signal closeClicked