╭ changed ────────╮ │src/ui/widget.zig│ ╰─────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────╮ │12 pub const thread = @import("widget/thread.zig");│ │13 │ │14 pub const Widget = union(enum) { │ │15 - text: wgt.Text(Widget), │ │15 + text: wgt.Text, │ │16 box: wgt.Box(Widget), │ │17 - text_box: wgt.TextBox(Widget), │ │18 - text_input: wgt.TextInput(Widget), │ │17 + text_box: wgt.TextBox, │ │18 + text_input: wgt.TextInput, │ │19 scroll: wgt.Scroll(Widget), │ │20 stack: wgt.Stack(Widget), │ │21 flow_box: FlowBox, │ ╰────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │112 pub const FlowBox = struct { │ │113 focus: *Focus, │ │114 grid: ?Grid, │ │115 - text_boxes: std.ArrayList(wgt.TextBox(Widget)), │ │115 + text_boxes: std.ArrayList(wgt.TextBox), │ │116 // backs each link item's `.custom` focus kind (e.g. "a:/user/foo"). reset│ │117 // wholesale on each setItems so there's no per-string ownership to track.│ │118 arena: std.heap.ArenaAllocator, │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │170 self.focus.child_id = null; │ │171 │ │172 for (items) |item| { │ │173 - var text_box = try wgt.TextBox(Widget).init(allocator, item.text, .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .word });│ │173 + var text_box = try wgt.TextBox.init(allocator, item.text, .{ .border_style = .hidden, .rounded_corners = true, .wrap_kind = .word }); │ │174 errdefer text_box.deinit(allocator); │ │175 text_box.getFocus().focusable = true; │ │176 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────╮ │267 │ │268 pub fn indexOfFocusId(self: FlowBox, focus_id: usize) ?usize {│ │269 for (self.text_boxes.items, 0..) |tb, i| { │ │270 - if (tb.box.focus.id == focus_id) return i; │ │270 + if (tb.focus.id == focus_id) return i; │ │271 } │ │272 return null; │ │273 } │ ╰───────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │385 pub const TagFlow = struct { │ │386 focus: *Focus, │ │387 grid: ?Grid, │ │388 - text_boxes: std.ArrayList(wgt.TextBox(Widget)), │ │388 + text_boxes: std.ArrayList(wgt.TextBox), │ │389 // last build's item rects (content space), for vertical navigation and│ │390 // scroll-into-view. │ │391 rects: std.ArrayList(layout.IRect), │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │429 self.focus.child_id = null; │ │430 │ │431 for (items) |item| { │ │432 - var text_box = try wgt.TextBox(Widget).init(allocator, item.text, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ │432 + var text_box = try wgt.TextBox.init(allocator, item.text, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │433 errdefer text_box.deinit(allocator); │ │434 text_box.getFocus().focusable = true; │ │435 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────╮ │519 │ │520 pub fn indexOfFocusId(self: TagFlow, focus_id: usize) ?usize {│ │521 for (self.text_boxes.items, 0..) |tb, i| { │ │522 - if (tb.box.focus.id == focus_id) return i; │ │522 + if (tb.focus.id == focus_id) return i; │ │523 } │ │524 return null; │ │525 } │ ╰───────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │643 errdefer grid.deinit(); │ │644 var utf8 = (std.unicode.Utf8View.init(text) catch return).iterator();│ │645 var i: usize = 0; │ │646 - while (utf8.nextCodepointSlice()) |ch| { │ │647 - if (i == width) break; │ │648 - grid.cells.items[try grid.cells.at(.{ 0, i })].rune = ch; │ │649 - i += 1; │ │646 + while (utf8.nextCodepoint()) |ch| { │ │647 + const rune_width = xitui.width.cellWidth(ch); │ │648 + if (i + rune_width > width) break; │ │649 + try grid.setRune(i, 0, ch); │ │650 + i += rune_width; │ │651 } │ │652 self.url_width = i; │ │653 self.grid = grid; │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │692 errdefer box.deinit(allocator); │ │693 │ │694 { │ │694 - var gap = try wgt.Text(Widget).init(allocator, " "); │ │695 + var gap = try wgt.Text.init(allocator, " "); │ │696 errdefer gap.deinit(allocator); │ │697 try box.children.put(allocator, gap.getFocus().id, .{ .widget = .{ .text = gap }, .rect = null, .min_size = null });│ │698 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │699 │ │700 { │ │700 - var tb = try wgt.TextBox(Widget).init(allocator, content, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ │701 + var tb = try wgt.TextBox.init(allocator, content, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); │ │702 errdefer tb.deinit(allocator); │ │703 tb.getFocus().focusable = true; │ │704 try box.children.put(allocator, tb.getFocus().id, .{ .widget = .{ .text_box = tb }, .rect = null, .min_size = null }); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