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