From 30c2c8a154e770b3920bcfd7d553825fe9182bf4 Mon Sep 17 00:00:00 2001 From: Gabriel Schneider Date: Mon, 28 Sep 2026 12:57:47 -0300 Subject: Move the frame into draw.zig and the transitions out of layout.zig Pure moves, no behaviour change. draw.zig holds the whole core frame in order: render, the pane, tag, header and notice painters it calls, and the character-effect composition (Pardes.render stays a declaration alias). Presentation.zig is the panel presentation state as a file struct, and animation.zig the easing curves, transition kinds, tracks and boxes, the character effects' sources and the generic displayed-value transition, all of which lived in layout.zig. layout.zig keeps only layout. --- src/gui/gui.zig | 66 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'src/gui') diff --git a/src/gui/gui.zig b/src/gui/gui.zig index 6978284b..0737bb63 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -209,11 +209,11 @@ const AnimationClock = struct { return false; } if (clock.next_ns == 0) { - clock.next_ns = now_ns +| pardes.layout.Animation.frame_ns; + clock.next_ns = now_ns +| pardes.animation.Animation.frame_ns; return false; } if (now_ns < clock.next_ns) return false; - clock.next_ns = now_ns +| pardes.layout.Animation.frame_ns; + clock.next_ns = now_ns +| pardes.animation.Animation.frame_ns; return true; } }; @@ -221,7 +221,7 @@ const AnimationClock = struct { fn finishPresentedAnimationFrame( clock: *AnimationClock, core: *pardes.Pardes, - tracks: []const pardes.layout.Track, + tracks: []const pardes.animation.Track, now_ns: u64, ) void { core.acknowledgePanelPresentation(tracks); @@ -232,9 +232,9 @@ test "GUI animation clock is active-only and cadence gated" { var clock: AnimationClock = .{}; try std.testing.expect(!clock.due(false, 100)); try std.testing.expect(!clock.due(true, 100)); - try std.testing.expect(!clock.due(true, 100 + pardes.layout.Animation.frame_ns - 1)); - try std.testing.expect(clock.due(true, 100 + pardes.layout.Animation.frame_ns)); - try std.testing.expect(!clock.due(false, 100 + 2 * pardes.layout.Animation.frame_ns)); + try std.testing.expect(!clock.due(true, 100 + pardes.animation.Animation.frame_ns - 1)); + try std.testing.expect(clock.due(true, 100 + pardes.animation.Animation.frame_ns)); + try std.testing.expect(!clock.due(false, 100 + 2 * pardes.animation.Animation.frame_ns)); try std.testing.expectEqual(@as(u64, 0), clock.next_ns); } @@ -248,7 +248,7 @@ test "a persistent scene presents a new panel's frame zero before advancing it" core.settings.scene_effects.crt = true; const scene_frame = try core.render(arena.allocator()); finishPresentedAnimationFrame(&clock, core, scene_frame.panelTracks(), 100); - try std.testing.expectEqual(@as(u64, 100 + pardes.layout.Animation.frame_ns), clock.next_ns); + try std.testing.expectEqual(@as(u64, 100 + pardes.animation.Animation.frame_ns), clock.next_ns); core.settings.panel_transition = .slide; core.update(.{ .command = "Newcol" }); @@ -262,7 +262,7 @@ test "a persistent scene presents a new panel's frame zero before advancing it" &clock, core, first.panelTracks(), - 100 + pardes.layout.Animation.frame_ns, + 100 + pardes.animation.Animation.frame_ns, ); _ = arena.reset(.retain_capacity); const second = try core.render(arena.allocator()); @@ -557,8 +557,8 @@ const SavedImagePlace = struct { const PreparedImage = struct { place: SavedImagePlace, texture: *c.SDL_GPUTexture, - track: ?pardes.layout.Track = null, - clip: ?pardes.layout.Box = null, + track: ?pardes.animation.Track = null, + clip: ?pardes.animation.Box = null, old_layer: bool = false, }; @@ -592,7 +592,7 @@ test "shader instance ABI carries aligned transition vectors" { try std.testing.expectEqual(@as(usize, 64), @offsetOf(ImageInstance, "effect")); try std.testing.expectEqual(@as(usize, 32), @sizeOf([8]f32)); - const tracks = [_]pardes.layout.Track{ + const tracks = [_]pardes.animation.Track{ .{ .pane = 0, .phase = .opening, .effect = .slide }, .{ .pane = 1, .phase = .moving, .effect = .slide }, .{ .pane = 2, .phase = .moving, .effect = .slide }, @@ -606,19 +606,19 @@ test "shader instance ABI carries aligned transition vectors" { } test "GUI paint plan snaps history effects without a frozen grid" { - const tracks = [_]pardes.layout.Track{ + const tracks = [_]pardes.animation.Track{ .{ .pane = 0, .phase = .opening, .effect = .ascii }, .{ .pane = 1, .phase = .closing, .effect = .vertical }, }; try std.testing.expectEqual(@as(usize, 1), makePaintPlan(&tracks, false).len); const ready = makePaintPlan(&tracks, true); try std.testing.expectEqual(@as(usize, 3), ready.len); - try std.testing.expectEqual(pardes.layout.Phase.opening, ready.batches[1].track.?.phase); - try std.testing.expectEqual(pardes.layout.Phase.closing, ready.batches[2].track.?.phase); + try std.testing.expectEqual(pardes.animation.Phase.opening, ready.batches[1].track.?.phase); + try std.testing.expectEqual(pardes.animation.Phase.closing, ready.batches[2].track.?.phase); } test "closing tombstone overlays but never owns canonical cells" { - const closing: pardes.layout.Track = .{ + const closing: pardes.animation.Track = .{ .pane = 0, .phase = .closing, .effect = .vertical, @@ -628,7 +628,7 @@ test "closing tombstone overlays but never owns canonical cells" { const plan = makePaintPlan(&.{closing}, true); try std.testing.expectEqual(@as(usize, 0), paintBatchAt(&plan, 4, 4)); try std.testing.expectEqual(@as(usize, 2), plan.len); - try std.testing.expectEqual(pardes.layout.Phase.closing, plan.batches[1].track.?.phase); + try std.testing.expectEqual(pardes.animation.Phase.closing, plan.batches[1].track.?.phase); } fn updateCoreResize(core: *pardes.Pardes, cols: u16, rows: u16, cell_w: u32, cell_h: u32, tag_w: u32, tag_h: u32) bool { @@ -2031,10 +2031,10 @@ fn taglineLayoutForCell(g: *const Gui, col: u16) CellLayout { return compactTaglineLayout(g, @floatFromInt(col)); } -const boxContains = pardes.layout.Box.contains; +const boxContains = pardes.animation.Box.contains; const PaintBatch = struct { - track: ?pardes.layout.Track = null, + track: ?pardes.animation.Track = null, cell_start: u32 = 0, cell_count: u32 = 0, image_start: u32 = 0, @@ -2046,9 +2046,9 @@ const PaintPlan = struct { len: usize = 1, }; -fn makePaintPlan(tracks: []const pardes.layout.Track, has_diff: bool) PaintPlan { +fn makePaintPlan(tracks: []const pardes.animation.Track, has_diff: bool) PaintPlan { var plan: PaintPlan = .{}; - for ([_]pardes.layout.Phase{ .moving, .opening, .closing }) |phase| { + for ([_]pardes.animation.Phase{ .moving, .opening, .closing }) |phase| { for (tracks) |track| { if (!track.active() or track.phase != phase) continue; if (track.effect.needsPreviousGrid() and !has_diff) continue; @@ -2074,21 +2074,21 @@ fn paintBatchForSerial(plan: *const PaintPlan, serial: u32) usize { return 0; } -fn panelCellCoord(track: pardes.layout.Track, col: u16, row: u16) u32 { +fn panelCellCoord(track: pardes.animation.Track, col: u16, row: u16) u32 { const source = track.contentBox(); const x0: u16 = @intFromFloat(@max(0.0, @floor(source.x))); const y0: u16 = @intFromFloat(@max(0.0, @floor(source.y))); return @as(u32, row -| y0) << 16 | @as(u32, col -| x0); } -fn panelGridSize(track: pardes.layout.Track) u32 { +fn panelGridSize(track: pardes.animation.Track) u32 { const source = track.contentBox(); const cols: u16 = @intFromFloat(@min(@as(f32, std.math.maxInt(u16)), @max(1.0, @ceil(source.w)))); const rows: u16 = @intFromFloat(@min(@as(f32, std.math.maxInt(u16)), @max(1.0, @ceil(source.h)))); return @as(u32, rows) << 16 | @as(u32, cols); } -fn ndcBox(box: pardes.layout.Box, layout: CellLayout, win_w: f32, win_h: f32) [4]f32 { +fn ndcBox(box: pardes.animation.Box, layout: CellLayout, win_w: f32, win_h: f32) [4]f32 { const px0 = layout.x_off + box.x * layout.w; const py0 = layout.y_off + box.y * layout.h; const px1 = px0 + box.w * layout.w; @@ -2103,7 +2103,7 @@ fn ndcBox(box: pardes.layout.Box, layout: CellLayout, win_w: f32, win_h: f32) [4 fn setTransitionFields( instance: anytype, - track: ?pardes.layout.Track, + track: ?pardes.animation.Track, layout: CellLayout, win_w: f32, win_h: f32, @@ -4636,7 +4636,7 @@ fn snapshotContainsPlacement(g: *const Gui, current: pardes.ImagePlace) bool { return false; } -fn placeIntersectsBox(place: SavedImagePlace, box: pardes.layout.Box) bool { +fn placeIntersectsBox(place: SavedImagePlace, box: pardes.animation.Box) bool { const x0: f32 = @floatFromInt(place.x); const y0: f32 = @floatFromInt(place.y); const x1: f32 = @floatFromInt(@as(u32, place.x) + place.w); @@ -4808,8 +4808,8 @@ fn appendPreparedImage( g: *Gui, gpa: std.mem.Allocator, place: SavedImagePlace, - track: ?pardes.layout.Track, - clip: ?pardes.layout.Box, + track: ?pardes.animation.Track, + clip: ?pardes.animation.Box, old_layer: bool, ) void { const texture = g.native_images.get(place.key) orelse return; @@ -4998,7 +4998,7 @@ fn imageScissor( }; } -fn panelBoxScissor(g: *const Gui, box: pardes.layout.Box, max_w: u32, max_h: u32) c.SDL_Rect { +fn panelBoxScissor(g: *const Gui, box: pardes.animation.Box, max_w: u32, max_h: u32) c.SDL_Rect { const x0: i32 = @intFromFloat(@floor(box.x * @as(f32, @floatFromInt(g.cell_w)))); const y0: i32 = @intFromFloat(@floor(box.y * @as(f32, @floatFromInt(g.cell_h)))); const x1: i32 = @intFromFloat(@ceil((box.x + box.w) * @as(f32, @floatFromInt(g.cell_w)))); @@ -5059,7 +5059,7 @@ fn renderFrame( theme_bg: ?[3]u8, topbar_pane_border_rgb: [3]u8, tagline_rgb: [3]u8, - scene_effects: pardes.layout.SceneEffect, + scene_effects: pardes.animation.SceneEffect, debug_on: bool, ) !bool { if (surface.pointer_shape != g.pointer_shape) { @@ -5763,7 +5763,7 @@ fn tagLayerCellCount(g: *const Gui, layer: *const pardes.TagLayer) u32 { return @min(layer.cols, (pixels + g.tagline_width - 1) / g.tagline_width); } -fn emitTagLayer(g: *Gui, instances: [*]CellInstance, next: *u32, layer: *const pardes.TagLayer, win_w: f32, win_h: f32, track: ?pardes.layout.Track, page: Ground, show_cursor: bool, old_layer: bool) void { +fn emitTagLayer(g: *Gui, instances: [*]CellInstance, next: *u32, layer: *const pardes.TagLayer, win_w: f32, win_h: f32, track: ?pardes.animation.Track, page: Ground, show_cursor: bool, old_layer: bool) void { const bw: f32 = @floatFromInt(g.cell_w); const bh: f32 = @floatFromInt(g.cell_h); const tw: f32 = @floatFromInt(g.tagline_width); @@ -5826,7 +5826,7 @@ fn clipBodyInstance(instance: *CellInstance, bottom: f32, win_h: f32) void { instance.y1 = limit; } -fn emitBodyLayer(g: *Gui, instances: [*]CellInstance, next: *u32, layer: *const pardes.BodyLayer, win_w: f32, win_h: f32, track: ?pardes.layout.Track, page: Ground, show_cursor: bool, old_layer: bool, border_rgb: [3]u8) void { +fn emitBodyLayer(g: *Gui, instances: [*]CellInstance, next: *u32, layer: *const pardes.BodyLayer, win_w: f32, win_h: f32, track: ?pardes.animation.Track, page: Ground, show_cursor: bool, old_layer: bool, border_rgb: [3]u8) void { const bw: f32 = @floatFromInt(g.cell_w); const bh: f32 = @floatFromInt(g.cell_h); const tw: f32 = @floatFromInt(g.tagline_width); @@ -5919,7 +5919,7 @@ fn emitSurfaceCell( body_layout: CellLayout, win_w: f32, win_h: f32, - track: ?pardes.layout.Track, + track: ?pardes.animation.Track, line: []const pardes.Cell, at: usize, cursor: ?usize, @@ -6018,7 +6018,7 @@ fn emitInstance( layout: CellLayout, win_w: f32, win_h: f32, - track: ?pardes.layout.Track, + track: ?pardes.animation.Track, role: pardes.FontRole, line: []const pardes.Cell, at: usize, -- cgit v1.3