feat(Framing): border, style, title with styling

This commit is contained in:
2024-11-11 12:29:53 +01:00
parent 53fc34ba69
commit 1605cd78dc

View File

@@ -8,6 +8,7 @@ const terminal = @import("../terminal.zig");
const isTaggedUnion = @import("../event.zig").isTaggedUnion;
const Error = @import("../event.zig").Error;
const Key = terminal.Key;
const Style = terminal.Style;
const log = std.log.scoped(.layout_framing);
@@ -24,9 +25,27 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
size: terminal.Size = undefined,
element: Element = undefined,
events: Events = undefined,
config: Config = undefined,
pub fn init(allocator: std.mem.Allocator, element: Element) @This() {
const Config = struct {
style: Style = .{ .fg = .default },
frame: Frame = .round,
title: Title = .{},
const Title = struct {
str: []const u8 = &.{},
style: Style = .{ .fg = .default },
};
const Frame = enum {
round,
square,
};
};
pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) @This() {
return .{
.config = config,
.element = element,
.events = Events.init(allocator),
};
@@ -96,18 +115,28 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
return &this.events;
}
pub fn render(this: *@This(), renderer: Renderer) !void {
// TODO: render frame around the "1" padding
try renderer.clear(this.size);
// NOTE: round corners: .{ "╭", "─", "╮", "│", "╯", "╰" }
// NOTE: hard corners: .{ "┌", "─", "┐", "│", "┘", "└" }
const round_frame = .{ "", "", "", "", "", "" };
const square_frame = .{ "", "", "", "", "", "" };
fn renderFrame(this: *@This(), renderer: Renderer) !void {
// FIXME: use renderer instead!
_ = renderer;
const frame = switch (this.config.frame) {
.round => round_frame,
.square => square_frame,
};
std.debug.assert(frame.len == 6);
// render top: +---+
try terminal.setCursorPosition(this.size.anchor);
_ = try terminal.write("");
for (0..this.size.cols -| 2) |_| {
_ = try terminal.write("");
const writer = terminal.writer();
try this.config.style.value(writer, frame[0]);
if (this.config.title.str.len > 0) {
try this.config.title.style.value(writer, this.config.title.str);
}
_ = try terminal.write("");
for (0..this.size.cols -| 2 -| this.config.title.str.len) |_| {
try this.config.style.value(writer, frame[1]);
}
try this.config.style.value(writer, frame[2]);
// render left: |
for (1..this.size.rows -| 1) |r| {
const row: u16 = @truncate(r);
@@ -115,7 +144,7 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
.col = this.size.anchor.col,
.row = this.size.anchor.row + row,
});
_ = try terminal.write("");
try this.config.style.value(writer, frame[3]);
}
// render right: |
for (1..this.size.rows -| 1) |r| {
@@ -124,18 +153,23 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
.col = this.size.anchor.col + this.size.cols -| 1,
.row = this.size.anchor.row + row,
});
_ = try terminal.write("");
try this.config.style.value(writer, frame[3]);
}
// render bottom: +---+
try terminal.setCursorPosition(.{
.col = this.size.anchor.col,
.row = this.size.anchor.row + this.size.rows,
});
_ = try terminal.write("");
try this.config.style.value(writer, frame[4]);
for (0..this.size.cols -| 2) |_| {
_ = try terminal.write("");
try this.config.style.value(writer, frame[1]);
}
_ = try terminal.write("");
try this.config.style.value(writer, frame[5]);
}
pub fn render(this: *@This(), renderer: Renderer) !void {
try renderer.clear(this.size);
try this.renderFrame(renderer);
switch ((&this.element).*) {
.layout => |*layout| {