Something went wrong. Try again.
A charm-like tui library
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143//! Mirrors bubbletea's `examples/table`: a paginated table of 100 cities,//! cursor selection with j/k or arrows, esc to toggle focus, q to quit.const std = @import("std");const matcha = @import("matcha");const blush = @import("blush");const leaves = @import("leaves");
const Writer = std.Io.Writer;
const Model = struct { model: matcha.Model = .{ .vtable = &.{ .init = init, .update = update, .view = view, } }, table: leaves.Table = .{ .focused = true, .height = 7, .width = 42, // Match the bubbletea example's selected style: fg 229 on bg 57. .styles = .{ .header = .{ .bold = true }, .selected = .{ .foreground = .{ .ansi256 = 229 }, .background = .{ .ansi256 = 57 }, }, }, }, quitting: bool = false,
fn init(_: *matcha.Model) ?matcha.Cmd { return null; }
fn update(m: *matcha.Model, msg: matcha.Msg) ?matcha.Cmd { const self: *Model = @fieldParentPtr("model", m); switch (msg) { .key_press => |k| switch (k.kind) { .escape => { if (self.table.focused) self.table.blur() else self.table.focus(); return null; }, .rune => switch (k.rune) { 'q' => { self.quitting = true; return .quit; }, 'c' => if (k.mods.ctrl) { self.quitting = true; return .quit; }, else => {}, }, else => {}, }, .interrupt => return .quit, else => {}, } return self.table.update(msg); }
fn view(m: *matcha.Model, w: *Writer) Writer.Error!matcha.View { const self: *Model = @fieldParentPtr("model", m); if (self.quitting) { try w.writeAll("Bye!\n"); return .{}; } try self.table.view(w); try w.writeAll("\n\n ↑/k up • ↓/j down • esc focus • q quit\n"); return .{}; }};
const columns = [_]leaves.Table.Column{ .{ .title = "Rank", .width = 4 }, .{ .title = "City", .width = 10 }, .{ .title = "Country", .width = 10 }, .{ .title = "Population", .width = 10 },};
const rows = [_]leaves.Table.Row{ &[_][]const u8{ "1", "Tokyo", "Japan", "37,274,000" }, &[_][]const u8{ "2", "Delhi", "India", "32,065,760" }, &[_][]const u8{ "3", "Shanghai", "China", "28,516,904" }, &[_][]const u8{ "4", "Dhaka", "Bangladesh", "22,478,116" }, &[_][]const u8{ "5", "São Paulo", "Brazil", "22,429,800" }, &[_][]const u8{ "6", "Mexico City", "Mexico", "22,085,140" }, &[_][]const u8{ "7", "Cairo", "Egypt", "21,750,020" }, &[_][]const u8{ "8", "Beijing", "China", "21,333,332" }, &[_][]const u8{ "9", "Mumbai", "India", "20,961,472" }, &[_][]const u8{ "10", "Osaka", "Japan", "19,059,856" }, &[_][]const u8{ "11", "Chongqing", "China", "16,874,740" }, &[_][]const u8{ "12", "Karachi", "Pakistan", "16,839,950" }, &[_][]const u8{ "13", "Istanbul", "Turkey", "15,636,243" }, &[_][]const u8{ "14", "Kinshasa", "DR Congo", "15,628,085" }, &[_][]const u8{ "15", "Lagos", "Nigeria", "15,387,639" }, &[_][]const u8{ "16", "Buenos Aires", "Argentina", "15,369,919" }, &[_][]const u8{ "17", "Kolkata", "India", "15,133,888" }, &[_][]const u8{ "18", "Manila", "Philippines", "14,406,059" }, &[_][]const u8{ "19", "Tianjin", "China", "14,011,828" }, &[_][]const u8{ "20", "Guangzhou", "China", "13,964,637" }, &[_][]const u8{ "21", "Rio De Janeiro", "Brazil", "13,634,274" }, &[_][]const u8{ "22", "Lahore", "Pakistan", "13,541,764" }, &[_][]const u8{ "23", "Bangalore", "India", "13,193,035" }, &[_][]const u8{ "24", "Shenzhen", "China", "12,831,330" }, &[_][]const u8{ "25", "Moscow", "Russia", "12,640,818" }, &[_][]const u8{ "26", "Chennai", "India", "11,503,293" }, &[_][]const u8{ "27", "Bogota", "Colombia", "11,344,312" }, &[_][]const u8{ "28", "Paris", "France", "11,142,303" }, &[_][]const u8{ "29", "Jakarta", "Indonesia", "11,074,811" }, &[_][]const u8{ "30", "Lima", "Peru", "11,044,607" }, &[_][]const u8{ "31", "Bangkok", "Thailand", "10,899,698" }, &[_][]const u8{ "32", "Hyderabad", "India", "10,534,418" }, &[_][]const u8{ "33", "Seoul", "South Korea", "9,975,709" }, &[_][]const u8{ "34", "Nagoya", "Japan", "9,571,596" }, &[_][]const u8{ "35", "London", "United Kingdom", "9,540,576" }, &[_][]const u8{ "36", "Chengdu", "China", "9,478,521" }, &[_][]const u8{ "37", "Nanjing", "China", "9,429,381" }, &[_][]const u8{ "38", "Tehran", "Iran", "9,381,546" }, &[_][]const u8{ "39", "Ho Chi Minh City", "Vietnam", "9,077,158" }, &[_][]const u8{ "40", "Luanda", "Angola", "8,952,496" }, &[_][]const u8{ "41", "Wuhan", "China", "8,591,611" }, &[_][]const u8{ "42", "Xi An Shaanxi", "China", "8,537,646" }, &[_][]const u8{ "43", "Ahmedabad", "India", "8,450,228" }, &[_][]const u8{ "44", "Kuala Lumpur", "Malaysia", "8,419,566" }, &[_][]const u8{ "45", "New York City", "United States", "8,177,020" }, &[_][]const u8{ "46", "Hangzhou", "China", "8,044,878" }, &[_][]const u8{ "47", "Surat", "India", "7,784,276" }, &[_][]const u8{ "48", "Suzhou", "China", "7,764,499" }, &[_][]const u8{ "49", "Hong Kong", "Hong Kong", "7,643,256" }, &[_][]const u8{ "50", "Riyadh", "Saudi Arabia", "7,538,200" },};
pub fn table(init: std.process.Init) !void { var m: Model = .{}; m.table.setColumns(&columns); m.table.setRows(&rows);
var program: matcha.Program = try .init(init, &m.model, .{}); defer program.deinit(); try program.run();}