const dims = @import("dimensions.zig"); const colors = @import("colors.zig"); const log = @import("log.zig"); const menu = @import("menu.zig"); const pane = @import("pane.zig"); const term = @import("term.zig"); const std = @import("std"); const Pane = pane.Pane; const TermIO = term.TermIO; pub const Tab = struct { name: []const u8, pane: *Pane, }; pub const TabBar = struct { pane: Pane, config: Config, tabs: []Tab, index: usize, const Config = struct { align_text: menu.TextAlignment = .Center, highlight_color: colors.Color, expand_highlight: bool = true, underline: bool = true, }; pub fn create(mem: *TabBar, config: Config, tabs: []Tab) *Pane { mem.config = config; mem.tabs = tabs; mem.index = 0; mem.pane = Pane{ .focusable = true, .vtable = .{ .draw = draw, .update = update, }, }; return &mem.pane; } fn draw(pane_ptr: *pane.Pane, term_io: *TermIO) !void { var self: *TabBar = @fieldParentPtr("pane", pane_ptr); const tab_width = self.pane.dimensions.internal_size.width / self.tabs.len; const extra = self.pane.dimensions.internal_size.width - (tab_width * self.tabs.len); var writer = pane_ptr.writer(term_io); self.pane.cursor = .{ .x = 0, .y = 0 }; self.pane.moveCursor(term_io); const normal_background = self.pane.background; term_io.enableFormats(.{ .underline = self.config.underline }); for (self.tabs, 0..) |tab, i| { if (i == self.index) { self.pane.background = self.config.highlight_color; } else { self.pane.background = normal_background; } const width = if (i < extra) tab_width + 1 else tab_width; if (tab.name.len >= width) { try writer.writeAll(tab.name[0..width]); continue; } const left = (width - tab.name.len) / 2; try writer.writeByteNTimes(' ', left); try writer.writeAll(tab.name); try writer.writeByteNTimes(' ', width - (tab.name.len + left)); } self.pane.background = normal_background; term_io.disableFormats(.{ .underline = self.config.underline }); } fn update(pane_ptr: *pane.Pane, term_io: *TermIO, key: term.Key) !bool { var self: *TabBar = @fieldParentPtr("pane", pane_ptr); if (key.type == .SEQUENCE) { const seq: term.SequenceKey = @enumFromInt(key.value); switch (seq) { .LEFT => { if (self.index > 0) { self.index -= 1; try draw(pane_ptr, term_io); return true; } }, .RIGHT => { self.index = @min(self.index + 1, self.tabs.len - 1); try draw(pane_ptr, term_io); return true; }, else => {}, } } switch (key.value) { 'h' => { if (self.index > 0) { self.index -= 1; try draw(pane_ptr, term_io); return true; } }, 'l' => { self.index = @min(self.index + 1, self.tabs.len - 1); try draw(pane_ptr, term_io); return true; }, else => {}, } return false; } };