From 117545ca4b56deba3a342e32c1ce88536a5893ef Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Tue, 26 Mar 2024 11:41:54 -0500 Subject: [PATCH] window: add custom border location option Add a way to draw borders in custom locations --- examples/text_input.zig | 18 ++++--- src/Window.zig | 104 +++++++++++++++++++++------------------- 2 files changed, 67 insertions(+), 55 deletions(-) diff --git a/examples/text_input.zig b/examples/text_input.zig index 0d7f8a2..2bde6ed 100644 --- a/examples/text_input.zig +++ b/examples/text_input.zig @@ -112,17 +112,21 @@ pub fn main() !void { // vaxis double buffers the screen. This new frame will be compared to // the old and only updated cells will be drawn win.clear(); - const child = win.initChild( - win.width / 2 - 20, - win.height / 2 - 3, - .{ .limit = 40 }, - .{ .limit = 3 }, - ); // draw the text_input using a bordered window const style: vaxis.Style = .{ .fg = .{ .index = color_idx }, }; - text_input.draw(border.all(child, style)); + const child = win.child(.{ + .x_off = win.width / 2 - 20, + .y_off = win.height / 2 - 3, + .width = .{ .limit = 40 }, + .height = .{ .limit = 3 }, + .border = .{ + .where = .all, + .style = style, + }, + }); + text_input.draw(child); // Render the screen try vx.render(); diff --git a/src/Window.zig b/src/Window.zig index 363a0a2..65e4a59 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -77,16 +77,24 @@ pub const ChildOptions = struct { pub const BorderOptions = struct { style: Cell.Style = .{}, - where: enum { + where: union(enum) { none, all, top, right, bottom, left, + other: Locations, } = .none, glyphs: Glyphs = .single_rounded, + pub const Locations = packed struct { + top: bool = false, + right: bool = false, + bottom: bool = false, + left: bool = false, + }; + pub const Glyphs = union(enum) { single_rounded, single_square, @@ -126,56 +134,56 @@ pub fn child(self: Window, opts: ChildOptions) Window { const h = result.height; const w = result.width; - switch (opts.border.where) { + const loc: BorderOptions.Locations = switch (opts.border.where) { .none => return result, - .all => { - result.writeCell(0, 0, .{ .char = top_left, .style = style }); - result.writeCell(0, h -| 1, .{ .char = bottom_left, .style = style }); - result.writeCell(w - 1, 0, .{ .char = top_right, .style = style }); - result.writeCell(w - 1, h -| 1, .{ .char = bottom_right, .style = style }); - var i: usize = 1; - while (i < (h - 1)) : (i += 1) { - result.writeCell(0, i, .{ .char = vertical, .style = style }); - result.writeCell(w -| 1, i, .{ .char = vertical, .style = style }); - } - i = 1; - while (i < w - 1) : (i += 1) { - result.writeCell(i, 0, .{ .char = horizontal, .style = style }); - result.writeCell(i, h -| 1, .{ .char = horizontal, .style = style }); - } - return result.initChild(1, 1, .{ .limit = w - 2 }, .{ .limit = h - 2 }); - }, - .top => { - var i: usize = 0; - while (i < w) : (i += 1) { - result.writeCell(i, 0, .{ .char = horizontal, .style = style }); - } - return result.initChild(1, 0, .expand, .expand); - }, - .right => { - var i: usize = 0; - while (i < h) : (i += 1) { - result.writeCell(w -| 1, i, .{ .char = vertical, .style = style }); - } - return result.initChild(0, 0, .{ .limit = w -| 1 }, .expand); - }, - .bottom => { - var i: usize = 0; - while (i < w) : (i += 1) { - result.writeCell(i, h -| 1, .{ .char = horizontal, .style = style }); - } - return result.initChild(0, 0, .expand, .{ .limit = h -| 1 }); - }, - .left => { - var i: usize = 0; - while (i < h) : (i += 1) { - result.writeCell(0, i, .{ .char = vertical, .style = style }); - } - return result.initChild(1, 0, .expand, .expand); - }, + .all => .{ .top = true, .bottom = true, .right = true, .left = true }, + .bottom => .{ .bottom = true }, + .right => .{ .right = true }, + .left => .{ .left = true }, + .top => .{ .top = true }, + .other => |loc| loc, + }; + if (loc.top) { + var i: usize = 0; + while (i < w) : (i += 1) { + result.writeCell(i, 0, .{ .char = horizontal, .style = style }); + } } + if (loc.bottom) { + var i: usize = 0; + while (i < w) : (i += 1) { + result.writeCell(i, h -| 1, .{ .char = horizontal, .style = style }); + } + } + if (loc.left) { + var i: usize = 0; + while (i < h) : (i += 1) { + result.writeCell(0, i, .{ .char = vertical, .style = style }); + } + } + if (loc.right) { + var i: usize = 0; + while (i < h) : (i += 1) { + result.writeCell(w -| 1, i, .{ .char = vertical, .style = style }); + } + } + // draw corners + if (loc.top and loc.left) + result.writeCell(0, 0, .{ .char = top_left, .style = style }); + if (loc.top and loc.right) + result.writeCell(w - 1, 0, .{ .char = top_right, .style = style }); + if (loc.bottom and loc.left) + result.writeCell(0, h -| 1, .{ .char = bottom_left, .style = style }); + if (loc.bottom and loc.right) + result.writeCell(w - 1, h -| 1, .{ .char = bottom_right, .style = style }); - return result; + const x_off: usize = if (loc.left) 1 else 0; + const y_off: usize = if (loc.top) 1 else 0; + const h_delt: usize = if (loc.bottom) 1 else 0; + const w_delt: usize = if (loc.right) 1 else 0; + const h_ch: usize = h - y_off - h_delt; + const w_ch: usize = w - x_off - w_delt; + return result.initChild(x_off, y_off, .{ .limit = w_ch }, .{ .limit = h_ch }); } /// writes a cell to the location in the window