// Imports const std = @import("std"); const fz = @import("flipperzero"); // const Zlipper = struct { // allocator: std.mem.Allocator, // mutex: *anyopaque, // gui: *anyopaque, // view_port: *anyopaque, // input_queue: *anyopaque, // input_event: ?*c.InputEvent, // running: bool, // acc: u32, // const Self = @This(); // pub fn init(allocator: std.mem.Allocator) *Self { // const self = allocator.create(Self) catch unreachable; // self.* = Self{ // .allocator = allocator, // .mutex = c.furi_mutex_alloc(c.FuriMutexType.FuriMutexTypeNormal), // .gui = c.furi_record_open(c.RECORD_GUI), // .view_port = c.view_port_alloc(), // .input_queue = c.furi_message_queue_alloc(8, @sizeOf(c.InputEvent)), // .input_event = null, // .running = true, // .acc = 0, // }; // c.view_port_draw_callback_set(self.view_port, Self.draw_callback, @ptrCast(self)); // c.view_port_input_callback_set(self.view_port, Self.input_callback, @ptrCast(self)); // c.gui_add_view_port(self.gui, self.view_port, c.GuiLayer.GuiLayerFullscreen); // return self; // } // pub fn deinit(self: *Self) void { // c.view_port_enabled_set(self.view_port, false); // c.gui_remove_view_port(self.gui, self.view_port); // c.view_port_free(self.view_port); // c.furi_message_queue_free(self.input_queue); // c.furi_mutex_free(self.mutex); // c.furi_record_close(c.RECORD_GUI); // self.allocator.destroy(self); // } // pub fn update(self: *Self) void { // var event: c.InputEvent = undefined; // _ = c.furi_message_queue_get(self.input_queue, @ptrCast(&event), @intFromEnum(c.FuriWait.FuriWaitForever)); // self.input_event = &event; // if (event.type == c.InputType.InputTypeShort and event.key == c.InputKey.InputKeyBack) { // self.running = !self.running; // } // c.view_port_update(self.view_port); // self.acc += 1; // } // fn draw_callback(canvas: *anyopaque, context: ?*anyopaque) callconv(.C) void { // const self: *Self = @alignCast(@ptrCast(context.?)); // var c_buf = std.mem.zeroes([32:0]u8); // _ = c.snprintf(&c_buf, 32, "snprintf: %d", self.acc); // var zig_buf = std.mem.zeroes([32:0]u8); // _ = std.fmt.bufPrint(&zig_buf, "bufPrint: {}", .{self.acc}) catch return; // const alloc_buf = std.fmt.allocPrintZ(self.allocator, "allocPrint: {}", .{self.acc}) catch return; // defer self.allocator.free(alloc_buf); // c.canvas_clear(canvas); // c.canvas_set_font(canvas, c.Font.FontPrimary); // c.canvas_draw_str(canvas, 0, 10, &c_buf); // c.canvas_draw_str(canvas, 0, 20, &zig_buf); // c.canvas_draw_str(canvas, 0, 30, alloc_buf); // if (self.input_event) |input_event| { // const type_buf = std.fmt.allocPrintZ(self.allocator, "InputType: {s}", .{c.input_get_type_name(input_event.type)}) catch return; // defer self.allocator.free(type_buf); // c.canvas_draw_str(canvas, 0, 40, type_buf); // const key_buf = std.fmt.allocPrintZ(self.allocator, "InputKey: {s}", .{c.input_get_key_name(input_event.key)}) catch return; // defer self.allocator.free(key_buf); // c.canvas_draw_str(canvas, 0, 50, key_buf); // } // } // fn input_callback(input_event: *c.InputEvent, context: ?*anyopaque) callconv(.C) void { // const self: *Self = @alignCast(@ptrCast(context.?)); // _ = c.furi_message_queue_put(self.input_queue, input_event, @intFromEnum(c.FuriWait.FuriWaitForever)); // } // }; const Zlipper = struct { allocator: std.mem.Allocator, mutex: *fz.thread.FuriMutex, gui: *fz.gui.Gui, view_port: *fz.gui.ViewPort, input_queue: *fz.atomic.FuriMessageQueue(fz.c.InputEvent), input_event: ?*const fz.c.InputEvent, running: bool, acc: u32, const Self = @This(); pub fn init(allocator: std.mem.Allocator) *Self { const self = allocator.create(Self) catch unreachable; self.* = Self{ .allocator = allocator, .mutex = fz.thread.FuriMutex.create(fz.c.FuriMutexType.FuriMutexTypeNormal), .gui = fz.gui.Gui.open(), .view_port = fz.gui.ViewPort.create(), .input_queue = fz.atomic.FuriMessageQueue(fz.c.InputEvent).create(8), .input_event = null, .running = true, .acc = 0, }; self.view_port.setDrawCallback(Self.draw_callback, @ptrCast(self)); self.view_port.setInputCallback(Self.input_callback, @ptrCast(self)); self.gui.addViewPort(self.view_port, fz.c.GuiLayer.GuiLayerFullscreen); return self; } pub fn deinit(self: *Self) void { self.view_port.setEnabled(false); self.gui.removeViewPort(self.view_port); self.view_port.destroy(); self.input_queue.destroy(); self.mutex.destroy(); self.gui.close(); self.allocator.destroy(self); } pub fn update(self: *Self) void { var event: fz.c.InputEvent = undefined; self.input_queue.get(&event, @intFromEnum(fz.c.FuriWait.FuriWaitForever)); self.input_event = &event; if (event.type == fz.c.InputType.InputTypeShort and event.key == fz.c.InputKey.InputKeyBack) { self.running = !self.running; } self.view_port.update(); self.acc += 1; } fn draw_callback(canvas_: *anyopaque, context: ?*anyopaque) callconv(.C) void { const self: *Self = @alignCast(@ptrCast(context.?)); const canvas: *fz.gui.Canvas = @ptrCast(canvas_); var c_buf = std.mem.zeroes([32:0]u8); _ = fz.c.snprintf(&c_buf, 32, "snprintf: %d", self.acc); var zig_buf = std.mem.zeroes([32:0]u8); _ = std.fmt.bufPrint(&zig_buf, "bufPrint: {}", .{self.acc}) catch return; const alloc_buf = std.fmt.allocPrintZ(self.allocator, "allocPrint: {}", .{self.acc}) catch return; defer self.allocator.free(alloc_buf); canvas.clear(); canvas.setFont(fz.c.Font.FontPrimary); canvas.drawStr(0, 10, &c_buf); canvas.drawStr(0, 20, &zig_buf); canvas.drawStr(0, 30, alloc_buf); if (self.input_event) |input_event| { const type_buf = std.fmt.allocPrintZ(self.allocator, "InputType: {s}", .{fz.c.input_get_type_name(input_event.type)}) catch return; defer self.allocator.free(type_buf); canvas.drawStr(0, 40, type_buf); const key_buf = std.fmt.allocPrintZ(self.allocator, "InputKey: {s}", .{fz.c.input_get_key_name(input_event.key)}) catch return; defer self.allocator.free(key_buf); canvas.drawStr(0, 50, key_buf); } } fn input_callback(input_event: *fz.c.InputEvent, context: ?*anyopaque) callconv(.C) void { const self: *Self = @alignCast(@ptrCast(context.?)); self.input_queue.put(input_event, @intFromEnum(fz.c.FuriWait.FuriWaitForever)); } }; // const ZlipperView = enum(u8) { // MainMenu, // FileBrowser, // }; // const Zlipper = struct { // allocator: std.mem.Allocator, // gui: *fz.gui.Gui, // storage: *fz.storage.Storage, // scene_manager: *fz.gui.SceneManager, // view_dispatcher: *fz.gui.ViewDispatcher, // // file_browser_output: *fz.string. // running: bool, // const Self = @This(); // pub fn init(allocator: std.mem.Allocator) *Self { // const self = allocator.create(Self) catch unreachable; // self.* = Self { // .allocator = allocator, // .gui = fz.gui.Gui.open(), // .storage = fz.storage.Storage.open(), // .scene_manager = fz.gui.SceneManager.create(), // .view_dispatcher = fz.gui.ViewDispatcher.create(), // .running = true, // }; // self.view_dispatcher.enableQueue(); // self.view_dispatcher.setEventCallbackContext(@ptrCast(self)); // self.view_dispatcher.setCustomEventCallback(Self.customEventCallback); // self.view_dispatcher.setNavigationEventCallback(Self.navigationEventCallback); // self.view_dispatcher.attachToGui(self.gui, fz.c.ViewDispatcherType.ViewDispatcherTypeFullscreen); // return self; // } // pub fn customEventCallback(context: ?*anyopaque, event: u32) callconv(.C) void { // const self: *Self = @alignCast(@ptrCast(context)); // _ = self; // _ = event; // } // pub fn navigationEventCallback(context: ?*anyopaque) callconv(.C) void { // const self: *Self = @alignCast(@ptrCast(context)); // _ = self; // } // pub fn update(self: *Self) void { // self.running = false; // } // pub fn deinit(self: *Self) void { // self.view_dispatcher.removeView(ZlipperView.MainMenu); // self.view_dispatcher.destroy(); // self.scene_manager.destroy(); // self.storage.close(); // self.gui.close(); // self.allocator.destroy(self); // } // }; // Application pub fn main(args: *u8) i32 { _ = args; var zlipper = Zlipper.init(fz.heap.furi_allocator); defer zlipper.deinit(); while (zlipper.running) { zlipper.update(); } return 0; }