diff --git a/src/tui/Menu.zig b/src/tui/Menu.zig index 331c2933..d7f8bfed 100644 --- a/src/tui/Menu.zig +++ b/src/tui/Menu.zig @@ -186,7 +186,14 @@ pub fn State(ctx_type: type) type { } pub fn walk(self: *Self, walk_ctx: *anyopaque, f: Widget.WalkFn) bool { - return self.menu.walk(walk_ctx, f, if (self.frame_widget) |*frame| frame else &self.container_widget); + for (self.menu.widgets.items) |*w| + if (w.widget.walk(walk_ctx, f)) + return true; + + return if (self.frame_widget) |frame| + frame.walk(walk_ctx, f) + else + self.container_widget.walk(walk_ctx, f); } pub fn count(self: *Self) usize { diff --git a/src/tui/Widget.zig b/src/tui/Widget.zig index e298fb52..6db55a94 100644 --- a/src/tui/Widget.zig +++ b/src/tui/Widget.zig @@ -21,7 +21,7 @@ vtable: *const VTable, const Self = @This(); -pub const WalkFn = *const fn (ctx: *anyopaque, w: *Self) bool; +pub const WalkFn = *const fn (ctx: *anyopaque, w: Self) bool; pub const Direction = enum { horizontal, vertical }; pub const Layout = union(enum) { @@ -51,8 +51,8 @@ pub const VTable = struct { layout: *const fn (ctx: *anyopaque) Layout, subscribe: *const fn (ctx: *anyopaque, h: EventHandler) error{NotSupported}!void, unsubscribe: *const fn (ctx: *anyopaque, h: EventHandler) error{NotSupported}!void, - get: *const fn (ctx: *const anyopaque, name_: []const u8) ?*const Self, - walk: *const fn (ctx: *anyopaque, walk_ctx: *anyopaque, f: WalkFn, self_widget: *Self) bool, + get: *const fn (ctx: *const anyopaque, name_: []const u8) ?Self, + walk: *const fn (ctx: *anyopaque, walk_ctx: *anyopaque, f: WalkFn) bool, focus: *const fn (ctx: *anyopaque) void, unfocus: *const fn (ctx: *anyopaque) void, hover: *const fn (ctx: *const anyopaque) bool, @@ -134,13 +134,13 @@ pub fn to(pimpl: anytype) Self { } }.unsubscribe, .get = struct { - pub fn get(ctx: *const anyopaque, name_: []const u8) ?*const Self { + pub fn get(ctx: *const anyopaque, name_: []const u8) ?Self { return if (comptime @hasDecl(child, "get")) child.get(@as(*const child, @ptrCast(@alignCast(ctx))), name_) else null; } }.get, .walk = struct { - pub fn walk(ctx: *anyopaque, walk_ctx: *anyopaque, f: WalkFn, self: *Self) bool { - return if (comptime @hasDecl(child, "walk")) child.walk(@as(*child, @ptrCast(@alignCast(ctx))), walk_ctx, f, self) else false; + pub fn walk(ctx: *anyopaque, walk_ctx: *anyopaque, f: WalkFn) bool { + return if (comptime @hasDecl(child, "walk")) child.walk(@as(*child, @ptrCast(@alignCast(ctx))), walk_ctx, f) else false; } }.walk, .focus = struct { @@ -225,16 +225,16 @@ pub fn unsubscribe(self: Self, h: EventHandler) !void { return self.vtable.unsubscribe(self.ptr, h); } -pub fn get(self: *const Self, name_: []const u8) ?*const Self { +pub fn get(self: *const Self, name_: []const u8) ?Self { var buf: [256]u8 = undefined; return if (std.mem.eql(u8, self.plane.name(&buf), name_)) - self + self.* else self.vtable.get(self.ptr, name_); } -pub fn walk(self: *Self, walk_ctx: *anyopaque, f: WalkFn) bool { - return if (self.vtable.walk(self.ptr, walk_ctx, f, self)) true else f(walk_ctx, self); +pub fn walk(self: *const Self, walk_ctx: *anyopaque, f: WalkFn) bool { + return if (self.vtable.walk(self.ptr, walk_ctx, f)) true else f(walk_ctx, self.*); } pub fn focus(self: *Self) void { @@ -300,12 +300,12 @@ pub fn empty(allocator: Allocator, parent: Plane, layout_: Layout) !Self { } }.unsubscribe, .get = struct { - pub fn get(_: *const anyopaque, _: []const u8) ?*const Self { + pub fn get(_: *const anyopaque, _: []const u8) ?Self { return null; } }.get, .walk = struct { - pub fn walk(_: *anyopaque, _: *anyopaque, _: WalkFn, _: *Self) bool { + pub fn walk(_: *anyopaque, _: *anyopaque, _: WalkFn) bool { return false; } }.walk, diff --git a/src/tui/WidgetList.zig b/src/tui/WidgetList.zig index 91c38aaa..69304845 100644 --- a/src/tui/WidgetList.zig +++ b/src/tui/WidgetList.zig @@ -115,7 +115,7 @@ pub fn addP(self: *Self, w_: Widget) !*Widget { return &w.widget; } -pub fn get(self: *const Self, name_: []const u8) ?*const Widget { +pub fn get(self: *const Self, name_: []const u8) ?Widget { for (self.widgets.items) |*w| if (w.widget.get(name_)) |p| return p; @@ -347,10 +347,10 @@ fn do_resize(self: *Self, padding: Widget.Style.Margin) void { } } -pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn, self_w: *Widget) bool { +pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn) bool { for (self.widgets.items) |*w| if (w.widget.walk(ctx, f)) return true; - return f(ctx, self_w); + return f(ctx, Widget.to(self)); } pub fn focus(self: *Self) void { diff --git a/src/tui/editor_gutter.zig b/src/tui/editor_gutter.zig index 4ef2f47c..7f2e2583 100644 --- a/src/tui/editor_gutter.zig +++ b/src/tui/editor_gutter.zig @@ -38,7 +38,7 @@ highlight: bool, symbols: bool, width: usize, editor: *ed.Editor, -editor_widget: ?*const Widget = null, +editor_widget: ?Widget = null, differ: diffz.AsyncDiffer, const Self = @This(); diff --git a/src/tui/filelist_view.zig b/src/tui/filelist_view.zig index 33a7cd4d..ff820e13 100644 --- a/src/tui/filelist_view.zig +++ b/src/tui/filelist_view.zig @@ -107,8 +107,8 @@ pub fn handle_resize(self: *Self, pos: Widget.Box) void { self.update_scrollbar(); } -pub fn walk(self: *Self, walk_ctx: *anyopaque, f: Widget.WalkFn, w: *Widget) bool { - return self.menu.container_widget.walk(walk_ctx, f) or f(walk_ctx, w); +pub fn walk(self: *Self, walk_ctx: *anyopaque, f: Widget.WalkFn) bool { + return self.menu.container_widget.walk(walk_ctx, f) or f(walk_ctx, Widget.to(self)); } pub fn add_item(self: *Self, entry_: Entry) !void { diff --git a/src/tui/home.zig b/src/tui/home.zig index 5fae6c0a..9cdb16f0 100644 --- a/src/tui/home.zig +++ b/src/tui/home.zig @@ -201,8 +201,8 @@ pub fn update(self: *Self) void { self.menu.update(); } -pub fn walk(self: *Self, walk_ctx: *anyopaque, f: Widget.WalkFn, w: *Widget) bool { - return self.menu.walk(walk_ctx, f) or f(walk_ctx, w); +pub fn walk(self: *Self, walk_ctx: *anyopaque, f: Widget.WalkFn) bool { + return self.menu.walk(walk_ctx, f) or f(walk_ctx, Widget.to(self)); } pub fn receive(_: *Self, _: tp.pid_ref, m: tp.message) error{Exit}!bool { diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index 58fb5627..178f7e55 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -1732,8 +1732,8 @@ pub fn get_active_buffer(self: *Self) ?*Buffer { return if (self.get_active_editor()) |editor| editor.buffer orelse null else null; } -pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn, w: *Widget) bool { - return self.floating_views.walk(ctx, f) or self.widgets.walk(ctx, f, &self.widgets_widget) or f(ctx, w); +pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn) bool { + return self.floating_views.walk(ctx, f) or self.widgets.walk(ctx, f) or f(ctx, Widget.to(self)); } fn close_all_editors(self: *Self) !void { @@ -1754,12 +1754,12 @@ fn add_and_activate_view(self: *Self, widget: Widget) !void { _ = try self.widgets_widget.msg(.{"splits_updated"}); } -pub fn find_view_for_widget(self: *Self, w_: *const Widget) ?usize { +pub fn find_view_for_widget(self: *Self, w_: Widget) ?usize { const Ctx = struct { - w: *const Widget, - fn find(ctx_: *anyopaque, w: *Widget) bool { + w: Widget, + fn find(ctx_: *anyopaque, w: Widget) bool { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); - return ctx.w == w; + return ctx.w.ptr == w.ptr; } }; var ctx: Ctx = .{ .w = w_ }; @@ -1768,7 +1768,7 @@ pub fn find_view_for_widget(self: *Self, w_: *const Widget) ?usize { return null; } -pub fn focus_view_by_widget(self: *Self, w: *const Widget) tui.FocusAction { +pub fn focus_view_by_widget(self: *Self, w: Widget) tui.FocusAction { const n = self.find_view_for_widget(w) orelse return .notfound; if (n >= self.views.widgets.items.len) return .notfound; if (n == self.active_view) return .same; diff --git a/src/tui/status/tabs.zig b/src/tui/status/tabs.zig index 2e3f320e..2d76eaf7 100644 --- a/src/tui/status/tabs.zig +++ b/src/tui/status/tabs.zig @@ -286,11 +286,11 @@ pub const TabBar = struct { self.plane = self.splits_list.plane; } - pub fn get(self: *const Self, name: []const u8) ?*const Widget { + pub fn get(self: *const Self, name: []const u8) ?Widget { return self.splits_list_widget.get(name); } - pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn, self_w: *Widget) bool { + pub fn walk(self: *Self, ctx: *anyopaque, f: Widget.WalkFn) bool { for (self.tabs) |*tab| { const clipped, _ = self.is_tab_clipped(tab); if (!clipped) @@ -300,14 +300,14 @@ pub const TabBar = struct { for (split.widgets.items) |*widget_state| if (widget_state.widget.dynamic_cast(drop_target.ButtonType)) |_| { if (widget_state.widget.walk(ctx, f)) return true; }; - return f(ctx, self_w); + return f(ctx, Widget.to(self)); } pub fn hover(self: *Self) bool { return self.splits_list_widget.hover(); } - fn update_tabs(self: *Self, drag_source: ?*Widget) !void { + fn update_tabs(self: *Self, drag_source: ?Widget) !bool { const buffers_changed = try self.update_tab_buffers(); const dragging = for (self.tabs) |*tab| { if (tab.widget.dynamic_cast(Tab.ButtonType)) |btn| diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 4ba86c09..408ff074 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -54,12 +54,12 @@ input_mode_outer_: ?Mode = null, input_listeners_: EventHandler.List, keyboard_focus: ?Widget = null, mini_mode_: ?MiniMode = null, -hover_focus: ?*Widget = null, +hover_focus: ?Widget = null, last_hover_x: c_int = -1, last_hover_y: c_int = -1, commands: Commands = undefined, logger: log.Logger, -drag_source: ?*Widget = null, +drag_source: ?Widget = null, drag_button: input.MouseType = 0, dark_theme: Widget.Theme, dark_parsed_theme: ?std.json.Parsed(Widget.Theme), @@ -787,12 +787,12 @@ fn handle_system_clipboard(self: *Self, text: []const u8) !void { return command.executeName("paste", command.fmt(.{text})); } -fn find_coord_widget(self: *Self, y: usize, x: usize) ?*Widget { +fn find_coord_widget(self: *Self, y: usize, x: usize) ?Widget { const Ctx = struct { - widget: ?*Widget = null, + widget: ?Widget = null, y: usize, x: usize, - fn find(ctx_: *anyopaque, w: *Widget) bool { + fn find(ctx_: *anyopaque, w: Widget) bool { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); if (w.box().is_abs_coord_inside(ctx.y, ctx.x)) { ctx.widget = w; @@ -810,12 +810,12 @@ pub fn is_abs_coord_in_widget(w: *const Widget, y: usize, x: usize) bool { return w.box().is_abs_coord_inside(y, x); } -fn is_live_widget_ptr(self: *Self, w_: *Widget) bool { +fn is_live_widget_ptr(self: *Self, w_: Widget) bool { const Ctx = struct { - w: *Widget, - fn find(ctx_: *anyopaque, w: *Widget) bool { + w: Widget, + fn find(ctx_: *anyopaque, w: Widget) bool { const ctx = @as(*@This(), @ptrCast(@alignCast(ctx_))); - return ctx.w == w; + return ctx.w.ptr == w.ptr; } }; var ctx: Ctx = .{ .w = w_ }; @@ -824,7 +824,7 @@ fn is_live_widget_ptr(self: *Self, w_: *Widget) bool { pub const FocusAction = enum { same, changed, notfound }; -pub fn set_focus_by_widget(w: *const Widget) FocusAction { +pub fn set_focus_by_widget(w: Widget) FocusAction { const mv = mainview() orelse return .notfound; return mv.focus_view_by_widget(w); } @@ -869,12 +869,12 @@ fn send_mouse_drag(self: *Self, y: c_int, x: c_int, from: tp.pid_ref, m: tp.mess if (self.drag_source) |w| _ = try w.send(from, m); } -fn update_hover(self: *Self, y: c_int, x: c_int) !?*Widget { +fn update_hover(self: *Self, y: c_int, x: c_int) !?Widget { self.last_hover_y = y; self.last_hover_x = x; if (y >= 0 and x >= 0) if (self.find_coord_widget(@intCast(y), @intCast(x))) |w| { - if (if (self.hover_focus) |h| h != w else true) { - tp.trace(tp.channel.debug, .{ "update_hover", if (self.hover_focus) |h| @intFromPtr(h) else 0, @intFromPtr(w) }); + if (if (self.hover_focus) |h| h.ptr != w.ptr else true) { + tp.trace(tp.channel.debug, .{ "update_hover", if (self.hover_focus) |h| @as(u64, @intFromPtr(h.ptr)) else 0, @as(u64, @intFromPtr(w.ptr)) }); if (self.hover_focus) |h| if (self.is_live_widget_ptr(h)) try send_hover_msg(h, false); self.hover_focus = w; @@ -889,19 +889,19 @@ fn update_hover(self: *Self, y: c_int, x: c_int) !?*Widget { fn clear_hover_focus(self: *Self, src: std.builtin.SourceLocation) tp.result { if (self.hover_focus) |h| if (self.is_live_widget_ptr(h)) try send_hover_msg(h, false); - tp.trace(tp.channel.debug, .{ "tui", "clear_hover_focus", if (self.hover_focus) |h| @intFromPtr(h) else 0, src.fn_name, src.file, src.line }); + tp.trace(tp.channel.debug, .{ "tui", "clear_hover_focus", if (self.hover_focus) |h| @intFromPtr(h.ptr) else 0, src.fn_name, src.file, src.line }); self.hover_focus = null; } -fn send_hover_msg(widget: *const Widget, hover: bool) tp.result { +fn send_hover_msg(widget: Widget, hover: bool) tp.result { var buf: [256]u8 = undefined; - tp.trace(tp.channel.debug, .{ "hover_msg", @intFromPtr(widget), hover }); + tp.trace(tp.channel.debug, .{ "hover_msg", @intFromPtr(widget.ptr), hover }); _ = try widget.send(tp.self_pid(), tp.message.fmtbuf(&buf, .{ "H", hover }) catch |e| return tp.exit_error(e, @errorReturnTrace())); } pub fn refresh_hover(src: std.builtin.SourceLocation) void { const self = current(); - tp.trace(tp.channel.debug, .{ "tui", "refresh_hover", if (self.hover_focus) |h| @intFromPtr(h) else 0, src.fn_name, src.file, src.line }); + tp.trace(tp.channel.debug, .{ "tui", "refresh_hover", if (self.hover_focus) |h| @intFromPtr(h.ptr) else 0, src.fn_name, src.file, src.line }); _ = self.update_hover(self.last_hover_y, self.last_hover_x) catch {}; } @@ -1906,18 +1906,18 @@ pub fn get_keybind_mode() ?Mode { return self.input_mode_ orelse self.delayed_init_input_mode; } -pub fn update_drag_source(drag_source: *Widget, btn: input.MouseType) void { +pub fn update_drag_source(drag_source: Widget, btn: input.MouseType) void { const self = current(); self.drag_source = drag_source; self.drag_button = btn; } -fn set_drag_source(self: *Self, drag_source: ?*Widget, btn: input.MouseType) void { +fn set_drag_source(self: *Self, drag_source: ?Widget, btn: input.MouseType) void { self.drag_source = drag_source; self.drag_button = btn; } -pub fn get_drag_source() struct { ?*Widget, input.MouseType } { +pub fn get_drag_source() struct { ?Widget, input.MouseType } { const self = current(); return .{ self.drag_source, self.drag_button }; }