summaryrefslogtreecommitdiffstats
path: root/examples/interfaceframework/qface-climate/doc
diff options
context:
space:
mode:
authorDominik Holland <dominik.holland@qt.io>2021-09-16 16:00:07 +0200
committerDominik Holland <dominik.holland@qt.io>2021-09-22 13:51:56 +0200
commitfe874d5625c324e76f2beccb16b8036498c26165 (patch)
tree6c832a2f4b42fd0b0bc4f94b53f3f3087f4c90fa /examples/interfaceframework/qface-climate/doc
parent69377143cc5fab6cf68c892305252ef00c0a6d05 (diff)
Refactor examples and its documentation
* Remove -if- in example names * Replace _ in example names with - * Move all related docs and images to the example folder Pick-to: 6.2 Change-Id: I1fe38c7d4d735c48224c8bdf8622c701ab056070 Reviewed-by: Robert Griebl <robert.griebl@qt.io>
Diffstat (limited to 'examples/interfaceframework/qface-climate/doc')
-rw-r--r--examples/interfaceframework/qface-climate/doc/images/qface-climate.pngbin0 -> 39319 bytes
-rw-r--r--examples/interfaceframework/qface-climate/doc/src/qface-climate.qdoc325
2 files changed, 325 insertions, 0 deletions
diff --git a/examples/interfaceframework/qface-climate/doc/images/qface-climate.png b/examples/interfaceframework/qface-climate/doc/images/qface-climate.png
new file mode 100644
index 00000000..7c4f943c
--- /dev/null
+++ b/examples/interfaceframework/qface-climate/doc/images/qface-climate.png
Binary files differ
diff --git a/examples/interfaceframework/qface-climate/doc/src/qface-climate.qdoc b/examples/interfaceframework/qface-climate/doc/src/qface-climate.qdoc
new file mode 100644
index 00000000..7cfc0ac1
--- /dev/null
+++ b/examples/interfaceframework/qface-climate/doc/src/qface-climate.qdoc
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\example interfaceframework/qface-climate
+\brief This Example shows how to use the Qt Interface Framework Generator.
+\ingroup qtinterfaceframework-examples
+\title Qt Interface Framework Generator Climate Example
+\image qface-climate.png
+
+\section1 Introduction
+
+This example shows you how you can use the Qt Interface Framework Generator to build a new component. Based on a
+single QFace IDL file, the example generates:
+
+\list
+ \li a shared library with the frontend code
+ \li a backend simulator plugin
+ \li a demo application that shows the values in the current module
+\endlist
+
+\section1 The IDL File
+
+The IDL file used in this example represents a simplified climate control interface that contains a
+single interface and some enumerated types.
+
+Let's take a look at a minimal version of the same QFace IDL file:
+
+\code
+module Example.If.Climate 1.0;
+
+interface ClimateControl {
+ bool airConditioning;
+ int fanSpeedLevel;
+ RecirculationMode recirculationMode;
+ AirflowDirection airflowDirections;
+}
+
+enum RecirculationMode {
+ RecirculationOff = 0x0,
+ RecirculationOn = 0x1,
+ AutoRecirculation = 0x2
+}
+
+flag AirflowDirection {
+ Windshield = 1,
+ Dashboard = 2,
+ Floor = 4
+}
+\endcode
+
+\section2 Walkthrough
+
+First, we need to define which \c module we want to describe. The \c module acts as a namespace,
+because the IDL file can contain multiple interfaces.
+
+\code
+module Example.If.Climate 1.0;
+\endcode
+
+The most important part of the \c module is its \c interface definition.
+
+\code
+interface ClimateControl {
+ bool airConditioning;
+ int fanSpeedLevel;
+ RecirculationMode recirculationMode;
+ AirflowDirection airflowDirections;
+}
+\endcode
+
+In this case, we define an \c interface named \b ClimateControl consisting of a few properties it
+should offer. Each property definition must contain at least a type and a name. Most of the
+basic types are built-in and can be found in the \l {QFace IDL syntax}. The last two properties
+are special as they use custom types, that are defined after the \c interface definition.
+
+\code
+enum RecirculationMode {
+ RecirculationOff = 0x0,
+ RecirculationOn = 0x1,
+ AutoRecirculation = 0x2
+}
+
+flag AirflowDirection {
+ Windshield = 1,
+ Dashboard = 2,
+ Floor = 4
+}
+\endcode
+
+The first definition is an \c enum with all the values it supports, including the numeric value
+of each individual item. The second definition is similar, but using the \c flag type.
+
+\section2 Comments and Annotations
+
+Compared to the minimal IDL we saw in the previous section, the full
+\fileLink {examples/interfaceframework/qface-climate/example-climate.qface}{IDL file} contains a lot of comments
+and annotations.
+
+Comments starting with \c /** define documentation statements and can be converted into
+documentation markup like QDoc or Doxygen, by the generation template.
+
+\section3 Annotations
+
+Annotations are used to add additional information to the IDL statements. They are YAML fragments
+that provide a key-value store. The generation template defines the supported annotations.
+
+Here's an overview of all the annotations used in this example and what they do:
+
+\table
+ \header
+ \li Annotation
+ \li Description
+ \row
+ \li \code
+ @config: {zoned: true}
+ \endcode
+ \li Specifies that the interface supports different zones.
+ \row
+ \li \code
+ @config: {qml_type: "UiClimateControl"}
+ \endcode
+ \li Specifies the component name when used from QML.
+ \row
+ \li \code
+ @config: {id: "example.interfaceframework.ClimateControl/1.0"}
+ \endcode
+ \li Specifies the ID used to match backend plugins.
+ \row
+ \li \code
+ @config_simulator: { range:[0, 50] }
+ \endcode
+ \li Specifies a range of valid values for numerical properties.
+ \note The \c {range} annotation used here is a shortcut to specify both minimum and
+ maximum values.
+ \row
+ \li
+ \code
+ @config_simulator: { minimum: 0; maximum: 50 }
+ \endcode
+ \li Specifies the minimum and maximum values for numerical properties.
+
+ \row
+ \li \code
+ @config_simulator: { domain: ["cold", "mild", "warm" ] }
+ \endcode
+ \li Specifies a list of valid values for properties.
+ \row
+ \li \code
+ @config: {interfaceBuilder: "echoInterfaceBuilder"}
+ \endcode
+ \li Specifies that the plugin should use a custom function to generate the backend
+ instances.
+\endtable
+
+In addition to the IDL file, a YAML file with the same basename is used to add extra
+configurations. These configurations may also be added directly into the IDL file, but we choose
+to keep them separate for readability.
+
+Some of these extra configurations are highlighted below:
+
+\table
+ \row
+ \li
+ \code
+ Example.If.Climate.ClimateControl:
+ config_simulator:
+ zones: { left : FrontLeft, right : FrontRight, rear: Rear }
+ \endcode
+ \li Defines the names for the supported zones.
+ \row
+ \li
+ \code
+ Example.If.Climate.ClimateControl#recirculationMode:
+ config_simulator:
+ default: RecirculationMode.RecirculationOff
+ \endcode
+ \li Specifies the default value assigned to a property in the simulator backend plugin.
+\endtable
+
+
+\section1 Frontend Library
+
+Now we want to use the Interface Framework Generator to generate a shared library that contains a C++
+implementation of our module and its interface.
+
+In this case, we use the \c frontend template, that generates a class derived from
+\c {QIfAbstractZonedFeature} including all the specified properties. The generated library uses
+the \l {Dynamic Backend System} from QtInterfaceFramework, providing an easy way to change the behavior
+implementations. For more details, see \l {Backend Simulator Plugin}.
+
+To call the autogenerator for our shared library, it needs to be integrated into the build system.
+
+\e CMake:
+
+First the \c InterfaceFramework package needs to be found using \c find_package:
+
+\snippet interfaceframework/qface-climate/frontend/CMakeLists.txt 0
+
+Afterwards we proceed to build a library and let the autogenerator extend this target with
+the generated source code by invoking \l {qt6_ifcodegen_extend_target}.
+
+\snippet interfaceframework/qface-climate/frontend/CMakeLists.txt 1
+
+\e qmake:
+
+The qmake project file needs to use the \c ifcodegen qmake feature. The snippet below shows how
+to do this:
+
+\snippet interfaceframework/qface-climate/frontend/frontend.pro 1
+
+By adding \c ifcodegen to the \c CONFIG variable, the \c ifcodegen feature file is loaded
+and interprets the \c IFCODEGEN_SOURCES variable just like the \c SOURCES variable in normal qmake
+projects.
+
+However, activating the qmake feature using the \c CONFIG variable has one disadvantage: it
+doesn't report any errors if this feature is not available. But, you can use the following
+additional code to report errors:
+
+\snippet interfaceframework/qface-climate/frontend/frontend.pro 0
+
+The other part of the project file is a normal library setup which should work on Linux, macOS,
+and Windows.
+
+\section1 Backend Simulator Plugin
+
+Since the \c frontend library uses the \l {Dynamic Backend System}, we need a corresponding
+\c backend plugin, for the library to provide some functionality. To generate a mock version of
+the backend plugin called "Simulator Backend", you can use the \c backend_simulator template from
+the same IDL file as the \c frontend library. The build system integration works in the same way, but it
+uses a different generation template.
+
+\e CMake:
+
+A plugin is defined and extended by calling the codegenerator, this time with the \c backend_simulator
+template:
+
+\snippet interfaceframework/qface-climate/backend_simulator/CMakeLists.txt 2
+
+\e qmake:
+
+As we want to generate a plugin instead of a plain library, we need to instruct qmake to do so by
+adding \c plugin to the \c CONFIG variable.
+
+\snippet interfaceframework/qface-climate/backend_simulator/backend_simulator.pro 2
+
+For the plugin to compile correctly it needs to get the backend interface header from the previously
+created library. However, this header is not part of our source tree but the build tree, because it
+is also generated. We provide this header by adding it to the include path using the following code:
+
+\e CMake:
+
+\snippet interfaceframework/qface-climate/backend_simulator/CMakeLists.txt 1
+
+\e qmake:
+
+\snippet interfaceframework/qface-climate/backend_simulator/backend_simulator.pro 1
+
+The \c backend_simulator template makes use of the \b @config_simulator annotations explained
+\l{Annotations}{above}. This means that the generated backend provides the default values defined
+in the annotations and checks the boundaries of new values using the \c minimum/maximum or \c range
+annotations.
+
+Using the \c zones annotations, the generated backend provides individual values for every zone
+and communicates the available zones to the frontend library. For more information, see the
+\l {Climate Control QML Example}.
+
+\section1 Demo Application
+
+The demo application presents a simple QML interface with all the properties of the generated
+interface.
+
+Since we do not provide a QML plugin, the application needs to link to the generated frontend
+library and call the \c {ClimateModule::registerTypes} and \c {ClimateModule::registerQmlTypes}
+methods that are generated in the module singleton to register all autogenerated interfaces and
+types with the QML engine.
+
+In our QML application, we still need to import the module using the same module URI used
+in the IDL file. Afterwards, the interface can be instantiated like a regular QML item.
+
+\snippet interfaceframework/qface-climate/demo/main.qml 0
+\dots 0
+
+Our application doesn't know about our backend plugin, so, we need to put this plugin in the folder
+where our application looks for plugins. By default, Qt looks in the \b plugins folder within its
+installation directory or in the application's current working directory. For QtInterfaceFramework plugins to be
+found, they need to be placed within a \b interfaceframework sub-folder.
+
+To make sure this is done automatically, we add the following line to our backend build system file:
+
+\e CMake:
+
+\snippet interfaceframework/qface-climate/backend_simulator/CMakeLists.txt 0
+
+\e qmake:
+
+\snippet interfaceframework/qface-climate/backend_simulator/backend_simulator.pro 0
+
+*/