feat: the host form, and the help window, are UI files
src/ui/source-form.ui is the form a source is added or edited with: an AdwDialog of AdwPreferencesGroup rows (AdwEntryRow, AdwSpinRow, AdwSwitchRow) with its action in the header bar, where the label says which mode the form is in -- Connect for a new host, Save for an existing configuration. The grid of labels and bare entries it replaces had its hints in placeholders, which vanish as soon as there is a value; they are the groups' descriptions now. src/ui/help.ui is the help window's chrome: an AdwWindow with a header bar and an AdwNavigationSplitView whose sidebar is the page list. The rows stay in C++ because the fourteen pages are data, not template. Four UI files now, 653 lines of template that used to be widget construction. Two libadwaita traps cost a run each and are in docs/claude/invariants-gtk-and-chrome.md: an AdwDialog has no content property (its child is a plain <child>, unlike an AdwToolbarView), and AdwEntryRow has no subtitle (it is an AdwPreferencesRow, not an AdwActionRow). The unused form_field() helper went with them. Every probe reading is unchanged -- [sources] form:, [sources] edit form:, [help] -- which is what refactoring a shape rather than a behaviour should look like.
This commit is contained in:
1 parent
4c56172005
commit
68743a7d7f
8 files changed
+388
-184
No files matched your search
@@ -213,6 +213,10 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
- **A UI file is data, and a mistake in it is a runtime abort, not a build failure.** `.ui` files live in
|
||||
`src/ui/` and are compiled into the binary by the third GResource (`udpscope-ui.gresource.xml`,
|
||||
`prefix=/org/udpscope/ui`), loaded with `gtk_builder_new_from_resource()`. `preprocess="xml-stripblanks"`
|
||||
catches a *malformed* file at build time — and that includes an XML rule easy to break by hand: **a
|
||||
comment may not contain a double hyphen**, so prose written the way every C++ comment in this project
|
||||
is written (` -- like this -- `) fails the build with a caret under the offending character. Use an em
|
||||
dash in a UI file. `preprocess="xml-stripblanks"`
|
||||
catches a *malformed* file at build time -- and nothing else does, which is why it is on every file in
|
||||
every bundle. What it cannot catch is a file that is valid XML but wrong for GTK: `GtkBuilder` reports
|
||||
that with a **`Gtk-ERROR`, which aborts the process** by default, so a window built by hand from bad
|
||||
@@ -244,6 +248,14 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
||||
answer writes a row, and the row is gone once the dialog closes. `PrefsForm::browse_cancel` is
|
||||
cancelled by the `closed` handler and replaced by the next chooser: one open picker at a time, and none
|
||||
that can call back into a cleared form. It is also how a probe takes the cancel path without a mouse.
|
||||
- **libadwaita's rows do not share one property set, and a `.ui` is where that shows.** An
|
||||
`AdwEntryRow` is an `AdwPreferencesRow`: it has a `title` and **no `subtitle`**. `AdwSpinRow` and
|
||||
`AdwSwitchRow` are `AdwActionRow`s and have both. A hint about an entry -- "empty = unicast" --
|
||||
therefore belongs in the *group's* `description`, which is the better place for it anyway: a
|
||||
placeholder vanishes as soon as there is a value, and a description does not. And an `AdwDialog` has
|
||||
**no `content` property**: its child is a plain `<child>`, where an `AdwToolbarView` does take
|
||||
`content`. Both mistakes are a `Gtk-ERROR` at load, so both abort the process, and both are caught by
|
||||
the probe that opens every window rather than by anything at build time.
|
||||
- **A dialog reachable from two windows cannot own its state in either.** The preferences open from
|
||||
the main window's menu *and* from the source chooser, which exists before `App` does (`main()`
|
||||
chooses a source, then builds the model and the UI). The widgets therefore live in a `PrefsForm` the
|
||||
|
||||
@@ -43,6 +43,11 @@ needs a probe that proves it *loads* and that its contents match whatever drives
|
||||
|
||||
## Already done
|
||||
|
||||
- `src/ui/source-form.ui` -- the form a source is added or edited with: an `AdwDialog` of
|
||||
`AdwPreferencesGroup` rows, with its action in the header bar where the label says which mode it is in.
|
||||
- `src/ui/help.ui` -- the help window's chrome: an `AdwWindow` with a header bar and an
|
||||
`AdwNavigationSplitView` whose sidebar is the page list. The rows stay in C++ because the fourteen
|
||||
pages are data, not template.
|
||||
- `src/ui/preferences.ui` -- the preferences, as an `AdwPreferencesDialog` with `AdwEntryRow`,
|
||||
`AdwSpinRow`, `AdwSwitchRow`, `AdwComboRow` and `AdwButtonRow` rows. The Apply button is gone: a row
|
||||
applies as it changes, which is what those widgets are designed around, and `[prefs-probe]` reads the
|
||||
@@ -56,8 +61,7 @@ needs a probe that proves it *loads* and that its contents match whatever drives
|
||||
|
||||
| where | what | why it is the right next step |
|
||||
|---|---|---|
|
||||
| `src/help_window.cpp` (351 lines) | the help window's chrome as a `.ui` (the pages themselves stay resources) | small, self-contained, and its probe already opens it |
|
||||
| `src/source_dialog.cpp` (~900 lines) | the source chooser and the host form: `.ui` + `AdwDialog`, with `AdwEntryRow`/`AdwSpinRow` for the form | the form is the second-biggest hand-built surface, and its probes drive every branch of it |
|
||||
| `src/source_dialog.cpp` (the chooser's own window) | the chooser: `.ui` for the window, its two pages and its action row. Its **host form is done**; what is left is the list, the notebook and the buttons around it | the last hand-built UI outside `ui.cpp`, and the file is already open |
|
||||
| `src/ui.cpp` (5774 lines) | the main window's **skeleton** only -- the `AdwApplicationWindow`, the header bar, the plot area's placeholder, the panes' containers, the status bar -- with the custom widgets, popovers and dialogs left in code | one file, one window: converting the skeleton is reviewable, converting the whole file is not. Do it in slices (header bar, then the panes, then the trigger panel, then the left panes) with the probe suite after each |
|
||||
|
||||
Nothing in this list should be done in one pass. Each row is its own change, verified on its own.
|
||||
Reference in new issue
Block a user