Panes/src/tabs.zig

122 lines
3.8 KiB
Zig
Raw Normal View History

2024-10-13 22:28:15 +00:00
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 TermIO = term.TermIO;
pub const Tab = struct {
name: []const u8,
pane: *pane.Pane,
};
pub const TabBar = struct {
pane: pane.Pane,
config: Config,
tabs: []Tab,
index: usize = 0,
const Config = struct {
align_text: menu.TextAlignment = .Center,
highlight_color: colors.Color,
expand_highlight: bool = true,
underline: bool = true,
};
pub fn create(parent: *pane.Pane, config: Config, tabs: []Tab, width: dims.Dimension) TabBar {
return TabBar{
.pane = pane.Pane{
.parent = parent,
.children = null,
.focusable = true,
.vtable = .{
.draw = draw,
.update = update,
},
.dimensions = .{
.x = width,
.y = .{ .value = 1, .type = .Absolute },
},
},
.config = config,
.tabs = tabs,
};
}
fn draw(pane_ptr: *pane.Pane, term_io: *TermIO) !void {
var self: *TabBar = @fieldParentPtr("pane", pane_ptr);
const tab_width = self.pane.calcDims.internal_size.width / self.tabs.len;
const extra = self.pane.calcDims.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;
}
};