From 8f86718d0f8a7040c80bde64524ebf09757eeb71 Mon Sep 17 00:00:00 2001 From: CJ van den Berg Date: Tue, 5 Aug 2025 20:09:35 +0200 Subject: [PATCH] WIP: feat: add pop up completion list to file browser --- src/tui/mode/mini/file_browser.zig | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/tui/mode/mini/file_browser.zig b/src/tui/mode/mini/file_browser.zig index c47d088..e8f13ec 100644 --- a/src/tui/mode/mini/file_browser.zig +++ b/src/tui/mode/mini/file_browser.zig @@ -13,6 +13,10 @@ const Buffer = @import("Buffer"); const tui = @import("../../tui.zig"); const MessageFilter = @import("../../MessageFilter.zig"); +const Button = @import("../../Button.zig"); +const Menu = @import("../../Menu.zig"); +const ModalBackground = @import("../../ModalBackground.zig"); +const Widget = @import("../../Widget.zig"); const max_complete_paths = 1024; @@ -27,6 +31,8 @@ pub fn Create(options: type) type { total_matches: usize = 0, matched_entry: usize = 0, commands: Commands = undefined, + modal: *ModalBackground.State(*Self), + menu: *Menu.State(*Self), const Commands = command.Collection(cmds); const Self = @This(); @@ -37,6 +43,7 @@ pub fn Create(options: type) type { }; pub fn create(allocator: std.mem.Allocator, _: command.Context) !struct { tui.Mode, tui.MiniMode } { + const mv = tui.mainview() orelse return error.NotFound; const self = try allocator.create(Self); errdefer allocator.destroy(self); self.* = .{ @@ -45,6 +52,11 @@ pub fn Create(options: type) type { .query = std.ArrayList(u8).init(allocator), .match = std.ArrayList(u8).init(allocator), .entries = std.ArrayList(Entry).init(allocator), + .modal = try ModalBackground.create(*Self, allocator, tui.mainview_widget(), .{ .ctx = self }), + .menu = try Menu.create(*Self, allocator, tui.plane(), .{ + .ctx = self, + .on_render = on_render_menu, + }), }; try self.commands.init(self); try tui.message_filters().add(MessageFilter.bind(self, receive_path_entry)); @@ -55,6 +67,9 @@ pub fn Create(options: type) type { .insert_command = "mini_mode_insert_bytes", }); mode.event_handler = EventHandler.to_owned(self); + try mv.floating_views.add(self.modal.widget()); + try mv.floating_views.add(self.menu.container_widget); + return .{ mode, .{ .name = options.name(self) } }; } @@ -353,5 +368,21 @@ pub fn Create(options: type) type { } pub const mini_mode_paste_meta: Meta = .{ .arguments = &.{.string} }; }; + + fn on_render_menu(self: *Self, button: *Button.State(*Menu.State(*Self)), theme: *const Widget.Theme, selected: bool) bool { + const style_base = theme.editor_widget; + const style_label = if (button.active) theme.editor_cursor else if (button.hover or selected) theme.editor_selection else theme.editor_widget; + button.plane.set_base_style(style_base); + button.plane.erase(); + button.plane.home(); + button.plane.set_style(style_label); + message("{d}/{d}", .{ self.matched_entry + 1, self.entries.items.len }); + return false; + } + + inline fn max_menu_width() usize { + const width = tui.screen().w; + return @max(15, width - (width / 5)); + } }; }