Have a workingscreen except in kitty where the process keeps running after completion

This commit is contained in:
Warwick 2024-11-15 16:29:12 +00:00
parent e5a927657a
commit 20cae4b6e0
4 changed files with 114 additions and 16 deletions

View file

@ -22,6 +22,10 @@ pub fn build(b: *std.Build) void {
.optimize = optimize,
});
// Add Vaxis - tui library
const vaxis = b.dependency("vaxis", .{ .target = target, .optimize = optimize });
exe.root_module.addImport("vaxis", vaxis.module("vaxis"));
// This declares intent for the executable to be installed into the
// standard location when the user invokes the "install" step (the default
// step when running `zig build`).

View file

@ -4,10 +4,6 @@ pub const ScreenInterface = struct {
ptr: *anyopaque,
vtable: VTable,
pub fn init(self: ScreenInterface) anyerror!ScreenInterface {
return self.vtable.initFn(self.ptr);
}
pub fn deinit(self: ScreenInterface) anyerror!void {
return self.vtable.deinitFn(self.ptr);
}
@ -18,7 +14,21 @@ pub const ScreenInterface = struct {
};
const VTable = struct {
initFn: *const fn (self: *anyopaque) anyerror!ScreenInterface,
deinitFn: *const fn (self: *anyopaque) anyerror!void,
runFn: *const fn (self: *anyopaque) anyerror!void,
};
pub const ScreenEvent = union(enum) {
key_press: vaxis.Key,
key_release: vaxis.Key,
//mouse: vaxis.Mouse,
focus_in, // window has gained focus
focus_out, // window has lost focus
paste_start, // bracketed paste start
paste_end, // bracketed paste end
paste: []const u8, // osc 52 paste, caller must free
color_report: vaxis.Color.Report, // osc 4, 10, 11, 12 response
color_scheme: vaxis.Color.Scheme, // light / dark OS theme changes
winsize: vaxis.Winsize, // the window size has changed. This event is always sent when the loop
// is started
};

View file

@ -1,13 +1,21 @@
const std = @import("std");
const vaxis = @import("vaxis");
const ScreenInterface = @import("ScreenInterface.zig").ScreenInterface;
const ScreenEvent = @import("ScreenInterface.zig").ScreenEvent;
pub const TopicScreen = struct {
topic: []const u8 = "ayy",
allocator: *std.mem.Allocator,
vx: *vaxis.Vaxis,
tty: *vaxis.Tty,
topic: []const u8 = "deinit\n",
quit: bool = false,
pub fn init(ptr: *anyopaque) !ScreenInterface {
const self: *TopicScreen = @ptrCast(@alignCast(ptr));
std.debug.print("{s}", .{self.topic});
return self.screenInterface();
pub fn init(allocator: *std.mem.Allocator, tty: *vaxis.Tty, vaxis_instance: *vaxis.Vaxis) !TopicScreen {
return .{
.allocator = allocator,
.tty = tty,
.vx = vaxis_instance,
};
}
pub fn deinit(ptr: *anyopaque) !void {
const self: *TopicScreen = @ptrCast(@alignCast(ptr));
@ -15,12 +23,62 @@ pub const TopicScreen = struct {
}
pub fn run(ptr: *anyopaque) !void {
const self: *TopicScreen = @ptrCast(@alignCast(ptr));
return std.debug.print("{s}", .{self.topic});
var loop: vaxis.Loop(ScreenEvent) = .{
.tty = self.tty,
.vaxis = self.vx,
};
try loop.init();
try loop.start();
//defer loop.stop();
try self.vx.enterAltScreen(self.tty.anyWriter());
try self.vx.queryTerminal(self.tty.anyWriter(), 1 * std.time.ns_per_s);
while (!self.quit) {
loop.pollEvent();
while (loop.tryEvent()) |event| {
try self.update(event);
}
self.draw();
var buffered = self.tty.bufferedWriter();
try self.vx.render(buffered.writer().any());
try buffered.flush();
}
}
pub fn update(self: *TopicScreen, event: ScreenEvent) !void {
switch (event) {
.key_press => |key| {
if (key.matches('c', .{ .ctrl = true }))
self.quit = true;
},
.winsize => |ws| try self.vx.resize(self.allocator.*, self.tty.anyWriter(), ws),
else => {},
}
}
pub fn draw(self: *TopicScreen) void {
const msg = "Hello, world!";
const win = self.vx.window();
win.clear();
//self.vx.setMouseShape(.default);
const child = win.child(.{
.x_off = (win.width / 2) - 7,
.y_off = win.height / 2 + 1,
.width = .{ .limit = msg.len },
.height = .{ .limit = 1 },
});
_ = try child.printSegment(.{ .text = msg, .style = .{} }, .{});
}
pub fn screenInterface(self: *TopicScreen) ScreenInterface {
return .{ .ptr = self, .vtable = .{
.initFn = TopicScreen.init,
.deinitFn = TopicScreen.deinit,
.runFn = TopicScreen.run,
} };

View file

@ -1,10 +1,36 @@
const std = @import("std");
const vaxis = @import("vaxis");
const TopicScreen = @import("TopicScreen.zig").TopicScreen;
pub const panic = vaxis.panic_handler;
/// Set some scope levels for the vaxis scopes
pub const std_options: std.Options = .{
.log_scope_levels = &.{
.{ .scope = .vaxis, .level = .warn },
.{ .scope = .vaxis_parser, .level = .warn },
},
};
pub fn main() !void {
var topic_screen = TopicScreen{ .topic = "it worked?" };
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
//fail test; can't try in defer as defer is executed after we return
if (deinit_status == .leak) {
std.log.err("memory leak ", .{});
}
}
var allocator = gpa.allocator();
var tty = try vaxis.Tty.init();
var vx = try vaxis.init(allocator, .{});
defer vx.deinit(allocator, tty.anyWriter());
defer tty.deinit();
var topic_screen: TopicScreen = try TopicScreen.init(&allocator, &tty, &vx);
var screen_interface = topic_screen.screenInterface();
_ = try screen_interface.init();
_ = try screen_interface.run();
_ = try screen_interface.deinit();
try screen_interface.run();
try screen_interface.deinit();
}