Compare commits

..

4 Commits

5 changed files with 105 additions and 14 deletions

View File

@ -2,8 +2,9 @@ build OPTIMIZE="Debug":
zig build -Doptimize={{OPTIMIZE}} zig build -Doptimize={{OPTIMIZE}}
run OPTIMIZE="Debug": (build OPTIMIZE) run OPTIMIZE="Debug": (build OPTIMIZE)
-rm panes.log
./zig-out/bin/panes ./zig-out/bin/panes
cat panes.log -cat panes.log
debug: (build "Debug") debug: (build "Debug")
gdb ./zig-out/bin/panes gdb ./zig-out/bin/panes

View File

@ -25,6 +25,7 @@ pub fn setLevel(level: Level) void {
pub fn deinit() void { pub fn deinit() void {
if (writer) |w| { if (writer) |w| {
w.context.close(); w.context.close();
writer = null;
} }
} }

View File

@ -39,7 +39,9 @@ fn on_select(item: usize) void {
} }
pub fn main() !void { pub fn main() !void {
if (@import("builtin").mode == .Debug) {
try log.init("panes.log", .Debug); try log.init("panes.log", .Debug);
}
defer log.deinit(); defer log.deinit();
const stdin = std.io.getStdIn().reader(); const stdin = std.io.getStdIn().reader();
@ -53,9 +55,16 @@ pub fn main() !void {
var lineV: line.VerticalLine = undefined; var lineV: line.VerticalLine = undefined;
var lineH: line.HorizontalLine = undefined; var lineH: line.HorizontalLine = undefined;
var target: tabs.TabbedTarget = undefined;
var child1: stack.Stack = undefined;
var child2: btn.Button = undefined;
var child3: btn.Button = undefined;
var child4: btn.Button = undefined;
var child5: btn.Button = undefined;
var items = [_]menu.MenuItem{ .{ .name = "Item 1" }, .{ .name = "Item ab" } }; var items = [_]menu.MenuItem{ .{ .name = "Item 1" }, .{ .name = "Item ab" } };
var items2 = [_]menu.MenuItem{ .{ .name = "Item 1" }, .{ .name = "Item ab" } }; var items2 = [_]menu.MenuItem{ .{ .name = "Item 1" }, .{ .name = "Item ab" } };
var tabs_ = [_]tabs.Tab{ .{ .name = "Tab 1", .pane = &side_menu.pane }, .{ .name = "Tab 2", .pane = &child.pane }, .{ .name = "Tab 3", .pane = &child.pane }, .{ .name = "Tab 4", .pane = &child.pane }, .{ .name = "Tab 5", .pane = &child.pane } }; var tabs_ = [_]tabs.Tab{ .{ .name = "Tab 1", .pane = &child1.pane }, .{ .name = "Tab 2", .pane = &child2.pane }, .{ .name = "Tab 3", .pane = &child3.pane }, .{ .name = "Tab 4", .pane = &child4.pane }, .{ .name = "Tab 5", .pane = &child5.pane } };
const gray = color.RGB(80, 80, 80); const gray = color.RGB(80, 80, 80);
const green = color.RGB(0, 255, 0); const green = color.RGB(0, 255, 0);
@ -67,28 +76,45 @@ pub fn main() !void {
.pane = menu.Menu.create(&side_menu, .{ .title = "Menu", .style = s, .align_text = .Center, .expand_highlight = true, .on_select = on_side_select }, &items2), .pane = menu.Menu.create(&side_menu, .{ .title = "Menu", .style = s, .align_text = .Center, .expand_highlight = true, .on_select = on_side_select }, &items2),
.dimensions = .{ .width = .{ .type = .Fill, .value = 1 }, .height = .{ .type = .Fill, .value = 100 } }, .dimensions = .{ .width = .{ .type = .Fill, .value = 1 }, .height = .{ .type = .Fill, .value = 100 } },
}, },
.{ .pane = line.VerticalLine.create(&lineV, .{ .border = borders.BoldBorder, .style = s }), .dimensions = .{ .width = .{ .type = .Absolute, .value = 1 }, .height = .{ .type = .Fill, .value = 100 } } }, .{
.pane = line.VerticalLine.create(&lineV, .{ .border = borders.BoldBorder, .style = s }),
.dimensions = .{ .width = .{ .type = .Absolute, .value = 1 }, .height = .{ .type = .Fill, .value = 100 } },
},
.{ .{
.pane = stack.Stack.create(&child, .{ .direction = .Vertical, .style = s }, &[_]stack.StackedPane{ .pane = stack.Stack.create(&child, .{ .direction = .Vertical, .style = s }, &[_]stack.StackedPane{
.{ .{
.pane = tabs.TabBar.create(&tabbar, .{ .style = s, .highlight_color = green }, &tabs_), .pane = tabs.TabBar.create(&tabbar, .{ .target = &target, .style = s, .highlight_color = green }, &tabs_),
.dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Absolute, .value = 1 } }, .dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Absolute, .value = 1 } },
}, },
.{ .{
.pane = menu.Menu.create(&m, .{ .title = "Test", .style = s, .align_text = .Left, .expand_highlight = true, .on_select = on_select }, &items), .pane = tabs.TabbedTarget.create(&target, s),
.dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Fill, .value = 1 } }, .dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Fill, .value = 1 } },
}, },
.{ .pane = line.HorizontalLine.create(&lineH, .{ .border = borders.BoldBorder, .style = s }), .dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Absolute, .value = 1 } } },
.{
.pane = btn.Button.create(&button, .{ .text = "<Button>", .style = s, .callback = on_click }),
.dimensions = .{ .width = .{ .type = .Absolute, .value = 8 }, .height = .{ .type = .Absolute, .value = 1 } },
},
}), }),
.dimensions = .{ .width = .{ .type = .Fill, .value = 9 }, .height = .{ .type = .Fill, .value = 100 } }, .dimensions = .{ .width = .{ .type = .Fill, .value = 9 }, .height = .{ .type = .Fill, .value = 100 } },
}, },
}); });
pane.set_layout(&top.pane, &m.pane); _ = btn.Button.create(&child2, .{ .text = "Page 2", .callback = on_click, .style = s });
_ = btn.Button.create(&child3, .{ .text = "Page 3", .callback = on_click, .style = s });
_ = btn.Button.create(&child4, .{ .text = "Page 4", .callback = on_click, .style = s });
_ = btn.Button.create(&child5, .{ .text = "Page 5", .callback = on_click, .style = s });
_ = stack.Stack.create(&child1, .{ .direction = .Vertical, .style = s }, &[_]stack.StackedPane{
.{
.pane = menu.Menu.create(&m, .{ .title = "Test", .style = s, .align_text = .Left, .expand_highlight = true, .on_select = on_select }, &items),
.dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Fill, .value = 1 } },
},
.{
.pane = line.HorizontalLine.create(&lineH, .{ .border = borders.BoldBorder, .style = s }),
.dimensions = .{ .width = .{ .type = .Fill, .value = 100 }, .height = .{ .type = .Absolute, .value = 1 } },
},
.{
.pane = btn.Button.create(&button, .{ .text = "<Button>", .style = s, .callback = on_click }),
.dimensions = .{ .width = .{ .type = .Absolute, .value = 8 }, .height = .{ .type = .Absolute, .value = 1 } },
},
});
pane.set_layout(&top.pane, &tabbar.pane);
try pane.init(&term_io); try pane.init(&term_io);
defer pane.cleanup(&term_io); defer pane.cleanup(&term_io);

