json сохранение
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
const dvui = @import("dvui");
|
||||
const WindowContext = @import("../WindowContext.zig");
|
||||
const menu_bar = @import("menu_bar.zig");
|
||||
const tab_bar = @import("tab_bar.zig");
|
||||
const left_panel = @import("left_panel.zig");
|
||||
const right_panel = @import("right_panel.zig");
|
||||
@@ -16,6 +17,7 @@ pub fn guiFrame(ctx: *WindowContext) bool {
|
||||
.{ .expand = .both, .background = true, .style = .window },
|
||||
);
|
||||
{
|
||||
menu_bar.menuBar(ctx);
|
||||
tab_bar.tabBar(ctx);
|
||||
|
||||
var content_row = dvui.box(@src(), .{ .dir = .horizontal }, .{ .expand = .both });
|
||||
|
||||
89
src/ui/menu_bar.zig
Normal file
89
src/ui/menu_bar.zig
Normal file
@@ -0,0 +1,89 @@
|
||||
const std = @import("std");
|
||||
const dvui = @import("dvui");
|
||||
const WindowContext = @import("../WindowContext.zig");
|
||||
const document_json = @import("../persistence/document_json.zig");
|
||||
|
||||
pub fn menuBar(ctx: *WindowContext) void {
|
||||
var m = dvui.menu(@src(), .horizontal, .{ .background = true, .expand = .horizontal });
|
||||
defer m.deinit();
|
||||
|
||||
if (dvui.menuItemLabel(@src(), "File", .{ .submenu = true }, .{ .expand = .none })) |r| {
|
||||
var fm = dvui.floatingMenu(@src(), .{ .from = r }, .{});
|
||||
defer fm.deinit();
|
||||
|
||||
if (dvui.menuItemLabel(@src(), "Open", .{}, .{ .expand = .horizontal }) != null) {
|
||||
m.close();
|
||||
openDocumentDialog(ctx);
|
||||
}
|
||||
|
||||
if (dvui.menuItemLabel(@src(), "Save As", .{}, .{ .expand = .horizontal }) != null) {
|
||||
m.close();
|
||||
saveAsDialog(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn openDocumentDialog(ctx: *WindowContext) void {
|
||||
const path_z = dvui.dialogNativeFileOpen(ctx.allocator, .{
|
||||
.title = "Open",
|
||||
.filters = &.{ "*.json" },
|
||||
.filter_description = "JSON files",
|
||||
}) catch |err| {
|
||||
std.debug.print("Open dialog error: {}\n", .{err});
|
||||
return;
|
||||
} orelse return;
|
||||
defer ctx.allocator.free(path_z);
|
||||
|
||||
const path = path_z[0..path_z.len];
|
||||
const doc = document_json.loadFromFile(ctx.allocator, path) catch |err| {
|
||||
std.debug.print("Open file error: {}\n", .{err});
|
||||
return;
|
||||
};
|
||||
ctx.addDocument(doc) catch |err| {
|
||||
std.debug.print("Add document error: {}\n", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
fn saveAsDialog(ctx: *WindowContext) void {
|
||||
const open_doc = ctx.activeDocument() orelse return;
|
||||
const path_z = dvui.dialogNativeFileSave(ctx.allocator, .{
|
||||
.title = "Save As",
|
||||
.filters = &.{ "*.json" },
|
||||
.filter_description = "JSON files",
|
||||
}) catch |err| {
|
||||
std.debug.print("Save dialog error: {}\n", .{err});
|
||||
return;
|
||||
} orelse return;
|
||||
defer ctx.allocator.free(path_z);
|
||||
|
||||
const path_raw = path_z[0..path_z.len];
|
||||
const resolved = ensureJsonPath(ctx.allocator, path_raw) catch |err| {
|
||||
std.debug.print("Save path error: {}\n", .{err});
|
||||
return;
|
||||
};
|
||||
defer if (resolved.owned) ctx.allocator.free(resolved.path);
|
||||
|
||||
document_json.saveToFile(&open_doc.document, resolved.path) catch |err| {
|
||||
std.debug.print("Save file error: {}\n", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
const ResolvedPath = struct {
|
||||
path: []const u8,
|
||||
owned: bool,
|
||||
};
|
||||
|
||||
fn ensureJsonPath(allocator: std.mem.Allocator, path: []const u8) !ResolvedPath {
|
||||
if (endsWithIgnoreCase(path, ".json")) {
|
||||
return .{ .path = path, .owned = false };
|
||||
}
|
||||
const joined = try std.mem.concat(allocator, u8, &.{ path, ".json" });
|
||||
return .{ .path = joined, .owned = true };
|
||||
}
|
||||
|
||||
fn endsWithIgnoreCase(haystack: []const u8, needle: []const u8) bool {
|
||||
if (haystack.len < needle.len) return false;
|
||||
return std.ascii.eqlIgnoreCase(haystack[haystack.len - needle.len ..], needle);
|
||||
}
|
||||
Reference in New Issue
Block a user