chat: dockable-panel layout foundation (mouse resize/dock — RFC, coordinating with your interface work)#419
Conversation
|
yeah, i would love to test this new idea, so if its not a problem, pls do the follow up of 1 and 2 for now:
|
Wire the tested dock layout (common/dock.rs) into the live home screen, the follow-up asked for on mpiorowski#419: 1. The home's two side columns now take their widths from DockLayout instead of the hardcoded 24. The default is 24/24, so the render is byte-identical until a divider is moved. 2. A drag state machine on the existing MouseEventKind::{Down,Drag,Up} path: pressing a column border grabs its divider, dragging resizes the column live (clamped so the centre chat is never squeezed away), and release ends it. Reuses the model's hit()/resize(); the column rects are recorded each frame like the pet-strip click targets. Session-only for now - per-user persistence (step 3) is still to come. Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
329e58d to
fbf03e6
Compare
|
Thanks Mat — pushed the follow-up for 1 and 2 (rebased onto current 1. The home now renders from 2. A drag state machine on the existing Scope note (so nothing surprises you): this slice is the column-resize half of the drag. I deliberately held back cross-side panel docking (dragging the bonsai header over to the left) — the right sidebar's contents come from your configurable Session-only for now; per-user persistence (3) is still to come whenever you want it.
|
Step 3 of the dockable-panel work (mpiorowski#419): the resized layout now survives reconnects. - late-core stores the layout under a home_dock_layout settings key (extract_home_dock_layout / set_home_dock_layout); the blob is opaque to the core, keyed by the SSH client. - DockLayout gains to_value()/from_value() using the stable panel/side keys, so the JSON survives enum reordering. from_value() is defensive: unknown panels are skipped, missing ones are filled from the default (so a new panel is never hidden by an old save), bad widths fall back. - The layout is seeded from the user's settings at session start and persisted fire-and-forget when a resize drag settles. - Render now clamps the column widths to the live area, so a layout saved on a wide terminal can never squeeze the centre chat on a narrow one (the default 24 is unchanged on normal widths). Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
|
And 3 — per-user persistence is in too, so the whole thing round-trips now:
|
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
The load-bearing core for a mouse-driven, dockable home layout: a pure,
fully-tested model with no UI wiring yet.
- DockPanel (room rail + visualizer/music/bonsai/lobby), DockSide, and a
PanelSlot { side, weight, enabled }; DockLayout holds the ordered slots
plus the two column widths, with a default matching today's layout.
- frame(area) computes the left/centre/right column rects and stacks each
side's panels by weight; columns clamp to a min/max and never eat the
centre.
- hit(point) classifies a mouse point as a column divider, a panel header
(drag to move), or a panel body; drop_zone(point) picks the side + the
panel a drag would land above; resize()/dock() apply clamped edits.
Seven unit tests cover the geometry, resize clamps, cross-side docking,
hit-testing, and drop-zone selection. Nothing renders from it yet, so it's
additive and safe. cargo test / clippy / fmt green.
Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Wire the tested dock layout (common/dock.rs) into the live home screen, the follow-up asked for on mpiorowski#419: 1. The home's two side columns now take their widths from DockLayout instead of the hardcoded 24. The default is 24/24, so the render is byte-identical until a divider is moved. 2. A drag state machine on the existing MouseEventKind::{Down,Drag,Up} path: pressing a column border grabs its divider, dragging resizes the column live (clamped so the centre chat is never squeezed away), and release ends it. Reuses the model's hit()/resize(); the column rects are recorded each frame like the pet-strip click targets. Session-only for now - per-user persistence (step 3) is still to come. Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
Step 3 of the dockable-panel work (mpiorowski#419): the resized layout now survives reconnects. - late-core stores the layout under a home_dock_layout settings key (extract_home_dock_layout / set_home_dock_layout); the blob is opaque to the core, keyed by the SSH client. - DockLayout gains to_value()/from_value() using the stable panel/side keys, so the JSON survives enum reordering. from_value() is defensive: unknown panels are skipped, missing ones are filled from the default (so a new panel is never hidden by an old save), bad widths fall back. - The layout is seeded from the user's settings at session start and persisted fire-and-forget when a resize drag settles. - Render now clamps the column widths to the live area, so a layout saved on a wide terminal can never squeeze the centre chat on a narrow one (the default 24 is unchanged on normal widths). Signed-off-by: Tony Hosaroygard <tasmaniamate@gmail.com>
c0674b0 to
3ce0100
Compare
Thanks @mpiorowski! Opened this early to coordinate — I saw you mention your next PR is interface-related, and I'm building mouse-driven dockable panels for the home screen (drag a divider to resize a column; later, drag a panel's header to move it to the other side / reorder — including sending the bonsai over to the left). It started as just the tested model; per your steer below it now also renders from that model and does live divider-resize (steps 1 & 2).
What's here
A pure, self-contained layout model —
late-ssh/src/app/common/dock.rs— now wired into the live home screen:DockLayout= the movable panels (room rail + visualizer / music / bonsai / lobby), each with a side, a height weight, and enabled — plus the two column widths. Itsdefault()matches today's layout exactly.frame(area)computes the left/centre/right column rects and stacks each side's panels by weight; columns clamp to a min/max and can never squeeze the centre chat away.hit(point)classifies a mouse point as a column divider (→ resize), a panel header (→ drag to move), or a body;drop_zone(point)picks the side + the panel a drag would land above;resize()/dock()apply clamped edits.Now wired (steps 1 & 2)
DockLayout. The two side columns take their widths from the model instead of the hardcoded24; default is 24/24, so the render is byte-identical until a divider is dragged — zero behaviour change out of the box.MouseEventKind::{Down,Drag,Up}path. Grab a column border and drag to resize the room rail or the right sidebar live, clamped so the centre chat can never be squeezed away. Reuses the model'shit()/resize(); the column rects are recorded each frame like the existing pet-strip click targets.Scope note: this is the column-resize half of the drag. Cross-side panel docking (dragging the bonsai header over to the left) is held back on purpose — the right sidebar's contents come from your configurable
right_sidebar_componentslist, so making panels physically movable means reconciling that with the dock model, and I didn't want to change sidebar behaviour under your interface work. It's the natural next slice.users.settingsunder one opaquehome_dock_layoutkey (no migration);DockLayout::to_value()/from_value()use the stable panel/side keys and defensively fill any missing panel from the default. Seeded at session start, saved fire-and-forget when a resize settles. Render also clamps widths to the live area so a wide-terminal save can't squeeze the centre on a narrow one.Still to come
right_sidebar_componentsreconciliation is agreed.Tests
The dock model has 10 unit tests covering the geometry, resize clamps + the drag-resize math, cross-side docking, hit-testing, drop-zone selection, and the JSON persistence round-trip + malformed-blob fallback.
Rebased onto current
main. Totally fine to hold or reshape this if it overlaps what you're already doing — I'd rather build it the way that fits your interface work than duplicate it.