mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Save/Load the gui layout.
This commit is contained in:
parent
fbb28869f6
commit
bb904828e8
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,4 +3,5 @@ saves/
|
||||
zig-out/
|
||||
zig-cache/
|
||||
serverAssets/
|
||||
settings.json
|
||||
settings.json
|
||||
gui_layout.json
|
@ -16,10 +16,10 @@ const GuiComponent = gui.GuiComponent;
|
||||
|
||||
const GuiWindow = @This();
|
||||
|
||||
const AttachmentPoint = enum {
|
||||
lower,
|
||||
middle,
|
||||
upper,
|
||||
pub const AttachmentPoint = enum(u8) {
|
||||
lower = 0,
|
||||
middle = 1,
|
||||
upper = 2,
|
||||
};
|
||||
|
||||
const OrientationLine = struct {
|
||||
|
102
src/gui/gui.zig
102
src/gui/gui.zig
@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
|
||||
const main = @import("root");
|
||||
const graphics = main.graphics;
|
||||
const draw = graphics.draw;
|
||||
const JsonElement = main.JsonElement;
|
||||
const settings = main.settings;
|
||||
const vec = main.vec;
|
||||
const Vec2f = vec.Vec2f;
|
||||
@ -42,9 +43,13 @@ pub fn init(_allocator: Allocator) !void {
|
||||
try ScrollBar.__init();
|
||||
try Slider.__init();
|
||||
try TextInput.__init();
|
||||
try load();
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
save() catch |err| {
|
||||
std.log.err("Got error while saving gui layout: {s}", .{@errorName(err)});
|
||||
};
|
||||
windowList.deinit();
|
||||
hudWindows.deinit();
|
||||
for(openWindows.items) |window| {
|
||||
@ -59,6 +64,103 @@ pub fn deinit() void {
|
||||
TextInput.__deinit();
|
||||
}
|
||||
|
||||
fn save() !void {
|
||||
const guiJson = try JsonElement.initObject(main.threadAllocator);
|
||||
defer guiJson.free(main.threadAllocator);
|
||||
for(windowList.items) |window| {
|
||||
const windowJson = try JsonElement.initObject(main.threadAllocator);
|
||||
for(window.relativePosition, 0..) |relPos, i| {
|
||||
const relPosJson = try JsonElement.initObject(main.threadAllocator);
|
||||
switch(relPos) {
|
||||
.ratio => |ratio| {
|
||||
try relPosJson.put("type", "ratio");
|
||||
try relPosJson.put("ratio", ratio);
|
||||
},
|
||||
.attachedToFrame => |attachedToFrame| {
|
||||
try relPosJson.put("type", "attachedToFrame");
|
||||
try relPosJson.put("selfAttachmentPoint", @enumToInt(attachedToFrame.selfAttachmentPoint));
|
||||
try relPosJson.put("otherAttachmentPoint", @enumToInt(attachedToFrame.otherAttachmentPoint));
|
||||
},
|
||||
.relativeToWindow => |relativeToWindow| {
|
||||
try relPosJson.put("type", "relativeToWindow");
|
||||
try relPosJson.put("reference", relativeToWindow.reference.id);
|
||||
try relPosJson.put("ratio", relativeToWindow.ratio);
|
||||
},
|
||||
.attachedToWindow => |attachedToWindow| {
|
||||
try relPosJson.put("type", "attachedToWindow");
|
||||
try relPosJson.put("reference", attachedToWindow.reference.id);
|
||||
try relPosJson.put("selfAttachmentPoint", @enumToInt(attachedToWindow.selfAttachmentPoint));
|
||||
try relPosJson.put("otherAttachmentPoint", @enumToInt(attachedToWindow.otherAttachmentPoint));
|
||||
},
|
||||
}
|
||||
try windowJson.put(([_][]const u8{"relPos0", "relPos1"})[i], relPosJson);
|
||||
}
|
||||
try windowJson.put("scale", window.scale);
|
||||
try guiJson.put(window.id, windowJson);
|
||||
}
|
||||
|
||||
const string = try guiJson.toStringEfficient(main.threadAllocator, "");
|
||||
defer main.threadAllocator.free(string);
|
||||
|
||||
var file = try std.fs.cwd().createFile("gui_layout.json", .{});
|
||||
defer file.close();
|
||||
|
||||
try file.writeAll(string);
|
||||
}
|
||||
|
||||
fn load() !void {
|
||||
const json: JsonElement = blk: {
|
||||
var file = std.fs.cwd().openFile("gui_layout.json", .{}) catch break :blk JsonElement{.JsonNull={}};
|
||||
defer file.close();
|
||||
const fileString = try file.readToEndAlloc(main.threadAllocator, std.math.maxInt(usize));
|
||||
defer main.threadAllocator.free(fileString);
|
||||
break :blk JsonElement.parseFromString(main.threadAllocator, fileString);
|
||||
};
|
||||
defer json.free(main.threadAllocator);
|
||||
|
||||
for(windowList.items) |window| {
|
||||
const windowJson = json.getChild(window.id);
|
||||
for(&window.relativePosition, 0..) |*relPos, i| {
|
||||
const relPosJson = windowJson.getChild(([_][]const u8{"relPos0", "relPos1"})[i]);
|
||||
const typ = relPosJson.get([]const u8, "type", "ratio");
|
||||
if(std.mem.eql(u8, typ, "ratio")) {
|
||||
relPos.* = .{.ratio = relPosJson.get(f32, "ratio", 0.5)};
|
||||
} else if(std.mem.eql(u8, typ, "attachedToFrame")) {
|
||||
relPos.* = .{.attachedToFrame = .{
|
||||
.selfAttachmentPoint = @intToEnum(GuiWindow.AttachmentPoint, relPosJson.get(u8, "selfAttachmentPoint", 0)),
|
||||
.otherAttachmentPoint = @intToEnum(GuiWindow.AttachmentPoint, relPosJson.get(u8, "otherAttachmentPoint", 0)),
|
||||
}};
|
||||
} else if(std.mem.eql(u8, typ, "relativeToWindow")) {
|
||||
const reference = getWindowById(relPosJson.get([]const u8, "reference", "")) orelse continue;
|
||||
relPos.* = .{.relativeToWindow = .{
|
||||
.reference = reference,
|
||||
.ratio = relPosJson.get(f32, "ratio", 0.5),
|
||||
}};
|
||||
} else if(std.mem.eql(u8, typ, "attachedToWindow")) {
|
||||
const reference = getWindowById(relPosJson.get([]const u8, "reference", "")) orelse continue;
|
||||
relPos.* = .{.attachedToWindow = .{
|
||||
.reference = reference,
|
||||
.selfAttachmentPoint = @intToEnum(GuiWindow.AttachmentPoint, relPosJson.get(u8, "selfAttachmentPoint", 0)),
|
||||
.otherAttachmentPoint = @intToEnum(GuiWindow.AttachmentPoint, relPosJson.get(u8, "otherAttachmentPoint", 0)),
|
||||
}};
|
||||
} else {
|
||||
std.log.warn("Unknown window attachment type: {s}", .{typ});
|
||||
}
|
||||
}
|
||||
window.scale = windowJson.get(f32, "scale", 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn getWindowById(id: []const u8) ?*GuiWindow {
|
||||
for(windowList.items) |window| {
|
||||
if(std.mem.eql(u8, id, window.id)) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
std.log.warn("Could not find window with id: {s}", .{id});
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn updateGuiScale() void {
|
||||
if(settings.guiScale) |guiScale| {
|
||||
scale = guiScale;
|
||||
|
11
src/json.zig
11
src/json.zig
@ -37,7 +37,7 @@ pub const JsonElement = union(JsonType) {
|
||||
return JsonElement{.JsonArray=list};
|
||||
}
|
||||
|
||||
pub fn getAtIndex(self: *const JsonElement, comptime _type: type, index: usize, replacement: _type) @TypeOf(replacement) {
|
||||
pub fn getAtIndex(self: *const JsonElement, comptime _type: type, index: usize, replacement: _type) _type {
|
||||
if(self.* != .JsonArray) {
|
||||
return replacement;
|
||||
} else {
|
||||
@ -61,7 +61,7 @@ pub const JsonElement = union(JsonType) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(self: *const JsonElement, comptime _type: type, key: []const u8, replacement: _type) @TypeOf(replacement) {
|
||||
pub fn get(self: *const JsonElement, comptime _type: type, key: []const u8, replacement: _type) _type {
|
||||
if(self.* != .JsonObject) {
|
||||
return replacement;
|
||||
} else {
|
||||
@ -148,7 +148,12 @@ pub const JsonElement = union(JsonType) {
|
||||
if(ptr.child == u8 and ptr.size == .Slice) {
|
||||
return JsonElement{.JsonString=value};
|
||||
} else {
|
||||
@compileError("Unknown value type.");
|
||||
const childInfo = @typeInfo(ptr.child);
|
||||
if(ptr.size == .One and childInfo == .Array and childInfo.Array.child == u8) {
|
||||
return JsonElement{.JsonString=value};
|
||||
} else {
|
||||
@compileError("Unknown value type.");
|
||||
}
|
||||
}
|
||||
},
|
||||
.Optional => {
|
||||
|
@ -10,7 +10,7 @@ pub const game = @import("game.zig");
|
||||
pub const graphics = @import("graphics.zig");
|
||||
pub const itemdrop = @import("itemdrop.zig");
|
||||
pub const items = @import("items.zig");
|
||||
pub const JsonElement = @import("json.zig");
|
||||
pub const JsonElement = @import("json.zig").JsonElement;
|
||||
pub const models = @import("models.zig");
|
||||
pub const network = @import("network.zig");
|
||||
pub const random = @import("random.zig");
|
||||
|
@ -75,11 +75,8 @@ pub fn init() !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
const jsonObject = JsonElement.initObject(main.threadAllocator) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
fn flawedDeinit() !void {
|
||||
const jsonObject = try JsonElement.initObject(main.threadAllocator);
|
||||
defer jsonObject.free(main.threadAllocator);
|
||||
|
||||
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
||||
@ -90,13 +87,9 @@ pub fn deinit() void {
|
||||
@compileError("Not implemented yet.");
|
||||
}
|
||||
if(declType == []const u8) {
|
||||
jsonObject.putOwnedString(decl.name, @field(@This(), decl.name)) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
try jsonObject.putOwnedString(decl.name, @field(@This(), decl.name));
|
||||
} else {
|
||||
jsonObject.put(decl.name, @field(@This(), decl.name)) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
try jsonObject.put(decl.name, @field(@This(), decl.name));
|
||||
}
|
||||
if(@typeInfo(declType) == .Pointer) {
|
||||
if(@typeInfo(declType).Pointer.size == .Slice) {
|
||||
@ -109,48 +102,30 @@ pub fn deinit() void {
|
||||
}
|
||||
|
||||
// keyboard settings:
|
||||
const keyboard = JsonElement.initObject(main.threadAllocator) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
const keyboard = try JsonElement.initObject(main.threadAllocator);
|
||||
inline for(comptime std.meta.fieldNames(@TypeOf(main.keyboard))) |keyName| {
|
||||
const keyJson = JsonElement.initObject(main.threadAllocator) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
const keyJson = try JsonElement.initObject(main.threadAllocator);
|
||||
const key = &@field(main.keyboard, keyName);
|
||||
keyJson.put("key", key.key) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
keyJson.put("mouseButton", key.mouseButton) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
keyJson.put("scancode", key.scancode) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
keyboard.put(keyName, keyJson) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
try keyJson.put("key", key.key);
|
||||
try keyJson.put("mouseButton", key.mouseButton);
|
||||
try keyJson.put("scancode", key.scancode);
|
||||
try keyboard.put(keyName, keyJson);
|
||||
}
|
||||
jsonObject.put("keyboard", keyboard) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
};
|
||||
try jsonObject.put("keyboard", keyboard);
|
||||
|
||||
// Write to file:
|
||||
|
||||
const string = jsonObject.toStringEfficient(main.threadAllocator, "") catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
const string = try jsonObject.toStringEfficient(main.threadAllocator, "");
|
||||
defer main.threadAllocator.free(string);
|
||||
|
||||
var file = std.fs.cwd().createFile("settings.json", .{}) catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
var file = try std.fs.cwd().createFile("settings.json", .{});
|
||||
defer file.close();
|
||||
|
||||
file.writeAll(string) catch |err| {
|
||||
try file.writeAll(string);
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
flawedDeinit() catch |err| {
|
||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user