summaryrefslogtreecommitdiff
path: root/src/gui/gui.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-15 15:33:30 -0300
committerGabriel Schneider <[email protected]>2026-09-15 17:24:42 -0300
commit8ac4a48a2e8e66a9e72bcbc61c114be8db9215fd (patch)
tree4c48ecd42a800b12daed0712a4620639d1631f7e /src/gui/gui.zig
parentc1787ff868ee723629c1d500098d36dc419f77c3 (diff)
downloadpardes-8ac4a48a2e8e66a9e72bcbc61c114be8db9215fd.tar.gz
pardes-8ac4a48a2e8e66a9e72bcbc61c114be8db9215fd.zip
Separate discontinuous pinned source context with thin borders
Diffstat (limited to 'src/gui/gui.zig')
-rw-r--r--src/gui/gui.zig41
1 files changed, 27 insertions, 14 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig
index 91176a63..0c0a5651 100644
--- a/src/gui/gui.zig
+++ b/src/gui/gui.zig
@@ -4937,7 +4937,7 @@ fn renderFrame(
const bottom = @as(f32, @floatFromInt(layer.viewport.y + layer.viewport.h)) * layout.h;
for (0..layer.rows) |lr| {
if (layer.rowTop(@intCast(lr), layout.h, @floatFromInt(g.tagline_height)) >= bottom) break;
- batch.cell_count += layer.cols + @as(u32, if (lr < layer.context_rows) 1 else 0);
+ batch.cell_count += layer.cols + @as(u32, if (lr < layer.context_rows) 1 else 0) + @as(u32, @intFromBool(layer.hasContextBorderAfter(lr)));
}
}
for (paint_plan.batches[1..paint_plan.len], 1..) |batch, batch_index| {
@@ -4950,7 +4950,7 @@ fn renderFrame(
const bottom = @as(f32, @floatFromInt(layer.viewport.y + layer.viewport.h)) * layout.h;
for (0..layer.rows) |lr| {
if (layer.rowTop(@intCast(lr), layout.h, @floatFromInt(g.tagline_height)) >= bottom) break;
- destination.cell_count += layer.cols + @as(u32, if (lr < layer.context_rows) 1 else 0);
+ destination.cell_count += layer.cols + @as(u32, if (lr < layer.context_rows) 1 else 0) + @as(u32, @intFromBool(layer.hasContextBorderAfter(lr)));
}
}
}
@@ -5027,7 +5027,7 @@ fn renderFrame(
for (surface.bodyLayers()) |*layer| {
if (layer.rows == 0) continue;
const batch_index = paintBatchAt(&paint_plan, layer.viewport.x, layer.viewport.y);
- emitBodyLayer(g, instances, &cell_next[batch_index], layer, win_w, win_h, paint_plan.batches[batch_index].track, page, paint_plan.len == 1, false);
+ emitBodyLayer(g, instances, &cell_next[batch_index], layer, win_w, win_h, paint_plan.batches[batch_index].track, page, paint_plan.len == 1, false, topbar_pane_border_rgb);
}
for (paint_plan.batches[1..paint_plan.len], 1..) |batch, batch_index| {
const track = batch.track.?;
@@ -5036,7 +5036,7 @@ fn renderFrame(
for (surface.previous_body_layers) |*layer| {
if (layer.rows == 0 or layer.serial != track.serial) continue;
const destination: usize = if (under) 0 else batch_index;
- emitBodyLayer(g, instances, &cell_next[destination], layer, win_w, win_h, if (under) null else track, page, false, track.effect == .dissolve);
+ emitBodyLayer(g, instances, &cell_next[destination], layer, win_w, win_h, if (under) null else track, page, false, track.effect == .dissolve, topbar_pane_border_rgb);
}
}
for (paint_plan.batches[1..paint_plan.len], 1..) |batch, batch_index| {
@@ -5357,7 +5357,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) void {
+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 {
const bw: f32 = @floatFromInt(g.cell_w);
const bh: f32 = @floatFromInt(g.cell_h);
const tw: f32 = @floatFromInt(g.tagline_width);
@@ -5387,6 +5387,17 @@ fn emitBodyLayer(g: *Gui, instances: [*]CellInstance, next: *u32, layer: *const
clipBodyInstance(&instances[next.*], bottom, win_h);
next.* += 1;
}
+ if (layer.hasContextBorderAfter(row)) {
+ const border: pardes.Cell = .{ .default = false, .style = .{ .bg = .{ .rgb = border_rgb } } };
+ emitInstance(g, instances, next.*, 0, 0, .{
+ .w = @as(f32, @floatFromInt(layer.viewport.w)) * bw,
+ .h = 1,
+ .x_off = left,
+ .y_off = top + height - 1,
+ }, win_w, win_h, track, .body, &border, old_layer, false, page);
+ clipBodyInstance(&instances[next.*], bottom, win_h);
+ next.* += 1;
+ }
}
}
@@ -6243,10 +6254,7 @@ fn buildOverlay(
if (transient_on) for (surface.bodyLayers()) |*layer| {
if (layer.rows == 0) continue;
const left = @as(f32, @floatFromInt(layer.viewport.x)) * layout.w;
- const right = left + @as(f32, @floatFromInt(layer.viewport.w)) * layout.w;
const bottom = @as(f32, @floatFromInt(layer.viewport.y + layer.viewport.h)) * layout.h;
- const border = layer.rowTop(layer.context_rows, layout.h, @floatFromInt(g.tagline_height));
- if (border <= bottom) builder.addRect(left, border - 1, right, border, overlayRgb(topbar_pane_border_rgb));
if (layer.cursor) |cursor| {
if (!cursor.bar or cursor.y >= layer.rows or cursor.x >= layer.cols) continue;
const top = layer.rowTop(cursor.y, layout.h, @floatFromInt(g.tagline_height));
@@ -6812,21 +6820,26 @@ test "compact body layer rendering fills recovered rows and clips the final glyp
g.tagline_height = 12;
g.space_slot = .{ .u = 0, .v = 0 };
var cells: [24]pardes.Cell = @splat(.{});
- const layer: pardes.BodyLayer = .{
+ var layer: pardes.BodyLayer = .{
.viewport = .{ .x = 3, .y = 2, .w = 2, .h = 5 },
.cols = 2,
.rows = 12,
.context_rows = 4,
.cells = &cells,
};
+ layer.setContextLines(&.{ 0, 4, 5, 6 });
var instances: [32]CellInstance = undefined;
var next: u32 = 0;
- emitBodyLayer(&g, &instances, &next, &layer, 200, 200, null, Ground.opaqueRgb(bg_default), false, false);
+ emitBodyLayer(&g, &instances, &next, &layer, 200, 200, null, Ground.opaqueRgb(bg_default), false, false, .{ 80, 90, 100 });
// Four compact header rows (48px), then three body rows: two complete
// and a third clipped to the remaining12px of the100px viewport.
- try std.testing.expectEqual(@as(u32, 18), next);
+ try std.testing.expectEqual(@as(u32, 20), next);
+ try std.testing.expectApproxEqAbs(@as(f32, 0.49), instances[3].y0, 0.0001);
+ try std.testing.expectApproxEqAbs(@as(f32, 0.48), instances[3].y1, 0.0001);
+ try std.testing.expectApproxEqAbs(@as(f32, 80.0 / 255.0), instances[3].br, 0.0001);
+ try std.testing.expectApproxEqAbs(instances[3].br, instances[13].br, 0.0001);
try std.testing.expectApproxEqAbs(@as(f32, 0.6), instances[0].y0, 0.0001);
- try std.testing.expectApproxEqAbs(@as(f32, 0.12), instances[12].y0, 0.0001);
- try std.testing.expectApproxEqAbs(@as(f32, -0.4), instances[17].y1, 0.0001);
- try std.testing.expectApproxEqAbs(instances[17].v0 + @as(f32, 12) / atlas_h, instances[17].v1, 0.0001);
+ try std.testing.expectApproxEqAbs(@as(f32, 0.12), instances[14].y0, 0.0001);
+ try std.testing.expectApproxEqAbs(@as(f32, -0.4), instances[19].y1, 0.0001);
+ try std.testing.expectApproxEqAbs(instances[19].v0 + @as(f32, 12) / atlas_h, instances[19].v1, 0.0001);
}