diff --git a/build.zig b/build.zig index 035b480f..f73830e8 100644 --- a/build.zig +++ b/build.zig @@ -593,6 +593,8 @@ pub fn build_exe( .{ .name = "cbor", .module = cbor_mod }, .{ .name = "vaxis", .module = vaxis_mod }, .{ .name = "xterm", .module = gui_xterm_mod }, + .{ .name = "soft_root", .module = soft_root_mod }, + .{ .name = "gui_config", .module = gui_config_mod }, }, }); diff --git a/src/gui/wio/app.zig b/src/gui/wio/app.zig index 3237ea87..6474f4b7 100644 --- a/src/gui/wio/app.zig +++ b/src/gui/wio/app.zig @@ -17,6 +17,8 @@ const cbor = @import("cbor"); const vaxis = @import("vaxis"); const input_translate = @import("input.zig"); +const root = @import("soft_root").root; +const gui_config = @import("gui_config"); const log = std.log.scoped(.wio_app); @@ -42,6 +44,9 @@ var font_name_len: usize = 0; var font_dirty: std.atomic.Value(bool) = .init(true); var stop_requested: std.atomic.Value(bool) = .init(false); +var config_arena_instance: std.heap.ArenaAllocator = std.heap.ArenaAllocator.init(std.heap.page_allocator); +const config_arena = config_arena_instance.allocator(); + // HiDPI scale factor (logical → physical pixels). Updated from wio .scale events. // Only read/written on the wio thread after initialisation. var dpi_scale: f32 = 1.0; @@ -75,6 +80,7 @@ pub fn start() !std.Thread { tui_pid = thespian.self_pid().clone(); font_name_len = 0; stop_requested.store(false, .release); + loadConfig(); return std.Thread.spawn(.{}, wioLoop, .{}); } @@ -143,6 +149,7 @@ pub fn requestRender() void { pub fn setFontSize(size_px: f32) void { font_size_px = @intFromFloat(@max(4, size_px)); + saveConfig(); font_dirty.store(true, .release); requestRender(); } @@ -152,10 +159,29 @@ pub fn adjustFontSize(delta: f32) void { setFontSize(new); } +pub fn resetFontSize() void { + const default = comptime blk: { + const field = std.meta.fieldInfo(gui_config, .fontsize); + const ptr: *const field.type = @ptrCast(@alignCast(field.default_value_ptr.?)); + break :blk ptr.*; + }; + setFontSize(@floatFromInt(default)); +} + +pub fn resetFontFace() void { + const default = comptime blk: { + const field = std.meta.fieldInfo(gui_config, .fontface); + const ptr: *const field.type = @ptrCast(@alignCast(field.default_value_ptr.?)); + break :blk ptr.*; + }; + setFontFace(default); +} + pub fn setFontFace(name: []const u8) void { const copy_len = @min(name.len, font_name_buf.len); @memcpy(font_name_buf[0..copy_len], name[0..copy_len]); font_name_len = copy_len; + saveConfig(); font_dirty.store(true, .release); requestRender(); } @@ -206,6 +232,25 @@ pub fn getFontName() []const u8 { return if (font_name_len > 0) font_name_buf[0..font_name_len] else "monospace"; } +pub fn loadConfig() void { + const conf, _ = root.read_config(gui_config, config_arena); + root.write_config(conf, config_arena) catch + log.err("failed to write gui config file", .{}); + font_size_px = conf.fontsize; + const name = conf.fontface; + const copy_len = @min(name.len, font_name_buf.len); + @memcpy(font_name_buf[0..copy_len], name[0..copy_len]); + font_name_len = copy_len; +} + +fn saveConfig() void { + var conf, _ = root.read_config(gui_config, config_arena); + conf.fontsize = @truncate(font_size_px); + conf.fontface = getFontName(); + root.write_config(conf, config_arena) catch + log.err("failed to write gui config file", .{}); +} + pub fn requestAttention() void { attention_pending.store(true, .release); wio.cancelWait(); diff --git a/src/renderer/gui/renderer.zig b/src/renderer/gui/renderer.zig index 3890fcea..bb3d0675 100644 --- a/src/renderer/gui/renderer.zig +++ b/src/renderer/gui/renderer.zig @@ -367,7 +367,7 @@ pub fn set_fontsize(self: *Self, fontsize: f32) void { pub fn reset_fontsize(self: *Self) void { _ = self; - app.setFontSize(16); + app.resetFontSize(); } pub fn set_fontface(self: *Self, fontface: []const u8) void { @@ -377,7 +377,7 @@ pub fn set_fontface(self: *Self, fontface: []const u8) void { pub fn reset_fontface(self: *Self) void { _ = self; - app.setFontFace("monospace"); + app.resetFontFace(); } pub fn get_fontfaces(self: *Self) void {