diff --git a/src/tui/Menu.zig b/src/tui/Menu.zig index 813051c..601c4e3 100644 --- a/src/tui/Menu.zig +++ b/src/tui/Menu.zig @@ -60,7 +60,7 @@ pub fn Options(context: type) type { pub fn create(ctx_type: type, allocator: std.mem.Allocator, parent: Plane, opts: Options(ctx_type)) !*State(ctx_type) { const self = try allocator.create(State(ctx_type)); errdefer allocator.destroy(self); - const container = try WidgetList.createHStyled(allocator, parent, @typeName(@This()), .dynamic, Widget.Style.boxed); + const container = try WidgetList.createHStyled(allocator, parent, @typeName(@This()), .dynamic, Widget.Style.thick_boxed); self.* = .{ .allocator = allocator, .menu = try WidgetList.createV(allocator, container.plane, @typeName(@This()), .dynamic), diff --git a/src/tui/Widget.zig b/src/tui/Widget.zig index 7de2347..0aff980 100644 --- a/src/tui/Widget.zig +++ b/src/tui/Widget.zig @@ -67,11 +67,22 @@ pub const Style = struct { const @"0": Margin = .{ .top = 0, .bottom = 0, .left = 0, .right = 0 }; const @"1": Margin = .{ .top = 1, .bottom = 1, .left = 1, .right = 1 }; const @"2": Margin = .{ .top = 2, .bottom = 2, .left = 2, .right = 2 }; + const @"3": Margin = .{ .top = 3, .bottom = 3, .left = 3, .right = 3 }; + const @"1/2": Margin = .{ .top = 1, .bottom = 1, .left = 2, .right = 1 }; + const @"2/3": Margin = .{ .top = 2, .bottom = 2, .left = 3, .right = 2 }; + const @"2/4": Margin = .{ .top = 2, .bottom = 2, .left = 4, .right = 3 }; + + const top_bottom_1: Margin = .{ .top = 1, .bottom = 1, .left = 0, .right = 0 }; + const top_bottom_2: Margin = .{ .top = 2, .bottom = 2, .left = 0, .right = 0 }; + const left_right_1: Margin = .{ .top = 0, .bottom = 0, .left = 1, .right = 1 }; + const left_right_2: Margin = .{ .top = 0, .bottom = 0, .left = 2, .right = 2 }; }; pub const borders = struct { const blank: Border = .{ .nw = " ", .n = " ", .ne = " ", .e = " ", .se = " ", .s = " ", .sw = " ", .w = " " }; const box: Border = .{ .nw = "┌", .n = "─", .ne = "┐", .e = "│", .se = "┘", .s = "─", .sw = "└", .w = "│" }; + const thick_box: Border = .{ .nw = "▛", .n = "▀", .ne = "▜", .e = "▐", .se = "▟", .s = "▄", .sw = "▙", .w = "▌" }; + const thick_box_sextant: Border = .{ .nw = "🬕", .n = "🬂", .ne = "🬨", .e = "▐", .se = "🬷", .s = "🬭", .sw = "🬲", .w = "▌" }; }; pub const default_static: @This() = .{}; @@ -82,6 +93,24 @@ pub const Style = struct { .border = borders.box, }; pub const boxed = &boxed_static; + + pub const thick_boxed_static: @This() = .{ + .padding = margins.@"1/2", + .border = borders.thick_box_sextant, + }; + pub const thick_boxed = &thick_boxed_static; + + pub const bars_top_bottom_static: @This() = .{ + .padding = margins.top_bottom_1, + .border = borders.thick_box, + }; + pub const bars_top_bottom = &bars_top_bottom_static; + + pub const bars_left_right_static: @This() = .{ + .padding = margins.left_right_1, + .border = borders.box, + }; + pub const bars_left_right = &bars_left_right_static; }; pub const VTable = struct { diff --git a/src/tui/WidgetList.zig b/src/tui/WidgetList.zig index 4acfc3b..dceaf09 100644 --- a/src/tui/WidgetList.zig +++ b/src/tui/WidgetList.zig @@ -172,11 +172,17 @@ pub fn render(self: *Self, theme: *const Widget.Theme) bool { self.on_render(self.ctx, theme); self.render_decoration(theme); + const client_box = self.to_client_box(self.deco_box); + var more = false; - for (self.widgets.items) |*w| + for (self.widgets.items) |*w| { + const widget_box = w.widget.box(); + if (client_box.y + client_box.h <= widget_box.y) break; + if (client_box.x + client_box.w <= widget_box.x) break; if (w.widget.render(theme)) { more = true; - }; + } + } self.after_render(self.ctx, theme); return more; @@ -192,6 +198,7 @@ fn render_decoration(self: *Self, theme: *const Widget.Theme) void { const border = self.style.border; plane.set_style(style); + plane.fill(" "); if (padding.top > 0 and padding.left > 0) put_at_pos(plane, 0, 0, border.nw); if (padding.top > 0 and padding.right > 0) put_at_pos(plane, 0, box.w - 1, border.ne); @@ -316,7 +323,7 @@ inline fn from_client_box(self: *const Self, box_: Widget.Box) Widget.Box { const total_y_padding = padding.top + padding.bottom; const total_x_padding = padding.left + padding.right; const y = if (box_.y < padding.top) padding.top else box_.y; - const x = if (box_.x < padding.left) padding.top else box_.x; + const x = if (box_.x < padding.left) padding.left else box_.x; var box = box_; box.y = y - padding.top; box.h += total_y_padding; diff --git a/src/tui/filelist_view.zig b/src/tui/filelist_view.zig index 6f4e824..cc1e289 100644 --- a/src/tui/filelist_view.zig +++ b/src/tui/filelist_view.zig @@ -33,6 +33,7 @@ view_rows: usize = 0, view_cols: usize = 0, entries: std.ArrayList(Entry) = undefined, selected: ?usize = null, +box: Widget.Box = .{}, const path_column_ratio = 4; @@ -86,9 +87,11 @@ fn scrollbar_style(sb: *scrollbar_v, theme: *const Widget.Theme) Widget.Theme.St pub fn handle_resize(self: *Self, pos: Widget.Box) void { self.plane.move_yx(@intCast(pos.y), @intCast(pos.x)) catch return; self.plane.resize_simple(@intCast(pos.h), @intCast(pos.w)) catch return; - self.menu.container_widget.resize(pos); - self.view_rows = pos.h; - self.view_cols = pos.w; + self.box = pos; + self.menu.container.resize(self.box); + const client_box = self.menu.container.to_client_box(pos); + self.view_rows = client_box.h; + self.view_cols = client_box.w; self.update_scrollbar(); } @@ -107,7 +110,7 @@ pub fn add_item(self: *Self, entry_: Entry) !void { const writer = label.writer(); cbor.writeValue(writer, idx) catch return; self.menu.add_item_with_handler(label.items, handle_menu_action) catch return; - self.menu.container_widget.resize(Widget.Box.from(self.plane)); + self.menu.resize(self.box); self.update_scrollbar(); } diff --git a/src/tui/home.zig b/src/tui/home.zig index e00a16a..ae8f267 100644 --- a/src/tui/home.zig +++ b/src/tui/home.zig @@ -145,7 +145,7 @@ fn add_menu_command(self: *Self, command_name: []const u8, description: []const _ = try writer.write(leader); try writer.print(" :{s}", .{hint}); const label = fis.getWritten(); - self.menu_w = @max(self.menu_w, label.len + 1); + self.menu_w = @max(self.menu_w, label.len + 1 + menu.container.style.padding.left + menu.container.style.padding.right); } var value = std.ArrayList(u8).init(self.allocator);