diff --git a/src/tui/keyhints.zig b/src/tui/keyhints.zig index e65b674..268ec1d 100644 --- a/src/tui/keyhints.zig +++ b/src/tui/keyhints.zig @@ -8,51 +8,70 @@ const Widget = @import("Widget.zig"); const widget_type: Widget.Type = .hint_window; -pub fn render_current_key_event_sequence(allocator: std.mem.Allocator, theme: *const Widget.Theme) void { +pub fn render_current_input_mode(allocator: std.mem.Allocator, select_mode: keybind.SelectMode, theme: *const Widget.Theme) void { const mode = tui.input_mode() orelse return; - const bindings = mode.current_key_event_sequence_bindings(allocator) catch return; + const bindings = mode.current_bindings(allocator, select_mode) catch return; defer allocator.free(bindings); - return render(bindings, theme); + return render(mode.bindings.press.items, theme, .full); } -pub fn render(bindings: []const keybind.Binding, theme: *const Widget.Theme) void { +pub fn render_current_key_event_sequence(allocator: std.mem.Allocator, select_mode: keybind.SelectMode, theme: *const Widget.Theme) void { + const mode = tui.input_mode() orelse return; + const bindings = mode.current_key_event_sequence_bindings(allocator, select_mode) catch return; + defer allocator.free(bindings); + return render(bindings, theme, .no_key_event_prefix); +} + +const RenderMode = enum { full, no_key_event_prefix }; + +pub fn render(bindings: []const keybind.Binding, theme: *const Widget.Theme, mode: RenderMode) void { // return if something is already rendering to the top layer if (tui.have_top_layer()) return; if (bindings.len == 0) return; var key_events_buf: [256]u8 = undefined; - const key_events = blk: { - var writer = std.Io.Writer.fixed(&key_events_buf); - writer.print("{f}", .{keybind.current_key_event_sequence_fmt()}) catch {}; - break :blk writer.buffered(); + const key_events = switch (mode) { + .no_key_event_prefix => blk: { + var writer = std.Io.Writer.fixed(&key_events_buf); + writer.print("{f}", .{keybind.current_key_event_sequence_fmt()}) catch {}; + break :blk writer.buffered(); + }, + .full => &.{}, }; const max_prefix_len = get_max_prefix_len(bindings) - key_events.len; const max_description_len = get_max_description_len(bindings); const max_len = max_prefix_len + max_description_len + 2 + 2; const widget_style = tui.get_widget_style(widget_type); - const scr = tui.screen(); + const max_screen_height = scr.h -| widget_style.padding.top -| widget_style.padding.bottom -| 1; + const max_items = @min(bindings.len, max_screen_height); + var box: Widget.Box = .{ - .h = bindings.len, + .h = max_items, .w = max_len, .x = scr.w -| max_len -| 2 -| widget_style.padding.left -| widget_style.padding.right, - .y = scr.h -| bindings.len -| 1 -| widget_style.padding.top -| widget_style.padding.bottom, + .y = scr.h -| max_items -| 1 -| widget_style.padding.top -| widget_style.padding.bottom, }; const deco_box = box.from_client_box(widget_style.padding); - // reset position for top layer offset - box.x -= deco_box.x; - box.y -= deco_box.y; - const top_layer_ = tui.top_layer(deco_box.to_layer()) orelse return; widget_style.render_decoration(deco_box, widget_type, top_layer_, theme); - // var plane = top_layer_; - var plane = try Plane.init(&(Widget.Box{}).opts(@typeName(@This())), top_layer_.*); - defer plane.deinit(); - plane.resize_simple(@intCast(box.h), @intCast(box.w)) catch return; - plane.move_yx(@intCast(box.y), @intCast(box.x)) catch return; + // workaround vaxis.Layer issue + const top_layer_window = top_layer_.window; + defer { + top_layer_.window.y_off = top_layer_window.y_off; + top_layer_.window.x_off = top_layer_window.x_off; + top_layer_.window.height = top_layer_window.height; + top_layer_.window.width = top_layer_window.width; + } + top_layer_.window.y_off += widget_style.padding.top; + top_layer_.window.x_off += widget_style.padding.left; + top_layer_.window.height -= widget_style.padding.top + widget_style.padding.bottom; + top_layer_.window.width -= widget_style.padding.left + widget_style.padding.right; + + const plane = top_layer_; const style_base = theme.editor_widget; const style_label = theme.editor_widget; @@ -66,6 +85,7 @@ pub fn render(bindings: []const keybind.Binding, theme: *const Widget.Theme) voi plane.set_style(style_hint); for (bindings, 0..) |binding, y| { + if (y >= max_items) break; var keybind_buf: [256]u8 = undefined; const keybind_txt = blk: { var writer = std.Io.Writer.fixed(&keybind_buf); @@ -79,6 +99,7 @@ pub fn render(bindings: []const keybind.Binding, theme: *const Widget.Theme) voi plane.set_style(style_label); for (bindings, 0..) |binding, y| { + if (y >= max_items) break; const padding = max_prefix_len + 2; const description = blk: {