WIP: add Container type with corresponding Properties configuration
The configuration of the `Container` types is very much inspired by [clay](https://github.com/nicbarker/clay).
This commit is contained in:
59
src/app.zig
59
src/app.zig
@@ -7,6 +7,7 @@ const mergeTaggedUnions = event.mergeTaggedUnions;
|
||||
const isTaggedUnion = event.isTaggedUnion;
|
||||
|
||||
const Key = @import("key.zig");
|
||||
const Size = @import("size.zig");
|
||||
const Queue = @import("queue.zig").Queue;
|
||||
|
||||
const log = std.log.scoped(.app);
|
||||
@@ -15,14 +16,6 @@ const log = std.log.scoped(.app);
|
||||
/// an tagged union for all the user events that can be send through the
|
||||
/// applications event loop.
|
||||
///
|
||||
/// _R_ is the type function for the `Renderer` to use. The parameter boolean
|
||||
/// will be set to the _fullscreen_ value at compile time. The corresponding
|
||||
/// `Renderer` type is accessible through the generated type of this function.
|
||||
///
|
||||
/// _fullscreen_ will be used to configure the `App` and the `Renderer` to
|
||||
/// respect the corresponding configuration whether to render a fullscreen tui
|
||||
/// or an inline tui.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Create an `App` which renders using the `PlainRenderer` in fullscreen with
|
||||
@@ -32,41 +25,35 @@ const log = std.log.scoped(.app);
|
||||
/// const zterm = @import("zterm");
|
||||
/// const App = zterm.App(
|
||||
/// union(enum) {},
|
||||
/// zterm.Renderer.Direct,
|
||||
/// true,
|
||||
/// );
|
||||
/// // later on use
|
||||
/// // later on create an `App` instance and start the event loop
|
||||
/// var app: App = .{};
|
||||
/// var renderer: App.Renderer = .{};
|
||||
/// try app.start(null);
|
||||
/// defer app.stop() catch unreachable;
|
||||
/// ```
|
||||
pub fn App(comptime E: type, comptime R: fn (comptime bool) type, comptime fullscreen: bool) type {
|
||||
pub fn App(comptime E: type) type {
|
||||
if (!isTaggedUnion(E)) {
|
||||
@compileError("Provided user event `E` for `App(comptime E: type)` is not of type `union(enum)`.");
|
||||
}
|
||||
return struct {
|
||||
pub const Event = mergeTaggedUnions(event.SystemEvent, E);
|
||||
pub const Renderer = R(fullscreen);
|
||||
pub const Layout = @import("layout.zig").Layout(Event, Renderer);
|
||||
pub const Widget = @import("widget.zig").Widget(Event, Renderer);
|
||||
pub const View = @import("view.zig").View(Event, Renderer);
|
||||
pub const Container = @import("container.zig").Container(Event);
|
||||
|
||||
queue: Queue(Event, 256) = .{},
|
||||
thread: ?std.Thread = null,
|
||||
quit_event: std.Thread.ResetEvent = .{},
|
||||
termios: ?std.posix.termios = null,
|
||||
attached_handler: bool = false,
|
||||
min_size: ?terminal.Size = null,
|
||||
prev_size: terminal.Size = .{ .cols = 0, .rows = 0 },
|
||||
min_size: ?Size = null,
|
||||
prev_size: Size = .{ .cols = 0, .rows = 0 },
|
||||
|
||||
pub const SignalHandler = struct {
|
||||
context: *anyopaque,
|
||||
callback: *const fn (context: *anyopaque) void,
|
||||
};
|
||||
|
||||
pub fn start(this: *@This(), min_size: ?terminal.Size) !void {
|
||||
if (fullscreen) { // a minimal size only really makes sense if the application is rendered fullscreen
|
||||
this.min_size = min_size;
|
||||
}
|
||||
pub fn start(this: *@This(), min_size: ?Size) !void {
|
||||
this.min_size = min_size;
|
||||
if (this.thread) |_| return;
|
||||
|
||||
if (!this.attached_handler) {
|
||||
@@ -92,19 +79,17 @@ pub fn App(comptime E: type, comptime R: fn (comptime bool) type, comptime fulls
|
||||
if (this.termios) |_| {} else {
|
||||
this.termios = termios;
|
||||
}
|
||||
if (fullscreen) {
|
||||
try terminal.saveScreen();
|
||||
try terminal.enterAltScreen();
|
||||
try terminal.hideCursor();
|
||||
}
|
||||
try terminal.saveScreen();
|
||||
try terminal.enterAltScreen();
|
||||
try terminal.hideCursor();
|
||||
// post init event (as the very first element to be in the queue - event loop)
|
||||
this.postEvent(.init);
|
||||
}
|
||||
|
||||
pub fn interrupt(this: *@This()) !void {
|
||||
this.quit_event.set();
|
||||
if (fullscreen) {
|
||||
try terminal.exitAltScreen();
|
||||
try terminal.restoreScreen();
|
||||
}
|
||||
try terminal.exitAltScreen();
|
||||
try terminal.restoreScreen();
|
||||
if (this.thread) |thread| {
|
||||
thread.join();
|
||||
this.thread = null;
|
||||
@@ -115,11 +100,9 @@ pub fn App(comptime E: type, comptime R: fn (comptime bool) type, comptime fulls
|
||||
try this.interrupt();
|
||||
if (this.termios) |*termios| {
|
||||
try terminal.disableRawMode(termios);
|
||||
if (fullscreen) {
|
||||
try terminal.showCursor();
|
||||
try terminal.exitAltScreen();
|
||||
try terminal.restoreScreen();
|
||||
}
|
||||
try terminal.showCursor();
|
||||
try terminal.exitAltScreen();
|
||||
try terminal.restoreScreen();
|
||||
}
|
||||
this.termios = null;
|
||||
}
|
||||
@@ -322,7 +305,7 @@ pub fn App(comptime E: type, comptime R: fn (comptime bool) type, comptime fulls
|
||||
|
||||
// TODO: only post the event if the size has changed?
|
||||
// because there might be too many resize events (which force a re-draw of the entire screen)
|
||||
const size: terminal.Size = .{
|
||||
const size: Size = .{
|
||||
.rows = std.fmt.parseUnsigned(u16, height_char, 10) catch break,
|
||||
.cols = std.fmt.parseUnsigned(u16, width_char, 10) catch break,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user