widgets: add LineNumbers widget

The LineNumbers widget draws vertical list of numbers.
This can be used as a line number bar for a text editor for example.
This commit is contained in:
Jari Vetoniemi 2024-06-01 00:12:44 +09:00 committed by Tim Culverhouse
parent f25b8ab421
commit b215aec75b
2 changed files with 55 additions and 0 deletions

View file

@ -7,3 +7,4 @@ pub const Table = @import("widgets/Table.zig");
pub const TextInput = @import("widgets/TextInput.zig");
pub const nvim = @import("widgets/nvim.zig");
pub const ScrollView = @import("widgets/ScrollView.zig");
pub const LineNumbers = @import("widgets/LineNumbers.zig");

View file

@ -0,0 +1,54 @@
const std = @import("std");
const vaxis = @import("../main.zig");
const digits = "0123456789";
num_lines: usize = std.math.maxInt(usize),
highlighted_line: usize = 0,
style: vaxis.Style = .{ .dim = true },
highlighted_style: vaxis.Style = .{ .dim = true, .bg = .{ .index = 0 } },
pub fn extractDigit(v: usize, n: usize) usize {
return (v / (std.math.powi(usize, 10, n) catch unreachable)) % 10;
}
pub fn numDigits(v: usize) usize {
return switch (v) {
0...9 => 1,
10...99 => 2,
100...999 => 3,
1000...9999 => 4,
10000...99999 => 5,
100000...999999 => 6,
1000000...9999999 => 7,
10000000...99999999 => 8,
else => 0,
};
}
pub fn draw(self: @This(), win: vaxis.Window, y_scroll: usize) void {
for (1 + y_scroll..self.num_lines) |line| {
if (line - 1 >= y_scroll +| win.height) {
break;
}
const highlighted = line == self.highlighted_line;
const num_digits = numDigits(line);
for (0..num_digits) |i| {
const digit = extractDigit(line, i);
win.writeCell(win.width -| (i + 2), line -| (y_scroll +| 1), .{
.char = .{
.width = 1,
.grapheme = digits[digit .. digit + 1],
},
.style = if (highlighted) self.highlighted_style else self.style,
});
}
if (highlighted) {
for (num_digits + 1..win.width) |i| {
win.writeCell(i, line -| (y_scroll +| 1), .{
.style = if (highlighted) self.highlighted_style else self.style,
});
}
}
}
}