From ca32edc7e27db1b2a3adfa8407a99837b8c6568f Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+ttytm@users.noreply.github.com> Date: Fri, 18 Oct 2024 15:02:42 +0200 Subject: [PATCH] feat!: refine API for initial public release --- examples/build.zig | 6 +++--- examples/build.zig.zon | 4 ++-- examples/src/main.zig | 27 ++++++++++++++++--------- src/lib.zig | 46 +++++++++++++++--------------------------- 4 files changed, 39 insertions(+), 44 deletions(-) diff --git a/examples/build.zig b/examples/build.zig index eaa403a..4c0987e 100644 --- a/examples/build.zig +++ b/examples/build.zig @@ -4,18 +4,18 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const dep = b.dependency("os_open", .{ + const dep = b.dependency("osdialog", .{ .target = target, .optimize = optimize, }); const exe = b.addExecutable(.{ - .name = "os_open-examples", + .name = "osdialog-examples", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); - exe.root_module.addImport("os_open", dep.module("os_open")); + exe.root_module.addImport("osdialog", dep.module("osdialog")); b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); diff --git a/examples/build.zig.zon b/examples/build.zig.zon index 1e4d495..38696fd 100644 --- a/examples/build.zig.zon +++ b/examples/build.zig.zon @@ -1,8 +1,8 @@ .{ - .name = "os_open-examples", + .name = "osdialog-examples", .version = "0.0.0", .dependencies = .{ - .os_open = .{ .path = "../" }, + .osdialog = .{ .path = "../" }, }, .paths = .{ "build.zig", diff --git a/examples/src/main.zig b/examples/src/main.zig index 63bf231..b7637b7 100644 --- a/examples/src/main.zig +++ b/examples/src/main.zig @@ -1,22 +1,31 @@ const std = @import("std"); -const open = @import("os_open"); +const osd = @import("osdialog"); pub fn main() void { - _ = open.message("Hello, World!", .{}); - if (!open.message("Do you want to continue?", .{ .buttons = .yes_no })) { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer _ = gpa.deinit(); + + _ = osd.message("Hello, World!", .{}); + if (!osd.message("Do you want to continue?", .{ .buttons = .yes_no })) { std.process.exit(0); } - if (open.prompt("Give me some input", .{})) |input| { + if (osd.prompt(allocator, "Give me some input", .{})) |input| { + defer allocator.free(input); std.debug.print("Input: {s}\n", .{input}); } - if (open.colorPicker(.{ .color = .{ .r = 247, .g = 163, .b = 29, .a = 255 } })) |selected| { + if (osd.color(.{ .color = .{ .r = 247, .g = 163, .b = 29, .a = 255 } })) |selected| { std.debug.print("Color RRR,GGG,BBB,AAA: {d},{d},{d},{d}\n", .{ selected.r, selected.g, selected.b, selected.a }); } - if (open.filePath(.{})) |path| { - std.debug.print("Selected File: {s}\n", .{path}); + if (osd.path(allocator, .open, .{})) |path| { + defer allocator.free(path); + std.debug.print("Selected file: {s}\n", .{path}); + } + if (osd.path(allocator, .open_dir, .{})) |path| { + defer allocator.free(path); } - if (open.savePath(.{ .path = ".", .filename = "myfile.txt" })) |path| { + if (osd.path(allocator, .save, .{ .path = ".", .filename = "myfile.txt" })) |path| { + defer allocator.free(path); std.debug.print("Save location: {s}\n", .{path}); } - _ = open.dirPath(.{}); } diff --git a/src/lib.zig b/src/lib.zig index f22fa45..d6b6f8c 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -4,9 +4,16 @@ const osdialog_color = extern struct { r: u8, g: u8, b: u8, a: u8 }; const osdialog_filters = extern struct {}; extern fn osdialog_message(level: c_int, buttons: c_int, message: [*c]const u8) c_int; -extern fn osdialog_prompt(level: c_int, message: [*c]const u8, text: [*c]const u8) [*c]const u8; +extern fn osdialog_prompt(level: c_int, message: [*c]const u8, text: [*c]const u8) [*c]u8; extern fn osdialog_color_picker(color: *osdialog_color, opacity: c_int) c_int; -extern fn osdialog_file(action: c_int, path: [*c]const u8, filename: [*c]const u8, filters: ?*osdialog_filters) [*c]const u8; +extern fn osdialog_file(action: c_int, path: [*c]const u8, filename: [*c]const u8, filters: ?*osdialog_filters) [*c]u8; + +fn toZString(allocator: std.mem.Allocator, c_str_opt: ?[*c]u8) ?[:0]u8 { + const c_string = c_str_opt orelse return null; + defer std.c.free(c_string); + const z_string: [:0]u8 = std.mem.span(c_string); + return allocator.dupeZ(u8, z_string) catch return null; +} pub const Buttons = enum { ok, @@ -41,17 +48,10 @@ pub const ColorPickerOptions = struct { opacity: bool = true, }; -pub const OpenPathOptions = struct { +pub const PathOptions = struct { /// The initial path the dialog will attempt to open in. path: [*:0]const u8 = "", - // TODO: - filters: ?*osdialog_filters = null, -}; - -pub const SavePathOptions = struct { - /// The initial path the dialog will attempt to open in. - path: [*:0]const u8 = "", - /// The initial path the dialog will attempt to open in. + /// The initial filename in the input field. filename: [*:0]const u8 = "", // TODO: filters: ?*osdialog_filters = null, @@ -63,33 +63,19 @@ pub fn message(text: [*:0]const u8, opts: MessageOptions) bool { } /// Opens an input prompt with an "OK" and "Cancel" button. -pub fn prompt(text: [*:0]const u8, opts: PromptOptions) ?[*:0]const u8 { - return osdialog_prompt(@intFromEnum(opts.level), text, opts.text); +pub fn prompt(allocator: std.mem.Allocator, text: [*:0]const u8, opts: PromptOptions) ?[:0]u8 { + return toZString(allocator, osdialog_prompt(@intFromEnum(opts.level), text, opts.text)); } /// Opens an RGBA color picker dialog and returns the selected `Color` or `null` /// if the selection was canceled. The argument takes optional fields that allow /// to set the inital `color` and to disable the `opacity` on unix-like systems. -pub fn colorPicker(options: ColorPickerOptions) ?Color { +pub fn color(options: ColorPickerOptions) ?Color { var col = options.color; return if (osdialog_color_picker(&col, @intFromBool(options.opacity)) == 1) col else null; } -fn fileDialog(action: enum { open, open_dir, save }, path: [*:0]const u8, filename: [*:0]const u8) ?[*:0]const u8 { - return osdialog_file(@intFromEnum(action), path, filename, null); -} - -/// Opens a file dialog and returns the selected path or `null` if the selection was canceled. -pub fn filePath(options: OpenPathOptions) ?[*:0]const u8 { - return fileDialog(.open, options.path, ""); -} - -/// Opens a file dialog and returns the selected path or `null` if the selection was canceled. -pub fn dirPath(options: OpenPathOptions) ?[*:0]const u8 { - return fileDialog(.open_dir, options.path, ""); -} - /// Opens a file dialog and returns the selected path or `null` if the selection was canceled. -pub fn savePath(options: SavePathOptions) ?[*:0]const u8 { - return fileDialog(.save, options.path, options.filename); +pub fn path(allocator: std.mem.Allocator, action: enum { open, open_dir, save }, options: PathOptions) ?[:0]u8 { + return toZString(allocator, osdialog_file(@intFromEnum(action), options.path, options.filename, null)); }