╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Markdown.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
425 .title => (try ui.Title.init(&arena, text, .solid)).content, 426 .sub_title => (try ui.SubTitle.init(&arena, text)).content, 427 }); 428 } 429 try self.font_box.setContent(allocator, out.items); 430 return true; 431 } 432 433 fn buildShown(self: *Heading, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus, widget: anytype) !void { 434 try widget.build(allocator, constraint, root_focus); 435 const grid = widget.getGrid() orelse return; 436 try self.focus.addChild(allocator, widget.getFocus(), grid.size, 0, 0); 437 } 438 439 pub fn input(self: *Heading, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 440 _ = self; 441 _ = allocator; 442 _ = key; 443 _ = root_focus; 444 } 445 446 pub fn clearGrid(self: *Heading) void { 447 self.text.clearGrid(); 448 self.font_box.clearGrid(); 449 } 450 451 pub fn getGrid(self: Heading) ?Grid { 452 // only the one last built has a grid 453 return self.font_box.getGrid() orelse self.text.getGrid(); 454 } 455 456 pub fn getFocus(self: *Heading) *Focus { 457 return self.focus; 458 } 459 }; 460 461 // a marker column beside a child, so wrapped lines hang under the child's 462 // first line: a list item's bullet, or a quote's bar on every row. 463 pub const Gutter = struct { 464 focus: *Focus, 465 grid: ?Grid, 466 child: wgt.Box(ui.Widget), 467 marker: []const u8, 468 // draw the marker on every row rather than only the first 469 repeat: bool, 470 style: Grid.Style, 471 472 // takes ownership of `child` on success 473 fn init(allocator: std.mem.Allocator, marker: []const u8, repeat: bool, style: Grid.Style, child: wgt.Box(ui.Widget)) !Gutter { 474 return .{ .focus = try Focus.create(allocator, .container), .grid = null, .child = child, .marker = marker, .repeat = repeat, .style = style }; 475 } 476 477 pub fn deinit(self: *Gutter, allocator: std.mem.Allocator) void { 478 self.focus.destroy(allocator); 479 self.clearGrid(); 480 self.child.deinit(allocator); 481 } 482 483 pub fn build(self: *Gutter, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 484 self.clearGrid(); 485 self.focus.clear(); 486 const marker_width = try xitui.width.displayWidth(self.marker); 487 if (constraint.max_size.width) |w| if (w <= marker_width) return; 488 if (constraint.max_size.height == 0) return; 489 490 try self.child.build(allocator, .{ 491 .min_size = .{ .width = null, .height = null }, 492 .max_size = .{ .width = if (constraint.max_size.width) |w| w - marker_width else null, .height = constraint.max_size.height }, 493 }, root_focus); 494 const child_grid = self.child.getGrid(); 495 const child_size: layout.Size = if (child_grid) |g| g.size else .{ .width = 0, .height = 0 }; 496 497 var grid = try Grid.init(allocator, .{ .width = marker_width + child_size.width, .height = @max(1, child_size.height) }); 498 errdefer grid.deinit(); 499 for (0..if (self.repeat) grid.size.height else 1) |y| { 500 var x: usize = 0; 501 var utf8 = (try std.unicode.Utf8View.init(self.marker)).iterator(); 502 while (utf8.nextCodepoint()) |rune| { 503 (try grid.cell(x, y)).style = self.style; 504 try grid.setRune(x, y, rune); 505 x += xitui.width.cellWidth(rune); 506 } 507 } 508 if (child_grid) |g| { 509 try grid.drawGrid(g, marker_width, 0); 510 try self.focus.addChild(allocator, self.child.getFocus(), g.size, marker_width, 0); 511 } 512 self.grid = grid; 513 } 514 515 pub fn input(self: *Gutter, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 516 _ = self; 517 _ = allocator; 518 _ = key; 519 _ = root_focus; 520 } 521 522 pub fn clearGrid(self: *Gutter) void { 523 if (self.grid) |*grid| { 524 grid.deinit(); 525 self.grid = null; 526 } 527 self.child.clearGrid(); 528 } 529 530 pub fn getGrid(self: Gutter) ?Grid { 531 return self.grid; 532 } 533 534 pub fn getFocus(self: *Gutter) *Focus { 535 return self.focus; 536 } 537 }; 538