From 8ae8ce9ac76661bbde6f1553e1b8f0412aa44e09 Mon Sep 17 00:00:00 2001 From: Cameron Reed Date: Thu, 31 Oct 2024 12:58:59 -0600 Subject: [PATCH] Add text pane --- src/main.zig | 19 ++++++++-------- src/pane.zig | 4 +++- src/tabs.zig | 5 ++++- src/text.zig | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 11 deletions(-) create mode 100644 src/text.zig diff --git a/src/main.zig b/src/main.zig index 62b3493..e5e8f3f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -10,6 +10,7 @@ const log = @import("log.zig"); const line = @import("line.zig"); const tabs = @import("tabs.zig"); const stack = @import("stack.zig"); +const text = @import("text.zig"); var term_io: term.TermIO = undefined; var side_menu: menu.Menu = undefined; @@ -57,14 +58,14 @@ pub fn main() !void { 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 child2: text.Text = undefined; + var child3: text.Text = undefined; + var child4: text.Text = undefined; + var child5: text.Text = undefined; var items = [_]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 = &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 } }; + var tabs_ = [_]tabs.Tab{ .{ .name = "Tab 1", .pane = &child1.pane }, .{ .name = "Tab 2", .pane = &child2.pane }, .{ .name = "Tab 3", .pane = &child1.pane }, .{ .name = "Tab 4", .pane = &child4.pane }, .{ .name = "Tab 5", .pane = &child1.pane } }; const gray = color.RGB(80, 80, 80); const green = color.RGB(0, 255, 0); @@ -95,10 +96,10 @@ pub fn main() !void { }, }); - _ = 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 }); + _ = text.Text.create(&child2, .{ .text = "Page 2; This now has a lot of extra text and should wrap. This is to test that break_on works. You should be able to set it to \" \" and it wont break words when wrapping, but we will see", .break_on = " ", .style = s }); + _ = text.Text.create(&child3, .{ .text = "Page 3", .style = s }); + _ = text.Text.create(&child4, .{ .text = "Page 4", .style = s }); + _ = text.Text.create(&child5, .{ .text = "Page 5", .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), diff --git a/src/pane.zig b/src/pane.zig index 0329a8a..e7d6453 100644 --- a/src/pane.zig +++ b/src/pane.zig @@ -110,6 +110,8 @@ pub fn tick(term_io: *TermIO) !void { } pub fn cycle_focus(term_io: *TermIO) void { + // TODO: There must be a better way of doing this + const parent_stack: *stack.Stack = @fieldParentPtr("pane", focused_pane.parent); var index = (focused_index + 1) % parent_stack.children.len; var to_focus = parent_stack.children[index].pane; @@ -300,7 +302,7 @@ pub const Pane = struct { self.vtable.focus(self, term_io) catch {}; } - fn nextLine(self: *Pane, term_io: *const TermIO) void { + pub fn nextLine(self: *Pane, term_io: *const TermIO) void { self.cursor.x = 0; self.cursor.y += 1; diff --git a/src/tabs.zig b/src/tabs.zig index a68a1e5..069bfe8 100644 --- a/src/tabs.zig +++ b/src/tabs.zig @@ -46,7 +46,6 @@ 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; } @@ -124,6 +123,10 @@ pub const TabBar = struct { try self.config.target.update_content(self.tabs[self.index].pane, term_io); return true; }, + '\r' => { + pane.focus(self.config.target.content, term_io); + return true; + }, else => {}, } diff --git a/src/text.zig b/src/text.zig new file mode 100644 index 0000000..946d0b6 --- /dev/null +++ b/src/text.zig @@ -0,0 +1,61 @@ +const std = @import("std"); +const pane = @import("pane.zig"); +const term = @import("term.zig"); + +const Pane = pane.Pane; +const Style = pane.Style; +const TermIO = term.TermIO; + +pub const Text = struct { + pane: Pane, + text: []const u8, + break_on: ?[]const u8, + + const Config = struct { + text: []const u8, + break_on: ?[]const u8 = null, + style: Style = .{}, + }; + + pub fn create(mem: *Text, config: Config) *Pane { + mem.pane = Pane{ + .overflow = .{ .x = .Wrap, .y = .Hidden }, + .style = config.style, + .vtable = .{ + .draw = draw, + }, + }; + mem.text = config.text; + mem.break_on = config.break_on; + + return &mem.pane; + } + + fn draw(pane_ptr: *Pane, term_io: *TermIO) !void { + var self: *Text = @fieldParentPtr("pane", pane_ptr); + + self.pane.cursor = .{ .x = 0, .y = 0 }; + self.pane.moveCursor(term_io); + + var writer = self.pane.writer(term_io); + + if (self.break_on) |break_on| { + var first = true; + var ittr = std.mem.splitAny(u8, self.text, break_on); + while (ittr.next()) |word| { + if (word.len >= self.pane.dimensions.internal_size.width - self.pane.cursor.x) { + self.pane.nextLine(term_io); + first = true; + } + + if (!first) { + try writer.writeByte(' '); + } + try writer.writeAll(word); + first = false; + } + } else { + try writer.writeAll(self.text); + } + } +};