help: the search block's (i) on its header, a 12 px mark, and a real search page
This commit is contained in:
1 parent
d549223889
commit
fe499bfe41
10 files changed
+178
-53
No files matched your search
+16
-1
@@ -214,8 +214,23 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander" id="search_exp">
|
||||
<property name="label" translatable="yes">Search the buffer</property>
|
||||
<property name="tooltip-text" translatable="yes">find every place in the retained buffer where the condition above holds, and step through them</property>
|
||||
<!-- The header is a box, not a plain label, so the contextual help's "(i)" has a row to join
|
||||
as its last child and sits beside the text while the block is collapsed. The block's own
|
||||
*child* is not in the widget-parent chain until the expander is expanded (see
|
||||
docs/claude/invariants-gtk-and-chrome.md), so a hint hung there would be off screen. -->
|
||||
<child type="label">
|
||||
<object class="GtkBox" id="search_head">
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Search the buffer</property>
|
||||
<property name="halign">start</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<property name="child">
|
||||
|
||||
<object class="GtkBox" id="search_sbox">
|
||||
|
||||
+8
-1
@@ -246,6 +246,9 @@ struct App {
|
||||
GtkWidget* search_marks_label = nullptr;
|
||||
GtkWidget* search_prev_button = nullptr;
|
||||
GtkWidget* search_next_button = nullptr;
|
||||
/// The expander the block lives in, so the probe can read its collapsed state when it reads the
|
||||
/// header hint.
|
||||
GtkWidget* search_exp = nullptr;
|
||||
/// Set true when the last `search_jump()` produced an empty cut — the hit was so close to the
|
||||
/// oldest retained sample that `publish_pause_view()` held nothing. Cleared at every jump.
|
||||
bool search_jump_empty = false;
|
||||
@@ -284,10 +287,14 @@ struct App {
|
||||
GtkWidget* status_row = nullptr;
|
||||
GtkWidget* window_control_slot = nullptr;
|
||||
/// The hint hosts that are *not* a pane's heading row: a specific control's own row, so the "?" sits
|
||||
/// beside the thing it explains -- the "record events" switch, the search block's action row, and the
|
||||
/// beside the thing it explains -- the "record events" switch, the pre-trigger share row, and the
|
||||
/// signals pane's hint line (whose box exists so a hint can join it beside the text).
|
||||
GtkWidget* trigger_record_row = nullptr;
|
||||
GtkWidget* trigger_pre_row = nullptr;
|
||||
/// The search block's expander *header* -- the box the contextual help's "trigger_search" hint joins
|
||||
/// as its last child. The header, not the block: the expander's child is out of the widget-parent
|
||||
/// chain until the block is expanded, so a hint there is invisible while it is collapsed.
|
||||
GtkWidget* trigger_search = nullptr;
|
||||
GtkWidget* signals_note = nullptr;
|
||||
/// The guided tour. `tour.overlay` is a `GtkOverlay` inserted above the window's content, and the
|
||||
/// four dim rectangles, the spotlight and the card are its overlay children; `tour.plan` is the
|
||||
|
||||
@@ -109,6 +109,12 @@ constexpr HelpHint kHelpHints[] = {
|
||||
"is the quiet time after a latch in which nothing new can be armed -- the two that decide what a "
|
||||
"capture looks like. The condition rows above appear and disappear with the condition chosen.",
|
||||
"", &App::trigger_pre_row},
|
||||
{"trigger_search", "Searching the buffer",
|
||||
"Applies the condition above to the whole retained ring -- the *same* evaluator the trigger runs, "
|
||||
"so a hit is an instant the trigger would have fired on -- and lists every place it holds. The "
|
||||
"arrows step through the hits, pausing centred on each, and up to sixteen in view are marked on "
|
||||
"every row.",
|
||||
"", &App::trigger_search},
|
||||
{"signals_config", "Configuring signals",
|
||||
"The list is locked until the pencil above opens the per-signal controls: the calibration that "
|
||||
"maps raw counts to a unit, the colour a trace is drawn in, and which plot a signal is dragged "
|
||||
|
||||
@@ -4773,6 +4773,24 @@ gboolean helpui_probe_step(gpointer user) {
|
||||
helpui_probe_next(*a, 8, 400);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
// The search block's "(i)" rides the expander's *header* box, which is in the widget tree and on
|
||||
// screen while the block is collapsed -- unlike the expander's child, which is out of the
|
||||
// widget-parent chain until it is expanded (see the invariant). Read here, in config mode with the
|
||||
// pane and the sidebar up and the block still collapsed: `mapped=1` and a real size *on a collapsed
|
||||
// expander* is the whole point, and a hint hung on the child would read 0x0 here.
|
||||
if (a->trigger_search != nullptr) {
|
||||
GtkWidget* hint = gtk_widget_get_last_child(a->trigger_search);
|
||||
int sw = 0;
|
||||
int sh = 0;
|
||||
context_help_size_in(hint, &sw, &sh);
|
||||
std::fprintf(stderr,
|
||||
"[helpui] collapsed search: expanded=%d mapped=%d mapped_header=%d hint=%dx%d\n",
|
||||
a->search_exp != nullptr && gtk_expander_get_expanded(GTK_EXPANDER(a->search_exp))
|
||||
? 1
|
||||
: 0,
|
||||
hint != nullptr && gtk_widget_get_mapped(hint) ? 1 : 0,
|
||||
gtk_widget_get_mapped(a->trigger_search) ? 1 : 0, sw, sh);
|
||||
}
|
||||
std::fflush(stderr);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@@ -599,6 +599,11 @@ GtkWidget* build_trigger_panel(App& app) {
|
||||
app.search_pos_label = GTK_WIDGET(gtk_builder_get_object(ui, "search_pos"));
|
||||
app.search_next_button = GTK_WIDGET(gtk_builder_get_object(ui, "search_next"));
|
||||
app.search_marks_label = GTK_WIDGET(gtk_builder_get_object(ui, "search_marks"));
|
||||
app.search_exp = GTK_WIDGET(gtk_builder_get_object(ui, "search_exp"));
|
||||
// The expander's header box, where the contextual help's "trigger_search" hint joins as its last
|
||||
// child (see `ui_context_help.cpp`): a hint on the block's own child would leave it unreachable
|
||||
// while the block is collapsed.
|
||||
app.trigger_search = GTK_WIDGET(gtk_builder_get_object(ui, "search_head"));
|
||||
if (app.search_run_button != nullptr) {
|
||||
g_signal_connect(app.search_run_button, "clicked", G_CALLBACK(+[](GtkButton*, gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
|
||||
+16
-8
@@ -71,16 +71,24 @@ void install_css() {
|
||||
" border-radius: 12px; padding: 12px; box-shadow: 0 3px 12px rgba(0, 0, 0, 0.45); }\n"
|
||||
// The contextual-help "(i)": a *mark*, not a button. Adwaita's menu button is a 34x34 control
|
||||
// (a 24 px floor plus 5 px of padding) with a 16 px glyph, which beside a heading reads as a
|
||||
// second toolbar button -- the size the ask calls too big. Measured on libadwaita 1.10: the
|
||||
// outer `menubutton` node *and* its `button` subnode both carry a floor and padding, and a class
|
||||
// selector on either alone leaves the other at 34 (`min-width` on the widget itself is ignored
|
||||
// by `GtkMenuButton`'s measure, and so is a size request -- tried both). Zeroing all three --
|
||||
// the outer node, the subnode and its glyph -- is what brings it to **16x16**: the icon's own
|
||||
// size and nothing else, because a `min-width` is a floor, not a cap, so 16 px is where a 16 px
|
||||
// Adwaita glyph stops. That is the reading `hint=WxH` in the dump prints.
|
||||
// second toolbar button. Measured on libadwaita 1.10: the outer `menubutton` node *and* its
|
||||
// `button` subnode both carry a floor and padding, and a class selector on either alone leaves
|
||||
// the other at 34 (`min-width` on the widget itself is ignored by `GtkMenuButton`'s measure, and
|
||||
// so is a size request -- tried both). Beyond those two there is a third node, and getting its
|
||||
// path wrong is silent: the button's own tree is `menubutton > button > box > image` (read off
|
||||
// the CSS node dump), so the direct-grandchild form `> button > image` matches *nothing* and
|
||||
// leaves the glyph at its natural 16 px -- which is the 16x16 the first version shipped and
|
||||
// mistook for a floor. The glyph is reached through the `box`; trimming the outer node, the
|
||||
// `button` subnode and the glyph together, and asking the glyph for 12 px with
|
||||
// `-gtk-icon-size` (which `GtkImage` honours when it is `GTK_ICON_SIZE_INHERIT`, and which
|
||||
// *scales* the drawing rather than merely clamping its box), is what brings the mark to
|
||||
// **12x12**. There is no lower floor to find: the symbolic glyph renders at any request
|
||||
// (measured down to 4 px), so 12 px is a legibility choice, and it is the size the rule always
|
||||
// meant -- the first version already wrote 12 px, on a selector that never matched. That is
|
||||
// the reading `hint=WxH` in the dump prints.
|
||||
"menubutton.udpscope-hint { min-width: 0; min-height: 0; padding: 0; margin: 0; }\n"
|
||||
"menubutton.udpscope-hint > button { min-width: 0; min-height: 0; padding: 0; }\n"
|
||||
"menubutton.udpscope-hint > button > image { min-width: 12px; min-height: 12px;"
|
||||
"menubutton.udpscope-hint > button > box > image { min-width: 12px; min-height: 12px;"
|
||||
" -gtk-icon-size: 12px; }\n";
|
||||
GtkCssProvider* p = gtk_css_provider_new();
|
||||
gtk_css_provider_load_from_string(p, kCss);
|
||||
|
||||
Reference in new issue
Block a user