/* * return the widget within tk with by point p (in widget coords) */ Tk* tkinwindow(Tk *tk, Point p, int descend) { Tk *f; Point q; if (ptinrect(p, tkrect(tk, 1)) == 0) return nil; for (;;) { if (descend && tkmethod[tk->type]->inwindow != nil) f = tkmethod[tk->type]->inwindow(tk, &p); else { q = p; for (f = tk->slave; f; f = f->next) { q.x = p.x - (f->act.x + f->borderwidth); q.y = p.y - (f->act.y + f->borderwidth); if (ptinrect(q, tkrect(f, 1))) break; } p = q; } if (f == nil || f == tk) return tk; tk = f; } }
static char* tkentryicursor(Tk *tk, char *arg, char **val) { TkEntry *tke = TKobj(TkEntry, tk); int index, locked; char *r, *buf; USED(val); buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tkword(tk->env->top, arg, buf, buf+Tkmaxitem, nil); r = tkentryparseindex(tk, buf, &index); free(buf); if(r != nil) return r; tke->icursor = index; locked = lockdisplay(tk->env->top->display); tke->xicursor = entrytextwidth(tk, tke->icursor); if (locked) unlockdisplay(tk->env->top->display); blinkreset(tk); tk->dirty = tkrect(tk, 1); return nil; }
static void tkentrysee(Tk *tk, int index, int jump) { TkEntry *tke = TKobj(TkEntry, tk); int dx, margin; Rectangle r; r = tkentrybbox(tk, index); dx = tk->act.width - 2*xinset(tk); if (jump) margin = dx / 4; else margin = 0; if (r.min.x <= tke->x0 || r.max.x > tke->x0 + dx) { if (r.min.x <= tke->x0) { tke->x0 = r.min.x - margin; if (tke->x0 < 0) tke->x0 = 0; } else if (r.max.x >= tke->x0 + dx) { tke->x0 = r.max.x - dx + margin; if (tke->x0 > tke->xlen - dx) tke->x0 = tke->xlen - dx; } tk->dirty = tkrect(tk, 0); } r = rectaddpt(r, Pt(xinset(tk) - tke->x0, yinset(tk))); tksee(tk, r, r.min); }
static char* tkscalebut1p(Tk *tk, char *arg, char **val) { int z[2]; char *v, *e; TkScale *tks = TKobj(TkScale, tk); int repeat; USED(val); v = tkscaleposn(tk->env, tk, arg, z); if(v == nil) return TkBadvl; e = nil; if(v[0] == '\0' || z[0] < tks->center-tks->sw || z[0] > tks->center+tks->sw) return nil; if(v == slider) { tks->flag |= Dragging; tks->relief = TKsunken; tks->pix = z[1]; tks->base = tks->value; tkscalecheckvalue(tk); } else { e = stepscale(tk, v, &repeat); if (e == nil && repeat) { tks->flag |= Autorepeat; tkrepeat(tk, screpeat, v, TkRptpause, TkRptinterval); } } tk->dirty = tkrect(tk, 1); return e; }
static char* tkentryb1p(Tk *tk, char* arg, char **ret) { TkEntry *tke = TKobj(TkEntry, tk); Point p; int i, locked, x; char buf[32], *e; USED(ret); x = atoi(arg); p = tkscrn2local(tk, Pt(x, 0)); sprint(buf, "@%d", p.x); e = tkentryparseindex(tk, buf, &i); if (e != nil) return e; tke->sel0 = 0; tke->sel1 = 0; tke->icursor = i; tke->anchor = i; tke->flag &= ~Ewordsel; locked = lockdisplay(tk->env->top->display); tke->xsel0 = 0; tke->xsel1 = 0; tke->xicursor = entrytextwidth(tk, tke->icursor); if (locked) unlockdisplay(tk->env->top->display); tke->oldx = x; blinkreset(tk); tkrepeat(tk, autoselect, nil, TkRptpause, TkRptinterval); tk->dirty = tkrect(tk, 0); return nil; }
static char* tklabelconf(Tk *tk, char *arg, char **val) { char *e; TkGeom g; int bd; TkOptab tko[3]; TkLabel *tkl = TKobj(TkLabel, tk); tko[0].ptr = tk; tko[0].optab = tkgeneric; tko[1].ptr = tkl; tko[1].optab = tklabelopts; tko[2].ptr = nil; if(*arg == '\0') return tkconflist(tko, val); g = tk->req; bd = tk->borderwidth; e = tkparse(tk->env->top, arg, tko, nil); tksizelabel(tk); tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkgeomchg(tk, &g, bd); tk->dirty = tkrect(tk, 1); return e; }
static char* tkscrollset(Tk *tk, char *arg, char **val) { TkTop *t; char *e; TkScroll *tks = TKobj(TkScroll, tk); USED(val); t = tk->env->top; e = tkfracword(t, &arg, &tks->top, nil); if (e != nil) return e; e = tkfracword(t, &arg, &tks->bot, nil); if (e != nil) return e; if(tks->top < 0) tks->top = 0; if(tks->top > TKI2F(1)) tks->top = TKI2F(1); if(tks->bot < 0) tks->bot = 0; if(tks->bot > TKI2F(1)) tks->bot = TKI2F(1); tk->dirty = tkrect(tk, 1); return nil; }
/* our dirty little secret */ static void focusdirty(Tk *tk) { if(tk->highlightwidth > 0){ tk->dirty = tkrect(tk, 1); tkdirty(tk); } }
void tksetslavereq(Tk *slave, TkGeom frame) { Point border; TkGeom pos, old; int slave2BW; void (*geomfn)(Tk*); border.x = slave->pad.x; border.y = slave->pad.y; slave2BW = slave->borderwidth * 2; pos.width = slave->req.width + slave2BW + slave->ipad.x; if((slave->flag&Tkfillx) || (pos.width > (frame.width - border.x))) pos.width = frame.width - border.x; pos.height = slave->req.height + slave2BW + slave->ipad.y; if((slave->flag&Tkfilly) || (pos.height > (frame.height - border.y))) pos.height = frame.height - border.y; border.x /= 2; border.y /= 2; if(slave->flag & Tknorth) pos.y = frame.y + border.y; else if(slave->flag & Tksouth) pos.y = frame.y + frame.height - pos.height - border.y; else pos.y = frame.y + (frame.height - pos.height)/2; if(slave->flag & Tkwest) pos.x = frame.x + border.x; else if(slave->flag & Tkeast) pos.x = frame.x + frame.width - pos.width - border.x; else pos.x = frame.x + (frame.width - pos.width)/2; pos.width -= slave2BW; pos.height -= slave2BW; if(memcmp(&slave->act, &pos, sizeof(TkGeom)) != 0) { old = slave->act; slave->act = pos; geomfn = tkmethod[slave->type]->geom; if(geomfn != nil) geomfn(slave); if(slave->slave) tkpackqit(slave); tkdeliver(slave, TkConfigure, &old); slave->dirty = tkrect(slave, 1); slave->flag |= Tkrefresh; } }
static char* tkcvsview(Tk *tk, char *arg, char **val, int nl, int *posn, int min, int max, int inc) { TkTop *t; int top, bot, diff, amount; char *e; char buf[Tkmaxitem], *v; diff = max-min; if(*arg == '\0') { if ( diff == 0 ) top = bot = 0; else { top = TKI2F(*posn-min)/diff; bot = TKI2F(*posn+nl-min)/diff; } v = tkfprint(buf, top); *v++ = ' '; tkfprint(v, bot); return tkvalue(val, "%s", buf); } t = tk->env->top; arg = tkword(t, arg, buf, buf+sizeof(buf), nil); if(strcmp(buf, "moveto") == 0) { e = tkfrac(&arg, &top, nil); if (e != nil) return e; *posn = min + TKF2I((top+1)*diff); } else if(strcmp(buf, "scroll") == 0) { arg = tkword(t, arg, buf, buf+sizeof(buf), nil); amount = atoi(buf); tkword(t, arg, buf, buf+sizeof(buf), nil); if(buf[0] == 'p') /* Pages */ amount = amount * nl * 9 /10; else if (inc > 0) amount *= inc; else amount = amount * nl / 10; *posn += amount; } else return TkBadcm; bot = max - nl; if(*posn > bot) *posn = bot; if(*posn < min) *posn = min; tk->dirty = tkrect(tk, 0); return nil; }
static void showcaret(Tk *tk, int on) { TkEntry *e = TKobj(TkEntry, tk); if (on) e->flag |= Ecursoron; else e->flag &= ~Ecursoron; tk->dirty = tkrect(tk, 0); }
static char* tkScrolBut1R(Tk *tk, char *arg, char **val) { TkScroll *tks = TKobj(TkScroll, tk); USED(val); USED(arg); tkcancelrepeat(tk); tks->flag &= ~(ActiveA1|ActiveA2|ActiveB1|ButtonA1|ButtonA2|ButtonB1|Autorepeat); tk->dirty = tkrect(tk, 1); return nil; }
char* tkseecmd(TkTop *t, char *arg, char **ret) { TkOptab tko[2]; TkSee opts; TkName *names; Tk *tk; char *e; Rectangle vr; Point vp; opts.r[0] = bbnil.min.x; opts.r[1] = bbnil.min.y; opts.r[2] = bbnil.max.x; opts.r[3] = bbnil.max.y; opts.p[0] = bbnil.max.x; opts.p[1] = bbnil.max.y; opts.query = 0; tko[0].ptr = &opts; tko[0].optab = seeopts; tko[1].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if (e != nil) return e; if (names == nil) return TkBadwp; tk = tklook(t, names->name, 0); tkfreename(names); if (tk == nil) return TkBadwp; if (opts.query) { if (!tkvisiblerect(tk, &vr)) return nil; /* XXX should this be converted into screen coords? */ return tkvalue(ret, "%d %d %d %d", vr.min.x, vr.min.y, vr.max.x, vr.max.y); } vr.min.x = opts.r[0]; vr.min.y = opts.r[1]; vr.max.x = opts.r[2]; vr.max.y = opts.r[3]; vp.x = opts.p[0]; vp.y = opts.p[1]; if (eqrect(vr, bbnil)) vr = tkrect(tk, 1); if (eqpt(vp, bbnil.max)) vp = vr.min; tksee(tk, vr, vp); return nil; }
/* tkScrolBut1P %x %y */ static char* tkScrolBut1P(Tk *tk, char *arg, char **val) { int pix; TkTop *t; char *e, *fmt, buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); USED(val); t = tk->env->top; if (tks->flag & Autorepeat) return nil; arg = tkword(t, arg, buf, buf+sizeof(buf), nil); if(tks->orient == Tkvertical) tkword(t, arg, buf, buf+sizeof(buf), nil); if(buf[0] == '\0') return TkBadvl; pix = atoi(buf); tks->dragpix = pix; tks->dragtop = tks->top; tks->dragbot = tks->bot; pix += tk->borderwidth; fmt = nil; e = nil; if(pix <= tks->a1) { fmt = "%s scroll -1 unit"; tks->flag |= ButtonA1; } if(pix > tks->a1 && pix <= tks->t1) fmt = "%s scroll -1 page"; if(pix > tks->t1 && pix < tks->t2) tks->flag |= ButtonB1; if(pix >= tks->t2 && pix < tks->a2) fmt = "%s scroll 1 page"; if(pix >= tks->a2) { fmt = "%s scroll 1 unit"; tks->flag |= ButtonA2; } if(tks->cmd != nil && fmt != nil) { snprint(buf, sizeof(buf), fmt, tks->cmd); e = tkexec(t, buf, nil); tks->flag |= Autorepeat; tkrepeat(tk, sbrepeat, fmt, TkRptpause, TkRptinterval); } tk->dirty = tkrect(tk, 1); return e; }
static void tkcvsgeom(Tk *tk) { TkCanvas *c; c = TKobj(TkCanvas, tk); tkcvsf2i(tk, c); tk->dirty = tkrect(tk, 1); c->update = c->region; tkcvssv(tk); tkcvssh(tk); }
static char* tkscaledrag(Tk *tk, char *arg, char **val) { int x, y, v; char *e, buf[Tkmaxitem], f[32]; TkScale *tks = TKobj(TkScale, tk); USED(val); if((tks->flag & Dragging) == 0) return nil; if(tks->flag & Autorepeat) return nil; e = tkfracword(tk->env->top, &arg, &x, tk->env); if(e != nil) return e; e = tkfracword(tk->env->top, &arg, &y, tk->env); if(e != nil) return e; if(tks->orient == Tkvertical) v = TKF2I(y) + tk->borderwidth; else v = TKF2I(x) + tk->borderwidth; v -= tks->pix; x = tks->pixmax-tks->pixmin; if (x!=tks->sl) v = tks->base + (vlong)v * (tks->to-tks->from)/(x-tks->sl); else v = tks->base; if(tks->res > 0) { int a = tks->res / 2; if (v < 0) a = -a; v = ((v+a)/tks->res)*tks->res; } tks->value = v; tkscalecheckvalue(tk); if(tks->command != nil && tks->jump != BoolT) { tkfprint(f, tks->value); snprint(buf, sizeof(buf), "%s %s", tks->command, f); e = tkexec(tk->env->top, buf, nil); } tk->dirty = tkrect(tk, 1); return e; }
static char* tkscaleset(Tk *tk, char *arg, char **val) { TkScale *tks = TKobj(TkScale, tk); char *e; USED(val); e = tkfracword(tk->env->top, &arg, &tks->value, tk->env); if (e != nil) return e; tkscalecheckvalue(tk); tk->dirty = tkrect(tk, 1); return nil; }
static void tkcvsseerect(Tk *tk, Rectangle r, Point p) { TkCanvas *c; int scrollh, scrollv; c = TKobj(TkCanvas, tk); scrollh = tkadjustvis(&c->view.x, c->view.x, c->view.x + tk->act.width, r.min.x, r.max.x, p.x); scrollv = tkadjustvis(&c->view.y, c->view.y, c->view.y + tk->act.height, r.min.y, r.max.y, p.y); if (scrollh) tkcvssh(tk); if (scrollv) tkcvssv(tk); if (scrollh || scrollv) tk->dirty = tkrect(tk, 0); }
static void screpeat(Tk *tk, void *v, int cancelled) { char *e, *pos; int repeat; TkScale *tks = TKobj(TkScale, tk); pos = v; if (cancelled) { tks->flag &= ~Autorepeat; return; } e = stepscale(tk, pos, &repeat); if(e != nil || !repeat) { tks->flag &= ~Autorepeat; tkcancelrepeat(tk); } tk->dirty = tkrect(tk, 1); tkupdate(tk->env->top); }
static char* tkcvsconf(Tk *tk, char *arg, char **val) { char *e; int bd; TkGeom g; Rectangle r; TkOptab tko[3]; TkCanvas *c = TKobj(TkCanvas, tk); tko[0].ptr = c; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; if(*arg == '\0') return tkconflist(tko, val); r.min = c->view; r.max.x = r.min.x+tk->act.width; r.max.y = r.min.y+tk->act.height; tkbbmax(&c->update, &r); tkbbmax(&c->update, &c->region); bd = tk->borderwidth; g = tk->req; e = tkparse(tk->env->top, arg, tko, nil); if(e != nil) return e; tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkcvsf2i(tk, c); tkcvsgeom(tk); tkgeomchg(tk, &g, bd); tkbbmax(&c->update, &c->region); tk->dirty = tkrect(tk, 1); return nil; }
static char* tkscrollidentify(Tk *tk, char *arg, char **val) { int gotarg; TkTop *t; char *v, buf[Tkmaxitem]; Point p; TkScroll *tks = TKobj(TkScroll, tk); t = tk->env->top; arg = tkword(t, arg, buf, buf+sizeof(buf), &gotarg); if (!gotarg) return TkBadvl; p.x = atoi(buf); tkword(t, arg, buf, buf+sizeof(buf), &gotarg); if (!gotarg) return TkBadvl; p.y = atoi(buf); if (!ptinrect(p, tkrect(tk, 0))) return nil; if (tks->orient == Tkvertical) p.x = p.y; p.x += tk->borderwidth; v = ""; if(p.x <= tks->a1) v = "arrow1"; if(p.x > tks->a1 && p.x <= tks->t1) v = "trough1"; if(p.x > tks->t1 && p.x < tks->t2) v = "slider"; if(p.x >= tks->t2 && p.x < tks->a2) v = "trough2"; if(p.x >= tks->a2) v = "arrow2"; return tkvalue(val, "%s", v); }
static char* tkdrawslaves1(Tk *tk, Point orig, Image *dst, int *dirty) { Tk *f; char *e = nil; Point worig; Rectangle r, oclip; worig.x = orig.x + tk->act.x + tk->borderwidth; worig.y = orig.y + tk->act.y + tk->borderwidth; r = rectaddpt(tk->dirty, worig); if (Dx(r) > 0 && rectXrect(r, dst->clipr)) { e = tkmethod[tk->type]->draw(tk, orig); tk->dirty = bbnil; *dirty = 1; } if(e != nil) return e; /* * grids need clipping * XXX BUG: they can't, 'cos text widgets don't clip appropriately. */ if (tk->grid != nil) { r = rectaddpt(tkrect(tk, 0), worig); if (rectclip(&r, dst->clipr) == 0) return nil; oclip = dst->clipr; replclipr(dst, 0, r); } for(f = tk->slave; e == nil && f; f = f->next) e = tkdrawslaves1(f, worig, dst, dirty); if (tk->grid != nil) replclipr(dst, 0, oclip); return e; }
static char* tkscrollactivate(Tk *tk, char *arg, char **val) { int s, gotarg; char buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); USED(val); tkword(tk->env->top, arg, buf, buf+sizeof(buf), &gotarg); s = tks->flag; if (!gotarg) { char *a; if (s & ActiveA1) a = "arrow1"; else if (s & ActiveA2) a = "arrow2"; else if (s & ActiveB1) a = "slider"; else a = ""; return tkvalue(val, a); } tks->flag &= ~(ActiveA1 | ActiveA2 | ActiveB1); if(strcmp(buf, "arrow1") == 0) tks->flag |= ActiveA1; else if(strcmp(buf, "arrow2") == 0) tks->flag |= ActiveA2; else if(strcmp(buf, "slider") == 0) tks->flag |= ActiveB1; if(s ^ tks->flag) tk->dirty = tkrect(tk, 1); return nil; }
static char* tkscalekey(Tk *tk, char *arg, char **val) { char *e; int key; char *pos = nil; USED(arg); USED(val); if(tk->flag & Tkdisabled) return nil; key = strtol(arg, nil, 0); if (key == Up || key == Left) pos = trough1; else if (key == Down || key == Right) pos = trough2; if (pos != nil) { e = stepscale(tk, pos, nil); tk->dirty = tkrect(tk, 1); return e; } return nil; }
static char* tkscalebut1r(Tk *tk, char *arg, char **val) { TkScale *tks = TKobj(TkScale, tk); char *e, buf[Tkmaxitem], f[32]; USED(val); USED(arg); if(tks->flag & Autorepeat) { tkcancelrepeat(tk); tks->flag &= ~Autorepeat; } e = nil; if (tks->flag & Dragging) { if (tks->command != nil && tks->jump == BoolT && (tks->flag & Dragging)) { tkfprint(f, tks->value); snprint(buf, sizeof(buf), "%s %s", tks->command, f); e = tkexec(tk->env->top, buf, nil); } tks->relief = TKraised; tks->flag &= ~Dragging; tk->dirty = tkrect(tk, 1); } return e; }
/* tkScaleMotion %x %y */ static char* tkscalemotion(Tk *tk, char *arg, char **val) { int o, z[2]; char *v; TkScale *tks = TKobj(TkScale, tk); extern int tkstylus; USED(val); v = tkscaleposn(tk->env, tk, arg, z); if(v == nil) return TkBadvl; o = tk->flag; if(v != slider || z[0] < tks->center-tks->sw || z[0] > tks->center+tks->sw) tk->flag &= ~Tkactivated; else if(tkstylus == 0 || tk->env->top->ctxt->mstate.b != 0) tk->flag |= Tkactivated; if((o & Tkactivated) != (tk->flag & Tkactivated)) tk->dirty = tkrect(tk, 1); return nil; }
char* tkentryselect(Tk *tk, char *arg, char **val) { TkTop *top; int start, from, to, locked; TkEntry *tke; char *e, *buf; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; tke = TKobj(TkEntry, tk); top = tk->env->top; arg = tkword(top, arg, buf, buf+Tkmaxitem, nil); if(strcmp(buf, "clear") == 0) { tke->sel0 = 0; tke->sel1 = 0; } else if(strcmp(buf, "from") == 0) { tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &tke->anchor); tke->flag &= ~Ewordsel; free(buf); return e; } else if(strcmp(buf, "to") == 0) { tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &to); if(e != nil) { free(buf); return e; } if(to < tke->anchor) { if(tke->flag & Ewordsel) while(to > 0 && tkiswordchar(tke->text[to-1])) --to; tke->sel0 = to; tke->sel1 = tke->anchor; } else if(to >= tke->anchor) { if(tke->flag & Ewordsel) while(to < tke->textlen && tkiswordchar(tke->text[to])) to++; tke->sel0 = tke->anchor; tke->sel1 = to; } tkentrysee(tk, to, 0); recalcentry(tk); } else if(strcmp(buf, "word") == 0) { /* inferno invention */ tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &start); if(e != nil) { free(buf); return e; } from = start; while(from > 0 && tkiswordchar(tke->text[from-1])) --from; to = start; while(to < tke->textlen && tkiswordchar(tke->text[to])) to++; tke->sel0 = from; tke->sel1 = to; tke->anchor = from; tke->icursor = from; tke->flag |= Ewordsel; locked = lockdisplay(tk->env->top->display); tke->xicursor = entrytextwidth(tk, tke->icursor); if (locked) unlockdisplay(tk->env->top->display); } else if(strcmp(buf, "present") == 0) { e = tkvalue(val, "%d", tke->sel1 > tke->sel0); free(buf); return e; } else if(strcmp(buf, "range") == 0) { arg = tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &from); if(e != nil) { free(buf); return e; } tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &to); if(e != nil) { free(buf); return e; } tke->sel0 = from; tke->sel1 = to; if(to <= from) { tke->sel0 = 0; tke->sel1 = 0; } } else if(strcmp(buf, "adjust") == 0) { tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &to); if(e != nil) { free(buf); return e; } if(tke->sel0 == 0 && tke->sel1 == 0) { tke->sel0 = tke->anchor; tke->sel1 = to; } else { if(abs(tke->sel0-to) < abs(tke->sel1-to)) { tke->sel0 = to; tke->anchor = tke->sel1; } else { tke->sel1 = to; tke->anchor = tke->sel0; } } if(tke->sel0 > tke->sel1) { to = tke->sel0; tke->sel0 = tke->sel1; tke->sel1 = to; } } else { free(buf); return TkBadcm; } locked = lockdisplay(tk->env->top->display); tke->xsel0 = entrytextwidth(tk, tke->sel0); tke->xsel1 = entrytextwidth(tk, tke->sel1); if (locked) unlockdisplay(tk->env->top->display); tk->dirty = tkrect(tk, 1); free(buf); return nil; }
static int tkpacker(Tk *master) { Tk *slave; TkGeom frame, cavity, pos; int maxwidth, maxheight, tmp, slave2BW; pos.width = 0; pos.height = 0; maxwidth = 0; maxheight = 0; master->flag |= Tkrefresh; for (slave = master->slave; slave != nil; slave = slave->next) { slave2BW = slave->borderwidth*2; if(slave->flag & (Tktop|Tkbottom)) { tmp = slave->req.width + slave2BW + slave->pad.x + slave->ipad.x + pos.width; if(tmp > maxwidth) maxwidth = tmp; pos.height += slave->req.height + slave2BW + slave->pad.y + slave->ipad.y; } else { tmp = slave->req.height + slave2BW + slave->pad.y + slave->ipad.y + pos.height; if(tmp > maxheight) maxheight = tmp; pos.width += slave->req.width + slave2BW + + slave->pad.x + slave->ipad.x; } } if(pos.width > maxwidth) maxwidth = pos.width; if(pos.height > maxheight) maxheight = pos.height; if(maxwidth != master->req.width || maxheight != master->req.height) if((master->flag & Tknoprop) == 0) { if(master->geom != nil) { master->geom(master, master->act.x, master->act.y, maxwidth, maxheight); } else { master->req.width = maxwidth; master->req.height = maxheight; tkpackqit(master->master); } return 0; } cavity.x = 0; cavity.y = 0; pos.x = 0; pos.y = 0; cavity.width = master->act.width; cavity.height = master->act.height; for(slave = master->slave; slave != nil; slave = slave->next) { slave2BW = slave->borderwidth*2; if(slave->flag & (Tktop|Tkbottom)) { frame.width = cavity.width; frame.height = slave->req.height + slave2BW + slave->pad.y + slave->ipad.y; if(slave->flag & Tkexpand) frame.height += tkexpandy(slave, cavity.height); cavity.height -= frame.height; if(cavity.height < 0) { frame.height += cavity.height; cavity.height = 0; } frame.x = cavity.x; if(slave->flag & Tktop) { frame.y = cavity.y; cavity.y += frame.height; } else frame.y = cavity.y + cavity.height; } else { frame.height = cavity.height; frame.width = slave->req.width + slave2BW + slave->pad.x + slave->ipad.x; if(slave->flag & Tkexpand) frame.width += tkexpandx(slave, cavity.width); cavity.width -= frame.width; if(cavity.width < 0) { frame.width += cavity.width; cavity.width = 0; } frame.y = cavity.y; if(slave->flag & Tkleft) { frame.x = cavity.x; cavity.x += frame.width; } else frame.x = cavity.x + cavity.width; } tksetslavereq(slave, frame); } master->dirty = tkrect(master, 1); tkdirty(master); return 1; }
char* tkdrawcanv(Tk *tk, Point orig) { Image *dst; TkCitem *i; Display *d; TkCanvas *c; Rectangle r, bufr, oclipr; int vis, alpha, buffer; Point rel, p; TkCimeth *imeth; c = TKobj(TkCanvas, tk); d = tk->env->top->display; dst = tkimageof(tk); /* * translation from local to screen coords */ rel.x = orig.x + tk->act.x + tk->borderwidth; rel.y = orig.y + tk->act.y + tk->borderwidth; buffer = c->buffer; if (buffer == TkCbufauto) buffer = TkCbufvisible; /* buffer = (dst == TKobj(TkWin, tk->env->top->root)->image) ? TkCbufvisible : TkCbufnone; */ if (buffer == TkCbufnone) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = dst; c->ialloc = 0; r = tkrect(tk, 0); bufr = r; rectclip(&bufr, tk->dirty); oclipr = dst->clipr; replclipr(dst, 0, rectaddpt(bufr, rel)); draw(dst, rectaddpt(bufr, rel), tkgc(tk->env, TkCbackgnd), nil, ZP); p = subpt(rel, c->view); p.x = TKI2F(p.x); p.y = TKI2F(p.y); bufr = rectaddpt(bufr, c->view); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, bufr)) { imeth = &tkcimethod[i->type]; imeth->coord(i, nil, p.x, p.y); imeth->draw(dst, i, tk->env); imeth->coord(i, nil, -p.x, -p.y); } } replclipr(dst, 0, oclipr); } else { if (c->buffer == TkCbufall) bufr = c->region; else { bufr.min = c->view; bufr.max.x = c->view.x + tk->act.width; bufr.max.y = c->view.y + tk->act.height; } alpha = (tk->env->colors[TkCbackgnd] & 0xff) != 0xff; if(c->image == nil || eqrect(bufr, c->image->r) == 0) { if(c->image != nil && c->ialloc) freeimage(c->image); c->image = allocimage(d, bufr, alpha?RGBA32:d->image->chan, 0, tk->env->colors[TkCbackgnd]); c->ialloc = 1; c->update = bufr; tkcvssetdirty(tk); /* unnecessary? */ } if(c->image == nil) return nil; r = c->update; if (rectclip(&r, c->image->r)) { if (alpha) drawop(c->image, c->update, nil, nil, ZP, Clear); draw(c->image, c->update, tkgc(tk->env, TkCbackgnd), nil, c->view); replclipr(c->image, 0, r); for(i = c->head; i; i = i->next) { if(rectXrect(i->p.bb, r)) tkcimethod[i->type].draw(c->image, i, tk->env); } replclipr(c->image, 0, c->image->r); } /* * if the visible area of the canvas image doesn't * fit completely within the dirty rectangle, * then we'll need to draw the background behind it */ r = tkrect(tk, 0); bufr = rectsubpt(bufr, c->view); vis = rectclip(&bufr, tkrect(tk, 0)); if (!vis || !rectinrect(tk->dirty, bufr)) draw(dst, rectaddpt(tk->dirty, rel), tkgc(tk->env, TkCbackgnd), nil, c->view); if (vis && rectclip(&bufr, tk->dirty)) draw(dst, rectaddpt(bufr, rel), c->image, nil, addpt(bufr.min, c->view)); } /* * if the border is dirty too, then draw that */ if (!rectinrect(tk->dirty, bufr)) { r.min = addpt(r.min, rel); r.min.x -= tk->borderwidth; r.min.y -= tk->borderwidth; tkdrawrelief(dst, tk, r.min, TkCbackgnd, tk->relief); } c->update = bbnil; return nil; }
static char* tkentrydelete(Tk *tk, char *arg, char **val) { TkTop *top; TkEntry *tke; int d0, d1, locked; char *e, *buf; Rune *text; USED(val); tke = TKobj(TkEntry, tk); top = tk->env->top; buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; arg = tkword(top, arg, buf, buf+Tkmaxitem, nil); e = tkentryparseindex(tk, buf, &d0); if(e != nil) { free(buf); return e; } d1 = d0+1; tkword(top, arg, buf, buf+Tkmaxitem, nil); if(buf[0] != '\0') { e = tkentryparseindex(tk, buf, &d1); if(e != nil) { free(buf); return e; } } free(buf); if(d1 <= d0 || tke->textlen == 0 || d0 >= tke->textlen) return nil; memmove(tke->text+d0, tke->text+d1, (tke->textlen-d1)*sizeof(Rune)); tke->textlen -= d1 - d0; text = realloc(tke->text, (tke->textlen+1) * sizeof(Rune)); if (text != nil) tke->text = text; tke->sel0 = adjustfordel(d0, d1, tke->sel0); tke->sel1 = adjustfordel(d0, d1, tke->sel1); tke->icursor = adjustfordel(d0, d1, tke->icursor); tke->anchor = adjustfordel(d0, d1, tke->anchor); locked = lockdisplay(tk->env->top->display); if (d1 < tke->v0) tke->x0 = entrytextwidth(tk, tke->v0 - (d1 - d0)) + (tke->x0 - tke->xv0); else if (d0 < tke->v0) tke->x0 = entrytextwidth(tk, d0); if (locked) unlockdisplay(tk->env->top->display); recalcentry(tk); e = tkentrysh(tk); blinkreset(tk); tk->dirty = tkrect(tk, 1); return e; }