View File

@ -29,6 +29,10 @@ fn exit_signal(_: i32) callconv(.C) void {
should_exit.store(true, .release); should_exit.store(true, .release);
} }
fn panic_signal(_: i32) callconv(.C) void {
@panic("Segmentation fault!!");
}
pub fn set_layout(layout: *Pane, initial_focus: *Pane) void { pub fn set_layout(layout: *Pane, initial_focus: *Pane) void {
layout.parent = &window.pane; layout.parent = &window.pane;
window.child = layout; window.child = layout;
@ -51,6 +55,13 @@ pub fn init(term_io: *TermIO) !void {
}; };
try std.posix.sigaction(std.posix.SIG.INT, &exit_handler, null); try std.posix.sigaction(std.posix.SIG.INT, &exit_handler, null);
var panic_handler = std.posix.Sigaction{
.handler = .{ .handler = panic_signal },
.mask = std.posix.empty_sigset,
.flags = 0,
};
try std.posix.sigaction(std.posix.SIG.SEGV, &panic_handler, null);
term_io.enterRawMode(); term_io.enterRawMode();
term_io.saveScreen(); term_io.saveScreen();
term_io.hideCursor(); term_io.hideCursor();
@ -259,14 +270,18 @@ pub const Pane = struct {
self.vtable.resize(self); self.vtable.resize(self);
} }
pub fn draw(self: *Pane, term_io: *TermIO) !void { pub fn clear(self: *Pane, term_io: *TermIO) !void {
if (self.style.border) |border| { if (self.style.border) |border| {
term_io.setColor(self.style.background, self.style.foreground); term_io.setColor(self.style.background, self.style.foreground);
try term_io.drawBox(self.dimensions, border, !self.style.background.equal(self.parent.style.background)); try term_io.drawBox(self.dimensions, border, !self.style.background.equal(self.parent.style.background));
} else if (!self.style.background.equal(self.parent.style.background)) { } else {
term_io.setColor(self.style.background, self.style.foreground); term_io.setColor(self.style.background, self.style.foreground);
term_io.fillBox(self.dimensions); term_io.fillBox(self.dimensions);
} }
}
pub fn draw(self: *Pane, term_io: *TermIO) !void {
try self.clear(term_io);
try self.vtable.draw(self, term_io); try self.vtable.draw(self, term_io);
} }

