aboutsummaryrefslogtreecommitdiffstats
path: root/widget.c
blob: ae41e89f3662de84fdfbc505cb30bf36b5fad533 (plain) (blame)
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
#include <stdio.h>
#include <string.h>

#include "microui.h"
#include "widget.h"


#define nelem(arr) (sizeof(arr)/sizeof(arr[0]))

static const mu_Color RED = {255, 0, 0, 255};


void
w_init_field(w_Field *f) {
	f->buf[0] = '\0';
	f->value = 0.0;
	f->invalid = 0;
}

/* field draws a Field widget and updates its value.
 * It returns MU_RES_CHANGE if the value has changed. */
int
w_field(mu_Context *ctx, w_Field *f) {
	mu_Rect rect;
	int changed;
	char s[2];
	double value;

	rect = mu_layout_next(ctx);
	mu_layout_set_next(ctx, rect, 0);

	changed = 0;
	if (mu_textbox(ctx, f->buf, sizeof(f->buf)) & MU_RES_CHANGE) {
		/* s used to catch erroneous chars at end of field. */
		if (sscanf(f->buf, "%lf %1s", &value, s) == 1) {
			f->value = value;
			f->invalid = 0;
			changed = 1;
		} else if (f->buf[0] == '\0') {
			f->value = 0.0;
			f->invalid = 0;
			changed = 1;
		} else {
			f->invalid = 1;
		}
	}

	if (f->invalid) {
		mu_draw_box(ctx, rect, RED);
	}

	return changed ? MU_RES_CHANGE : 0;
}

void
w_set_field(w_Field *f, double val) {
	f->value = val;
	snprintf(f->buf, sizeof(f->buf), "%.5f", val);
}

void
w_init_select(w_Select *select, int nopts, const char *const opts[]) {
	select->nopts = nopts;
	select->opts = opts;
	select->idx = 0;
	select->oldidx = 0;
	select ->active = 0;
}

int
w_select(mu_Context *ctx, w_Select *select) {
	mu_Id id;
	mu_Rect r;
	int width, res, i;

	mu_layout_begin_column(ctx);
	width = -1;
	mu_layout_row(ctx, 1, &width, 0);

	id = mu_get_id(ctx, &select, sizeof(select));
	r = mu_layout_next(ctx);
	mu_update_control(ctx, id, r, 0);

	select->active ^= (ctx->mouse_pressed == MU_MOUSE_LEFT && ctx->focus == id);

	mu_draw_control_frame(ctx, id, r, MU_COLOR_BUTTON, 0);
	const char *label = select->opts[select->idx];
	mu_draw_control_text(ctx, label, r, MU_COLOR_TEXT, 0);

	res = 0;
	if (select->active) {
		res = MU_RES_ACTIVE;
		for (i = 0; i < select->nopts; i++) {
			if (mu_button(ctx, select->opts[i])) {
				select->oldidx = select->idx;
				select->idx = i;
				res |= MU_RES_CHANGE;
				select->active = 0;
			}
		}
	}

	mu_layout_end_column(ctx);

	return res;
}

void
w_init_label(w_Label label) {
	label[0] = '\0';
}

void
w_label(mu_Context *ctx, const w_Label label) {
	mu_label(ctx, label);
}