Panes/src/tabs.zig

121 lines
3.7 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");
2024-10-14 23:05:56 +00:00
const Pane = pane.Pane;
2024-10-14 23:35:47 +00:00
const Style = pane.Style;
2024-10-13 22:28:15 +00:00
const TermIO = term.TermIO;
pub const Tab = struct {
name: []const u8,
2024-10-14 23:05:56 +00:00
pane: *Pane,
2024-10-13 22:28:15 +00:00
};
pub const TabBar = struct {
2024-10-14 23:05:56 +00:00
pane: Pane,
2024-10-13 22:28:15 +00:00
config: Config,
tabs: []Tab,
2024-10-14 23:05:56 +00:00
index: usize,
2024-10-13 22:28:15 +00:00
const Config = struct {
align_text: menu.TextAlignment = .Center,
2024-10-14 23:35:47 +00:00
style: Style = .{},
2024-10-13 22:28:15 +00:00
highlight_color: colors.Color,
expand_highlight: bool = true,
underline: bool = true,
};
2024-10-14 23:05:56 +00:00
pub fn create(mem: *TabBar, config: Config, tabs: []Tab) *Pane {
mem.config = config;
mem.tabs = tabs;
mem.index = 0;
mem.pane = Pane{
.focusable = true,
2024-10-14 23:35:47 +00:00
.style = config.style,
2024-10-14 23:05:56 +00:00
.vtable = .{
.draw = draw,
.update = update,
2024-10-13 22:28:15 +00:00
},
};
2024-10-14 23:05:56 +00:00
return &mem.pane;
2024-10-13 22:28:15 +00:00
}
fn draw(pane_ptr: *pane.Pane, term_io: *TermIO) !void {
var self: *TabBar = @fieldParentPtr("pane", pane_ptr);
2024-10-14 23:05:56 +00:00
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);
2024-10-13 22:28:15 +00:00
var writer = pane_ptr.writer(term_io);
self.pane.cursor = .{ .x = 0, .y = 0 };
self.pane.moveCursor(term_io);
2024-10-14 23:35:47 +00:00
const normal_background = self.pane.style.background;
2024-10-13 22:28:15 +00:00
term_io.enableFormats(.{ .underline = self.config.underline });
for (self.tabs, 0..) |tab, i| {
if (i == self.index) {
2024-10-14 23:35:47 +00:00
self.pane.style.background = self.config.highlight_color;
2024-10-13 22:28:15 +00:00
} else {
2024-10-14 23:35:47 +00:00
self.pane.style.background = normal_background;
2024-10-13 22:28:15 +00:00
}
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));
}
2024-10-14 23:35:47 +00:00
self.pane.style.background = normal_background;
2024-10-13 22:28:15 +00:00
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;
}
};