Files
Ely-GPUI-Components/examples/gallery/pages/tooling/inspection.rs
T
ZacharyZhang-NYandClaude Opus 5.5 d7272e88bd Port · Parity: every page matches gpui 0.2.2's; the rules re-tested
Every page and scripted state was shot with gpui 0.2.2 and with the
port, light and dark, full width and at 280px, judged pair by pair by
agents with skeptics, and every page's log diffed. What differed is
fixed, each with a test that fails without it where the test platform
can show it:

- The gallery's harness takes posted mouse moves (gpui_macos listens
  to a tracking area), posts each drag move twice (it no longer
  replays a held drag), and waits three frames before each shot.
- Rolling digits: a block column, so taffy 0.13 lends the cell no
  baseline, and a line of whole device pixels, since gpui snaps each
  length on its own. DescriptionList's row aligns ends.
- Margins that taffy 0.13 collapses through a plain block: the
  drawer's pull and snap, the stagger and transition rise, the dialog
  and palette rises, the fullscreen dialog's slide.
- An Input keeps room to type in a squeezed row; the field rows drop
  w_full, whose reason was taffy 0.9's.

AGENTS.md's rules that named gpui 0.2.2 or taffy 0.9 were re-tested
against both sources and rewritten, and new ones say what the port
changed. TASKS.md's tags follow: what the new gpui makes possible is
prove. Captions, doc comments and README say what holds now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 10:39:55 -04:00

146 lines
5.1 KiB
Rust

use ely_gpui_component::{
buttons::{Button, ButtonVariant},
forms::{Switch, TextInput},
theme::{ActiveTheme, Radius},
tooling::{EventLogger, FpsMeter, RenderCounter},
};
use gpui::{
AnyElement, AnyView, App, Context, IntoElement, ParentElement, Render, StyleRefinement, Styled,
Window, div, px,
};
use crate::probe::probe;
use crate::ui::section;
/// A view of its own, drawn cached, so only its own notify renders it again.
struct Apart;
impl Render for Apart {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
div()
.flex()
.items_center()
.gap_3()
.child(RenderCounter::new("apart-renders", "This view"))
.child(
Button::new("apart-redraw", "Redraw this view")
.variant(ButtonVariant::Outline)
.on_click(cx.listener(|_, _, _, cx| cx.notify())),
)
}
}
#[cfg(debug_assertions)]
fn inspect() -> AnyElement {
probe(
"inspect-button",
Button::new("inspect", "Inspect").on_click(|_, window, cx| window.toggle_inspector(cx)),
)
.into_any_element()
}
#[cfg(not(debug_assertions))]
fn inspect() -> AnyElement {
div()
.child("Release builds leave gpui's inspector out.")
.into_any_element()
}
pub fn sections(window: &mut Window, cx: &mut App) -> Vec<AnyElement> {
let measuring = window.use_keyed_state("fps-measuring", cx, |_, _| false);
let on = *measuring.read(cx);
let apart = window.use_keyed_state("renders-apart", cx, |_, _| Apart);
let field = window.use_keyed_state("events-field", cx, TextInput::new);
let theme = cx.theme();
let colors = &theme.colors;
let boxed = |element: gpui::Div| {
element
.border_2()
.border_color(colors.border)
.rounded(theme.radius(Radius::Md))
.bg(colors.surface)
};
vec![
section(
"InspectorOverlay",
"gpui's inspector, which debug builds have, drawn in Ely's look. Inspect opens it at the window's right: hovering picks a box and shows its margin, border, padding and size over the page, the wheel steps out to the boxes around it, and a press holds it.",
cx,
)
.child(
div()
.flex()
.flex_wrap()
.items_center()
.gap_4()
.child(inspect())
.child(probe(
"inspect-sample",
boxed(div().m_3().p_4()).child("A box to pick"),
)),
)
.into_any_element(),
section(
"FPSMeter / PerfOverlay",
"Frames per second over the last second, the worst frame, and a bar per frame against the 60 Hz budget: green on time, amber a frame late, red later. It keeps the window drawing while shown, so Measure shows it only while you look.",
cx,
)
.child(
div()
.flex()
.flex_wrap()
.items_center()
.gap_4()
.child(probe(
"fps-switch",
Switch::new("fps-measure", on)
.label("Measure")
.on_change(move |on, _, cx| {
measuring.update(cx, |measuring, cx| {
*measuring = on;
cx.notify();
})
}),
))
.children(on.then(|| FpsMeter::new("gallery-fps"))),
)
.into_any_element(),
section(
"RenderCounter",
"How often the view that draws it renders. The page's count climbs with every frame the window draws; the view beside it is drawn cached, so it renders only when it redraws itself or the window refreshes.",
cx,
)
.child(
div()
.flex()
.flex_wrap()
.items_center()
.gap_4()
.child(RenderCounter::new("page-renders", "Page"))
.child(probe(
"renders-apart",
div().w(px(320.0)).h(px(36.0)).child(
AnyView::from(apart)
.cached(StyleRefinement::default().w(px(320.0)).h(px(36.0))),
),
)),
)
.into_any_element(),
section(
"EventLogger",
"The input events that reach what it holds, newest first: presses, releases, moves run together while the pointer travels, wheels, keys and modifiers, each timed from the first.",
cx,
)
.child(probe(
"events",
div().w(px(420.0)).child(
EventLogger::new("gallery-events").child(
boxed(div().flex().flex_col().gap_2().p_3())
.child("Move, press or scroll here, or type in the field.")
.child(field),
),
),
))
.into_any_element(),
]
}