diff options
Diffstat (limited to 'props.c')
-rw-r--r-- | props.c | 151 |
1 files changed, 141 insertions, 10 deletions
@@ -1,16 +1,55 @@ #include <u.h> #include <libc.h> #include <draw.h> +#include <ctype.h> +#include <fcall.h> +#include <thread.h> +#include <9p.h> #include "guifs.h" #define Eparse "could not parse property" +int +allspace(char *r) +{ + while(*r){ + if(!isspace(*r)) + return 0; + r++; + } + return 1; +} + PropVal defbackground(void) { PropVal v; - v.colour = mkcolour(DBlack); + v.colour = mkcolour(DWhite); + return v; +} + +PropVal +defspacing(void) +{ + PropVal v; + v.spacing = emalloc(sizeof(Spacing)); + return v; +} + +PropVal +deforientation(void) +{ + PropVal v; + v.orientation = Horizontal; + return v; +} + +PropVal +defbordercolour(void) +{ + PropVal v; + v.colour = mkcolour(DRed); return v; } @@ -24,37 +63,129 @@ printcolour(PropVal p) } char * +printspacing(PropVal p) +{ + int bufsize = 256; + char *buf = emalloc(bufsize); + snprint(buf, bufsize, "%d %d %d %d\n", p.spacing->up, p.spacing->right, p.spacing->down, p.spacing->left); + return buf; +} + +char * +printorientation(PropVal p) +{ + char *str; + switch(p.orientation){ + case Horizontal: + str = estrdup9p("horizontal\n"); + break; + case Vertical: + str = estrdup9p("vertical\n"); + break; + default: + str = estrdup9p("???\n"); + break; + } + return str; +} + +char * parsecolour(char *str, PropVal *p) { char *r; ulong c = strtoul(str, &r, 16); - if((r - str) != 8) + if((r - str) != 8 || !allspace(r)) return Eparse; (*p).colour = mkcolour(c); return nil; } +char * +parsespacing(char *str, PropVal *p) +{ + USED(p); + char *fields[5]; + int spacings[4]; + + int n = getfields(str, fields, nelem(fields), 0, " "); + if(!(n == 4 || n == 2 || n == 1)) + return Eparse; + + for(int i = 0; i < n; i++){ + char *r; + spacings[i] = strtol(fields[i], &r, 10); + if(!allspace(r)) + return Eparse; + } + + Spacing *s = emalloc(sizeof(Spacing)); + switch(n){ + case 1: + s->up = s->down = s->left = s->right = spacings[0]; + break; + case 2: + s->up = s->down = spacings[0]; + s->left = s->right = spacings[1]; + break; + case 4: + s->up = spacings[0]; + s->right = spacings[1]; + s->down = spacings[2]; + s->left = spacings[3]; + break; + } + (*p).spacing = s; + + return nil; +} + +char * +parseorientation(char *str, PropVal *p) +{ + if(strncmp(str, "horizontal", 10) == 0 && allspace(str+10)) + (*p).orientation = Horizontal; + else if(strncmp(str, "vertical", 8) == 0 && allspace(str+8)) + (*p).orientation = Vertical; + else + return Eparse; + return nil; +} + PropVal getprop(GuiElement *g, int tag) { - for(int i = 0; i < g->nprops; i++) + PropVal *v = nil; + rlock(&g->lock); + for(int i = 0; i < g->nprops && v == nil; i++) if(g->props[i].tag == tag) - return g->props[i].val; - sysfatal("invalid prop for this gui element"); + v = &g->props[i].val; + runlock(&g->lock); + + if(v == nil) + sysfatal("invalid prop for this gui element"); + else + return *v; } void setprop(GuiElement *g, int tag, PropVal val) { + wlock(&g->lock); /* TODO: free old propval */ for(int i = 0; i < g->nprops; i++) - if(g->props[i].tag == tag){ + if(g->props[i].tag == tag) g->props[i].val = val; - updategui(0); - return; - } + wunlock(&g->lock); + updategui(0); } PropSpec propspecs[Pmax] = { [Pbackground] = {"background", defbackground, printcolour, parsecolour}, -};
\ No newline at end of file + [Pborder] = {"border", defspacing, printspacing, parsespacing}, + [Pmargin] = {"margin", defspacing, printspacing, parsespacing}, + [Ppadding] = {"padding", defspacing, printspacing, parsespacing}, + [Porientation] = {"orientation", deforientation, printorientation, parseorientation}, + [Pbordercolour] = {"bordercolour", defbordercolour, printcolour, parsecolour}, +}; + +int baseprops[nbaseprops] = {Pborder, Pmargin, Ppadding, Pbordercolour};
\ No newline at end of file |