//! Static progress example: bump by 25% every second using ViewAs. //! //! Demonstrates the "pure" pattern where the parent owns the percent and //! the Progress component just renders. const std = @import("std"); const matcha = @import("matcha"); const blush = @import("blush"); const leaves = @import("leaves"); const Writer = std.Io.Writer; const padding: u16 = 2; const max_width: u16 = 80; const pink: blush.Style.Color = .{ .rgb = .{ .r = 0xFF, .g = 0x7C, .b = 0xCB } }; const yellow: blush.Style.Color = .{ .rgb = .{ .r = 0xFD, .g = 0xFF, .b = 0x8C } }; const Model = struct { model: matcha.Model = .{ .vtable = &.{ .init = init, .update = update, .view = view, } }, percent: f64 = 0, progress: leaves.Progress = .{ .full_colors = &.{ pink, yellow }, .scale_blend = true, }, quitting: bool = false, fn init(m: *matcha.Model) ?matcha.Cmd { return matcha.Cmd.tick(m.gpa, std.time.ns_per_s, .tick) catch null; } fn update(m: *matcha.Model, msg: matcha.Msg) ?matcha.Cmd { const self: *Model = @fieldParentPtr("model", m); switch (msg) { .key_press => { self.quitting = true; return .quit; }, .window_size => |ws| { const desired: u16 = ws.width -| (padding * 2 + 4); self.progress.setWidth(@min(desired, max_width)); }, .tick => { if (self.quitting) return .quit; self.percent += 0.25; if (self.percent >= 1) { self.percent = 1; self.quitting = true; } return matcha.Cmd.tick(m.gpa, std.time.ns_per_s, .tick) catch null; }, else => {}, } return null; } fn view(m: *matcha.Model, w: *Writer) Writer.Error!matcha.View { const self: *Model = @fieldParentPtr("model", m); try w.writeByte('\n'); try writeSpaces(w, padding); try self.progress.viewAs(w, self.percent); try w.writeAll("\n\n"); try writeSpaces(w, padding); try w.writeAll("\x1b[38;5;243mPress any key to quit\x1b[0m\n"); return .{}; } }; fn writeSpaces(w: *Writer, n: u16) Writer.Error!void { var i: u16 = 0; while (i < n) : (i += 1) try w.writeByte(' '); } pub fn static(init: std.process.Init) !void { var m: Model = .{}; var program: matcha.Program = try .init(init, &m.model, .{}); defer program.deinit(); try program.run(); }