apprt: begin transition to making actions an enum and not use hasDecl

This commit is contained in:
Mitchell Hashimoto
2024-09-25 11:01:35 -07:00
parent fade882574
commit 13603c51a9
4 changed files with 62 additions and 17 deletions

View File

@ -241,19 +241,17 @@ fn redrawInspector(self: *App, rt_app: *apprt.App, surface: *apprt.Surface) !voi
/// Create a new window
pub fn newWindow(self: *App, rt_app: *apprt.App, msg: Message.NewWindow) !void {
if (!@hasDecl(apprt.App, "newWindow")) {
log.warn("newWindow is not supported by this runtime", .{});
return;
}
const target: apprt.Target = target: {
const parent = msg.parent orelse break :target .app;
if (self.hasSurface(parent)) break :target .{ .surface = parent };
break :target .app;
};
const parent = if (msg.parent) |parent| parent: {
break :parent if (self.hasSurface(parent))
parent
else
null;
} else null;
try rt_app.newWindow(parent);
try rt_app.performAction(
target,
.new_window,
{},
);
}
/// Start quitting

View File

@ -12,6 +12,7 @@ const std = @import("std");
const builtin = @import("builtin");
const build_config = @import("build_config.zig");
const action = @import("apprt/action.zig");
const structs = @import("apprt/structs.zig");
pub const glfw = @import("apprt/glfw.zig");
@ -21,6 +22,9 @@ pub const browser = @import("apprt/browser.zig");
pub const embedded = @import("apprt/embedded.zig");
pub const surface = @import("apprt/surface.zig");
pub const Action = action.Action;
pub const Target = action.Target;
pub const ContentScale = structs.ContentScale;
pub const Clipboard = structs.Clipboard;
pub const ClipboardRequest = structs.ClipboardRequest;
@ -84,4 +88,6 @@ pub const Runtime = enum {
test {
_ = Runtime;
_ = runtime;
_ = action;
_ = structs;
}

29
src/apprt/action.zig Normal file
View File

@ -0,0 +1,29 @@
const std = @import("std");
const assert = std.debug.assert;
const CoreSurface = @import("../Surface.zig");
/// The possible actions an apprt has to react to.
pub const Action = union(enum) {
new_window,
/// The enum of keys in the tagged union.
pub const Key = @typeInfo(Action).Union.tag_type.?;
/// Returns the value type for the given key.
pub fn Value(comptime key: Key) type {
inline for (@typeInfo(Action).Union.fields) |field| {
const field_key = @field(Key, field.name);
if (field_key == key) return field.type;
}
unreachable;
}
};
/// The target for an action. This is generally the thing that had focus
/// while the action was made but the concept of "focus" is not guaranteed
/// since actions can also be triggered by timers, scripts, etc.
pub const Target = union(enum) {
app,
surface: *CoreSurface,
};

View File

@ -127,6 +127,23 @@ pub const App = struct {
glfw.postEmptyEvent();
}
/// Perform a given action.
pub fn performAction(
self: *App,
target: apprt.Target,
comptime action: apprt.Action.Key,
value: apprt.Action.Value(action),
) !void {
_ = value;
switch (action) {
.new_window => _ = try self.newSurface(switch (target) {
.app => null,
.surface => |v| v,
}),
}
}
/// Open the configuration in the system editor.
pub fn openConfig(self: *App) !void {
try configpkg.edit.open(self.app.alloc);
@ -195,11 +212,6 @@ pub const App = struct {
win.setMonitor(monitor, 0, 0, video_mode.getWidth(), video_mode.getHeight(), 0);
}
/// Create a new window for the app.
pub fn newWindow(self: *App, parent_: ?*CoreSurface) !void {
_ = try self.newSurface(parent_);
}
/// Create a new tab in the parent surface.
fn newTab(self: *App, parent: *CoreSurface) !void {
if (!Darwin.enabled) {