summaryrefslogtreecommitdiff
path: root/libprefab/elistelement.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /libprefab/elistelement.c
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'libprefab/elistelement.c')
-rw-r--r--libprefab/elistelement.c113
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);
+}