Warning, /sdk/cutehmi/extensions/README.md is written in an unsupported language. File is not indexed.

0001 # Extensions directory
0002 
0003 Extensions can act as [QML extensions](http://doc.qt.io/qt-5/qtqml-index.html),
0004 but they can be also used like standard libraries.
0005 
0006 ## Directories
0007 
0008 Directory structure of extensions follows standard QML extensions scheme.
0009 According to [QML identified module rules][1] path of an extension relative
0010 to `extensions` directory defines module identifier, which is also extension
0011 __name__ denoted as __BaseName.MajorVersion__. Typically __BaseName__ consists
0012 of dot-separated _VendorName.ExtensionName_ parts, but this is a convention
0013 rather than a requirement. Extension name must only contain __base name__ and
0014 __major version__ suffix. Base name parts have no special meaning.
0015 
0016 As a reference we can take `Templates.CppSkeleton.0` extension. Fully qualified
0017 __name__ consists of __base name__ (`Templates.CppSkeleton`) and __major version__
0018 suffix (`0`). __Base name__ consists of two parts: _vendor name_ (`Templates`)
0019 and _extension name_ (`CppSkeleton`). It is allowed to omit _extension name_ for a
0020 single extension from a specific vendor. It is also allowed to provide
0021 dot-separated _extension name_ (e.g. `Examples.CppSkeleton`); or do the same with
0022 _vendor_ (e.g. `org.nokia`).
0023 
0024 Extension directories follow camel-case (PascalCase) rules in order to remain
0025 consistent with QML extension naming convention used by Qt. On the other hand
0026 following this convention within C++ would be inconvenient in many places, so
0027 compromises have been made. Sometimes semantic members of extension directory
0028 name are lowercased. To express such intention, a pattern
0029 _VendorName.ExtensionName.MajorVersion_ will be transformed according to the
0030 intention (i.e. _vendorname_ represents lowercased _VendorName_).
0031 
0032 Typically each extension will have directory structure similar to this one.
0033 
0034 - `include` - public header files (available to other modules).
0035     - _vendorname_ - for example `templates`.
0036         - _extensionname_ - for example `cppskeleton`.
0037             - `internal` - some headers need to be publicly available, but they
0038               are implementation detail. This directory is for such files.
0039 - `src` - private header files and implementation.
0040     - _vendorname_ - for example `templates`.
0041         - _extensionname_ - for example `cppskeleton`.
0042             - `internal` - corresponds with `internal` subdirectory inside
0043               `include` directory.
0044 - `tests` - Tests.
0045 - `doc` - Documentation related files.
0046 - `dev` - Development notes.
0047 
0048 To keep things in order and avoid naming conflicts, C++ namespaces should
0049 reflect above directory structure within `include` and `src` directories.
0050 
0051 ## Creating custom extensions
0052 
0053 CuteHMI uses Qbs as build system, therefore each extension starts its life in
0054 dedicated Qbs file. Extensions tend to produce many by-products (like tests for
0055 example), so commonly they are defined within
0056 [Project](https://doc.qt.io/qbs/qml-qbslanguageitems-project.html) Qbs item.
0057 
0058 Project item allows one to put inside a collection of
0059 [products](https://doc.qt.io/qbs/qml-qbslanguageitems-product.html) or reference
0060 subprojects. What products are placed inside project item depends on type of
0061 extension. CuteHMI provides customized Product items and a bunch of helper Qbs
0062 modules for fast and convenient extension setup.
0063 
0064 Every CuteHMI product item requires one to provide some basic metadata, such as
0065 vendor name, description or domain. This information can be extracted by
0066 `cutehmi.metadata` Qbs module and exported to JSON or header file.
0067 
0068 Extensions can be divided into two major categories:
0069 - pure QML extensions
0070 - extensions that use C++ code
0071 
0072 ### QML extensions
0073 
0074 Pure QML extensions are easy to deal with. In their roots they only need
0075 `qmldir` file to work. Such extensions should be defined with
0076 `cutehmi.Extension` product item, which takes care about things like tagging or
0077 intalling files to correct destination directories.
0078 
0079 If you would like to provide a QML extension, then you should refer to
0080 documentation on [qmldir] files. You can either create [qmldir] by hand or use
0081 `cutehmi.qmldir` Qbs module dependency to generate it automatically.
0082 ```
0083 Depends { name: "cutehmi.qmldir" }
0084 ```
0085 You can also use `cutehmi.qmltyperegistrar` Qbs module dependency to generate
0086 `plugins.qmltypes` file (though it is rather needed by C++ QML plugins).
0087 
0088 ### C++ extensions
0089 
0090 Extensions that use C++ code are more sophisticated than QML extensions. In
0091 order to create C++ extension one should use `cutehmi.CppExtension` product
0092 item. It hides unpleasant C++ aspects, so extension creator just has to provide
0093 the metadata and add some C++ or QML files (`cutehmi.CppExtension` extends
0094 `cutehmi.Extension`). To boost the process of creating C++ extension even
0095 further one may use `cutehmi.skeleton.cpp` module by adding it as product
0096 dependency.
0097 ```
0098 Depends { name: "cutehmi.skeleton.cpp" }
0099 ```
0100 
0101 This module will create skeletal header and source files commonly found in all
0102 C++ extensions. In fact it will create minimal operational C++ extension, which
0103 can be then provided with some custom code to do something useful.
0104 
0105 C++ extensions can act as libraries (to be linked against), QML plugins or they
0106 can be a mix of both.
0107 
0108 To create an extension that behaves like a library (i.e. other extensions can be
0109 linked against it) you should refer to Qt documentation on
0110 [Creating Shared Libraries](https://doc.qt.io/qt-6/sharedlibrary.html).
0111 Note that mentioned `MYSHAREDLIB_EXPORT` macros are defined within
0112 `platform.hpp` generated by `cutehmi.skeleton.cpp` module, according to the
0113 pattern `VENDORNAME_EXTENSIONNAME_API`.
0114 
0115 To make an extension that acts as a QML extension, but uses C++ code, you may
0116 refer to [Creating C++ Plugins for QML](https://doc.qt.io/qt-6/qtqml-modules-cppplugins.html).
0117 You can ignore the creation of `.pro` files and simply add files to Qbs project.
0118 Key concepts to focus on is a class that extends `QQmlExtensionPlugin`,
0119 `qmlRegisterType` function template that exposes `QObject` derived classes and
0120 entries in `qmldir` file. You may also check out the tutorial
0121 [Writing QML Extensions with C++](https://doc.qt.io/qt-6/qtqml-tutorials-extending-qml-example.html).
0122 
0123 C++ extensions, which act as QML plugins must provide QML plugin class. By
0124 convention in CuteHMI this class is called `QMLPlugin` and must be inside
0125 extension's `internal` namespace. Sticking to this convention allows one to
0126 rely on defaults, when using other Qbs helper modules, such as `cutehmi.qmldir`
0127 for example.
0128 
0129 All CuteHMI naming conventions have been defined in `cutehmi.conventions` Qbs
0130 module, which can be referenced by other Qbs modules. Among them there is
0131 mentioned QML plugin class name (`qmlPluginClassName` property). All properties
0132 can be printed to the console by setting `debugOutput` property to `true`. From
0133 the command line this can be done as follows.
0134 
0135 ```
0136 qbs resolve -f CuteHMI.qbs modules.cutehmi.conventions.debugOutput:true
0137 ```
0138 
0139 To print naming conventions for specific extension replace `modules` with
0140 `products.Vendor.Extension.MajorVersion.cutehmi.conventions.debugOutput:true`.
0141 
0142 As stated - sticking to naming conventions is not hard requirement, but it helps
0143 avoid setting property values of various Qbs modules explicitly.
0144 
0145 Following extensions can be used as a reference for creating custom extensions:
0146 - [Templates.QMLSkeleton](Templates/QMLSkeleton.0/) - pure QML extension
0147 - [Templates.CppSkeleton](Templates/CppSkeleton.0/) - C++ extension
0148 - [Templates.CppPluginSkeleton](Templates/CppPluginSkeleton.0/) - C++ extension with QML plugin
0149 
0150 ## Keeping custom extensions in separate repositories
0151 
0152 Often you may want to keep your extension in separate repository. A simple
0153 trick, which makes life easier is to create `.gitignore` file in `extensions`
0154 directory and make Git ignore the file itself along with your extension(s).
0155 
0156 ```
0157 /.gitignore
0158 
0159 /YourExtension
0160 ```
0161 
0162 This way you can clone your extension to `extensions` subdirectory and your
0163 reposiotry won't interfere with CuteHMI repository.
0164 
0165 
0166 [1]: https://doc.qt.io/qt-6/qtqml-modules-identifiedmodules.html#semantics-of-identified-modules
0167 [qmldir]: https://doc.qt.io/qt-6/qtqml-modules-qmldir.html
0168