window: add custom border location option

Add a way to draw borders in custom locations
This commit is contained in:
Tim Culverhouse 2024-03-26 11:41:54 -05:00
parent 6a31b71e33
commit 117545ca4b
2 changed files with 67 additions and 55 deletions

View file

@ -112,17 +112,21 @@ pub fn main() !void {
// vaxis double buffers the screen. This new frame will be compared to // vaxis double buffers the screen. This new frame will be compared to
// the old and only updated cells will be drawn // the old and only updated cells will be drawn
win.clear(); 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 // draw the text_input using a bordered window
const style: vaxis.Style = .{ const style: vaxis.Style = .{
.fg = .{ .index = color_idx }, .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 // Render the screen
try vx.render(); try vx.render();

View file

@ -77,16 +77,24 @@ pub const ChildOptions = struct {
pub const BorderOptions = struct { pub const BorderOptions = struct {
style: Cell.Style = .{}, style: Cell.Style = .{},
where: enum { where: union(enum) {
none, none,
all, all,
top, top,
right, right,
bottom, bottom,
left, left,
other: Locations,
} = .none, } = .none,
glyphs: Glyphs = .single_rounded, 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) { pub const Glyphs = union(enum) {
single_rounded, single_rounded,
single_square, single_square,
@ -126,56 +134,56 @@ pub fn child(self: Window, opts: ChildOptions) Window {
const h = result.height; const h = result.height;
const w = result.width; const w = result.width;
switch (opts.border.where) { const loc: BorderOptions.Locations = switch (opts.border.where) {
.none => return result, .none => return result,
.all => { .all => .{ .top = true, .bottom = true, .right = true, .left = true },
result.writeCell(0, 0, .{ .char = top_left, .style = style }); .bottom => .{ .bottom = true },
result.writeCell(0, h -| 1, .{ .char = bottom_left, .style = style }); .right => .{ .right = true },
result.writeCell(w - 1, 0, .{ .char = top_right, .style = style }); .left => .{ .left = true },
result.writeCell(w - 1, h -| 1, .{ .char = bottom_right, .style = style }); .top => .{ .top = true },
var i: usize = 1; .other => |loc| loc,
while (i < (h - 1)) : (i += 1) { };
result.writeCell(0, i, .{ .char = vertical, .style = style }); if (loc.top) {
result.writeCell(w -| 1, i, .{ .char = vertical, .style = style }); var i: usize = 0;
} while (i < w) : (i += 1) {
i = 1; result.writeCell(i, 0, .{ .char = horizontal, .style = style });
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);
},
} }
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 /// writes a cell to the location in the window