Make main code less directly dependent on termbox2

Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
AnErrupTion 2025-03-16 11:17:38 +01:00
parent e0ed1b4eb1
commit 1672d4a9ec
No known key found for this signature in database
9 changed files with 108 additions and 107 deletions

View File

@ -1,7 +1,7 @@
const std = @import("std");
const Animation = @import("../tui/Animation.zig");
const Cell = @import("../tui/Cell.zig");
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
const utils = @import("../tui/utils.zig");
const ColorMix = @This();
@ -19,7 +19,7 @@ terminal_buffer: *TerminalBuffer,
frames: u64,
pattern_cos_mod: f32,
pattern_sin_mod: f32,
palette: [palette_len]utils.Cell,
palette: [palette_len]Cell,
pub fn init(terminal_buffer: *TerminalBuffer, col1: u32, col2: u32, col3: u32) ColorMix {
return .{
@ -27,19 +27,19 @@ pub fn init(terminal_buffer: *TerminalBuffer, col1: u32, col2: u32, col3: u32) C
.frames = 0,
.pattern_cos_mod = terminal_buffer.random.float(f32) * math.pi * 2.0,
.pattern_sin_mod = terminal_buffer.random.float(f32) * math.pi * 2.0,
.palette = [palette_len]utils.Cell{
utils.initCell(0x2588, col1, col2),
utils.initCell(0x2593, col1, col2),
utils.initCell(0x2592, col1, col2),
utils.initCell(0x2591, col1, col2),
utils.initCell(0x2588, col2, col3),
utils.initCell(0x2593, col2, col3),
utils.initCell(0x2592, col2, col3),
utils.initCell(0x2591, col2, col3),
utils.initCell(0x2588, col3, col1),
utils.initCell(0x2593, col3, col1),
utils.initCell(0x2592, col3, col1),
utils.initCell(0x2591, col3, col1),
.palette = [palette_len]Cell{
Cell.init(0x2588, col1, col2),
Cell.init(0x2593, col1, col2),
Cell.init(0x2592, col1, col2),
Cell.init(0x2591, col1, col2),
Cell.init(0x2588, col2, col3),
Cell.init(0x2593, col2, col3),
Cell.init(0x2592, col2, col3),
Cell.init(0x2591, col2, col3),
Cell.init(0x2588, col3, col1),
Cell.init(0x2593, col3, col1),
Cell.init(0x2592, col3, col1),
Cell.init(0x2591, col3, col1),
},
};
}
@ -80,7 +80,7 @@ fn draw(self: *ColorMix) void {
}
const cell = self.palette[@as(usize, @intFromFloat(math.floor(length(uv) * 5.0))) % palette_len];
utils.putCell(x, y, cell);
cell.put(x, y);
}
}
}

View File

@ -1,8 +1,8 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const Animation = @import("../tui/Animation.zig");
const Cell = @import("../tui/Cell.zig");
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
const utils = @import("../tui/utils.zig");
const Doom = @This();
@ -11,7 +11,7 @@ pub const STEPS = 12;
allocator: Allocator,
terminal_buffer: *TerminalBuffer,
buffer: []u8,
fire: [STEPS + 1]utils.Cell,
fire: [STEPS + 1]Cell,
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, top_color: u32, middle_color: u32, bottom_color: u32) !Doom {
const buffer = try allocator.alloc(u8, terminal_buffer.width * terminal_buffer.height);
@ -21,20 +21,20 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, top_color: u
.allocator = allocator,
.terminal_buffer = terminal_buffer,
.buffer = buffer,
.fire = [_]utils.Cell{
utils.initCell(' ', 0x00000000, 0),
utils.initCell(0x2591, top_color, 0),
utils.initCell(0x2592, top_color, 0),
utils.initCell(0x2593, top_color, 0),
utils.initCell(0x2588, top_color, 0),
utils.initCell(0x2591, middle_color, 2),
utils.initCell(0x2592, middle_color, 2),
utils.initCell(0x2593, middle_color, 2),
utils.initCell(0x2588, middle_color, 2),
utils.initCell(0x2591, bottom_color, 4),
utils.initCell(0x2592, bottom_color, 4),
utils.initCell(0x2593, bottom_color, 4),
utils.initCell(0x2588, bottom_color, 4),
.fire = [_]Cell{
Cell.init(' ', 0x00000000, 0),
Cell.init(0x2591, top_color, 0),
Cell.init(0x2592, top_color, 0),
Cell.init(0x2593, top_color, 0),
Cell.init(0x2588, top_color, 0),
Cell.init(0x2591, middle_color, 2),
Cell.init(0x2592, middle_color, 2),
Cell.init(0x2593, middle_color, 2),
Cell.init(0x2588, middle_color, 2),
Cell.init(0x2591, bottom_color, 4),
Cell.init(0x2592, bottom_color, 4),
Cell.init(0x2593, bottom_color, 4),
Cell.init(0x2588, bottom_color, 4),
},
};
}
@ -73,11 +73,13 @@ fn draw(self: *Doom) void {
const dest_y = dest / self.terminal_buffer.width;
const dest_x = dest % self.terminal_buffer.width;
utils.putCell(dest_x, dest_y, self.fire[buffer_dest]);
const dest_cell = self.fire[buffer_dest];
dest_cell.put(dest_x, dest_y);
const source_y = source / self.terminal_buffer.width;
const source_x = source % self.terminal_buffer.width;
utils.putCell(source_x, source_y, self.fire[buffer_source]);
const source_cell = self.fire[buffer_source];
source_cell.put(source_x, source_y);
}
}
}

