diff --git a/src/layout/Framing.zig b/src/layout/Framing.zig index 90030f3..16c3539 100644 --- a/src/layout/Framing.zig +++ b/src/layout/Framing.zig @@ -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| {