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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* xmenu
* a simple fuzzy-selection menu made with Xlib
*/
#include <stdio.h>
#define ARENA_IMPL
#define STR_IMPL
#include "arena.h"
#include "dynarr.h"
#include "str.h"
#include "ui.h"
typedef DYNARR(char) DynStr;
int
umod(int a, int b)
{
if (a < 0) {
return b + a % b;
} else {
return a % b;
}
}
int
txt_insert(DynStr *s, int i, Str ins)
{
DA_FIT(s, s->n + ins.n);
if (i < s->n) {
memmove(s->v + i + ins.n, s->v + i, s->n - i);
}
memcpy(s->v + i, ins.s, ins.n);
s->n += ins.n;
return i + ins.n;
}
int
txt_delete(DynStr *s, int i, int n)
{
if (n > i) n = i;
if (n > 0) {
memmove(s->v + i - n, s->v + i, s->n - i);
s->n -= n;
}
return i - n;
}
int
main(int argc, char **argv)
{
ui_init(argc, argv);
DynStr input = { 0 };
int inpi = 0;
int seli = 0;
Str optv[] = {
S("she shit on my thang until i vomit"),
S("what"),
S("who are you"),
S("why are you"),
S("where'd you come from")
};
int optc = sizeof optv / sizeof *optv;
if (!optc) goto done;
for (UiEvent ev; ui_wait_event(&ev); ) {
switch (ev.type) {
case UI_KEY_DOWN:
switch (ev.key.key) {
case UIK_ESCAPE:
goto done;
case UIK_BACKSPACE:
inpi = txt_delete(&input, inpi, 1);
goto draw;
case UIK_RETURN: {
Str o = optv[seli];
printf("%.*s\n", (int)o.n, o.s);
} goto done;
case UIK_DOWN:
seli = umod(seli + 1, optc);
goto draw;
case UIK_UP:
seli = umod(seli - 1, optc);
goto draw;
case UIK_LEFT:
if (inpi > 0) inpi--;
goto draw;
case UIK_RIGHT:
if (inpi < input.n) inpi++;
goto draw;
case UIK_HOME:
inpi = 0;
goto draw;
case UIK_END:
inpi = input.n;
goto draw;
default:
if (!ev.key.strn) break;
inpi = txt_insert(&input, inpi, (Str) { ev.key.str, ev.key.strn });
seli = 0;
goto draw;
}
break;
case UI_REDRAW:
draw:
ui_draw(
(Str) { input.v, input.n },
inpi,
seli,
optv,
optc
);
break;
default:
break;
}
}
done:
ui_fini();
return 0;
}
|