diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /libprefab/elistelement.c | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'libprefab/elistelement.c')
| -rw-r--r-- | libprefab/elistelement.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/libprefab/elistelement.c b/libprefab/elistelement.c new file mode 100644 index 00000000..69ca2026 --- /dev/null +++ b/libprefab/elistelement.c @@ -0,0 +1,113 @@ +#include <lib9.h> +#include <draw.h> +#include <interp.h> +#include <isa.h> +#include "../libinterp/runt.h" +#include <drawif.h> +#include <prefab.h> +#include <kernel.h> + +List* +prefabwrap(void *elem) +{ + List *l; + Heap *h, *e; + + e = D2H(elem); + h = nheap(sizeof(List) + sizeof(WORD*)); + h->t = &Tlist; + Tlist.ref++; + l = H2D(List*, h); + l->tail = H; + l->t = &Tptr; + Tptr.ref++; + e->ref++; + *(WORD**)l->data = elem; + return l; +} + +static +PElement* +elistelement1(Prefab_Environ *e, Prefab_Element *elem, Prefab_Element *new, enum Elementtype kind) +{ + int first; + PElement *pelem; + List *atom; + + if(badenviron(e, 0)) + return H; + + gchalt++; + first = 0; + if(new == H) + atom = H; + else + atom = prefabwrap(new); + if(elem == H){ + pelem = mkelement(e, kind); + elem = &pelem->e; + pelem->first = H; + pelem->nkids = 0; + }else + pelem = (PElement*)elem; + if(atom == H) + goto Return; + + if(elem->kids != pelem->first) + error("list Element has been modified externally"); + if(elem->kids == H){ + elem->kids = atom; + pelem->first = atom; + pelem->last = atom; + pelem->vfirst = atom; + pelem->vlast = atom; + first = 1; + } + if(new->kind!=ESeparator && Dx(elem->r)==0){ + elem->r = new->r; + pelem->drawpt.x = elem->r.min.x; + pelem->drawpt.y = elem->r.min.y; + } + pelem->nkids++; + if(first) + goto Return; + pelem->last->tail = atom; + pelem->last = atom; + pelem->vlast = atom; + if(new->kind != ESeparator){ + if(kind == EVertical){ + elem->r.max.y += Dy(new->r); + if(elem->r.min.x > new->r.min.x) + elem->r.min.x = new->r.min.x; + if(elem->r.max.x < new->r.max.x) + elem->r.max.x = new->r.max.x; + }else{ + elem->r.max.x += Dx(new->r); + if(elem->r.min.y > new->r.min.y) + elem->r.min.y = new->r.min.y; + if(elem->r.max.y < new->r.max.y) + elem->r.max.y = new->r.max.y; + } + } + pelem->pkind = kind; + + Return: + gchalt--; + return pelem; +} + +PElement* +elistelement(Prefab_Environ *e, Prefab_Element *new, enum Elementtype kind) +{ + return elistelement1(e, H, new, kind); +} + +PElement* +appendelist(Prefab_Element *elem, Prefab_Element *new) +{ + if(elem->kind!=EVertical && elem->kind!=EHorizontal){ + kwerrstr("appendelist to non-list"); + return H; + } + return elistelement1(elem->environ, elem, new, elem->kind); +} |
