Skip to content

Commit 1b3ff76

Browse files
committed
docs(dev-guide): document generated settings pages workflow
1 parent ec98696 commit 1b3ff76

File tree

3 files changed

+149
-2
lines changed

3 files changed

+149
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# Top Level Views
22

33
This section contains topics about the code for the top level views: settings, setup, plan and fly.
4+
5+
- [Settings View](settings.md)
6+
- [Generated Settings Pages](settings_generation.md)
7+
- [Setup View](setup.md)
8+
- [Plan View](plan.md)
9+
- [Fly View](fly.md)
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
# Settings View
22

3-
- Top level QML code is **AppSettings.qml**
4-
- Each button loads a separate QML page
3+
The QGC Application Settings UI is built from a mix of generated and hand-written QML.
4+
5+
- The settings container/sidebar is implemented in [src/QmlControls/AppSettings.qml](../../../../src/QmlControls/AppSettings.qml).
6+
- Most settings content pages are generated from JSON definitions in [src/UI/AppSettings/pages](../../../../src/UI/AppSettings/pages).
7+
- Some pages are still hand-written and referenced directly (for example Help/Logging/debug pages).
8+
9+
## How It Is Generated
10+
11+
The generation pipeline is documented in: [Generated Settings Pages](settings_generation.md)
12+
13+
That page explains:
14+
15+
- Which JSON files define settings pages and controls
16+
- How `*.SettingsGroup.json` Fact metadata drives labels/types/visibility
17+
- How CMake runs the Python generator
18+
- How to add a new setting to an existing page
19+
- How to add an entirely new settings page
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Generated Settings Pages
2+
3+
This page explains how the new Application Settings pages are generated and how to extend them.
4+
5+
## Architecture Overview
6+
7+
The runtime stack is:
8+
9+
1. Fact metadata in `src/Settings/*.SettingsGroup.json`
10+
2. Settings Fact accessors in `src/Settings/*Settings.h/.cc`
11+
3. Settings UI page definitions in `src/UI/AppSettings/pages/*.SettingsUI.json`
12+
4. Page list in `src/UI/AppSettings/pages/SettingsPages.json`
13+
5. Python generator in `tools/generators/settings_qml`
14+
6. Generated QML loaded by `src/QmlControls/AppSettings.qml`
15+
16+
At build time, CMake runs the generator and places generated QML in the build tree. Those files are then compiled into the `QGroundControl.AppSettings` QML module.
17+
18+
## Where Generation Is Wired
19+
20+
Generation is configured in [src/UI/AppSettings/CMakeLists.txt](../../../../src/UI/AppSettings/CMakeLists.txt):
21+
22+
- Custom command runs:
23+
- `python -m tools.generators.settings_qml.generate_pages --output-dir <build>/generated`
24+
- Inputs:
25+
- `src/UI/AppSettings/pages/*.json`
26+
- `src/Settings/*.SettingsGroup.json`
27+
- Outputs:
28+
- Generated page QML files (for example `AppSettings.qml`, `FlyViewSettings.qml`, ...)
29+
- `SettingsPagesModel.qml`
30+
31+
The generator entry point is [tools/generators/settings_qml/generate_pages.py](../../../../tools/generators/settings_qml/generate_pages.py), with most logic in [tools/generators/settings_qml/page_generator.py](../../../../tools/generators/settings_qml/page_generator.py).
32+
33+
## JSON Files and Their Roles
34+
35+
1. `SettingsPages.json` controls sidebar/page registration:
36+
- Page name
37+
- Icon
38+
- Generated QML file name (`qml`)
39+
- Source page definition JSON (`pageDefinition`)
40+
- Optional visibility expression (`visible`)
41+
- Optional divider entries
42+
43+
2. `<Page>.SettingsUI.json` controls page content:
44+
- `bindings`: reusable QML expressions
45+
- `groups`: section blocks
46+
- Group options:
47+
- `heading`
48+
- `sectionName` (sidebar label override)
49+
- `showWhen`, `enableWhen`
50+
- `component` (embed a custom QML component)
51+
- `keywords` (for search on component-only groups)
52+
- Control options:
53+
- `setting` (required), format: `<settingsManager accessor>.<factName>`
54+
- Optional `control` override (`checkbox`, `combobox`, `textfield`, `slider`, `browse`, `scaler`)
55+
- Optional `label`, `showWhen`, `enableWhen`, `placeholder`
56+
- Slider-specific `enableCheckbox` and `button`
57+
58+
3. `*.SettingsGroup.json` provides Fact metadata used by both runtime and generation:
59+
- Type
60+
- Label/descriptions
61+
- Enum values
62+
- Visibility/user visibility
63+
- Search `keywords`
64+
65+
## How Controls Are Chosen
66+
67+
When `control` is omitted, the generator auto-selects from Fact metadata:
68+
69+
- `bool` -> checkbox control
70+
- Enum-backed facts -> combobox
71+
- Other types -> text field
72+
73+
Explicit `control` in `*.SettingsUI.json` overrides auto-selection.
74+
75+
## Sidebar, Sections, and Search
76+
77+
Generated `SettingsPagesModel.qml` is built from `SettingsPages.json` and each page definition.
78+
79+
It includes:
80+
81+
- `sections`: section names for expandable sidebar rows
82+
- `searchTerms`: page/section/fact keyword tokens used by the search field in [src/QmlControls/AppSettings.qml](../../../../src/QmlControls/AppSettings.qml)
83+
84+
Search terms are derived from:
85+
86+
- Page name
87+
- Section heading/section name
88+
- Fact metadata `keywords`
89+
- Group-level `keywords` when using `component` groups without explicit controls
90+
91+
## Add a New Setting to an Existing Generated Page
92+
93+
1. Add Fact metadata entry to the appropriate `src/Settings/<Group>.SettingsGroup.json` file.
94+
2. Expose that Fact through the corresponding settings class:
95+
- Add `DEFINE_SETTINGFACT(<factName>)` in the matching `*Settings.h`.
96+
- Ensure `DECLARE_SETTINGSFACT` exists in `*Settings.cc` if required by that file pattern.
97+
3. Add a control entry in the page JSON:
98+
- File: `src/UI/AppSettings/pages/<Page>.SettingsUI.json`
99+
- Add control: `{ "setting": "<accessor>.<factName>" }`
100+
4. Build QGC. CMake regenerates the QML page automatically.
101+
102+
## Add a New Generated Settings Page
103+
104+
1. Create a new page definition JSON in `src/UI/AppSettings/pages`, for example `MyFeature.SettingsUI.json`.
105+
2. Add a new entry to `src/UI/AppSettings/pages/SettingsPages.json`:
106+
- `name`
107+
- `icon`
108+
- `qml` (output file name, for example `MyFeatureSettings.qml`)
109+
- `pageDefinition` (your new JSON file)
110+
- Optional `visible` expression
111+
3. Update generated outputs list in [src/UI/AppSettings/CMakeLists.txt](../../../../src/UI/AppSettings/CMakeLists.txt):
112+
- Add your new QML file name to `_generated_qml_names`.
113+
4. Build QGC to generate and include the new page.
114+
115+
## Important Notes and Gotchas
116+
117+
- If a page exists in `SettingsPages.json` but has no `pageDefinition`, it is not generated; it is treated as hand-written QML/URL content.
118+
- The CMake `_generated_qml_names` list is explicit. If you forget to add a new page output file name there, generation/build integration will be incomplete.
119+
- The `setting` path in `*.SettingsUI.json` must match a valid `QGroundControl.settingsManager.<group>.<fact>` accessor.
120+
- Fact labels should be present in metadata. Missing labels are logged at runtime by `SettingsGroup`.
121+
122+
## Runtime Override Support
123+
124+
`SettingsManager` can load external settings override files (from `settingsSavePath()` with the configured settings file extension), then apply metadata/value/visibility overrides in `SettingsManager::adjustSettingMetaData(...)`.
125+
126+
This is separate from page generation, but it affects visibility/defaults in generated UI.

0 commit comments

Comments
 (0)