122 lines
3.8 KiB
Zig
122 lines
3.8 KiB
Zig
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;
|
|
}
|
|
};
|