//! Hello World - Basic zcatgui example //! //! Demonstrates: //! - Initializing the backend //! - Creating a framebuffer //! - Basic rendering //! - Event loop const std = @import("std"); const zcatgui = @import("zcatgui"); const Framebuffer = zcatgui.render.Framebuffer; const SoftwareRenderer = zcatgui.render.SoftwareRenderer; const Sdl2Backend = zcatgui.backend.Sdl2Backend; const Color = zcatgui.Color; const Command = zcatgui.Command; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); // Initialize backend var backend = try Sdl2Backend.init("zcatgui - Hello World", 800, 600); defer backend.deinit(); // Create framebuffer var fb = try Framebuffer.init(allocator, 800, 600); defer fb.deinit(); // Create renderer var renderer = SoftwareRenderer.init(&fb); var running = true; var frame: u32 = 0; while (running) { // Poll events while (backend.pollEvent()) |event| { switch (event) { .quit => running = false, .key => |key| { if (key.key == .escape and key.pressed) { running = false; } }, .resize => |size| { try fb.resize(size.width, size.height); }, else => {}, } } // Clear renderer.clear(Color.background); // Draw some rectangles renderer.execute(Command.rect(50, 50, 200, 100, Color.primary)); renderer.execute(Command.rect(300, 50, 200, 100, Color.success)); renderer.execute(Command.rect(550, 50, 200, 100, Color.danger)); // Draw rectangle outline renderer.execute(Command.rectOutline(50, 200, 700, 100, Color.border)); // Animate a rectangle const x = @as(i32, @intCast(50 + (frame % 600))); renderer.execute(Command.rect(x, 350, 100, 100, Color.warning)); // Draw some lines renderer.execute(Command.line(50, 500, 750, 500, Color.foreground)); renderer.execute(Command.line(400, 450, 400, 550, Color.foreground)); // Present backend.present(&fb); frame += 1; // Control frame rate (approx 60 FPS) const ts = std.posix.timespec{ .sec = 0, .nsec = 16 * std.time.ns_per_ms }; _ = std.posix.system.nanosleep(&ts, null); } }