View File

@ -1,11 +1,11 @@
const std = @import("std");
const interop = @import("../interop.zig");
const Animation = @import("../tui/Animation.zig");
const Cell = @import("../tui/Cell.zig");
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
const Allocator = std.mem.Allocator;
const Random = std.Random;
const Animation = @import("../tui/Animation.zig");
const TerminalBuffer = @import("../tui/TerminalBuffer.zig");
const utils = @import("../tui/utils.zig");
const interop = @import("../interop.zig");
const termbox = interop.termbox;
pub const FRAME_DELAY: usize = 8;
@ -13,6 +13,8 @@ pub const FRAME_DELAY: usize = 8;
// Characters change mid-scroll
pub const MID_SCROLL_CHANGE = true;
const DOT_HEAD_COLOR: u32 = @intCast(0x00FFFFFF | termbox.TB_BOLD); // White and bold
const Matrix = @This();
pub const Dot = struct {
@ -35,6 +37,7 @@ count: usize,
fg_ini: u32,
min_codepoint: u16,
max_codepoint: u16,
default_cell: Cell,
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, fg_ini: u32, min_codepoint: u16, max_codepoint: u16) !Matrix {
const dots = try allocator.alloc(Dot, terminal_buffer.width * (terminal_buffer.height + 1));
@ -52,6 +55,7 @@ pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, fg_ini: u32,
.fg_ini = fg_ini,
.min_codepoint = min_codepoint,
.max_codepoint = max_codepoint - min_codepoint,
.default_cell = .{ .ch = ' ', .fg = fg_ini, .bg = termbox.TB_DEFAULT },
};
}
@ -153,16 +157,13 @@ fn draw(self: *Matrix) void {
var y: usize = 1;
while (y <= self.terminal_buffer.height) : (y += 1) {
const dot = self.dots[buf_width * y + x];
const cell = if (dot.value == null or dot.value == ' ') self.default_cell else Cell{
.ch = @intCast(dot.value.?),
.fg = if (dot.is_head) DOT_HEAD_COLOR else self.fg_ini,
.bg = termbox.TB_DEFAULT,
};
var fg = self.fg_ini;
if (dot.value == null or dot.value == ' ') {
utils.putCell(x, y - 1, .{ .ch = ' ', .fg = fg, .bg = termbox.TB_DEFAULT });
continue;
}
if (dot.is_head) fg = @intCast(0x00FFFFFF | termbox.TB_BOLD); // White and bold
utils.putCell(x, y - 1, .{ .ch = @intCast(dot.value.?), .fg = fg, .bg = termbox.TB_DEFAULT });
cell.put(x, y - 1);
}
}
}

View File

