Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Has been cancelled
Show title stored in preemble of markdown file if available.
180 lines
5.4 KiB
Zig
180 lines
5.4 KiB
Zig
pub fn Content(App: type) type {
|
|
return struct {
|
|
page: App.Model.Pages,
|
|
|
|
pub fn init(allocator: Allocator) @This() {
|
|
_ = allocator;
|
|
return .{
|
|
.page = .blog,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(this: *@This()) void {
|
|
this.container.deinit();
|
|
}
|
|
|
|
pub fn element(this: *@This()) App.Element {
|
|
return .{
|
|
.ptr = this,
|
|
.vtable = &.{
|
|
.minSize = minSize,
|
|
.handle = handle,
|
|
.content = content,
|
|
},
|
|
};
|
|
}
|
|
|
|
fn minSize(ctx: *anyopaque, size: zterm.Point) zterm.Point {
|
|
const this: *const @This() = @ptrCast(@alignCast(ctx));
|
|
const text = switch (this.page) {
|
|
.about => @embedFile("about"),
|
|
.blog => @embedFile("blog"),
|
|
};
|
|
var index: usize = 0;
|
|
var new_size: zterm.Point = .{ .x = size.x };
|
|
|
|
for (0..text.len) |_| rows: {
|
|
for (0..size.x) |_| {
|
|
if (index == text.len) break :rows;
|
|
const cp = text[index];
|
|
index += 1;
|
|
|
|
switch (cp) {
|
|
'\n' => break,
|
|
else => {},
|
|
}
|
|
}
|
|
new_size.y += 1;
|
|
}
|
|
return new_size;
|
|
}
|
|
|
|
fn handle(ctx: *anyopaque, model: *App.Model, event: App.Event) !void {
|
|
const this: *@This() = @ptrCast(@alignCast(ctx));
|
|
switch (event) {
|
|
.about => {
|
|
model.page = .about;
|
|
model.document = .init(@embedFile("about"));
|
|
},
|
|
.blog => {
|
|
model.page = .blog;
|
|
model.document = .init(@embedFile("blog"));
|
|
},
|
|
else => {},
|
|
}
|
|
this.page = model.page;
|
|
}
|
|
|
|
fn content(ctx: *anyopaque, model: *const App.Model, cells: []zterm.Cell, size: zterm.Point) !void {
|
|
_ = ctx;
|
|
assert(cells.len == @as(usize, size.x) * @as(usize, size.y));
|
|
|
|
const text = model.document.content;
|
|
var index: usize = 0;
|
|
|
|
for (0..size.y) |row| {
|
|
for (0..size.x) |col| {
|
|
const cell = row * size.x + col;
|
|
|
|
if (index == text.len) return;
|
|
const cp = text[index];
|
|
index += 1;
|
|
|
|
cells[cell].cp = switch (cp) {
|
|
'\n' => break,
|
|
else => cp,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
pub fn Title(App: type) type {
|
|
return struct {
|
|
pub fn init() @This() {
|
|
return .{};
|
|
}
|
|
|
|
pub fn element(this: *@This()) App.Element {
|
|
return .{
|
|
.ptr = this,
|
|
.vtable = &.{
|
|
.content = content,
|
|
},
|
|
};
|
|
}
|
|
|
|
fn content(ctx: *anyopaque, model: *const App.Model, cells: []zterm.Cell, size: zterm.Point) !void {
|
|
const this: *const @This() = @ptrCast(@alignCast(ctx));
|
|
_ = this;
|
|
assert(cells.len == @as(usize, size.x) * @as(usize, size.y));
|
|
|
|
if (model.document.title) |text| {
|
|
for (0.., text) |idx, cp| {
|
|
cells[idx].style.fg = .green;
|
|
cells[idx].style.emphasis = &.{.bold};
|
|
cells[idx].cp = cp;
|
|
|
|
// NOTE do not write over the contents of this `Container`'s `Size`
|
|
if (idx == cells.len - 1) break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
pub fn InfoBanner(App: type) type {
|
|
return struct {
|
|
left_text: []const u8,
|
|
right_text: []const u8,
|
|
|
|
pub fn init() @This() {
|
|
return .{
|
|
.left_text = "Build with zig",
|
|
.right_text = "Yves Biener (@yves-biener)",
|
|
};
|
|
}
|
|
|
|
pub fn element(this: *@This()) App.Element {
|
|
return .{
|
|
.ptr = this,
|
|
.vtable = &.{
|
|
.content = content,
|
|
},
|
|
};
|
|
}
|
|
|
|
fn content(ctx: *anyopaque, _: *const App.Model, cells: []zterm.Cell, size: zterm.Point) !void {
|
|
const this: *const @This() = @ptrCast(@alignCast(ctx));
|
|
assert(cells.len == @as(usize, size.x) * @as(usize, size.y));
|
|
|
|
for (0.., this.left_text) |idx, cp| {
|
|
// NOTE do not write over the contents of this `Container`'s `Size`
|
|
if (idx == cells.len) break;
|
|
|
|
cells[idx].style.fg = .default;
|
|
cells[idx].style.emphasis = &.{.dim};
|
|
cells[idx].cp = cp;
|
|
}
|
|
|
|
var start_idx = size.x -| this.right_text.len;
|
|
if (start_idx <= this.left_text.len) start_idx = this.left_text.len + 1;
|
|
|
|
for (start_idx.., this.right_text) |idx, cp| {
|
|
// NOTE do not write over the contents of this `Container`'s `Size`
|
|
if (idx == cells.len) break;
|
|
|
|
cells[idx].style.fg = .default;
|
|
cells[idx].style.emphasis = &.{.dim};
|
|
cells[idx].cp = cp;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const assert = std.debug.assert;
|
|
const zterm = @import("zterm");
|