123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- #include "lib9.h"
- #include "draw.h"
- #include "tk.h"
- #include "canvs.h"
- #define O(t, e) ((long)(&((t*)0)->e))
- /* Window Options (+ means implemented)
- +tags
- +width
- +height
- +window
- +anchor
- */
- static
- TkOption windopts[] =
- {
- "width", OPTdist, O(TkCwind, width), nil,
- "height", OPTdist, O(TkCwind, height), nil,
- "anchor", OPTstab, O(TkCwind, flags), tkanchor,
- "window", OPTwinp, O(TkCwind, sub), nil,
- nil
- };
- static
- TkOption itemopts[] =
- {
- "tags", OPTctag, O(TkCitem, tags), nil,
- nil
- };
- static void
- tkcvswindsize(TkCitem *i)
- {
- Tk *s;
- int bw;
- Point p;
- TkGeom old;
- TkCwind *w;
- w = TKobj(TkCwind, i);
- s = w->sub;
- if(s == nil)
- return;
- if(w->width != s->act.width || w->height != s->act.height) {
- old = s->act;
- s->act.width = w->width;
- s->act.height = w->height;
- if(s->slave) {
- tkpackqit(s);
- tkrunpack(s->env->top);
- }
- tkdeliver(s, TkConfigure, &old);
- }
- p = tkcvsanchor(i->p.drawpt[0], s->act.width, s->act.height, w->flags);
- s->act.x = p.x;
- s->act.y = p.y;
- bw = 2*s->borderwidth;
- i->p.bb.min = p;
- i->p.bb.max.x = p.x + s->act.width + bw;
- i->p.bb.max.y = p.y + s->act.height + bw;
- }
- TkCitem*
- tkcvsfindwin(Tk *tk)
- {
- Tk *parent, *sub;
- TkCitem *i;
- TkCanvas *c;
- TkCwind *w;
- sub = tkfindsub(tk);
- if(sub == nil)
- return nil;
- parent = sub->parent;
- if(parent->type != TKcanvas)
- return nil; /* inconsistent */
- c = TKobj(TkCanvas, parent);
- for(i = c->head; i != nil; i = i->next) {
- if(i->type == TkCVwindow) {
- w = TKobj(TkCwind, i);
- if(w->sub == sub)
- return i;
- }
- }
- return nil;
- }
- void
- tkcvsforgetsub(Tk *sub, Tk *tk)
- {
- TkCwind *w;
- TkCitem *i;
- i = tkcvsfindwin(sub);
- if(i == nil)
- return;
- w = TKobj(TkCwind, i);
- if(w->focus == tk) {
- if(0)print("tkcsvsforget sub %p %q focus %p %q\n", sub, tkname(sub), tk, tkname(tk));
- w->focus = nil;
- }
- }
- static void
- tkcvswindgeom(Tk *sub, int x, int y, int w, int h)
- {
- TkCitem *i;
- Tk *parent;
- TkCanvas *c;
- TkCwind *win;
- USED(x);
- USED(y);
- parent = sub->parent;
- win = nil;
- c = TKobj(TkCanvas, parent);
- for(i = c->head; i; i = i->next) {
- if(i->type == TkCVwindow) {
- win = TKobj(TkCwind, i);
- if(win->sub == sub)
- break;
- }
- }
- tkbbmax(&c->update, &i->p.bb);
- if((win->flags & Tksetwidth) == 0)
- win->width = w;
- if ((win->flags & Tksetheight) == 0)
- win->height = h;
- sub->req.width = w;
- sub->req.height = h;
- tkcvswindsize(i);
- tkbbmax(&c->update, &i->p.bb);
- tkcvsdirty(parent);
- }
- static void
- tkcvssubdestry(Tk *sub)
- {
- Tk *tk;
- TkCitem *i;
- TkCanvas *c;
- TkCwind *win;
- tk = sub->parent;
- if(tk == nil)
- return;
- if(0)print("tkcvssubdestry %p %q\n", sub, tkname(sub));
- i = tkcvsfindwin(sub);
- if(i == nil)
- return;
- win = TKobj(TkCwind, i);
- if(win->sub != sub){
- if(win->sub != nil)
- print("inconsistent tkcvssubdestry %p %q\n", sub, tkname(sub));
- return;
- }
- c = TKobj(TkCanvas, tk);
- tkbbmax(&c->update, &i->p.bb);
- tkcvssetdirty(tk);
- win->focus = nil;
- win->sub = nil;
- sub->parent = nil;
- sub->geom = nil;
- }
- Point
- tkcvsrelpos(Tk *sub)
- {
- Tk *tk;
- TkCitem *i;
- TkCanvas *c;
- TkCwind *win;
- tk = sub->parent;
- if(tk == nil)
- return ZP;
- c = TKobj(TkCanvas, tk);
- for(i = c->head; i; i = i->next) {
- if(i->type == TkCVwindow) {
- win = TKobj(TkCwind, i);
- if(win->sub == sub)
- return subpt(i->p.bb.min, c->view);
- }
- }
- return ZP;
- }
- static char*
- tkcvswindchk(Tk *tk, TkCwind *w, Tk *oldsub)
- {
- Tk *sub;
- sub = w->sub;
- if (sub != oldsub) {
- w->sub = oldsub;
- if(sub == nil)
- return nil;
-
- if(sub->flag & Tkwindow)
- return TkIstop;
- if(sub->master != nil || sub->parent != nil)
- return TkWpack;
- if (oldsub != nil) {
- oldsub->parent = nil;
- oldsub->geom = nil;
- oldsub->destroyed = nil;
- }
- w->sub = sub;
- w->focus = nil;
- sub->parent = tk;
- tksetbits(w->sub, Tksubsub);
- sub->geom = tkcvswindgeom;
- sub->destroyed = tkcvssubdestry;
-
- if(w->width == 0)
- w->width = sub->req.width;
- if(w->height == 0)
- w->height = sub->req.height;
- }
- return nil;
- }
- char*
- tkcvswindcreat(Tk* tk, char *arg, char **val)
- {
- char *e;
- TkCwind *w;
- TkCitem *i;
- TkCanvas *c;
- TkOptab tko[3];
- c = TKobj(TkCanvas, tk);
- i = tkcnewitem(tk, TkCVwindow, sizeof(TkCitem)+sizeof(TkCwind));
- if(i == nil)
- return TkNomem;
- w = TKobj(TkCwind, i);
- w->flags = Tkcenter;
- e = tkparsepts(tk->env->top, &i->p, &arg, 0);
- if(e != nil) {
- tkcvsfreeitem(i);
- return e;
- }
- if(i->p.npoint != 1) {
- tkcvsfreeitem(i);
- return TkFewpt;
- }
- tko[0].ptr = w;
- tko[0].optab = windopts;
- tko[1].ptr = i;
- tko[1].optab = itemopts;
- tko[2].ptr = nil;
- e = tkparse(tk->env->top, arg, tko, nil);
- if(e != nil) {
- tkcvsfreeitem(i);
- return e;
- }
- e = tkcvswindchk(tk, w, nil);
- if(e != nil) {
- tkcvsfreeitem(i);
- return e;
- }
- e = tkcaddtag(tk, i, 1);
- if(e != nil) {
- tkcvsfreeitem(i);
- return e;
- }
- e = tkvalue(val, "%d", i->id);
- if(e != nil) {
- tkcvsfreeitem(i);
- return e;
- }
- tkcvsappend(c, i);
- tkcvswindsize(i);
- tkbbmax(&c->update, &i->p.bb);
- tkcvssetdirty(tk);
- return nil;
- }
- char*
- tkcvswindcget(TkCitem *i, char *arg, char **val)
- {
- TkOptab tko[3];
- TkCwind *w = TKobj(TkCwind, i);
- tko[0].ptr = w;
- tko[0].optab = windopts;
- tko[1].ptr = i;
- tko[1].optab = itemopts;
- tko[2].ptr = nil;
- return tkgencget(tko, arg, val, i->env->top);
- }
- char*
- tkcvswindconf(Tk *tk, TkCitem *i, char *arg)
- {
- char *e;
- int dx, dy;
- TkOptab tko[3];
- TkCwind *w = TKobj(TkCwind, i);
- Tk *oldsub;
- tko[0].ptr = w;
- tko[0].optab = windopts;
- tko[1].ptr = i;
- tko[1].optab = itemopts;
- tko[2].ptr = nil;
- dx = w->width;
- dy = w->height;
- w->width = -1;
- w->height = -1;
- oldsub = w->sub;
- e = tkparse(tk->env->top, arg, tko, nil);
- if(e == nil) {
- e = tkcvswindchk(tk, w, oldsub);
- if(e != nil)
- return e;
- if(w->width == -1)
- w->width = dx;
- else
- w->flags |= Tksetwidth;
- if(w->height == -1)
- w->height = dy;
- else
- w->flags |= Tksetheight;
- tkcvswindsize(i);
- } else {
- w->width = dx;
- w->height = dy;
- }
- return e;
- }
- void
- tkcvswindfree(TkCitem *i)
- {
- Tk *sub;
- TkCwind *w;
- w = TKobj(TkCwind, i);
- sub = w->sub;
- if(sub != nil) {
- sub->parent = nil;
- sub->geom = nil;
- sub->destroyed = nil;
- }
- w->focus = nil;
- w->sub = nil;
- }
- void
- tkcvswinddraw(Image *img, TkCitem *i, TkEnv *pe)
- {
- TkCwind *w;
- Point rel;
- Rectangle r;
- Tk *sub;
- USED(img); /* See tkimageof */
- USED(pe);
- w = TKobj(TkCwind, i);
- sub = w->sub;
- if(sub != nil) {
- int dirty;
- r = i->p.bb;
- rel.x = r.min.x + sub->borderwidth;
- rel.y = r.min.y + sub->borderwidth;
- if (rectclip(&r, img->clipr)) {
- sub->dirty = rectsubpt(r, rel);
- sub->flag |= Tkrefresh;
- tkdrawslaves(sub, ZP, &dirty); /* XXX - Tad: propagate err? */
- }
- }
- }
- char*
- tkcvswindcoord(TkCitem *i, char *arg, int x, int y)
- {
- char *e;
- TkCpoints p;
- /*
- TkCwind *w;
- int xi, yi;
- */
- if(arg == nil) {
- tkxlatepts(i->p.parampt, i->p.npoint, x, y);
- tkxlatepts(i->p.drawpt, i->p.npoint, TKF2I(x), TKF2I(y));
- tkcvswindsize(i);
- /*
- w = TKobj(TkCwind, i);
- xi = TKF2I(x);
- yi = TKF2I(y);
- if (w->sub != nil) {
- w->sub->act.x += xi;
- w->sub->act.y += yi;
- }
- i->p.bb = rectaddpt(i->p.bb, Pt(xi, yi));
- */
- }
- else {
- e = tkparsepts(i->env->top, &p, &arg, 0);
- if(e != nil)
- return e;
- if(p.npoint != 1) {
- tkfreepoint(&p);
- return TkFewpt;
- }
- tkfreepoint(&i->p);
- i->p = p;
- tkcvswindsize(i);
- }
- return nil;
- }
|