@ -1,36 +1,35 @@
const std = @import("std");
const interop = @import("interop.zig");
const utils = @import("tui/utils.zig");
const enums = @import("enums.zig");
const Lang = @import("bigclock/Lang.zig");
const en = @import("bigclock/en.zig");
const fa = @import("bigclock/fa.zig");
const Cell = @import("tui/Cell.zig");
const termbox = interop.termbox;
const Bigclock = enums.Bigclock;
pub const WIDTH = Lang.WIDTH;
pub const HEIGHT = Lang.HEIGHT;
pub const SIZE = Lang.SIZE;
pub fn clockCell(animate: bool, char: u8, fg: u32, bg: u32, bigclock: Bigclock) [SIZE]utils.Cell {
var cells: [SIZE]utils.Cell = undefined;
pub fn clockCell(animate: bool, char: u8, fg: u32, bg: u32, bigclock: Bigclock) [SIZE]Cell {
var cells: [SIZE]Cell = undefined;
var tv: interop.system_time.timeval = undefined;
_ = interop.system_time.gettimeofday(&tv, null);
const clock_chars = toBigNumber(if (animate and char == ':' and @divTrunc(tv.tv_usec, 500000) != 0) ' ' else char, bigclock);
for (0..cells.len) |i| cells[i] = utils.initCell(clock_chars[i], fg, bg);
for (0..cells.len) |i| cells[i] = Cell.init(clock_chars[i], fg, bg);
return cells;
}
pub fn alphaBlit(x: usize, y: usize, tb_width: usize, tb_height: usize, cells: [SIZE]utils.Cell) void {
pub fn alphaBlit(x: usize, y: usize, tb_width: usize, tb_height: usize, cells: [SIZE]Cell) void {
if (x + WIDTH >= tb_width or y + HEIGHT >= tb_height) return;
for (0..HEIGHT) |yy| {
for (0..WIDTH) |xx| {
const cell = cells[yy * WIDTH + xx];
if (cell.ch != 0) utils.putCell(x + xx, y + yy, cell);
cell.put(x + xx, y + yy);
}
}
}

View File

@ -21,7 +21,6 @@ const Lang = @import("config/Lang.zig");
const Save = @import("config/Save.zig");
const migrator = @import("config/migrator.zig");
const SharedError = @import("SharedError.zig");
const utils = @import("tui/utils.zig");
const Ini = ini.Ini;
const DisplayServer = enums.DisplayServer;
@ -358,15 +357,15 @@ pub fn main() !void {
const animate = config.animation != .none;
const shutdown_key = try std.fmt.parseInt(u8, config.shutdown_key[1..], 10);
const shutdown_len = try utils.strWidth(lang.shutdown);
const shutdown_len = try TerminalBuffer.strWidth(lang.shutdown);
const restart_key = try std.fmt.parseInt(u8, config.restart_key[1..], 10);
const restart_len = try utils.strWidth(lang.restart);
const restart_len = try TerminalBuffer.strWidth(lang.restart);
const sleep_key = try std.fmt.parseInt(u8, config.sleep_key[1..], 10);
const sleep_len = try utils.strWidth(lang.sleep);
const sleep_len = try TerminalBuffer.strWidth(lang.sleep);
const brightness_down_key = if (config.brightness_down_key) |key| try std.fmt.parseInt(u8, key[1..], 10) else null;
const brightness_down_len = try utils.strWidth(lang.brightness_down);
const brightness_down_len = try TerminalBuffer.strWidth(lang.brightness_down);
const brightness_up_key = if (config.brightness_down_key) |key| try std.fmt.parseInt(u8, key[1..], 10) else null;
const brightness_up_len = try utils.strWidth(lang.brightness_up);
const brightness_up_len = try TerminalBuffer.strWidth(lang.brightness_up);
var event: termbox.tb_event = undefined;
var run = true;

23
src/tui/Cell.zig Normal file
View File

@ -0,0 +1,23 @@
const interop = @import("../interop.zig");
const termbox = interop.termbox;
const Cell = @This();
ch: u32,
fg: u32,
bg: u32,
pub fn init(ch: u32, fg: u32, bg: u32) Cell {
return .{
.ch = ch,
.fg = fg,
.bg = bg,
};
}
pub fn put(self: Cell, x: usize, y: usize) void {
if (self.ch == 0) return;
_ = termbox.tb_set_cell(@intCast(x), @intCast(y), self.ch, self.fg, self.bg);
}

View File

@ -1,7 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const interop = @import("../interop.zig");
const utils = @import("utils.zig");
const Cell = @import("Cell.zig");
const Random = std.Random;
@ -41,6 +41,7 @@ box_width: usize,
box_height: usize,
margin_box_v: u8,
margin_box_h: u8,
blank_cell: Cell,
pub fn init(options: InitOptions, labels_max_length: usize, random: Random) TerminalBuffer {
return .{
@ -76,6 +77,7 @@ pub fn init(options: InitOptions, labels_max_length: usize, random: Random) Term
.box_height = 7 + (2 * options.margin_box_v),
.margin_box_v = options.margin_box_v,
.margin_box_h = options.margin_box_h,
.blank_cell = Cell.init(' ', options.fg, options.bg),
};
}
@ -125,29 +127,27 @@ pub fn drawBoxCenter(self: *TerminalBuffer, show_borders: bool, blank_box: bool)
_ = termbox.tb_set_cell(@intCast(x1 - 1), @intCast(y2), self.box_chars.left_down, self.border_fg, self.bg);
_ = termbox.tb_set_cell(@intCast(x2), @intCast(y2), self.box_chars.right_down, self.border_fg, self.bg);
var c1 = utils.initCell(self.box_chars.top, self.border_fg, self.bg);
var c2 = utils.initCell(self.box_chars.bottom, self.border_fg, self.bg);
var c1 = Cell.init(self.box_chars.top, self.border_fg, self.bg);
var c2 = Cell.init(self.box_chars.bottom, self.border_fg, self.bg);
for (0..self.box_width) |i| {
utils.putCell(x1 + i, y1 - 1, c1);
utils.putCell(x1 + i, y2, c2);
c1.put(x1 + i, y1 - 1);
c2.put(x1 + i, y2);
}
c1.ch = self.box_chars.left;
c2.ch = self.box_chars.right;
for (0..self.box_height) |i| {
utils.putCell(x1 - 1, y1 + i, c1);
utils.putCell(x2, y1 + i, c2);
c1.put(x1 - 1, y1 + i);
c2.put(x2, y1 + i);
}
}
if (blank_box) {
const blank = utils.initCell(' ', self.fg, self.bg);
for (0..self.box_height) |y| {
for (0..self.box_width) |x| {
utils.putCell(x1 + x, y1 + y, blank);
self.blank_cell.put(x1 + x, y1 + y);
}
}
}
@ -203,6 +203,16 @@ pub fn drawConfinedLabel(self: TerminalBuffer, text: []const u8, x: usize, y: us
}
pub fn drawCharMultiple(self: TerminalBuffer, char: u32, x: usize, y: usize, length: usize) void {
const cell = utils.initCell(char, self.fg, self.bg);
for (0..length) |xx| utils.putCell(x + xx, y, cell);
const cell = Cell.init(char, self.fg, self.bg);
for (0..length) |xx| cell.put(x + xx, y);
}
// Every codepoint is assumed to have a width of 1.
// Since Ly is normally running in a TTY, this should be fine.
pub fn strWidth(str: []const u8) !u8 {
const utf8view = try std.unicode.Utf8View.init(str);
var utf8 = utf8view.iterator();
var i: u8 = 0;
while (utf8.nextCodepoint()) |_| i += 1;
return i;
}

View File

@ -1,7 +1,6 @@
const std = @import("std");
const TerminalBuffer = @import("../TerminalBuffer.zig");
const generic = @import("generic.zig");
const utils = @import("../utils.zig");
const Allocator = std.mem.Allocator;
@ -32,7 +31,7 @@ pub fn addMessage(self: *InfoLine, text: []const u8, bg: u32, fg: u32) !void {
if (text.len == 0) return;
try self.label.addItem(.{
.width = try utils.strWidth(text),
.width = try TerminalBuffer.strWidth(text),
.text = text,
.bg = bg,
.fg = fg,

View File

@ -1,32 +0,0 @@
const std = @import("std");
const interop = @import("../interop.zig");
const termbox = interop.termbox;
pub const Cell = struct {
ch: u32,
fg: u32,
bg: u32,
};
pub fn initCell(ch: u32, fg: u32, bg: u32) Cell {
return .{
.ch = ch,
.fg = fg,
.bg = bg,
};
}
pub fn putCell(x: usize, y: usize, cell: Cell) void {
_ = termbox.tb_set_cell(@intCast(x), @intCast(y), cell.ch, cell.fg, cell.bg);
}
// Every codepoint is assumed to have a width of 1.
// Since ly should be running in a tty, this should be fine.
pub fn strWidth(str: []const u8) !u8 {
const utf8view = try std.unicode.Utf8View.init(str);
var utf8 = utf8view.iterator();
var i: u8 = 0;
while (utf8.nextCodepoint()) |_| i += 1;
return i;
}