╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────╮ │ 8 const Grid = xitui.grid.Grid; │ │ 9 const Focus = xitui.focus.Focus; │ │10 │ │11 -pub fn run(io: std.Io, allocator: std.mem.Allocator) !void { │ │11 +const html_width = 80; │ │12 +const html_height = 24; │ │13 + │ │14 +pub fn initRoot(allocator: std.mem.Allocator) !Widget { │ │15 var root = Widget{ .widget_list = try WidgetList.init(allocator) }; │ │13 - defer root.deinit(); │ │16 + errdefer root.deinit(); │ │17 + │ │18 + try buildRoot(&root, html_width, html_height); │ │19 + if (root.getFocus().child_id) |child_id| { │ │20 + try root.getFocus().setFocus(child_id); │ │21 + } │ │22 + │ │23 + return root; │ │24 +} │ │25 │ │26 +pub fn buildRoot(root: *Widget, width: usize, height: usize) !void { │ │27 try root.build(.{ │ │28 .min_size = .{ .width = null, .height = null }, │ │17 - .max_size = .{ .width = 10, .height = 10 }, │ │29 + .max_size = .{ .width = width, .height = height }, │ │30 }, root.getFocus()); │ │19 - if (root.getFocus().child_id) |child_id| { │ │20 - try root.getFocus().setFocus(child_id); │ │31 +} │ │32 + │ │33 +pub fn generateHtml(allocator: std.mem.Allocator, root: *Widget) ![]const u8 { │ │34 + const grid = root.getGrid() orelse return error.MissingGrid; │ │35 + │ │36 + var out: std.ArrayList(u8) = .empty; │ │37 + errdefer out.deinit(allocator); │ │38 + │ │39 + for (0..grid.size.height) |y| { │ │40 + for (0..grid.size.width) |x| { │ │41 + const rune = grid.cells.items[try grid.cells.at(.{ y, x })].rune orelse " ";│ │42 + try appendEscapedHtml(allocator, &out, rune); │ │43 + } │ │44 + try out.append(allocator, '\n'); │ │45 } │ │46 + │ │47 + return try out.toOwnedSlice(allocator); │ │48 +} │ │49 │ │50 +pub fn run(io: std.Io, allocator: std.mem.Allocator) !void { │ │51 + var root = try initRoot(allocator); │ │52 + defer root.deinit(); │ │53 + │ │54 var terminal = try term.Terminal.init(io, allocator); │ │55 defer terminal.deinit(io); │ │56 │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │69 try root.input(key, root.getFocus()); │ │70 } │ │71 │ │41 - try root.build(.{ │ │42 - .min_size = .{ .width = null, .height = null }, │ │43 - .max_size = .{ .width = last_size.width, .height = last_size.height }, │ │44 - }, root.getFocus()); │ │72 + try buildRoot(&root, last_size.width, last_size.height); │ │73 │ │74 try std.Io.sleep(io, .fromMilliseconds(5), .real); │ │75 + } │ │76 +} │ │77 + │ │78 +fn appendEscapedHtml(allocator: std.mem.Allocator, out: *std.ArrayList(u8), input: []const u8) !void {│ │79 + for (input) |ch| { │ │80 + switch (ch) { │ │81 + '&' => try out.appendSlice(allocator, "&amp;"), │ │82 + '<' => try out.appendSlice(allocator, "&lt;"), │ │83 + '>' => try out.appendSlice(allocator, "&gt;"), │ │84 + '"' => try out.appendSlice(allocator, "&quot;"), │ │85 + '\'' => try out.appendSlice(allocator, "&#39;"), │ │86 + else => try out.append(allocator, ch), │ │87 + } │ │88 } │ │89 } │ │90 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