feat(win32 gui): add gui_config.json config file
This commit is contained in:
parent
6d7a316abb
commit
eaa7ad87b7
6 changed files with 40 additions and 21 deletions
|
@ -252,6 +252,13 @@ pub fn build_exe(
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const gui_config_mod = b.createModule(.{
|
||||||
|
.root_source_file = b.path("src/gui_config.zig"),
|
||||||
|
.imports = &.{
|
||||||
|
.{ .name = "cbor", .module = cbor_mod },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const log_mod = b.createModule(.{
|
const log_mod = b.createModule(.{
|
||||||
.root_source_file = b.path("src/log.zig"),
|
.root_source_file = b.path("src/log.zig"),
|
||||||
.imports = &.{
|
.imports = &.{
|
||||||
|
@ -324,6 +331,7 @@ pub fn build_exe(
|
||||||
// TODO: we should be able to work without these modules
|
// TODO: we should be able to work without these modules
|
||||||
.{ .name = "vaxis", .module = vaxis_mod },
|
.{ .name = "vaxis", .module = vaxis_mod },
|
||||||
.{ .name = "color", .module = color_mod },
|
.{ .name = "color", .module = color_mod },
|
||||||
|
.{ .name = "gui_config", .module = gui_config_mod },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
gui_mod.addIncludePath(b.path("src/win32"));
|
gui_mod.addIncludePath(b.path("src/win32"));
|
||||||
|
|
4
src/gui_config.zig
Normal file
4
src/gui_config.zig
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fontface: [] const u8 = "Cascadia Code",
|
||||||
|
fontsize: f32 = 17.5,
|
||||||
|
|
||||||
|
config_files: []const u8 = "",
|
39
src/main.zig
39
src/main.zig
|
@ -389,28 +389,26 @@ pub fn exit(status: u8) noreturn {
|
||||||
std.posix.exit(status);
|
std.posix.exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = @import("config");
|
|
||||||
|
|
||||||
pub fn free_config(allocator: std.mem.Allocator, bufs: [][]const u8) void {
|
pub fn free_config(allocator: std.mem.Allocator, bufs: [][]const u8) void {
|
||||||
for (bufs) |buf| allocator.free(buf);
|
for (bufs) |buf| allocator.free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_config(allocator: std.mem.Allocator) struct { config, [][]const u8 } {
|
pub fn read_config(T: type, allocator: std.mem.Allocator) struct { T, [][]const u8 } {
|
||||||
var bufs: [][]const u8 = &[_][]const u8{};
|
var bufs: [][]const u8 = &[_][]const u8{};
|
||||||
const file_name = get_app_config_file_name(application_name) catch return .{ .{}, bufs };
|
const file_name = get_app_config_file_name(application_name, @typeName(T)) catch return .{ .{}, bufs };
|
||||||
var conf: config = .{};
|
var conf: T = .{};
|
||||||
read_config_file(allocator, &conf, &bufs, file_name);
|
read_config_file(T, allocator, &conf, &bufs, file_name);
|
||||||
read_nested_config_files(allocator, &conf, &bufs);
|
read_nested_config_files(T, allocator, &conf, &bufs);
|
||||||
return .{ conf, bufs };
|
return .{ conf, bufs };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_config_file(allocator: std.mem.Allocator, conf: *config, bufs: *[][]const u8, file_name: []const u8) void {
|
fn read_config_file(T: type, allocator: std.mem.Allocator, conf: *T, bufs: *[][]const u8, file_name: []const u8) void {
|
||||||
read_json_config_file(allocator, conf, bufs, file_name) catch |e|
|
read_json_config_file(T, allocator, conf, bufs, file_name) catch |e|
|
||||||
log.logger("config").print_err("read_config", "error reading config file: {any}", .{e});
|
log.logger("config").print_err("read_config", "error reading config file: {any}", .{e});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_json_config_file(allocator: std.mem.Allocator, conf: *config, bufs_: *[][]const u8, file_name: []const u8) !void {
|
fn read_json_config_file(T: type, allocator: std.mem.Allocator, conf: *T, bufs_: *[][]const u8, file_name: []const u8) !void {
|
||||||
const cbor = @import("cbor");
|
const cbor = @import("cbor");
|
||||||
var file = std.fs.openFileAbsolute(file_name, .{ .mode = .read_only }) catch |e| switch (e) {
|
var file = std.fs.openFileAbsolute(file_name, .{ .mode = .read_only }) catch |e| switch (e) {
|
||||||
error.FileNotFound => return,
|
error.FileNotFound => return,
|
||||||
|
@ -429,7 +427,7 @@ fn read_json_config_file(allocator: std.mem.Allocator, conf: *config, bufs_: *[]
|
||||||
while (len > 0) : (len -= 1) {
|
while (len > 0) : (len -= 1) {
|
||||||
var field_name: []const u8 = undefined;
|
var field_name: []const u8 = undefined;
|
||||||
if (!(try cbor.matchString(&iter, &field_name))) return error.InvalidConfig;
|
if (!(try cbor.matchString(&iter, &field_name))) return error.InvalidConfig;
|
||||||
inline for (@typeInfo(config).Struct.fields) |field_info|
|
inline for (@typeInfo(T).Struct.fields) |field_info|
|
||||||
if (comptime std.mem.eql(u8, "config_files", field_info.name)) {
|
if (comptime std.mem.eql(u8, "config_files", field_info.name)) {
|
||||||
if (std.mem.eql(u8, field_name, field_info.name)) {
|
if (std.mem.eql(u8, field_name, field_info.name)) {
|
||||||
var value: field_info.type = undefined;
|
var value: field_info.type = undefined;
|
||||||
|
@ -448,14 +446,14 @@ fn read_json_config_file(allocator: std.mem.Allocator, conf: *config, bufs_: *[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_nested_config_files(allocator: std.mem.Allocator, conf: *config, bufs: *[][]const u8) void {
|
fn read_nested_config_files(T: type, allocator: std.mem.Allocator, conf: *T, bufs: *[][]const u8) void {
|
||||||
if (conf.config_files.len == 0) return;
|
if (conf.config_files.len == 0) return;
|
||||||
var it = std.mem.splitScalar(u8, conf.config_files, std.fs.path.delimiter);
|
var it = std.mem.splitScalar(u8, conf.config_files, std.fs.path.delimiter);
|
||||||
while (it.next()) |path| read_config_file(allocator, conf, bufs, path);
|
while (it.next()) |path| read_config_file(T, allocator, conf, bufs, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_config(conf: config, allocator: std.mem.Allocator) !void {
|
pub fn write_config(conf: anytype, allocator: std.mem.Allocator) !void {
|
||||||
return write_json_file(config, conf, allocator, try get_app_config_file_name(application_name));
|
return write_json_file(@TypeOf(conf), conf, allocator, try get_app_config_file_name(application_name, @typeName(@TypeOf(conf))));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_json_file(comptime T: type, data: T, allocator: std.mem.Allocator, file_name: []const u8) !void {
|
fn write_json_file(comptime T: type, data: T, allocator: std.mem.Allocator, file_name: []const u8) !void {
|
||||||
|
@ -638,12 +636,15 @@ fn get_app_state_dir(appname: []const u8) ![]const u8 {
|
||||||
return state_dir;
|
return state_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_app_config_file_name(appname: []const u8) ![]const u8 {
|
fn get_app_config_file_name(appname: []const u8, comptime base_name: []const u8) ![]const u8 {
|
||||||
|
return get_app_config_dir_file_name(appname, base_name ++ ".json");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_app_config_dir_file_name(appname: []const u8, comptime config_file_name: []const u8) ![]const u8 {
|
||||||
const local = struct {
|
const local = struct {
|
||||||
var config_file_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
var config_file_buffer: [std.posix.PATH_MAX]u8 = undefined;
|
||||||
var config_file: ?[]const u8 = null;
|
var config_file: ?[]const u8 = null;
|
||||||
};
|
};
|
||||||
const config_file_name = "config.json";
|
|
||||||
const config_file = if (local.config_file) |file|
|
const config_file = if (local.config_file) |file|
|
||||||
file
|
file
|
||||||
else
|
else
|
||||||
|
@ -652,8 +653,8 @@ fn get_app_config_file_name(appname: []const u8) ![]const u8 {
|
||||||
return config_file;
|
return config_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_config_file_name() ![]const u8 {
|
pub fn get_config_file_name(T: type) ![]const u8 {
|
||||||
return get_app_config_file_name(application_name);
|
return get_app_config_file_name(application_name, @typeName(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_restore_file_name() ![]const u8 {
|
pub fn get_restore_file_name() ![]const u8 {
|
||||||
|
|
|
@ -378,7 +378,7 @@ const cmds = struct {
|
||||||
pub const open_help_meta = .{ .description = "Open help" };
|
pub const open_help_meta = .{ .description = "Open help" };
|
||||||
|
|
||||||
pub fn open_config(_: *Self, _: Ctx) Result {
|
pub fn open_config(_: *Self, _: Ctx) Result {
|
||||||
const file_name = try root.get_config_file_name();
|
const file_name = try root.get_config_file_name(@TypeOf(tui.current().config));
|
||||||
try tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_name } });
|
try tp.self_pid().send(.{ "cmd", "navigate", .{ .file = file_name } });
|
||||||
}
|
}
|
||||||
pub const open_config_meta = .{ .description = "Edit configuration file" };
|
pub const open_config_meta = .{ .description = "Edit configuration file" };
|
||||||
|
|
|
@ -83,7 +83,7 @@ fn start(args: StartArgs) tp.result {
|
||||||
fn init(allocator: Allocator) !*Self {
|
fn init(allocator: Allocator) !*Self {
|
||||||
var self = try allocator.create(Self);
|
var self = try allocator.create(Self);
|
||||||
|
|
||||||
var conf, const conf_bufs = root.read_config(allocator);
|
var conf, const conf_bufs = root.read_config(config, allocator);
|
||||||
defer root.free_config(allocator, conf_bufs);
|
defer root.free_config(allocator, conf_bufs);
|
||||||
|
|
||||||
const theme = get_theme_by_name(conf.theme) orelse get_theme_by_name("dark_modern") orelse return tp.exit("unknown theme");
|
const theme = get_theme_by_name(conf.theme) orelse get_theme_by_name("dark_modern") orelse return tp.exit("unknown theme");
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const root = @import("root");
|
||||||
|
|
||||||
const c = @cImport({
|
const c = @cImport({
|
||||||
@cInclude("ResourceNames.h");
|
@cInclude("ResourceNames.h");
|
||||||
|
@ -10,6 +11,7 @@ const ddui = @import("ddui");
|
||||||
const cbor = @import("cbor");
|
const cbor = @import("cbor");
|
||||||
const thespian = @import("thespian");
|
const thespian = @import("thespian");
|
||||||
const vaxis = @import("vaxis");
|
const vaxis = @import("vaxis");
|
||||||
|
const gui_config = @import("gui_config");
|
||||||
|
|
||||||
const RGB = @import("color").RGB;
|
const RGB = @import("color").RGB;
|
||||||
const input = @import("input");
|
const input = @import("input");
|
||||||
|
@ -381,6 +383,7 @@ fn calcWindowPlacement() WindowPlacement {
|
||||||
const CreateWindowArgs = struct {
|
const CreateWindowArgs = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
pid: thespian.pid,
|
pid: thespian.pid,
|
||||||
|
conf: gui_config,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn start() !std.Thread {
|
pub fn start() !std.Thread {
|
||||||
|
@ -418,9 +421,12 @@ fn entry(pid: thespian.pid) !void {
|
||||||
win32.GetLastError(),
|
win32.GetLastError(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const conf, _ = root.read_config(gui_config, arena_instance.allocator());
|
||||||
|
|
||||||
var create_args = CreateWindowArgs{
|
var create_args = CreateWindowArgs{
|
||||||
.allocator = arena_instance.allocator(),
|
.allocator = arena_instance.allocator(),
|
||||||
.pid = pid,
|
.pid = pid,
|
||||||
|
.conf = conf,
|
||||||
};
|
};
|
||||||
const hwnd = win32.CreateWindowExW(
|
const hwnd = win32.CreateWindowExW(
|
||||||
window_style_ex,
|
window_style_ex,
|
||||||
|
|
Loading…
Add table
Reference in a new issue