diff --git a/examples/table.zig b/examples/table.zig index 89199fc..d6b9715 100644 --- a/examples/table.zig +++ b/examples/table.zig @@ -79,6 +79,9 @@ pub fn main() !void { var demo_tbl: vaxis.widgets.Table.TableContext = .{ .active_bg = active_bg, .selected_bg = selected_bg, + .header_names = .{ .custom = &.{ "First", "Last", "Username", "Email", "Phone#" } }, + //.header_names = .{ .custom = &.{ "First", "Last", "Email", "Phone#" } }, + //.col_indexes = .{ .by_idx = &.{ 0, 1, 3, 4 } }, //.col_width = .{ .static_all = 15 }, //.col_width = .{ .dynamic_header_len = 3 }, //.col_width = .{ .static_individual = &.{ 10, 20, 15, 25, 15 } }, @@ -274,7 +277,6 @@ pub fn main() !void { try vaxis.widgets.Table.drawTable( event_alloc, middle_bar, - &.{ "First", "Last", "Username", "Email", "Phone#" }, //users_buf[0..], user_list, //user_mal, diff --git a/src/widgets/Table.zig b/src/widgets/Table.zig index ca85df7..f292bb7 100644 --- a/src/widgets/Table.zig +++ b/src/widgets/Table.zig @@ -49,6 +49,11 @@ pub const TableContext = struct { /// Note, if this is left `null` the Column Width will be dynamically calculated during `drawTable()`. //col_width: ?usize = null, col_width: WidthStyle = .dynamic_fill, + + // Header Names + header_names: HeaderNames = .field_names, + // Column Indexes + col_indexes: ColumnIndexes = .all, }; /// Width Styles for `col_width`. @@ -63,6 +68,22 @@ pub const WidthStyle = union(enum) { static_individual: []const usize, }; +/// Column Indexes +pub const ColumnIndexes = union(enum) { + /// Use all of the Columns. + all, + /// Use Columns from the specified indexes. + by_idx: []const usize, +}; + +/// Header Names +pub const HeaderNames = union(enum) { + /// Use Field Names as Headers + field_names, + /// Custom + custom: []const []const u8, +}; + /// Draw a Table for the TUI. pub fn drawTable( /// This should be an ArenaAllocator that can be deinitialized after each event call. @@ -73,8 +94,6 @@ pub fn drawTable( alloc: ?mem.Allocator, /// The parent Window to draw to. win: vaxis.Window, - /// Headers for the Table - headers: []const []const u8, /// This must be a Slice, ArrayList, or MultiArrayList. /// Note, MultiArrayList support currently requires allocation. data_list: anytype, @@ -131,6 +150,31 @@ pub fn drawTable( }; defer if (di_is_mal) alloc.?.free(data_items); + // Headers for the Table + var hdrs_buf: [100][]const u8 = undefined; + const headers = hdrs: { + switch (table_ctx.header_names) { + .field_names => { + const DataT = @TypeOf(data_items[0]); + const fields = meta.fields(DataT); + var num_hdrs: usize = 0; + inline for (fields, 0..) |field, idx| contFields: { + switch (table_ctx.col_indexes) { + .all => {}, + .by_idx => |idxs| { + if (mem.indexOfScalar(usize, idxs, idx) == null) break :contFields; + }, + } + num_hdrs += 1; + hdrs_buf[idx] = field.name; + } + break :hdrs hdrs_buf[0..num_hdrs]; + }, + .custom => |hdrs| break :hdrs hdrs, + } + }; + + const table_win = win.initChild( 0, table_ctx.y_off, @@ -214,7 +258,13 @@ pub fn drawTable( const DataT = @TypeOf(data); col_start = 0; const item_fields = meta.fields(DataT); - inline for (item_fields[0..], 0..) |item_field, item_idx| { + inline for (item_fields[0..], 0..) |item_field, item_idx| contFields: { + switch (table_ctx.col_indexes) { + .all => {}, + .by_idx => |idxs| { + if (mem.indexOfScalar(usize, idxs, item_idx) == null) break :contFields; + }, + } const col_width = try calcColWidth( item_idx, headers,