feat(Framing): border, style, title with styling
This commit is contained in:
@@ -8,6 +8,7 @@ const terminal = @import("../terminal.zig");
|
|||||||
const isTaggedUnion = @import("../event.zig").isTaggedUnion;
|
const isTaggedUnion = @import("../event.zig").isTaggedUnion;
|
||||||
const Error = @import("../event.zig").Error;
|
const Error = @import("../event.zig").Error;
|
||||||
const Key = terminal.Key;
|
const Key = terminal.Key;
|
||||||
|
const Style = terminal.Style;
|
||||||
|
|
||||||
const log = std.log.scoped(.layout_framing);
|
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,
|
size: terminal.Size = undefined,
|
||||||
element: Element = undefined,
|
element: Element = undefined,
|
||||||
events: Events = 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 .{
|
return .{
|
||||||
|
.config = config,
|
||||||
.element = element,
|
.element = element,
|
||||||
.events = Events.init(allocator),
|
.events = Events.init(allocator),
|
||||||
};
|
};
|
||||||
@@ -96,18 +115,28 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
|
|||||||
return &this.events;
|
return &this.events;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(this: *@This(), renderer: Renderer) !void {
|
const round_frame = .{ "╭", "─", "╮", "│", "╰", "╯" };
|
||||||
// TODO: render frame around the "1" padding
|
const square_frame = .{ "┌", "─", "┐", "│", "└", "┘" };
|
||||||
try renderer.clear(this.size);
|
|
||||||
// NOTE: round corners: .{ "╭", "─", "╮", "│", "╯", "╰" }
|
fn renderFrame(this: *@This(), renderer: Renderer) !void {
|
||||||
// NOTE: hard corners: .{ "┌", "─", "┐", "│", "┘", "└" }
|
// 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: +---+
|
// render top: +---+
|
||||||
try terminal.setCursorPosition(this.size.anchor);
|
try terminal.setCursorPosition(this.size.anchor);
|
||||||
_ = try terminal.write("╭");
|
const writer = terminal.writer();
|
||||||
for (0..this.size.cols -| 2) |_| {
|
try this.config.style.value(writer, frame[0]);
|
||||||
_ = try terminal.write("─");
|
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: |
|
// render left: |
|
||||||
for (1..this.size.rows -| 1) |r| {
|
for (1..this.size.rows -| 1) |r| {
|
||||||
const row: u16 = @truncate(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,
|
.col = this.size.anchor.col,
|
||||||
.row = this.size.anchor.row + row,
|
.row = this.size.anchor.row + row,
|
||||||
});
|
});
|
||||||
_ = try terminal.write("│");
|
try this.config.style.value(writer, frame[3]);
|
||||||
}
|
}
|
||||||
// render right: |
|
// render right: |
|
||||||
for (1..this.size.rows -| 1) |r| {
|
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,
|
.col = this.size.anchor.col + this.size.cols -| 1,
|
||||||
.row = this.size.anchor.row + row,
|
.row = this.size.anchor.row + row,
|
||||||
});
|
});
|
||||||
_ = try terminal.write("│");
|
try this.config.style.value(writer, frame[3]);
|
||||||
}
|
}
|
||||||
// render bottom: +---+
|
// render bottom: +---+
|
||||||
try terminal.setCursorPosition(.{
|
try terminal.setCursorPosition(.{
|
||||||
.col = this.size.anchor.col,
|
.col = this.size.anchor.col,
|
||||||
.row = this.size.anchor.row + this.size.rows,
|
.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) |_| {
|
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).*) {
|
switch ((&this.element).*) {
|
||||||
.layout => |*layout| {
|
.layout => |*layout| {
|
||||||
|
|||||||
Reference in New Issue
Block a user