aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols2/qquickstyleplugin.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Make tests explicitly use Basic where necessaryMitch Curtis2020-10-071-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | The previous commit changes the how the default style is set, and since the tests all assumed that Basic was the default, we now need to ensure it is explicitly set. If we want to, we can revert this patch (or file-by-file) later and ensure that these tests work with all styles. For now, just keep things working as they used to. Tests that use QTEST_QUICKCONTROLS_MAIN are not changed, as they already run with all built-in styles. Tests that don't use types that will cause issues, like tst_qquickcolor, do not need to be changed. tst_snippets can be run manually to produce screenshots, so we specify its style in a qtquickcontrols2.conf file to allow it to be overridden by e.g. application arguments (QQuickStyle::setStyle() takes precedence over all other approaches of setting a style). Change-Id: Ifae7e959f89a41a757c170272038fad139bba04f Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Support compile-time style selectionMitch Curtis2020-09-241-5/+70
| | | | | | | | | | | | | | By allowing importing styles without first importing QtQuick.Controls, which does runtime style selection. [ChangeLog][Styles] It's now possible to select a style at compile-time by importing that style explicitly instead of QtQuick.Controls. This avoids the need to do run-time style selection and hence deploy the QtQuick.Controls plugin with the application. Change-Id: I666d6dc7727fffd2c7b05743855f2086f076465a Fixes: QTBUG-86284 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Fix fallback styles overwriting themesMitch Curtis2020-09-241-7/+13
| | | | | | | | | | | | | | | | | | | | | In Qt 5, QtQuickControls2Plugin::registerTypes() was responsible for calling initializeTheme() on each style plugin. Now that we delegate more work to the QML engine, each style plugin calls initializeTheme() via registerTypes(). To avoid fallback styles overwriting font and palette data set by the current style, we need to check if the theme has been intialized before calling initializeTheme(). To do this, we add a static "themeInitialized" bool that QQuickStylePlugin sets to true after calling intializeTheme() for the first time. It checks this value and avoids calling intializeTheme() if it's true. We also need to make QQuickStylePlugin ensure that the theme it's initializing belongs to the current style. Fixes: QTBUG-86303 Change-Id: Ie65e646677c78622829f4949c41cb79204cf5786 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
* Fix crash when importing a style without first importing ControlsMitch Curtis2020-08-271-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The following code import QtQuick import QtQuick.Controls.Material ApplicationWindow { width: 200 height: 200 visible: true } produced an error in Qt 5: QQmlApplicationEngine failed to load component qrc:/main.qml:4 ApplicationWindow is not a type In Qt 6, the types are provided by the qmldir, so the import will work, but as QtQuickControls2Plugin has not been loaded, there is no QQuickTheme object yet, and so the style will not work as expected (any colors, fonts, etc. from the theme will not be used by the style). Produce a warning for this scenario, and test each style to make sure that we don't crash. Fixes: QTBUG-86280 Change-Id: I99f940255f56da0522ad192ae5da4c9110ea308e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Use qmlRegisterModuleImport() to register stylesMitch Curtis2020-08-261-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch completes the cumulative work done in previous patches. - Uses qmlRegisterModuleImport() to register styles. This has some added requirements: - Each style must now be a QML module -- that is, it must have a qmldir file. - As a result of the above, the module must be available within the QML import path in order to be found. - The various forms of accepted style names have been reduced down to one ("Material", "MyStyle", etc). See below for an explanation of why. - The following API in QQuickStyle is removed: addStylePath(), availableStyles(), path(), stylePathList(). These no longer make sense now that we reuse the existing QML import system. - Adds the tst_qquickstyleselector auto test back as "styleimports". qmlRegisterModuleImport() vs resolvedUrl() Previously we would use QQuickStyleSelector to select individual QML files based on which style was set. We'd do this once when QtQuick.Controls was first imported. With Qt 6, and the requirement that each style be a proper QML module, qmlRegisterModuleImport() was introduced. This allows us to "link" one import with another. For an example of what this looks like in practice, suppose the style was set to "MyStyle", and the fallback to "Material". The "QtQuick.Controls" import will be linked to "MyStyle", "MyStyle" to "QtQuick.Controls.Material", and as a final fallback (for controls like Action which only the Default style implements), "QtQuick.Controls.Material" to "QtQuick.Controls.Default". This is the same behavior as in Qt 5 (see qquickstyleselector.cpp): // 1) requested style (e.g. "MyStyle", included in d->selectors) // 2) fallback style (e.g. "Material", included in d->selectors) // 3) default style (empty selector, not in d->selectors) This is a necessary step to enable compilation of QML to C++. Reducing the set of accepted style names The problem In QtQuickControls2Plugin() we need to call QQuickStylePrivate::init(baseUrl()) in order to detect if the style is a custom style in QQuickStyleSpec::resolve() (by checking if the style path starts with the base URL). In Qt 5, init() is called in QtQuickControls2Plugin::registerTypes(), but in Qt 6 that's too late, because we need to call qmlRegisterModuleImport() in the constructor. qmlRegisterModuleImport() itself requires the style to have already been set in order to create the correct import URI ("QtQuick.Controls.X" for built-in styles, "MyCustomStyle" for custom styles). The solution By reducing the valid forms for style names down to one: ./myapp -style MyStyle we solve the problem of needing baseUrl() to determine if the style is a custom style or not, but needing to call it too early (since we now call qmlRegisterModuleImport() in QtQuickControls2Plugin(), which itself requires the style to have already been set). baseUrl() can't have been set before the constructor is finished. All of the various forms for _setting_ a style are still valid; environment variables, qtquickcontrols2.conf, etc. [ChangeLog][Important Behavior Changes] Custom styles must now have a qmldir that lists the files that the style implements. For example, for a style that only implements Button: --- module MyStyle Button 1.0 Button.qml --- In addition, there is now only one valid, case-sensitive form for style names: "Material", "MyStyle", etc. These changes are done to help enable the compilation of QML code to C++, as well as improve tooling capabilities. [ChangeLog][Important Behavior Changes] The following API was removed: - QQuickStyle::addStylePath() - QQuickStyle::availableStyles() - QQuickStyle::path() - QQuickStyle::stylePathList() - QT_QUICK_CONTROLS_STYLE_PATH This API is no longer necessary and/or able to be provided now that styles are treated as regular QML modules. Task-number: QTBUG-82922 Change-Id: I3b281131903c7c3c1cf0616eb7486a872dccd730 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Register C++ types declarativelyMitch Curtis2020-08-261-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Adapt to the new way of registering C++ types. The types need to be seen at compile time so that code can be generated that invokes them. This patch: - Adds QML_* macros where applicable. - Adapts the build system files to the new way of registering modules. - Splits up the QtQuick.Controls[.*].impl files into their own plugins, as we can only register one QML module per .pro file. - Removes C++ type registration calls in every plugin. - Moves private types from src/quickcontrols2/quickcontrols2.pro to src/quickcontrols2/impl/quickcontrols2-impl.pro. Some of these types need to be exposed to QML, but quickcontrols2.pro is already in use to declare the QtQuick.Controls import (and also provides the public C++ QQuickStyle API), and the new QML_IMPORT_NAME/VERSION syntax only allows one module per project. As some of the types that need to be exposed to QML are also referenced by some C++ code (e.g. tests, etc.), we just move all of the private types to the new library. Follow-up patches will register the QML types declaratively. Task-number: QTBUG-82922 Change-Id: Iaf9ee106237d61701d57a8896f3822304c8151a6 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Move Default style out into its own pluginMitch Curtis2020-08-261-9/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In upcoming patches, we start registering C++ types declaratively. A condition of doing so requires that each .pro corresponds to one QML module. This conflicts with the QtQuick.Controls import, which currently does quite a lot: - Registers (and selects) QML files for the style that was set - Registers private C++ utility types (such as IconLabel) that are useful for all styles under the QtQuick.Controls.impl import - Registers private C++ types that are only useful for the Default style (such as BusyIndicatorImpl). The reason it does so much can probably be explained by the intended usage of Qt Quick Controls 2; when you do import QtQuick.Controls 2.0 you get access to the QML types (e.g. Button) that the style you're using provides. So if you're using the Material style, you'll get a Material style button. API-wise, the button is identical to any other button, because the types in QtQuick.Templates are what we advertise as the public API. If we didn't have this functionality, users would need to import specific style imports to use controls, and the convenience of being able to simply start the application with a different style by e.g. passing an application argument would be lost. To support declarative registration of types while also supporting the existing use cases, we split out the Default-style-specific stuff into a QtQuick.Controls.Default import. Task-number: QTBUG-82922 Change-Id: Ib4f1620cae78d7acdc13d9ac0752a020bc22f3ea Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Stop using resolvedUrl() to resolve QML filesMitch Curtis2020-08-261-36/+6
| | | | | | | | | | | | | | | | | | | | This is necessary to move away from imperative type registration of QML files (i.e. qmlRegisterType()). A later patch will use qmlRegisterModuleImport() to register the QtQuick.Controls import with the style set by the user, which will require each style to have a qmldir listing the files that it provides. Note that some plugins still register QML files, but these registrations will have to stay for now until we can split out "impl" plugins in later patches where those files can be registered. tst_qquickstyleselector will be added back in some other form in a follow-up patch. Task-number: QTBUG-82922 Change-Id: I8182533d9912ed493efda6eb91c69fc064af07ee Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Add ; to Q_UNUSEDLars Schmertmann2020-06-301-1/+1
| | | | | | | | | This is required to remove the ; from the macro with Qt 6. Task-number: QTBUG-82978 Change-Id: I92ef02ede041d3965151165a479a1ea0549cc0f9 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Adapt to plugin unloading changesMitch Curtis2020-03-121-1/+9
| | | | | | | | | | | | | | | | | | | | As of c2081016e in qtdeclarative, plugins are no longer unloaded on macOS, and QQmlExtensionPlugin::unregisterTypes() should be used instead. This patch: - Moves everything that was done in destructors to unregisterTypes(). - Ensures that the style selector is destroyed in QQuickStylePlugin::unregisterTypes() so that previous styles that were set do not stick around after qmlClearTypeRegistrations() is called. This ensures that runtime style-switching continues to work. - Adds more logging output to make it easier to diagnose issues in the future. - Adds more code comments to ease maintenance. Change-Id: Ibbfeba4501d6ba0d5a257dcceace3498904a816e Fixes: QTBUG-82811 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Create and init QQuickTheme from QtQuickControls2PluginJ-P Nurmi2018-05-221-50/+2
| | | | | | | | | | | | | | | Instead of creating and setting the QQuickTheme instance from each style plugin (e.g. QtQuickControls2MaterialStylePlugin), create the QQuickTheme instance in QtQuickControls2Plugin when the style is being resolved, and just pass the instance to be initialized by the style plugin(s). This avoids the problem that QQuickTheme API was virtual, and sub-classes created from plugins would have vtables destroyed before the QQuickTheme was destroyed. Task-number: QTBUG-67062 Task-number: QTBUG-68087 Change-Id: I19e9ced5296b708c2668c30163389cb3da6be7cf Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Rename QQuickTheme::current to instanceJ-P Nurmi2018-05-161-3/+3
| | | | | | | | Avoid giving a wrong impression that the theme instance could be changed on the fly. Change-Id: Ifb5078422385d2f15da6a416d89cc9d6f46b0f40 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QQuickStylePlugin: use pimplJ-P Nurmi2018-05-161-14/+25
| | | | | | Task-number: QTBUG-67062 Change-Id: I3f7d81cbb4a0d8366b98eacf9cdbd64013b6ec47 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Move font/palette reading to QQuickStylePrivateJ-P Nurmi2018-05-161-83/+2
| | | | | | | | Instead of moving the code back and forth between different plugins, promote it to QQuickStylePrivate so it can be used from any plugin. Change-Id: Ifb80923750ff531676dc3347dacf0aff8c026fdb Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QQuickStylePlugin: prepare for Qt Quick CompilerJ-P Nurmi2018-05-121-13/+19
| | | | | | | | | | Don't hardcode the URL (QRC in static vs. FS in dynamic), but make use of QQuickFileSelector so the appropriate URL gets chosen "for free". This way, we can later add Qt Quick Compiler support for the internal QML files, such as CheckIndicator.qml. Change-Id: Ie1c55f3d82fbf92d0116966b354298338ef5ace6 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QQuickTheme: cleanup the APIJ-P Nurmi2018-03-151-7/+4
| | | | | | Task-number: QTBUG-67062 Change-Id: Id2f821bd41b72f7bce9885295e89c322eb3332f4 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QQuickTheme: don't inherit QPlatformThemeJ-P Nurmi2018-02-271-4/+6
| | | | | | | | | | | | | | | | Use QPlatformTheme as a fallback instead of inheriting from it. This way, Qt Quick Controls 2 themes don't mess up the fonts and palettes of Qt Quick Controls 1 and Qt Widgets applications. Note: QQuickTheme::Font and QQuickTheme::Palette enums are copies of the respective enums in QPlatformTheme, for now. This is the simplest first step, but later on, we can have our own set of enums that cover controls, such as Switch, that were previously entirely missing from QPlatformTheme. Task-number: QTBUG-51921 Change-Id: I8efe0ba2d03d65bc12b55b533ba9f2fab5320348 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Fix fonts and palettes in apps without :/qtquickcontrols2.confJ-P Nurmi2018-02-261-2/+6
| | | | | | | | Obviously theme fonts and palettes must be resolved regardless of QT_CONFIG(settings) and whether :/qtquickcontrols2.conf exists. Change-Id: I471af2af291dc4508f2eb3985b90faa6d530f096 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Promote QQuick(Proxy)Theme from libQQC2 to libQQT2J-P Nurmi2018-02-151-1/+1
| | | | | | | | | | QQuickTheme needs to be part of libQtQuickTemplates to be able to provide dark and light palettes (and later, icons). Task-number: QTBUG-63331 Change-Id: If7d3d279a07b6daf6701a1d3cd3686bec1d094b4 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Read :/qtquickcontrols2.conf in QQuickStylePluginJ-P Nurmi2018-02-151-3/+92
| | | | | | | | | | | | | | | | | QQuickTheme is going to be promoted from libQQC2 to libQQT2 so that it can provide dark and light palettes (and later, icons). The first step is to refactor out the :/qtquickcontrols2.conf reading code, which cannot be in style-agnostic libQQT2. Read the conf file in QQuickStyle Plugin instead. The additional benefit is that we don't need duplicate name() methods for styles and their themes. Even though QQuickStyle Plugin's name handling is case-insensitive, QSetting is case-sensitive. Therefore all QQuickStylePlugin::name() overrides have been updated to use capital first letter. This name is used to lookup the correct section in :/qtquickcontrols2.conf. Task-number: QTBUG-63331 Change-Id: I07b1269d9dbc2c9568e6f22f2da75951fde7b669 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Add QQuickDefaultThemeJ-P Nurmi2017-05-291-2/+11
| | | | | | | | | The Default style will be changed to use palettes, and it will be also possible to define the default fonts and palettes for any style in the qqc2.conf file, so the Default style needs its own proxy theme. Change-Id: I0262f7a1f783daa62ca4afbdf3c8fe29d989ca36 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Welcome to 2017J-P Nurmi2017-01-091-1/+1
| | | | | Change-Id: If68cff4efacc7dc5719c8b8e61937e85e9076870 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* QQuickStylePlugin: avoid re-creating the proxy themeJ-P Nurmi2016-08-231-0/+5
| | | | | | | | | | | | QQuickStylePlugin::initializeEngine() is called multiple times due to multiple QQmlEngine instances (like in qml2puppet). Don't attempt to re-create the proxy theme on the second round. Thanks to QScopedPointer, the old proxy theme instance was automatically destroyed and thus, the new proxy theme crashed. Task-number: QTBUG-54995 Change-Id: I1648c789df062fdfda54302c77f471139a8de88f Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
* Merge QQuickPluginUtils to QQuickStylePluginJ-P Nurmi2016-04-191-0/+16
| | | | | | | | | | | Now that we have a common base class for the plugins, we don't need a separate utils namespace. QQuickStylePlugin::typeUrl() is based on the former QQuickPluginUtils::pluginBasePath(). It returns a URL to the internal composite types that must be explicitly registered for static builds. Change-Id: Icf28c27c84f6b58b1e7b34203dad39c852f0d362 Reviewed-by: Mitch Curtis <mitch.curtis@theqtcompany.com>
* Controls: update license headersJ-P Nurmi2016-04-141-1/+1
| | | | | | | This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. Change-Id: Ib653135662bfd353a73290539995e8e5be211587 Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
* Controls: rename the C++ module to qtquickcontrols2J-P Nurmi2016-04-131-0/+81
Change-Id: I087a39baebc296a340739161874636926adaa56c Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>