diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-28 13:42:03 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 29e734cf91ffe5f4cca8b40a54aad91fff464a82 (patch) | |
| tree | 384056b816943fcff95a45d42cd1fd4be1fe6f1d /src/surface.zig | |
| parent | e11048c20a50b67841e648a4d5ddd7490bc9c9b7 (diff) | |
| download | pardes-29e734cf91ffe5f4cca8b40a54aad91fff464a82.tar.gz pardes-29e734cf91ffe5f4cca8b40a54aad91fff464a82.zip | |
Place every part of the frame once, before painting it
draw.place builds the Surface's region list at the head of render: the
page; each pane's grip, tag rows, body, rail with its thumb, and notice
chips; each column's grip and tag; the workspace tag. The painters read
their geometry from it instead of working it out again: the grid's notice
chips and the notice layers share one chip rectangle, the rails (file,
terminal, image, PDF page) paint the placed thumb (a native PDF measures
its own into the region as it places its pages), and the body, tag, notice
and column layers take their viewports from their regions. A collapsed pane
places only its grip and tag. The column-move rail's one-cell clip of the
layers under it is now a region field set in place, not a mutation of the
built layers. No behaviour change; a test checks every region against the
old geometry, the painted rail and the layer viewports across tag bottom,
column tags, notices, a collapsed pane and a multi-line tag.
Diffstat (limited to 'src/surface.zig')
| -rw-r--r-- | src/surface.zig | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/surface.zig b/src/surface.zig index eef787b4..b19c24c7 100644 --- a/src/surface.zig +++ b/src/surface.zig @@ -324,6 +324,51 @@ test "pixel attachment fit and pan do not invalidate cached pixels" { try std.testing.expect(key.eql(place.cacheKey())); } +/// One part of the frame and where it is, placed once by `draw.place` +/// before anything is painted: every painter and every shell reads the +/// geometry here instead of working it out again. `rect` is in grid cells +/// and is the hit-test geometry. +pub const Region = struct { + pub const Kind = enum(u8) { + /// The frame-wide border fill every other part is painted over. + page, + /// A pane's grip: the mode mark at the head of its tag rows. + grip, + /// A pane's tag rows, right of its grip. + tag, + /// A pane's body, right of its rail: absent while it is collapsed. + body, + /// The scroll rail down a pane's left edge, beside its body. + rail, + /// A transient band over the body's top rows (a message, a prompt). + notice, + column_grip, + column_tag, + workspace_tag, + }; + pub const none = std.math.maxInt(u8); + + kind: Kind, + /// The pane slot, or the column, the part belongs to; `none` for the + /// page and the workspace tag. + owner: u8 = none, + serial: u32 = 0, + rect: layout.Rect, + /// The pane or column has the keyboard's focus. + active: bool = false, + /// A rail's thumb: rows from the rail's top, and how many. Zero rows is + /// a rail with no thumb (an image). + thumb_y: u16 = 0, + thumb_h: u16 = 0, + /// A notice's index in its pane's `notices`. + notice: u8 = 0, + /// Cells the column-move rail takes off the right edge while it runs + /// there: layers and pixel shells stop short of them, the grid does not. + clip: u16 = 0, +}; + +pub const MAX_REGIONS = 1 + MAX_PANES * (4 + panes.Pane.Notices.max) + pardes.MAX_COLS * 2 + 1; + /// The canonical interface: what a frame of pardes IS. The tty shell writes /// these cells to vaxis one-to-one; the SDL shells rasterize them. pub const Surface = struct { @@ -337,6 +382,8 @@ pub const Surface = struct { tag_layers: [MAX_TAG_LAYERS]TagLayer = @splat(.{}), cols: u16 = 0, rows: u16 = 0, + regions: [MAX_REGIONS]Region = undefined, + nregions: u16 = 0, cells: []Cell = &.{}, /// bar: draw an insert-style thin cursor instead of the block cursor: ?struct { x: u16, y: u16, bar: bool = false } = null, @@ -357,6 +404,16 @@ pub const Surface = struct { return &s.body_layers; } + pub fn regionList(s: *const Surface) []const Region { + return s.regions[0..s.nregions]; + } + + /// The first part of `kind` that `owner` has: its tag, its rail. + pub fn region(s: *Surface, kind: Region.Kind, owner: usize) ?*Region { + for (s.regions[0..s.nregions]) |*r| if (r.kind == kind and r.owner == owner) return r; + return null; + } + pub fn panelTracks(s: *const Surface) []const animation.Track { return s.panel_tracks[0..s.npanel_tracks]; } |
