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
|
UI_Select_List :: struct {
#as using base : UI_Elem = .{type = .SELECT_LIST};
only_one := true;
options : []string;
selected : []bool;
selected_id := -1;
cursor, offset := 0, 0;
prefix_default := "[ ]";
prefix_selected := "[+]";
}
handle_key_select_list :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
using cast(*UI_Select_List) ui_elem;
assert(cursor_state != .OUTSIDE);
if cursor_state == .ON {
if key == .ENTER {
cursor_state = .IN;
return true;
}
} else {
if key == {
case .DOWN;
if cursor < options.count - 1 then cursor += 1;
case .UP;
if cursor > 0 then cursor -= 1;
case .ESCAPE;
cursor_state = .ON;
case .ENTER;
if only_one {
if cursor == selected_id {
selected_id = -1;
} else {
selected_id = cursor;
}
} else {
selected[cursor] ^= true;
}
case;
return false;
}
return true;
}
return false;
}
init :: (select_list : *UI_Select_List, only_one := true) {
select_list.only_one = only_one;
if !only_one select_list.selected = NewArray(select_list.options.count, bool);
}
deinit :: (using select_list : *UI_Select_List) {
array_free(selected);
}
c_draw_select_list :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
using cast(*UI_Select_List) ui_elem;
rows := min(cast(int) zone.height, options.count - offset);
fix_offset :: () #expand {
if cursor - offset < 0 {
offset = cursor;
} else if cursor - offset >= zone.height {
offset = cursor - zone.height + 1;
}
}
fix_offset();
for y : 0..rows-1 {
i := y + offset;
is_selected := ifx only_one then i == selected_id else selected[i];
prefix := ifx is_selected then prefix_selected else prefix_default;
mode := ifx i == cursor && cursor_state == .IN
ifx is_selected style.text.cursor_and_selection else style.text.cursor
else
ifx is_selected style.text.selection else style.text.default;
c_draw_line_ascii(canvas, prefix, zone, .{0, xx y}, mode);
c_draw_line_ascii(canvas, options[i], zone, .{xx prefix.count, xx y}, mode);
}
return true;
}
|