1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
UI_Table :: struct {
#as using base : UI_Elem = .{type = .TABLE};
// auto_scale := false;
// metrics : []int;
columns := 0;
rows := 0;
// description : []string;
content : [..]string;
cursor, offset := 0;
show_cursor := false;
}
handle_key_table :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
return false;
}
c_draw_table_content :: (canvas : *Canvas, using ui_table : *UI_Table, zone : Ibox2, style : *UI_Style, rows_visible : int) -> bool {
for y : 0..zone.height-1 {
is_selected := y == cursor && show_cursor;
mode := ifx is_selected then style.text.selection else style.text.default;
separator_char := Char.{code = style.box.default.tb, mode = mode};
if zone.width < columns {
for x : 0..zone.width {
c_putchar(canvas, separator_char, zone.corner + ivec2.{xx x, xx y});
}
} else {
i := y + offset;
for x : 0..columns-1 {
l := (zone.width + 1) * x / columns;
r := (zone.width + 1) * (x + 1) / columns - 1;
if y < rows_visible {
field_content := content[i * columns + x];
field_content.count = min(field_content.count, r - l);
c_draw_line_ascii(canvas, field_content, zone, .{xx l, xx y}, mode);
}
if x != columns-1 c_putchar(canvas, separator_char, zone.corner + ivec2.{xx r, xx y});
}
}
}
return true;
}
c_draw_table :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
using ui_table := cast(*UI_Table) ui_elem;
assert(rows * columns == content.count);
rows_visible := min(cast(int) zone.height, rows - offset);
fix_offset :: () #expand {
if cursor - offset < 0 {
offset = cursor;
} else if cursor - offset >= zone.height {
offset = cursor - zone.height + 1;
}
}
fix_offset();
ok := c_draw_table_content(canvas, ui_table, zone, style, rows_visible);
return ok;
}
init :: (table : *UI_Table, description : []string) {
table.columns = description.count;
table.description = description;
}
init :: (table : *UI_Table, columns : int) {
table.columns = columns;
}
add_line :: (using table : *UI_Table, line : ..string) {
assert(line.count == columns);
array_add(*content, ..line);
rows += 1;
}
deinit :: (using table : *UI_Table) {
array_free(content);
}
// TODO
// variadic columns count, different content types
// empty separator
// automatic scale, as option
// description
// align content left/right/center
|