this repo has no description
13
fork

Configure Feed

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

vxfw: add SizedBox widget

+110
+109
src/vxfw/SizedBox.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 SizedBox = @This(); 9 + 10 + child: vxfw.Widget, 11 + size: vxfw.Size, 12 + 13 + pub fn widget(self: *const SizedBox) vxfw.Widget { 14 + return .{ 15 + .userdata = @constCast(self), 16 + .eventHandler = typeErasedEventHandler, 17 + .drawFn = typeErasedDrawFn, 18 + }; 19 + } 20 + 21 + fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void { 22 + const self: *const SizedBox = @ptrCast(@alignCast(ptr)); 23 + return self.child.handleEvent(ctx, event); 24 + } 25 + 26 + fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 27 + const self: *const SizedBox = @ptrCast(@alignCast(ptr)); 28 + const max: vxfw.MaxSize = .{ 29 + .width = if (ctx.max.width) |max_w| @min(max_w, self.size.width) else self.size.width, 30 + .height = if (ctx.max.height) |max_h| @min(max_h, self.size.height) else self.size.height, 31 + }; 32 + const min: vxfw.Size = .{ 33 + .width = @max(ctx.min.width, max.width.?), 34 + .height = @max(ctx.min.height, max.height.?), 35 + }; 36 + return self.child.draw(ctx.withConstraints(min, max)); 37 + } 38 + 39 + test SizedBox { 40 + // Create a test widget that saves the constraints it was given 41 + const TestWidget = struct { 42 + min: vxfw.Size, 43 + max: vxfw.MaxSize, 44 + 45 + pub fn widget(self: *@This()) vxfw.Widget { 46 + return .{ 47 + .userdata = self, 48 + .eventHandler = vxfw.noopEventHandler, 49 + .drawFn = @This().typeErasedDrawFn, 50 + }; 51 + } 52 + 53 + fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) std.mem.Allocator.Error!vxfw.Surface { 54 + const self: *@This() = @ptrCast(@alignCast(ptr)); 55 + self.min = ctx.min; 56 + self.max = ctx.max; 57 + return .{ 58 + .size = ctx.min, 59 + .widget = self.widget(), 60 + .buffer = &.{}, 61 + .children = &.{}, 62 + }; 63 + } 64 + }; 65 + 66 + // Boiler plate draw context 67 + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); 68 + defer arena.deinit(); 69 + const ucd = try vaxis.Unicode.init(arena.allocator()); 70 + vxfw.DrawContext.init(&ucd, .unicode); 71 + 72 + var draw_ctx: vxfw.DrawContext = .{ 73 + .arena = arena.allocator(), 74 + .min = .{}, 75 + .max = .{ .width = 16, .height = 16 }, 76 + }; 77 + 78 + var test_widget: TestWidget = .{ .min = .{}, .max = .{} }; 79 + 80 + // SizedBox tries to draw the child widget at the specified size. It will shrink to fit within 81 + // constraints 82 + const sized_box: SizedBox = .{ 83 + .child = test_widget.widget(), 84 + .size = .{ .width = 10, .height = 10 }, 85 + }; 86 + 87 + const box_widget = sized_box.widget(); 88 + _ = try box_widget.draw(draw_ctx); 89 + 90 + // The sized box is smaller than the constraints, so we should be the desired size 91 + try std.testing.expectEqual(sized_box.size, test_widget.min); 92 + try std.testing.expectEqual(sized_box.size, test_widget.max.size()); 93 + 94 + draw_ctx.max.height = 8; 95 + _ = try box_widget.draw(draw_ctx); 96 + // The sized box is smaller than the constraints, so we should be that size 97 + try std.testing.expectEqual(@as(vxfw.Size, .{ .width = 10, .height = 8 }), test_widget.min); 98 + try std.testing.expectEqual(@as(vxfw.Size, .{ .width = 10, .height = 8 }), test_widget.max.size()); 99 + 100 + draw_ctx.max.width = 8; 101 + _ = try box_widget.draw(draw_ctx); 102 + // The sized box is smaller than the constraints, so we should be that size 103 + try std.testing.expectEqual(@as(vxfw.Size, .{ .width = 8, .height = 8 }), test_widget.min); 104 + try std.testing.expectEqual(@as(vxfw.Size, .{ .width = 8, .height = 8 }), test_widget.max.size()); 105 + } 106 + 107 + test "refAllDecls" { 108 + std.testing.refAllDecls(@This()); 109 + }
+1
src/vxfw/vxfw.zig
··· 18 18 pub const ListView = @import("ListView.zig"); 19 19 pub const Padding = @import("Padding.zig"); 20 20 pub const RichText = @import("RichText.zig"); 21 + pub const SizedBox = @import("SizedBox.zig"); 21 22 pub const Text = @import("Text.zig"); 22 23 pub const TextField = @import("TextField.zig"); 23 24