diff --git a/src/tui/mainview.zig b/src/tui/mainview.zig index f395d05..0f7d9d3 100644 --- a/src/tui/mainview.zig +++ b/src/tui/mainview.zig @@ -189,16 +189,24 @@ pub fn update(self: *Self) void { self.floating_views.update(); } -pub fn update_panes_layout(self: *Self) !void { - while (self.panes.pop()) |widget| if (widget.dynamic_cast(WidgetList) == null) - widget.deinit(self.allocator); - const centered_view_width = tui.config().centered_view_width; +pub fn is_view_centered(self: *const Self) bool { + const conf = tui.config(); + const centered_view_width = conf.centered_view_width; const screen_width = tui.screen().w; const need_padding = screen_width > centered_view_width; const have_vsplits = self.views.widgets.items.len > 1; - const have_min_screen_width = screen_width > tui.config().centered_view_min_screen_width; - const centered_view = need_padding and tui.config().centered_view and !have_vsplits and have_min_screen_width; - if (centered_view) { + const have_min_screen_width = screen_width > conf.centered_view_min_screen_width; + const centered_view = need_padding and conf.centered_view and !have_vsplits and have_min_screen_width; + return centered_view; +} + +pub fn update_panes_layout(self: *Self) !void { + while (self.panes.pop()) |widget| if (widget.dynamic_cast(WidgetList) == null) + widget.deinit(self.allocator); + if (self.is_view_centered()) { + const conf = tui.config(); + const centered_view_width = conf.centered_view_width; + const screen_width = tui.screen().w; const padding = (screen_width - centered_view_width) / 2; try self.panes.add(try self.create_padding_pane(padding, .pane_left)); try self.panes.add(self.views_widget); diff --git a/src/tui/mode/overlay/palette.zig b/src/tui/mode/overlay/palette.zig index 89d1866..9e1dcc5 100644 --- a/src/tui/mode/overlay/palette.zig +++ b/src/tui/mode/overlay/palette.zig @@ -22,6 +22,12 @@ pub const Menu = @import("../../Menu.zig"); const max_menu_width = 80; const widget_type: Widget.Type = .palette; +pub const Placement = enum { + top_center, + top_left, + top_right, +}; + pub fn Create(options: type) type { return struct { allocator: std.mem.Allocator, @@ -35,6 +41,7 @@ pub fn Create(options: type) type { entries: std.ArrayList(Entry) = undefined, longest_hint: usize = 0, initial_selected: ?usize = null, + placement: Placement, items: usize = 0, view_rows: usize, @@ -64,6 +71,13 @@ pub fn Create(options: type) type { .modal = try ModalBackground.create(*Self, allocator, tui.mainview_widget(), .{ .ctx = self, .on_click = mouse_palette_menu_cancel, + .on_render = if (@hasDecl(options, "modal_dim")) + if (options.modal_dim) + ModalBackground.Options(*Self).on_render_dim + else + ModalBackground.Options(*Self).on_render_default + else + ModalBackground.Options(*Self).on_render_default, }), .menu = try Menu.create(*Self, allocator, tui.plane(), .{ .ctx = self, @@ -87,6 +101,7 @@ pub fn Create(options: type) type { .mode = try keybind.mode("overlay/palette", allocator, .{ .insert_command = "overlay_insert_bytes", }), + .placement = if (@hasDecl(options, "placement")) options.placement else .top_center, }; try self.commands.init(self); self.mode.event_handler = EventHandler.to_owned(self); @@ -176,13 +191,43 @@ pub fn Create(options: type) type { fn prepare_resize(self: *Self) Widget.Box { const screen = tui.screen(); - const w = @max(@min(self.longest + 3, max_menu_width) + 2 + self.longest_hint, options.label.len + 2); - const x = if (screen.w > w) (screen.w - w) / 2 else 0; + const w = self.prepare_width(); + return switch (self.placement) { + .top_center => self.prepare_resize_top_center(screen, w), + .top_left => self.prepare_resize_top_left(screen, w), + .top_right => self.prepare_resize_top_right(screen, w), + }; + } + + fn prepare_width(self: *Self) usize { + return @max(@min(self.longest + 3, max_menu_width) + 2 + self.longest_hint, options.label.len + 2); + } + + fn prepare_resize_at_x(self: *Self, screen: Widget.Box, w: usize, x: usize) Widget.Box { self.view_rows = get_view_rows(screen); const h = @min(self.items + self.menu.header_count, self.view_rows + self.menu.header_count); return .{ .y = 0, .x = x, .w = w, .h = h }; } + fn prepare_resize_top_center(self: *Self, screen: Widget.Box, w: usize) Widget.Box { + const x = if (screen.w > w) (screen.w - w) / 2 else 0; + return self.prepare_resize_at_x(screen, w, x); + } + + fn prepare_resize_top_left(self: *Self, screen: Widget.Box, w: usize) Widget.Box { + return self.prepare_resize_at_x(screen, w, 0); + } + + fn prepare_resize_top_right(self: *Self, screen: Widget.Box, w: usize) Widget.Box { + const x = if (screen.w > w) (screen.w - w) else 0; + if (tui.mainview()) |mv| if (mv.is_view_centered()) { + const centered_view_width = tui.config().centered_view_width; + const right_edge = ((screen.w - centered_view_width) / 2) + centered_view_width; + return self.prepare_resize_at_x(screen, w, @min(x, right_edge)); + }; + return self.prepare_resize_at_x(screen, w, x); + } + fn after_resize_menu(self: *Self, _: *Menu.State(*Self), _: Widget.Box) void { return self.after_resize(); } diff --git a/src/tui/mode/overlay/symbol_palette.zig b/src/tui/mode/overlay/symbol_palette.zig index 3055bbd..21f3965 100644 --- a/src/tui/mode/overlay/symbol_palette.zig +++ b/src/tui/mode/overlay/symbol_palette.zig @@ -19,6 +19,8 @@ pub const label = "Go to Symbol"; pub const name = "Go to"; pub const description = "Symbols in scope"; pub const icon = "󱎸 "; +pub const modal_dim = false; +pub const placement = .top_right; const Column = struct { label: []const u8,