a modern tui library written in zig
at v0.1.0 2.7 kB view raw
1const std = @import("std"); 2const assert = std.debug.assert; 3const Style = @import("cell.zig").Style; 4const Cell = @import("cell.zig").Cell; 5const Shape = @import("Mouse.zig").Shape; 6 7const log = std.log.scoped(.internal_screen); 8 9const InternalScreen = @This(); 10 11pub const InternalCell = struct { 12 char: std.ArrayList(u8) = undefined, 13 style: Style = .{}, 14 uri: std.ArrayList(u8) = undefined, 15 uri_id: std.ArrayList(u8) = undefined, 16 // if we got skipped because of a wide character 17 skipped: bool = false, 18 19 pub fn eql(self: InternalCell, cell: Cell) bool { 20 return std.mem.eql(u8, self.char.items, cell.char.grapheme) and 21 std.meta.eql(self.style, cell.style) and 22 std.mem.eql(u8, self.uri.items, cell.link.uri) and 23 std.mem.eql(u8, self.uri_id.items, cell.link.params); 24 } 25}; 26 27width: usize = 0, 28height: usize = 0, 29 30buf: []InternalCell = undefined, 31 32cursor_row: usize = 0, 33cursor_col: usize = 0, 34cursor_vis: bool = false, 35 36mouse_shape: Shape = .default, 37 38/// sets each cell to the default cell 39pub fn init(alloc: std.mem.Allocator, w: usize, h: usize) !InternalScreen { 40 var screen = InternalScreen{ 41 .buf = try alloc.alloc(InternalCell, w * h), 42 }; 43 for (screen.buf, 0..) |_, i| { 44 screen.buf[i] = .{ 45 .char = try std.ArrayList(u8).initCapacity(alloc, 1), 46 .uri = std.ArrayList(u8).init(alloc), 47 .uri_id = std.ArrayList(u8).init(alloc), 48 }; 49 } 50 screen.width = w; 51 screen.height = h; 52 return screen; 53} 54 55pub fn deinit(self: *InternalScreen, alloc: std.mem.Allocator) void { 56 for (self.buf, 0..) |_, i| { 57 self.buf[i].char.deinit(); 58 self.buf[i].uri.deinit(); 59 self.buf[i].uri_id.deinit(); 60 } 61 62 alloc.free(self.buf); 63} 64 65/// writes a cell to a location. 0 indexed 66pub fn writeCell( 67 self: *InternalScreen, 68 col: usize, 69 row: usize, 70 cell: Cell, 71) void { 72 if (self.width < col) { 73 // column out of bounds 74 return; 75 } 76 if (self.height < row) { 77 // height out of bounds 78 return; 79 } 80 const i = (row * self.width) + col; 81 assert(i < self.buf.len); 82 self.buf[i].char.clearRetainingCapacity(); 83 self.buf[i].char.appendSlice(cell.char.grapheme) catch { 84 log.warn("couldn't write grapheme", .{}); 85 }; 86 self.buf[i].uri.clearRetainingCapacity(); 87 self.buf[i].uri.appendSlice(cell.link.uri) catch { 88 log.warn("couldn't write uri", .{}); 89 }; 90 self.buf[i].uri.clearRetainingCapacity(); 91 self.buf[i].uri_id.appendSlice(cell.link.params) catch { 92 log.warn("couldn't write uri_id", .{}); 93 }; 94 self.buf[i].style = cell.style; 95}