ref: 1110500359d75192a9e224f90fe6cc679a6e0a25
dir: /uiglue.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <thread.h> #include <9p.h> #include "uiglue.h" #include "aux.h" static FAUSTFLOAT *declzone; static const char *declkey; static const char *declvalue; static char * ui_readstr(Aux *a, UI *ui, int type, char *s, int sz) { if (type != Xuictl) sysfatal("unknown ui file"); switch (a->type) { case UITBox: snprint(s, sz, "tbox\n"); return s; case UIHBox: snprint(s, sz, "hbox\n"); return s; case UIVBox: snprint(s, sz, "vbox\n"); return s; case UIButton: snprint(s, sz, "button\t%s\t%d\n", ui->key, !!*ui->zone); return s; case UICheck: snprint(s, sz, "check\t%s\t%d\n", ui->key, !!*ui->zone); return s; case UIVSlider: snprint(s, sz, "vslider\t%s\t%f\t%f\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->init, ui->min, ui->max, ui->step); return s; case UIHSlider: snprint(s, sz, "hslider\t%s\t%f\t%f\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->init, ui->min, ui->max, ui->step); return s; case UINum: snprint(s, sz, "num\t%s\t%f\t%f\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->init, ui->min, ui->max, ui->step); return s; case UIHBarGraph: snprint(s, sz, "hbargraph\t%s\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->min, ui->max); return s; case UIVBarGraph: snprint(s, sz, "vbargraph\t%s\t%f\t%f\t%f\n", ui->key, *ui->zone, ui->min, ui->max); return s; } sysfatal("unknown ui type %d", a->type); return nil; } static int ui_write(Aux *a, UI *ui, int type, char *s) { float v; if (type != Xuictl) sysfatal("unknown ui file"); /* FIXME optional argument should specify at which frame to apply the change */ v = 0.0f; if (strncmp(s, "reset", 5) == 0) { /* FIXME reset for a box should reset ALL controls inside it */ v = ui->init; } else if (strncmp(s, "add", 3) == 0) { if (ui->zone != nil) v = *ui->zone + atof(s+3); } else if (strncmp(s, "sub", 3) == 0) { if (ui->zone != nil) v = *ui->zone - atof(s+3); } else { v = atof(s); } if (ui->zone != nil) { if (a->type == UIButton || a->type == UICheck) v = !!v; else if (*ui->zone < ui->min) v = ui->min; else if (*ui->zone > ui->max) v = ui->max; *ui->zone = v; } return 0; } static UI * newui(File *f, const char *label, int type) { Aux *a; a = calloc(1, sizeof(*a)+sizeof(UI)); a->ui = (UI*)(a+1); a->ctl = Xuictl; a->type = type; a->ui->label = label; a->ui->readstr = ui_readstr; a->ui->write = ui_write; if ((uiglue.uiInterface = createfile(f, label, nil, DMDIR|0775, a)) == nil) sysfatal("failed to create ui: %r"); if (createfile(uiglue.uiInterface, "ctl", nil, 0664, &a->ctl) == nil) sysfatal("failed to create ui ctl: %r"); return a->ui; } static void ui_tbox(void *f, const char *label) { newui(f, label, UITBox); } static void ui_hbox(void *f, const char *label) { newui(f, label, UIHBox); } static void ui_vbox(void *f, const char *label) { newui(f, label, UIVBox); } static void ui_close(void *file) { File *f; f = file; uiglue.uiInterface = f->parent; } static UI * ui_define(File *f, int type, const char *label, FAUSTFLOAT *zone) { UI *ui; if (zone != declzone) sysfatal("zone mismatch"); ui = newui(f, label, type); ui->zone = declzone; ui->key = declkey; ui->value = declvalue; uiglue.uiInterface = f; return ui; } static void ui_button(void *f, const char *label, FAUSTFLOAT *zone) { ui_define(f, UIButton, label, zone); } static void ui_check(void *f, const char *label, FAUSTFLOAT *zone) { ui_define(f, UICheck, label, zone); } static void ui_vslider(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { UI *ui; ui = ui_define(f, UIVSlider, label, zone); ui->init = init; ui->min = min; ui->max = max; ui->step = step; } static void ui_hslider(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { UI *ui; ui = ui_define(f, UIHSlider, label, zone); ui->init = init; ui->min = min; ui->max = max; ui->step = step; } static void ui_num(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { UI *ui; ui = ui_define(f, UINum, label, zone); ui->init = init; ui->min = min; ui->max = max; ui->step = step; } static void ui_hbargraph(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max) { UI *ui; ui = ui_define(f, UIHBarGraph, label, zone); ui->min = min; ui->max = max; } static void ui_vbargraph(void *f, const char *label, FAUSTFLOAT *zone, FAUSTFLOAT min, FAUSTFLOAT max) { UI *ui; ui = ui_define(f, UIVBarGraph, label, zone); ui->min = min; ui->max = max; } static void ui_declare(void *f, FAUSTFLOAT *zone, const char *key, const char *value) { USED(f); declzone = zone; declkey = key; declvalue = value; } UIGlue uiglue = { .openTabBox = ui_tbox, .openHorizontalBox = ui_hbox, .openVerticalBox = ui_vbox, .closeBox = ui_close, .addButton = ui_button, .addCheckButton = ui_check, .addVerticalSlider = ui_vslider, .addHorizontalSlider = ui_hslider, .addNumEntry = ui_num, .addHorizontalBargraph = ui_hbargraph, .addVerticalBargraph = ui_vbargraph, .declare = ui_declare, };