void tkcvssv(Tk *tk) { TkCanvas *c; int top, bot, height; char val[Tkminitem], cmd[Tkmaxitem], *v, *e; c = TKobj(TkCanvas, tk); if(c->yscroll == nil) return; top = 0; bot = TKI2F(1); height = Dy(c->region); if(height != 0) { top = TKI2F(c->view.y)/height; bot = TKI2F(c->view.y+tk->act.height)/height; } v = tkfprint(val, top); *v++ = ' '; tkfprint(v, bot); snprint(cmd, sizeof(cmd), "%s %s", c->yscroll, val); e = tkexec(tk->env->top, cmd, nil); if ((e != nil) && (tk->name != nil)) print("tk: yscrollcommand \"%s\": %s\n", tk->name->name, e); }
void tkcvssh(Tk *tk) { int top, bot, width; TkCanvas *c = TKobj(TkCanvas, tk); char val[Tkminitem], cmd[Tkmaxitem], *v, *e; if(c->xscroll == nil) return; top = 0; bot = TKI2F(1); width = Dx(c->region); if(width != 0) { top = TKI2F(c->view.x)/width; bot = TKI2F(c->view.x+tk->act.width)/width; } v = tkfprint(val, top); *v++ = ' '; tkfprint(v, bot); snprint(cmd, sizeof(cmd), "%s %s", c->xscroll, val); e = tkexec(tk->env->top, cmd, nil); if ((e != nil) && (tk->name != nil)) print("tk: xscrollcommand \"%s\": %s\n", tk->name->name, 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; }
static char* tkscrollfraction(Tk *tk, char *arg, char **val) { int len, frac, pos; char buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); arg = tkitem(buf, arg); if(tks->orient == Tkvertical) tkitem(buf, arg); if(*arg == '\0' || *buf == '\0') return TkBadvl; pos = atoi(buf); if(pos < tks->a1) pos = tks->a1; if(pos > tks->a2) pos = tks->a2; len = tks->a2 - tks->a1 - 4*Elembw; frac = TKI2F(1); if(len != 0) frac = TKI2F(pos-tks->a1)/len; tkfprint(buf, frac); return tkvalue(val, "%s", buf); }
char* tkscale(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkName *names; TkScale *tks; TkOptab tko[3]; tk = tknewobj(t, TKscale, sizeof(Tk)+sizeof(TkScale)); if(tk == nil) return TkNomem; tk->flag |= Tktakefocus; tks = TKobj(TkScale, tk); tks->res = TKI2F(1); tks->to = TKI2F(100); tks->len = ScaleLen; tks->orient = Tkvertical; tks->relief = TKraised; tks->sl = ScaleSlider; tks->sv = BoolT; tks->bigi = 0; tko[0].ptr = tk; tko[0].optab = tkgeneric; tko[1].ptr = tks; tko[1].optab = opts; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) { tkfreeobj(tk); return e; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkscalecheckvalue(tk); tksizescale(tk); if (tks->bigi == 0) tks->bigi = TKI2F(TKF2I(tks->to - tks->from) / 10); e = tkbindings(t, tk, b, nelem(b)); if(e != nil) { tkfreeobj(tk); return e; } e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreeobj(tk); return e; } tk->name->link = nil; return tkvalue(ret, "%s", tk->name->name); }
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; }
/* tkScrolDrag %x %y */ static char* tkScrollDrag(Tk *tk, char *arg, char **val) { TkTop *t; int pix, delta; char frac[32], buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); USED(val); t = tk->env->top; if (tks->flag & Autorepeat) return nil; if((tks->flag & ButtonB1) == 0) 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); delta = TKI2F(pix-tks->dragpix); if ( tks->a2 == tks->a1 ) return TkBadvl; delta = delta/(tks->a2-tks->a1-4*Elembw); if(tks->jump == BoolT) { if(tks->dragtop+delta >= 0 && tks->dragbot+delta <= TKI2F(1)) { tks->top = tks->dragtop+delta; tks->bot = tks->dragbot+delta; } return nil; } if(tks->cmd != nil) { delta += tks->dragtop; if(delta < 0) delta = 0; if(delta > TKI2F(1)) delta = TKI2F(1); tkfprint(frac, delta); snprint(buf, sizeof(buf), "%s moveto %s", tks->cmd, frac); return tkexec(t, buf, nil); } return nil; }
char* tkcvsrectcreat(Tk* tk, char *arg, char **val) { char *e; TkCrect *r; TkCitem *i; TkCanvas *c; TkOptab tko[3]; c = TKobj(TkCanvas, tk); i = tkcnewitem(tk, TkCVrect, sizeof(TkCitem)+sizeof(TkCrect)); if(i == nil) return TkNomem; r = TKobj(TkCrect, i); r->width = TKI2F(1); e = tkparsepts(tk->env->top, &i->p, &arg, 0); if(e != nil) { tkcvsfreeitem(i); return e; } if(i->p.npoint != 2) { tkcvsfreeitem(i); return TkFewpt; } tko[0].ptr = r; tko[0].optab = rectopts; 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; } tkmkstipple(r->stipple); e = tkcaddtag(tk, i, 1); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvsrectsize(i); e = tkvalue(val, "%d", i->id); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvsappend(c, i); tkbbmax(&c->update, &i->p.bb); tkcvssetdirty(tk); return nil; }
char* tkcvslinecreat(Tk* tk, char *arg, char **val) { char *e; TkCline *l; TkCitem *i; TkCanvas *c; TkOptab tko[3]; c = TKobj(TkCanvas, tk); i = tkcnewitem(tk, TkCVline, sizeof(TkCitem)+sizeof(TkCline)); if(i == nil) return TkNomem; l = TKobj(TkCline, i); l->width = TKI2F(1); e = tkparsepts(tk->env->top, &i->p, &arg, 0); if(e != nil) { tkcvsfreeitem(i); return e; } tko[0].ptr = l; tko[0].optab = lineopts; 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; } tkmkpen(&l->pen, i->env, l->stipple); e = tkcaddtag(tk, i, 1); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvslinesize(i); e = tkvalue(val, "%d", i->id); if(e != nil) { tkcvsfreeitem(i); return e; } tkcvsappend(c, i); tkbbmax(&c->update, &i->p.bb); tkcvssetdirty(tk); return nil; }
static char* tkscrolldelta(Tk *tk, char *arg, char **val) { int l, delta; char buf[Tkmaxitem]; TkScroll *tks = TKobj(TkScroll, tk); arg = tkitem(buf, arg); if(tks->orient == Tkvertical) tkitem(buf, arg); if(*arg == '\0' || *buf == '\0') return TkBadvl; l = tks->a2-tks->a1-4*Elembw; delta = TKI2F(1); if(l != 0) delta = TKI2F(atoi(buf)) / l; tkfprint(buf, delta); return tkvalue(val, "%s", buf); }
char* tkentrysh(Tk *tk) { TkEntry *tke = TKobj(TkEntry, tk); int dx, top, bot; char *val, *cmd, *v, *e; if(tke->xscroll == nil) return nil; bot = 0; top = Tkfpscalar; if(tke->text != 0 && tke->textlen != 0) { dx = tk->act.width - 2*xinset(tk); if (tke->xlen > dx) { bot = TKI2F(tke->x0) / tke->xlen; top = TKI2F(tke->x0 + dx) / tke->xlen; } } val = mallocz(Tkminitem, 0); if(val == nil) return TkNomem; v = tkfprint(val, bot); *v++ = ' '; tkfprint(v, top); cmd = mallocz(Tkminitem, 0); if(cmd == nil) { free(val); return TkNomem; } sprint(cmd, "%s %s", tke->xscroll, val); e = tkexec(tk->env->top, cmd, nil); free(cmd); free(val); return e; }
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; }
char* tkcanvas(TkTop *t, char *arg, char **ret) { Tk *tk; char *e; TkCanvas *tkc; TkName *names; TkOptab tko[3]; tk = tknewobj(t, TKcanvas, sizeof(Tk)+sizeof(TkCanvas)); if(tk == nil) return TkNomem; tkc = TKobj(TkCanvas, tk); tkc->close = TKI2F(1); tkc->xscrolli = TKI2F(1); tkc->yscrolli = TKI2F(1); tkc->width = TKI2F(360); tkc->height = TKI2F(270); tkc->actions = 0; tkc->actlim = Tksweep; tkc->mask = nil; tkc->sborderwidth = 1; tko[0].ptr = tkc; tko[0].optab = opts; tko[1].ptr = tk; tko[1].optab = tkgeneric; tko[2].ptr = nil; names = nil; e = tkparse(t, arg, tko, &names); if(e != nil) goto err; if(names == nil) { /* tkerr(t, arg); XXX */ e = TkBadwp; goto err; } tkc->current = tkmkname("current"); if(tkc->current == nil) { e = TkNomem; goto err; } tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd)); tkcvsf2i(tk, tkc); e = tkaddchild(t, tk, &names); tkfreename(names); if(e != nil) { tkfreename(tkc->current); tkc->current = nil; goto err; } tk->name->link = nil; e = tkvalue(ret, "%s", tk->name->name); if(e == nil) return nil; tkfreename(tkc->current); return e; err: tkfreeobj(tk); return e; }
"closeenough", OPTfrac, O(TkCanvas, close), nil, "confine", OPTfrac, O(TkCanvas, confine), nil, "scrollregion", OPTfrac, OA(TkCanvas, scrollr), IAUX(4), "xscrollincrement", OPTfrac, O(TkCanvas, xscrolli), nil, "yscrollincrement", OPTfrac, O(TkCanvas, yscrolli), nil, "xscrollcommand", OPTtext, O(TkCanvas, xscroll), nil, "yscrollcommand", OPTtext, O(TkCanvas, yscroll), nil, "width", OPTnnfrac, O(TkCanvas, width), nil, "height", OPTnnfrac, O(TkCanvas, height), nil, "buffer", OPTstab, O(TkCanvas, buffer), tkbuffer, "buffered", OPTstab, O(TkCanvas, buffer), tkbool, /* backwards compatibility */ "selectborderwidth", OPTnndist, O(TkCanvas, sborderwidth), nil, nil }; int cvslshape[] = { TKI2F(8), TKI2F(10), TKI2F(3) }; Rectangle bbnil = { 1000000, 1000000, -1000000, -1000000 }; Rectangle huger = { -1000000, -1000000, 1000000, 1000000 }; static void tkcvsgeom(Tk *tk); static void tkcvsf2i(Tk *tk, TkCanvas *tkc) { Rectangle r; tk->req.width = TKF2I(tkc->width); tk->req.height = TKF2I(tkc->height); r.min.x = TKF2I(tkc->scrollr[0]); r.min.y = TKF2I(tkc->scrollr[1]);
static char* tkentryxview(Tk *tk, char *arg, char **val) { int locked; TkEnv *env; TkEntry *tke; char *buf, *v; int dx, top, bot, amount, ix, x; char *e; tke = TKobj(TkEntry, tk); env = tk->env; dx = tk->act.width - 2*xinset(tk); buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; if(*arg == '\0') { if (tke->textlen == 0 || tke->xlen < dx) { bot = TKI2F(0); top = TKI2F(1); } else { bot = TKI2F(tke->x0) / tke->xlen; top = TKI2F(tke->x0 + dx) / tke->xlen; } v = tkfprint(buf, bot); *v++ = ' '; tkfprint(v, top); e = tkvalue(val, "%s", buf); free(buf); return e; } arg = tkitem(buf, arg); if(strcmp(buf, "moveto") == 0) { e = tkfracword(env->top, &arg, &top, nil); if (e != nil) { free(buf); return e; } tke->x0 = TKF2I(top*tke->xlen); } else if(strcmp(buf, "scroll") == 0) { arg = tkitem(buf, arg); amount = atoi(buf); if(*arg == 'p') /* Pages */ amount *= (9*tke->xlen)/10; else if(*arg == 's') { /* Inferno-ism, "scr", must be used in the context of button2p */ x = amount; amount = x < tke->oldx ? env->wzero : (x > tke->oldx ? -env->wzero : 0); tke->oldx = x; } tke->x0 += amount; } else { e = tkentryparseindex(tk, buf, &ix); if(e != nil) { free(buf); return e; } locked = lockdisplay(env->top->display); tke->x0 = entrytextwidth(tk, ix); if (locked) unlockdisplay(env->top->display); } free(buf); if (tke->x0 > tke->xlen - dx) tke->x0 = tke->xlen - dx; if (tke->x0 < 0) tke->x0 = 0; recalcentry(tk); e = tkentrysh(tk); blinkreset(tk); tk->dirty = tkrect(tk, 1); return e; }