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-out/
|
||||||
zig-cache/
|
zig-cache/
|
||||||
serverAssets/
|
serverAssets/
|
||||||
settings.json
|
settings.json
|
||||||
|
gui_layout.json
|
@ -16,10 +16,10 @@ const GuiComponent = gui.GuiComponent;
|
|||||||
|
|
||||||
const GuiWindow = @This();
|
const GuiWindow = @This();
|
||||||
|
|
||||||
const AttachmentPoint = enum {
|
pub const AttachmentPoint = enum(u8) {
|
||||||
lower,
|
lower = 0,
|
||||||
middle,
|
middle = 1,
|
||||||
upper,
|
upper = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
const OrientationLine = struct {
|
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 main = @import("root");
|
||||||
const graphics = main.graphics;
|
const graphics = main.graphics;
|
||||||
const draw = graphics.draw;
|
const draw = graphics.draw;
|
||||||
|
const JsonElement = main.JsonElement;
|
||||||
const settings = main.settings;
|
const settings = main.settings;
|
||||||
const vec = main.vec;
|
const vec = main.vec;
|
||||||
const Vec2f = vec.Vec2f;
|
const Vec2f = vec.Vec2f;
|
||||||
@ -42,9 +43,13 @@ pub fn init(_allocator: Allocator) !void {
|
|||||||
try ScrollBar.__init();
|
try ScrollBar.__init();
|
||||||
try Slider.__init();
|
try Slider.__init();
|
||||||
try TextInput.__init();
|
try TextInput.__init();
|
||||||
|
try load();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
pub fn deinit() void {
|
||||||
|
save() catch |err| {
|
||||||
|
std.log.err("Got error while saving gui layout: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
windowList.deinit();
|
windowList.deinit();
|
||||||
hudWindows.deinit();
|
hudWindows.deinit();
|
||||||
for(openWindows.items) |window| {
|
for(openWindows.items) |window| {
|
||||||
@ -59,6 +64,103 @@ pub fn deinit() void {
|
|||||||
TextInput.__deinit();
|
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 {
|
pub fn updateGuiScale() void {
|
||||||
if(settings.guiScale) |guiScale| {
|
if(settings.guiScale) |guiScale| {
|
||||||
scale = guiScale;
|
scale = guiScale;
|
||||||
|
11
src/json.zig
11
src/json.zig
@ -37,7 +37,7 @@ pub const JsonElement = union(JsonType) {
|
|||||||
return JsonElement{.JsonArray=list};
|
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) {
|
if(self.* != .JsonArray) {
|
||||||
return replacement;
|
return replacement;
|
||||||
} else {
|
} 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) {
|
if(self.* != .JsonObject) {
|
||||||
return replacement;
|
return replacement;
|
||||||
} else {
|
} else {
|
||||||
@ -148,7 +148,12 @@ pub const JsonElement = union(JsonType) {
|
|||||||
if(ptr.child == u8 and ptr.size == .Slice) {
|
if(ptr.child == u8 and ptr.size == .Slice) {
|
||||||
return JsonElement{.JsonString=value};
|
return JsonElement{.JsonString=value};
|
||||||
} else {
|
} 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 => {
|
.Optional => {
|
||||||
|
@ -10,7 +10,7 @@ pub const game = @import("game.zig");
|
|||||||
pub const graphics = @import("graphics.zig");
|
pub const graphics = @import("graphics.zig");
|
||||||
pub const itemdrop = @import("itemdrop.zig");
|
pub const itemdrop = @import("itemdrop.zig");
|
||||||
pub const items = @import("items.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 models = @import("models.zig");
|
||||||
pub const network = @import("network.zig");
|
pub const network = @import("network.zig");
|
||||||
pub const random = @import("random.zig");
|
pub const random = @import("random.zig");
|
||||||
|
@ -75,11 +75,8 @@ pub fn init() !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit() void {
|
fn flawedDeinit() !void {
|
||||||
const jsonObject = JsonElement.initObject(main.threadAllocator) catch |err| {
|
const jsonObject = try JsonElement.initObject(main.threadAllocator);
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
defer jsonObject.free(main.threadAllocator);
|
defer jsonObject.free(main.threadAllocator);
|
||||||
|
|
||||||
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
inline for(@typeInfo(@This()).Struct.decls) |decl| {
|
||||||
@ -90,13 +87,9 @@ pub fn deinit() void {
|
|||||||
@compileError("Not implemented yet.");
|
@compileError("Not implemented yet.");
|
||||||
}
|
}
|
||||||
if(declType == []const u8) {
|
if(declType == []const u8) {
|
||||||
jsonObject.putOwnedString(decl.name, @field(@This(), decl.name)) catch |err| {
|
try jsonObject.putOwnedString(decl.name, @field(@This(), decl.name));
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
jsonObject.put(decl.name, @field(@This(), decl.name)) catch |err| {
|
try jsonObject.put(decl.name, @field(@This(), decl.name));
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
if(@typeInfo(declType) == .Pointer) {
|
if(@typeInfo(declType) == .Pointer) {
|
||||||
if(@typeInfo(declType).Pointer.size == .Slice) {
|
if(@typeInfo(declType).Pointer.size == .Slice) {
|
||||||
@ -109,48 +102,30 @@ pub fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// keyboard settings:
|
// keyboard settings:
|
||||||
const keyboard = JsonElement.initObject(main.threadAllocator) catch |err| {
|
const keyboard = try JsonElement.initObject(main.threadAllocator);
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
inline for(comptime std.meta.fieldNames(@TypeOf(main.keyboard))) |keyName| {
|
inline for(comptime std.meta.fieldNames(@TypeOf(main.keyboard))) |keyName| {
|
||||||
const keyJson = JsonElement.initObject(main.threadAllocator) catch |err| {
|
const keyJson = try JsonElement.initObject(main.threadAllocator);
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
const key = &@field(main.keyboard, keyName);
|
const key = &@field(main.keyboard, keyName);
|
||||||
keyJson.put("key", key.key) catch |err| {
|
try keyJson.put("key", key.key);
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
try keyJson.put("mouseButton", key.mouseButton);
|
||||||
};
|
try keyJson.put("scancode", key.scancode);
|
||||||
keyJson.put("mouseButton", key.mouseButton) catch |err| {
|
try keyboard.put(keyName, keyJson);
|
||||||
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)});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
jsonObject.put("keyboard", keyboard) catch |err| {
|
try jsonObject.put("keyboard", keyboard);
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Write to file:
|
// Write to file:
|
||||||
|
|
||||||
const string = jsonObject.toStringEfficient(main.threadAllocator, "") catch |err| {
|
const string = try jsonObject.toStringEfficient(main.threadAllocator, "");
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
defer main.threadAllocator.free(string);
|
defer main.threadAllocator.free(string);
|
||||||
|
|
||||||
var file = std.fs.cwd().createFile("settings.json", .{}) catch |err| {
|
var file = try std.fs.cwd().createFile("settings.json", .{});
|
||||||
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
defer file.close();
|
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)});
|
std.log.err("Error in settings.deinit(): {s}", .{@errorName(err)});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user