2024-01-19 06:17:57 +01:00
|
|
|
const std = @import("std");
|
2024-01-19 17:21:49 +01:00
|
|
|
const assert = std.debug.assert;
|
2024-01-19 06:17:57 +01:00
|
|
|
|
2024-02-11 19:59:33 +01:00
|
|
|
const Cell = @import("Cell.zig");
|
2024-01-24 20:36:24 +01:00
|
|
|
const Shape = @import("Mouse.zig").Shape;
|
2024-01-30 23:26:35 +01:00
|
|
|
const Image = @import("Image.zig");
|
|
|
|
const Winsize = @import("Tty.zig").Winsize;
|
2024-04-29 20:01:04 +02:00
|
|
|
const Unicode = @import("Unicode.zig");
|
|
|
|
const Method = @import("gwidth.zig").Method;
|
2024-01-19 06:17:57 +01:00
|
|
|
|
2024-01-19 19:21:14 +01:00
|
|
|
const log = std.log.scoped(.screen);
|
|
|
|
|
2024-01-19 06:17:57 +01:00
|
|
|
const Screen = @This();
|
|
|
|
|
2024-01-19 20:13:20 +01:00
|
|
|
width: usize = 0,
|
|
|
|
height: usize = 0,
|
2024-01-19 06:17:57 +01:00
|
|
|
|
2024-01-30 23:26:35 +01:00
|
|
|
width_pix: usize = 0,
|
|
|
|
height_pix: usize = 0,
|
|
|
|
|
2024-01-19 06:17:57 +01:00
|
|
|
buf: []Cell = undefined,
|
|
|
|
|
2024-01-22 18:18:59 +01:00
|
|
|
cursor_row: usize = 0,
|
|
|
|
cursor_col: usize = 0,
|
|
|
|
cursor_vis: bool = false,
|
|
|
|
|
2024-04-29 20:01:04 +02:00
|
|
|
unicode: *const Unicode = undefined,
|
|
|
|
|
|
|
|
width_method: Method = .wcwidth,
|
2024-01-24 13:12:39 +01:00
|
|
|
|
2024-01-24 20:36:24 +01:00
|
|
|
mouse_shape: Shape = .default,
|
2024-04-15 14:14:31 +02:00
|
|
|
cursor_shape: Cell.CursorShape = .default,
|
2024-01-24 20:36:24 +01:00
|
|
|
|
2024-04-29 20:01:04 +02:00
|
|
|
pub fn init(alloc: std.mem.Allocator, winsize: Winsize, unicode: *const Unicode) !Screen {
|
2024-01-30 23:26:35 +01:00
|
|
|
const w = winsize.cols;
|
|
|
|
const h = winsize.rows;
|
2024-04-30 19:33:46 +02:00
|
|
|
const self = Screen{
|
2024-01-23 03:09:35 +01:00
|
|
|
.buf = try alloc.alloc(Cell, w * h),
|
|
|
|
.width = w,
|
|
|
|
.height = h,
|
2024-01-30 23:26:35 +01:00
|
|
|
.width_pix = winsize.x_pixel,
|
|
|
|
.height_pix = winsize.y_pixel,
|
2024-04-29 20:01:04 +02:00
|
|
|
.unicode = unicode,
|
2024-01-23 03:09:35 +01:00
|
|
|
};
|
2024-04-30 19:33:46 +02:00
|
|
|
const base_cell: Cell = .{};
|
|
|
|
@memset(self.buf, base_cell);
|
2024-01-23 03:09:35 +01:00
|
|
|
return self;
|
2024-01-19 06:17:57 +01:00
|
|
|
}
|
|
|
|
pub fn deinit(self: *Screen, alloc: std.mem.Allocator) void {
|
|
|
|
alloc.free(self.buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// writes a cell to a location. 0 indexed
|
2024-01-19 19:21:14 +01:00
|
|
|
pub fn writeCell(self: *Screen, col: usize, row: usize, cell: Cell) void {
|
2024-01-19 06:17:57 +01:00
|
|
|
if (self.width < col) {
|
|
|
|
// column out of bounds
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (self.height < row) {
|
|
|
|
// height out of bounds
|
|
|
|
return;
|
|
|
|
}
|
2024-01-19 19:21:14 +01:00
|
|
|
const i = (row * self.width) + col;
|
2024-01-19 17:21:49 +01:00
|
|
|
assert(i < self.buf.len);
|
2024-01-19 06:17:57 +01:00
|
|
|
self.buf[i] = cell;
|
|
|
|
}
|
2024-03-01 19:28:03 +01:00
|
|
|
|
|
|
|
pub fn readCell(self: *Screen, col: usize, row: usize) ?Cell {
|
|
|
|
if (self.width < col) {
|
|
|
|
// column out of bounds
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
if (self.height < row) {
|
|
|
|
// height out of bounds
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
const i = (row * self.width) + col;
|
|
|
|
assert(i < self.buf.len);
|
|
|
|
return self.buf[i];
|
|
|
|
}
|