#include #include #include #include #include "microui.h" #include "unit.h" #include "compressor.h" #include "widget.h" #include "util.h" #define FORMAT "%.5g" 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), FORMAT, 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; } /* Returns non-zero on error. */ int w_init_select_compressor(w_Select_Compressor *select, int n, const Compressor *comps) { int i; size_t namesize; select->comps = comps; select->n = n; select->filtered = malloc(n * sizeof(*select->filtered)); if (select->filtered == NULL) { return 1; } /* TODO: parallelize. */ for (i = 0; i < n; i++) { select->filtered[i] = i; } select->nfiltered = n; namesize = sizeof((*comps).brand) + sizeof((*comps).series) + sizeof((*comps).model) + 3; select->names = malloc(n * namesize); if (select->names == NULL) { free(select->filtered); return 1; } /* TODO: parallelize. */ for (i = 0; i < n; i++) { snprintf(select->names[i], namesize, "%s %s %s", comps[i].brand, comps[i].series, comps[i].model); } select->idx = 0; select -> oldidx = 0; select->active = 0; return 0; } void w_free_select_compressor(w_Select_Compressor *select) { free(select->filtered); free(select->names); } int w_select_compressor(mu_Context *ctx, w_Select_Compressor *select) { /* TODO */ } void w_init_number(w_Number num) { num[0] = '\0'; } void w_set_number(w_Number num, double val) { snprintf(num, sizeof(w_Number), FORMAT, val); } void w_number(mu_Context *ctx, const w_Number num) { mu_label(ctx, num); }