summaryrefslogtreecommitdiff
path: root/src/draw.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/draw.zig')
-rw-r--r--src/draw.zig62
1 files changed, 58 insertions, 4 deletions
diff --git a/src/draw.zig b/src/draw.zig
index 9c9e11dd..ad24153f 100644
--- a/src/draw.zig
+++ b/src/draw.zig
@@ -63,7 +63,7 @@ pub fn place(p: *Pardes, s: *Surface) void {
// A folded pane is its tag rows and nothing else.
if (pane.collapsed) continue;
const body_h = r.h -| pane.tag_rows;
- const line: i32 = if (pane.file) |f| @intCast(@min(f.scroll, std.math.maxInt(i32))) else if (pane.isTerminal()) panes.Terminal.gridOffset(pane) else 0;
+ const line: i32 = if (pane.file) |f| @intCast(@min(f.scroll, std.math.maxInt(i32))) else if (pane.isTerminal()) panes.terminal.gridOffset(pane) else 0;
s.addRegion(.{ .kind = .body, .owner = owner, .serial = pane.serial, .active = active, .line = line, .rect = .{ .x = r.x + config.GUTTER, .y = body_y, .w = r.w - config.GUTTER, .h = body_h } });
var rail: Region = .{ .kind = .rail, .owner = owner, .serial = pane.serial, .active = active, .rect = .{ .x = r.x, .y = body_y, .w = config.GUTTER, .h = body_h } };
// An image's rail has no thumb; a native PDF's is measured as its
@@ -78,7 +78,7 @@ pub fn place(p: *Pardes, s: *Surface) void {
.offset = page,
.len = 1,
} else blk: {
- const gsb = panes.Terminal.scrollbar(pane);
+ const gsb = panes.terminal.scrollbar(pane);
break :blk .{ .total = gsb.total, .offset = gsb.offset, .len = gsb.len };
};
const track_h: usize = body_h;
@@ -241,7 +241,7 @@ fn glideCursor(p: *Pardes, s: *Surface) void {
if (inside) frame = paneFrame(s, pane.serial, rect);
const origin: [2]f32 = .{ @floatFromInt(rect.x), @floatFromInt(rect.y) };
const view = p.cursor_view;
- const line: i64 = if (pane.file) |f| @intCast(f.scroll) else if (pane.isTerminal()) panes.Terminal.gridOffset(pane) else 0;
+ const line: i64 = if (pane.file) |f| @intCast(f.scroll) else if (pane.isTerminal()) panes.terminal.gridOffset(pane) else 0;
if (view.serial == pane.serial and view.inside == inside) {
// The pane moved in the layout: the springs move with it (its
// own cursor's; one in a column's tag stays).
@@ -719,7 +719,7 @@ pub fn render(p: *Pardes, arena: std.mem.Allocator) !*Surface {
sb_off = page;
sb_total = if (comptime pdf_enabled) at.pdf.?.page_count else 0;
} else {
- const sb = panes.Terminal.scrollbar(at);
+ const sb = panes.terminal.scrollbar(at);
sb_off = sb.offset;
sb_total = sb.total;
}
@@ -1477,6 +1477,60 @@ test "a grip's four states, focused or not and clean or dirty, are each its own
pane.file.?.revision = pane.file.?.saved_revision;
}
+test "every theme draws a file's name, a +Errors and a Tty word in a tint, never the tag's plain ink" {
+ const gpa = std.testing.allocator;
+ const p = try Pardes.init(gpa, .{ .cols = 120, .rows = 40, .tty_only = true });
+ defer p.deinit();
+ _ = try p.setTestFile("text\n");
+ try std.testing.expect(p.executeBuiltinLine(0, "Tty+sh"));
+ const terminal = p.active;
+ p.acknowledgeShell(terminal, "/bin/sh", false);
+ try @import("Output.zig").openErrors(p, 0, try gpa.dupe(u8, "oops\n"));
+ while (p.nextEffect()) |_| {}
+ p.animate_theme_changes = false;
+ const errors = for (p.panes, 0..) |slot, id| {
+ const pane = slot orelse continue;
+ if (pane.file) |f| if (std.mem.endsWith(u8, f.path, "+Errors")) break id;
+ } else return error.NoErrorsPane;
+ const Probe = struct { id: usize, word: []const u8 };
+ const probes = [_]Probe{ .{ .id = 0, .word = "test.txt" }, .{ .id = terminal, .word = "Tty+sh" }, .{ .id = errors, .word = "+Errors" } };
+ var arena: std.heap.ArenaAllocator = .init(gpa);
+ defer arena.deinit();
+ for (pardes.themes, 0..) |theme, index| {
+ colors.setThemeIndex(p, index);
+ // Each pane focused in turn: every word on both grounds.
+ for (probes) |focused| {
+ p.active = focused.id;
+ _ = arena.reset(.retain_capacity);
+ const s = try p.render(arena.allocator());
+ for (probes) |probe| {
+ const r = p.rects[probe.id];
+ const y = p.tagTop(p.panes[probe.id].?, r);
+ // The row's text, and the column each byte of it is drawn at.
+ var row: [512]u8 = undefined;
+ var cols: [512]u16 = undefined;
+ var len: usize = 0;
+ for (r.x..r.x + r.w) |x| {
+ const g = s.at(@intCast(x), y).grapheme();
+ for (if (g.len == 0) " " else g) |byte| if (len < row.len) {
+ row[len] = byte;
+ cols[len] = @intCast(x);
+ len += 1;
+ };
+ }
+ const name = std.mem.indexOf(u8, row[0..len], probe.word) orelse return error.WordNotDrawn;
+ const plain = std.mem.indexOf(u8, row[0..len], " Del") orelse return error.WordNotDrawn;
+ const tint = s.at(cols[name], y).style.fg;
+ const ink = s.at(cols[plain + 1], y).style.fg;
+ if (std.meta.eql(tint, ink)) std.debug.print("{s}: {s} drawn in the tag's ink\n", .{ theme.name, probe.word });
+ try std.testing.expect(!std.meta.eql(tint, ink));
+ // The whole word, in the one tint.
+ try std.testing.expect(std.meta.eql(s.at(cols[name + probe.word.len - 1], y).style.fg, tint));
+ }
+ }
+ }
+}
+
test "a tag of three rows has its grip on the first, and band under it that still grabs the pane" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 30 });
defer p.deinit();