aboutsummaryrefslogtreecommitdiffstats
path: root/src/config.zig
diff options
context:
space:
mode:
authorkj_sh6042026-06-05 15:29:19 -0400
committerkj_sh6042026-06-05 15:29:19 -0400
commit393fd854892d1e2a31fce009c68c6cfb293fc9af (patch)
treea36d559444e2678c3e7aab91a2b3ffbc05423260 /src/config.zig
parent44f510c75fa470654aa607e2860571382dcde638 (diff)
refactor: src/config.zig
Diffstat (limited to 'src/config.zig')
-rw-r--r--src/config.zig133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/config.zig b/src/config.zig
new file mode 100644
index 0000000..6325b0b
--- /dev/null
+++ b/src/config.zig
@@ -0,0 +1,133 @@
+const std = @import("std");
+
+const c = @import("c.zig").c;
+
+pub const Config = struct {
+ // camera settings
+ min_scale: f32 = 0.5,
+ scroll_speed: f32 = 1.5,
+ drag_friction: f32 = 6.0,
+ scale_friction: f32 = 4.0,
+ velocity_threshold: f32 = 15.0,
+ scale_change_threshold: f32 = 0.5,
+
+ // flashlight settings
+ initial_radius: f32 = 200.0,
+ initial_delta_radius: f32 = 250.0,
+ radius_damping: f32 = 10.0,
+ fade_speed: f32 = 6.0,
+ max_shadow_opacity: f32 = 0.8,
+ radius_change_threshold: f32 = 1.0,
+ feather: f32 = 0.0,
+
+ // opengl settings
+ texture_filter: i32 = 0,
+
+ // key bindings (KeySym = c_ulong on x86_64 linux)
+ key_escape: c_ulong = c.XK_Escape,
+ key_flashlight: c_ulong = c.XK_f,
+ key_reset: c_ulong = c.XK_0,
+ key_mirror: c_ulong = c.XK_m,
+ key_zoom_in: c_ulong = c.XK_equal,
+ key_zoom_out: c_ulong = c.XK_minus,
+
+ modifier_flashlight: c_uint = c.ControlMask,
+ button_drag: c_uint = c.Button1,
+ button_zoom_in: c_uint = c.Button4,
+ button_zoom_out: c_uint = c.Button5,
+
+ pub fn default() Config {
+ return .{};
+ }
+
+ pub fn applyValue(self: *Config, key: []const u8, value: f32) void {
+ if (std.mem.eql(u8, key, "min_scale")) self.min_scale = value;
+ if (std.mem.eql(u8, key, "scroll_speed")) self.scroll_speed = value;
+ if (std.mem.eql(u8, key, "drag_friction")) self.drag_friction = value;
+ if (std.mem.eql(u8, key, "scale_friction")) self.scale_friction = value;
+ if (std.mem.eql(u8, key, "velocity_threshold")) self.velocity_threshold = value;
+ if (std.mem.eql(u8, key, "scale_change_threshold")) self.scale_change_threshold = value;
+ if (std.mem.eql(u8, key, "initial_radius")) self.initial_radius = value;
+ if (std.mem.eql(u8, key, "initial_delta_radius")) self.initial_delta_radius = value;
+ if (std.mem.eql(u8, key, "radius_damping")) self.radius_damping = value;
+ if (std.mem.eql(u8, key, "fade_speed")) self.fade_speed = value;
+ if (std.mem.eql(u8, key, "max_shadow_opacity")) self.max_shadow_opacity = value;
+ if (std.mem.eql(u8, key, "radius_change_threshold")) self.radius_change_threshold = value;
+ if (std.mem.eql(u8, key, "feather")) self.feather = value;
+ if (std.mem.eql(u8, key, "texture_filter")) self.texture_filter = @intFromFloat(value);
+ }
+
+ pub fn loadFromFile(self: *Config, path: []const u8) void {
+ var path_buf: [1024]u8 = undefined;
+ @memcpy(path_buf[0..@min(path.len, path_buf.len - 1)], path);
+ path_buf[@min(path.len, path_buf.len - 1)] = 0;
+ const path_z: [*:0]const u8 = @ptrCast(&path_buf);
+
+ const f = c.fopen(path_z, "r") orelse return;
+ defer _ = c.fclose(f);
+
+ var buf: [4096]u8 = undefined;
+ while (c.fgets(&buf, buf.len, f) != null) {
+ const raw = buf[0 .. std.mem.indexOfScalar(u8, &buf, 0) orelse buf.len];
+ const line = std.mem.trimStart(u8, raw, " \t");
+ if (line.len == 0 or line[0] == '#') continue;
+
+ var parts = std.mem.splitScalar(u8, line, '=');
+ const key = std.mem.trimEnd(u8, parts.first(), " \t");
+ const val_str = if (parts.next()) |v| std.mem.trimStart(u8, v, " \t") else continue;
+ const value = std.fmt.parseFloat(f32, val_str) catch continue;
+
+ self.applyValue(key, value);
+ }
+ }
+
+ pub fn writeDefault(self: Config, path: []const u8) !void {
+ var path_buf: [1024]u8 = undefined;
+ @memcpy(path_buf[0..@min(path.len, path_buf.len - 1)], path);
+ path_buf[@min(path.len, path_buf.len - 1)] = 0;
+ const path_z: [*:0]const u8 = @ptrCast(&path_buf);
+
+ const f = c.fopen(path_z, "w") orelse {
+ std.debug.print("error: could not write config to {s}\n", .{path});
+ return error.ConfigWriteFailed;
+ };
+ defer _ = c.fclose(f);
+
+ _ = c.fprintf(f, "min_scale = %.1f\n", self.min_scale);
+ _ = c.fprintf(f, "scroll_speed = %.1f\n", self.scroll_speed);
+ _ = c.fprintf(f, "drag_friction = %.1f\n", self.drag_friction);
+ _ = c.fprintf(f, "scale_friction = %.1f\n", self.scale_friction);
+ _ = c.fprintf(f, "velocity_threshold = %.1f\n", self.velocity_threshold);
+ _ = c.fprintf(f, "scale_change_threshold = %.2f\n", self.scale_change_threshold);
+ _ = c.fprintf(f, "initial_radius = %.1f\n", self.initial_radius);
+ _ = c.fprintf(f, "initial_delta_radius = %.1f\n", self.initial_delta_radius);
+ _ = c.fprintf(f, "radius_damping = %.1f\n", self.radius_damping);
+ _ = c.fprintf(f, "fade_speed = %.1f\n", self.fade_speed);
+ _ = c.fprintf(f, "max_shadow_opacity = %.2f\n", self.max_shadow_opacity);
+ _ = c.fprintf(f, "radius_change_threshold = %.2f\n", self.radius_change_threshold);
+ _ = c.fprintf(f, "feather = %.2f\n", self.feather);
+ _ = c.fprintf(f, "texture_filter = %d\n", self.texture_filter);
+ }
+
+ pub fn defaultConfigPath(alloc: std.mem.Allocator) ?[]const u8 {
+ const home = std.c.getenv("HOME") orelse return null;
+ const home_slice = std.mem.sliceTo(home, 0);
+ const path = std.fs.path.join(alloc, &.{ home_slice, ".config", "boomer", "config" }) catch return null;
+ return path;
+ }
+
+ pub fn mkdirP(path: []const u8) void {
+ var buf: [1024]u8 = undefined;
+ const len = @min(path.len, buf.len - 1);
+ @memcpy(buf[0..len], path[0..len]);
+ buf[len] = 0;
+ for (1..len) |i| {
+ if (buf[i] == '/') {
+ buf[i] = 0;
+ _ = std.c.mkdir((buf[0..i :0]).ptr, 0o755);
+ buf[i] = '/';
+ }
+ }
+ _ = std.c.mkdir((buf[0..len :0]).ptr, 0o755);
+ }
+}; \ No newline at end of file