View File

@ -22,6 +22,8 @@ pub const TabBar = struct {
index: usize, index: usize,
const Config = struct { const Config = struct {
target: *TabbedTarget,
align_text: menu.TextAlignment = .Center, align_text: menu.TextAlignment = .Center,
style: Style = .{}, style: Style = .{},
highlight_color: colors.Color, highlight_color: colors.Color,
@ -43,6 +45,9 @@ pub const TabBar = struct {
}, },
}; };
mem.config.target.content = mem.tabs[mem.index].pane;
log.debug("{*} - {*}", .{ mem.tabs[mem.index].pane, mem.config.target.content });
return &mem.pane; return &mem.pane;
} }
@ -90,12 +95,14 @@ pub const TabBar = struct {
if (self.index > 0) { if (self.index > 0) {
self.index -= 1; self.index -= 1;
try draw(pane_ptr, term_io); try draw(pane_ptr, term_io);
try self.config.target.update_content(self.tabs[self.index].pane, term_io);
return true; return true;
} }
}, },
.RIGHT => { .RIGHT => {
self.index = @min(self.index + 1, self.tabs.len - 1); self.index = @min(self.index + 1, self.tabs.len - 1);
try draw(pane_ptr, term_io); try draw(pane_ptr, term_io);
try self.config.target.update_content(self.tabs[self.index].pane, term_io);
return true; return true;
}, },
else => {}, else => {},
@ -107,12 +114,14 @@ pub const TabBar = struct {
if (self.index > 0) { if (self.index > 0) {
self.index -= 1; self.index -= 1;
try draw(pane_ptr, term_io); try draw(pane_ptr, term_io);
try self.config.target.update_content(self.tabs[self.index].pane, term_io);
return true; return true;
} }
}, },
'l' => { 'l' => {
self.index = @min(self.index + 1, self.tabs.len - 1); self.index = @min(self.index + 1, self.tabs.len - 1);
try draw(pane_ptr, term_io); try draw(pane_ptr, term_io);
try self.config.target.update_content(self.tabs[self.index].pane, term_io);
return true; return true;
}, },
else => {}, else => {},
@ -125,3 +134,42 @@ pub const TabBar = struct {
try draw(pane_ptr, term_io); try draw(pane_ptr, term_io);
} }
}; };
pub const TabbedTarget = struct {
pane: Pane,
content: *Pane = undefined,
pub fn create(mem: *TabbedTarget, style: Style) *Pane {
mem.pane = Pane{
.style = style,
.vtable = .{
.resize = resize,
.draw = draw,
},
};
return &mem.pane;
}
fn update_content(self: *TabbedTarget, new_content: *Pane, term_io: *TermIO) !void {
self.content = new_content;
try self.pane.clear(term_io);
resize(&self.pane);
try self.content.draw(term_io);
}
fn resize(pane_ptr: *Pane) void {
var self: *TabbedTarget = @fieldParentPtr("pane", pane_ptr);
self.content.dimensions.size = self.pane.dimensions.internal_size;
self.content.dimensions.pos = self.pane.dimensions.internal_pos;
self.content.resize();
}
fn draw(pane_ptr: *Pane, term_io: *TermIO) !void {
var self: *TabbedTarget = @fieldParentPtr("pane", pane_ptr);
try self.content.draw(term_io);
}
};