this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

vxfw: add Border widget

+105
+104
src/vxfw/Border.zig
··· 1 + const std = @import("std"); 2 + const vaxis = @import("../main.zig"); 3 + 4 + const Allocator = std.mem.Allocator; 5 + 6 + const vxfw = @import("vxfw.zig"); 7 + 8 + const Border = @This(); 9 + 10 + child: vxfw.Widget, 11 + style: vaxis.Style = .{}, 12 + 13 + pub fn widget(self: *const Border) vxfw.Widget { 14 + return .{ 15 + .userdata = @constCast(self), 16 + .drawFn = typeErasedDrawFn, 17 + }; 18 + } 19 + 20 + fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 21 + const self: *const Border = @ptrCast(@alignCast(ptr)); 22 + return self.draw(ctx); 23 + } 24 + 25 + /// If Border has a bounded maximum size, it will shrink the maximum size to account for the border 26 + /// before drawing the child. If the size is unbounded, border will draw the child and then itself 27 + /// around the childs size 28 + pub fn draw(self: *const Border, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 29 + const max_width: ?u16 = if (ctx.max.width) |width| width -| 2 else null; 30 + const max_height: ?u16 = if (ctx.max.height) |height| height -| 2 else null; 31 + 32 + const child_ctx = ctx.withConstraints(ctx.min, .{ 33 + .width = max_width, 34 + .height = max_height, 35 + }); 36 + const child = try self.child.draw(child_ctx); 37 + 38 + const children = try ctx.arena.alloc(vxfw.SubSurface, 1); 39 + children[0] = .{ 40 + .origin = .{ .col = 1, .row = 1 }, 41 + .z_index = 0, 42 + .surface = child, 43 + }; 44 + 45 + const size: vxfw.Size = .{ .width = child.size.width + 2, .height = child.size.height + 2 }; 46 + 47 + var surf = try vxfw.Surface.initWithChildren(ctx.arena, self.widget(), size, children); 48 + 49 + // Draw the border 50 + const right_edge = size.width -| 1; 51 + const bottom_edge = size.height -| 1; 52 + surf.writeCell(0, 0, .{ .char = .{ .grapheme = "╭", .width = 1 } }); 53 + surf.writeCell(right_edge, 0, .{ .char = .{ .grapheme = "╮", .width = 1 } }); 54 + surf.writeCell(right_edge, bottom_edge, .{ .char = .{ .grapheme = "╯", .width = 1 } }); 55 + surf.writeCell(0, bottom_edge, .{ .char = .{ .grapheme = "╰", .width = 1 } }); 56 + 57 + var col: u16 = 1; 58 + while (col < right_edge) : (col += 1) { 59 + surf.writeCell(col, 0, .{ .char = .{ .grapheme = "─", .width = 1 } }); 60 + surf.writeCell(col, bottom_edge, .{ .char = .{ .grapheme = "─", .width = 1 } }); 61 + } 62 + 63 + var row: u16 = 1; 64 + while (row < bottom_edge) : (row += 1) { 65 + surf.writeCell(0, row, .{ .char = .{ .grapheme = "│", .width = 1 } }); 66 + surf.writeCell(right_edge, row, .{ .char = .{ .grapheme = "│", .width = 1 } }); 67 + } 68 + return surf; 69 + } 70 + 71 + test Border { 72 + const Text = @import("Text.zig"); 73 + // Will be height=1, width=3 74 + const text: Text = .{ .text = "abc" }; 75 + 76 + const border: Border = .{ .child = text.widget() }; 77 + 78 + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); 79 + defer arena.deinit(); 80 + const ucd = try vaxis.Unicode.init(arena.allocator()); 81 + vxfw.DrawContext.init(&ucd, .unicode); 82 + 83 + // Border will draw itself tightly around the child 84 + const ctx: vxfw.DrawContext = .{ 85 + .arena = arena.allocator(), 86 + .min = .{}, 87 + .max = .{ .width = 10, .height = 10 }, 88 + }; 89 + 90 + const surface = try border.draw(ctx); 91 + // Border should be the size of Text + 2 92 + try std.testing.expectEqual(5, surface.size.width); 93 + try std.testing.expectEqual(3, surface.size.height); 94 + // Border has 1 child 95 + try std.testing.expectEqual(1, surface.children.len); 96 + const child = surface.children[0]; 97 + // The child is 1x3 98 + try std.testing.expectEqual(3, child.surface.size.width); 99 + try std.testing.expectEqual(1, child.surface.size.height); 100 + } 101 + 102 + test "refAllDecls" { 103 + std.testing.refAllDecls(@This()); 104 + }
+1
src/vxfw/vxfw.zig
··· 11 11 pub const App = @import("App.zig"); 12 12 13 13 // Widgets 14 + pub const Border = @import("Border.zig"); 14 15 pub const Button = @import("Button.zig"); 15 16 pub const Center = @import("Center.zig"); 16 17 pub const FlexColumn = @import("FlexColumn.zig");