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:
Martino Ferrari committed 2026-10-11 17:27:05 +02:00
1 parent 4c56172005
commit 68743a7d7f
8 files changed
+388 -184

No files matched your search

+93
View File
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-License-Identifier: MIT -->
<!-- SPDX-FileCopyrightText: 2026 Martino Ferrari -->
<!--
The help window's chrome: a window, its own header bar, and a two-pane split whose sidebar is the
list of pages and whose content is one page at a time.
The split is AdwNavigationSplitView rather than a GtkBox with a separator in it, so the sidebar
collapses on a narrow window and comes back behind the header bar's button instead of squeezing the
text. On a wide one it is the same two panes it always was.
The page list itself is *not* here: its rows are the fourteen pages in `help_window.cpp`, each with
section headings between the groups, and a template cannot know them. What is here is the shape they
are put into: an id to find the list by, the scroller around the page, and the label that holds one
page's markup with the screenshot column above it.
-->
<interface>
<object class="AdwWindow" id="help_window">
<property name="title" translatable="yes">udpscope help</property>
<property name="default-width">860</property>
<property name="default-height">640</property>
<property name="content">
<object class="AdwToolbarView">
<child type="top">
<object class="AdwHeaderBar">
<property name="show-title">1</property>
</object>
</child>
<property name="content">
<object class="AdwNavigationSplitView">
<property name="sidebar">
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Pages</property>
<property name="child">
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="width-request">220</property>
<property name="child">
<object class="GtkListBox" id="page_list">
<property name="selection-mode">single</property>
</object>
</property>
</object>
</property>
</object>
</property>
<property name="content">
<object class="AdwNavigationPage">
<property name="title" translatable="yes">Page</property>
<property name="child">
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="hexpand">1</property>
<property name="child">
<object class="GtkBox" id="page_box">
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="shot_box">
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="margin-top">14</property>
<property name="visible">0</property>
</object>
</child>
<child>
<object class="GtkLabel" id="body">
<property name="use-markup">1</property>
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="selectable">1</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="margin-top">14</property>
<property name="margin-bottom">14</property>
</object>
</child>
</object>
</property>
</object>
</property>
</object>
</property>
</object>
</property>
</object>
</property>
</object>
</interface>