void tkcvsrectdraw(Image *img, TkCitem *i, TkEnv *pe) { int lw, rw; TkEnv *e; TkCrect *r; Rectangle d, rr; Point tr, bl; Image *pen; USED(pe); d.min = i->p.drawpt[0]; d.max = i->p.drawpt[1]; e = i->env; r = TKobj(TkCrect, i); pen = nil; if((e->set & (1<<TkCfill))) pen = tkgc(e, TkCfill); if(pen != nil) draw(img, d, pen, r->stipple, d.min); tr.x = d.max.x; tr.y = d.min.y; bl.x = d.min.x; bl.y = d.max.y; rw = (TKF2I(r->width) + 1)/2; if(rw <= 0) return; lw = (TKF2I(r->width))/2; pen = tkgc(e, TkCforegnd); if(pen != nil) { /* horizontal lines first */ rr.min.x = d.min.x - lw; rr.max.x = d.max.x + rw; rr.min.y = d.min.y - lw; rr.max.y = d.min.y + rw; draw(img, rr, pen, nil, rr.min); rr.min.y += Dy(d); rr.max.y += Dy(d); draw(img, rr, pen, nil, rr.min); /* now the vertical */ /* horizontal lines first */ rr.min.x = d.min.x - lw; rr.max.x = d.min.x + rw; rr.min.y = d.min.y + rw; rr.max.y = d.max.y - lw; draw(img, rr, pen, nil, rr.min); rr.min.x += Dx(d); rr.max.x += Dx(d); draw(img, rr, pen, nil, rr.min); } }
static void tkentrytext(Image *i, Rectangle s, Tk *tk, TkEnv *env) { TkEntry *tke = TKobj(TkEntry, tk); Point dp; int s0, s1, xs0, xs1, j; Rectangle r; Rune showr, *text; dp = Pt(s.min.x - (tke->x0 - tke->xv0), s.min.y); if (tke->show) { chartorune(&showr, tke->show); text = mallocz(sizeof(Rune) * (tke->textlen+1), 0); if (text == nil) return; for (j = 0; j < tke->textlen; j++) text[j] = showr; } else text = tke->text; runestringn(i, dp, tkgc(env, TkCforegnd), dp, env->font, text+tke->v0, tke->v1-tke->v0); if (tke->sel0 < tke->v1 && tke->sel1 > tke->v0) { if (tke->sel0 < tke->v0) { s0 = tke->v0; xs0 = tke->xv0 - tke->x0; } else { s0 = tke->sel0; xs0 = tke->xsel0 - tke->x0; } if (tke->sel1 > tke->v1) { s1 = tke->v1; xs1 = s.max.x; } else { s1 = tke->sel1; xs1 = tke->xsel1 - tke->x0; } r = rectaddpt(Rect(xs0, 0, xs1, env->font->height), s.min); tktextsdraw(i, r, env, 1); runestringn(i, r.min, tkgc(env, TkCselectfgnd), r.min, env->font, text+s0, s1-s0); } if((tke->flag&Ecursoron) && tke->icursor >= tke->v0 && tke->icursor <= tke->v1) { r = Rect( tke->xicursor - tke->x0, 0, tke->xicursor - tke->x0 + Inswidth, env->font->height ); draw(i, rectaddpt(r, s.min), tkgc(env, TkCforegnd), nil, ZP); } if (tke->show) free(text); }
void tkcvslinedraw(Image *img, TkCitem *i, TkEnv *pe) { int w; Point *p; TkCline *l; Image *pen; USED(pe); l = TKobj(TkCline, i); pen = l->pen; if(pen == nil) pen = tkgc(i->env, TkCforegnd); w = TKF2I(l->width)/2; if(w < 0) return; p = i->p.drawpt; if(l->smooth == BoolT && i->p.npoint >= 3) bezspline(img, p, i->p.npoint, l->arrowf, l->arrowl, w, pen, p[0]); else poly(img, p, i->p.npoint, l->arrowf, l->arrowl, w, pen, p[0]); }
static void tktriangle(Point u, Image *i, TkEnv *e) { Point p[3]; u.y++; p[0].x = u.x + CheckButton; p[0].y = u.y + CheckButton/2; p[1].x = u.x; p[1].y = u.y + CheckButton; p[2].x = u.x; p[2].y = u.y; fillpoly(i, p, 3, ~0, tkgc(e, TkCforegnd), p[0]); }
static void drawslider(TkScroll *tks, Image *i, Point o, int w, int h, TkEnv *e) { Image *l, *d; Rectangle r; int bgnd; bgnd = TkCbackgnd; if(tks->flag & (ActiveB1|ButtonB1)) { r.min = o; r.max.x = o.x + w + Elembw*2; r.max.y = o.y + h + Elembw*2; bgnd = TkCactivebgnd; draw(i, r, tkgc(e, bgnd), nil, ZP); } l = tkgc(e, bgnd+TkLightshade); d = tkgc(e, bgnd+TkDarkshade); if(tks->flag & ButtonB1) tkbevel(i, o, w, h, Scrollbw, d, l); else tkbevel(i, o, w, h, Scrollbw, l, d); }
static void drawarrow(TkScroll *tks, Image *i, Point p[3], TkEnv *e, int activef, int buttonf) { Image *l, *d, *t; int bgnd; bgnd = TkCbackgnd; if(tks->flag & (activef|buttonf)) { bgnd = TkCactivebgnd; fillpoly(i, p, 3, ~0, tkgc(e, bgnd), p[0]); } l = tkgc(e, bgnd+TkLightshade); d = tkgc(e, bgnd+TkDarkshade); if(tks->flag & buttonf) { t = d; d = l; l = t; } line(i, p[1], p[2], 0, 0, Tribw-1, d, p[1]); line(i, p[2], p[0], 0, 0, Tribw-1, d, p[2]); line(i, p[0], p[1], 0, 0, Tribw-1, l, p[0]); }
Image* tkitmp(TkEnv *e, Point p, int fillcol) { Image *i, **ip; TkTop *t; TkCtxt *ti; Display *d; Rectangle r; ulong pix; int alpha; t = e->top; ti = t->ctxt; d = t->display; pix = e->colors[fillcol]; alpha = (pix & 0xff) != 0xff; ip = alpha ? &ti->ia : &ti->i; if(*ip != nil) { i = *ip; if(p.x <= i->r.max.x && p.y <= i->r.max.y) { r.min = ZP; r.max = p; if (alpha) drawop(i, r, nil, nil, ZP, Clear); draw(i, r, tkgc(e, fillcol), nil, ZP); return i; } r = i->r; freeimage(i); if(p.x < r.max.x) p.x = r.max.x; if(p.y < r.max.y) p.y = r.max.y; } r.min = ZP; r.max = p; *ip = allocimage(d, r, alpha?RGBA32:d->image->chan, 0, pix); return *ip; }
char* tkdrawentry(Tk *tk, Point orig) { Point p; TkEnv *env; Rectangle r, s; Image *i; int xp, yp; env = tk->env; r.min = ZP; r.max.x = tk->act.width + 2*tk->borderwidth; r.max.y = tk->act.height + 2*tk->borderwidth; i = tkitmp(env, r.max, TkCbackgnd); if(i == nil) return nil; xp = tk->borderwidth + xinset(tk); yp = tk->borderwidth + yinset(tk); s = r; s.min.x += xp; s.max.x -= xp; s.min.y += yp; s.max.y -= yp; tkentrytext(i, s, tk, env); tkdrawrelief(i, tk, ZP, TkCbackgnd, tk->relief); if (tkhaskeyfocus(tk)) tkbox(i, insetrect(r, tk->borderwidth), tk->highlightwidth, tkgc(tk->env, TkChighlightfgnd)); p.x = tk->act.x + orig.x; p.y = tk->act.y + orig.y; r = rectaddpt(r, p); draw(tkimageof(tk), r, i, nil, ZP); return nil; }
char* tkdrawscale(Tk *tk, Point orig) { Point p; TkEnv *env; TkScale *tks; Rectangle r, fr; Image *i; tks = TKobj(TkScale, tk); env = tk->env; r.min = ZP; r.max.x = tk->act.width + 2*tk->borderwidth; r.max.y = tk->act.height + 2*tk->borderwidth; i = tkitmp(env, r.max, TkCbackgnd); if(i == nil) return nil; if(tks->orient == Tkvertical) tkscalevert(tk, i); else tkscalehoriz(tk, i); tkdrawrelief(i, tk, ZP, TkCbackgnd, tk->relief); if (tkhaskeyfocus(tk)) { fr = insetrect(r, tk->borderwidth); tkbox(i, fr, tk->highlightwidth, tkgc(env, TkChighlightfgnd)); } p.x = tk->act.x + orig.x; p.y = tk->act.y + orig.y; r = rectaddpt(r, p); draw(tkimageof(tk), r, i, nil, ZP); return nil; }
void tkcvstextdraw(Image *img, TkCitem *i, TkEnv *pe) { TkEnv *e; TkCtext *t; Point o, dp; Rectangle r; char *p, *next; Image *pen; int len, lw, end, start; t = TKobj(TkCtext, i); e = i->env; pen = t->pen; if(pen == nil) { if (e->set & (1<<TkCfill)) pen = tkgc(e, TkCfill); else pen = img->display->black; } o = addpt(t->anchorp, i->p.drawpt[0]); p = t->text; while(p && *p) { next = tkcvstextgetl(t, e->font, p, &len); dp = o; if(t->justify != Tkleft) { lw = stringnwidth(e->font, p, len); if(t->justify == Tkcenter) dp.x += (t->pixwidth - lw)/2; else if(t->justify == Tkright) dp.x += t->pixwidth - lw; } lw = p - t->text; if(t->self != -1 && lw+len > t->self) { if(t->sell >= t->self) { start = t->self - lw; end = t->sell - lw; } else { start = t->sell - lw; end = t->self - lw; } if(start < 0) r.min.x = o.x; else r.min.x = dp.x + stringnwidth(e->font, p, start); r.min.y = dp.y; if(end > len) r.max.x = o.x + t->pixwidth; else r.max.x = dp.x + stringnwidth(e->font, p, end); r.max.y = dp.y + e->font->height; tktextsdraw(img, r, pe, t->sbw); r.max.y = dp.y; if(start > 0) stringn(img, dp, pen, dp, e->font, p, start); if(end > start) stringn(img, r.min, tkgc(pe, TkCselectfgnd), r.min, e->font, p+start, end-start); if(len > end) stringn(img, r.max, pen, r.max, e->font, p+end, len-end); } else stringn(img, dp, pen, dp, e->font, p, len); if(t->focus) { lw = p - t->text; if(t->icursor >= lw && t->icursor <= lw+len) { lw = t->icursor - lw; if(lw > 0) lw = stringnwidth(e->font, p, lw); r.min.x = dp.x + lw; r.min.y = dp.y - 1; r.max.x = r.min.x + 2; r.max.y = r.min.y + e->font->height + 1; draw(img, r, pen, nil, ZP); } } o.y += e->font->height; p = next; } }
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; }
/* * draw TKlabel, TKseparator, and TKcascade (cascade should really be a button) */ char* tkdrawlabel(Tk *tk, Point orig) { TkEnv *e; TkLabel *tkl; Rectangle r, s, mainr, focusr; int dx, dy, h; Point p, u, v; Image *i, *dst, *ct, *img; int relief, bgnd, fgnd; e = tk->env; dst = tkimageof(tk); if(dst == nil) return nil; v.x = tk->act.width + 2*tk->borderwidth; v.y = tk->act.height + 2*tk->borderwidth; r.min = ZP; r.max = v; focusr = insetrect(r, tk->borderwidth); mainr = insetrect(focusr, tk->highlightwidth); relief = tk->relief; tkl = TKobj(TkLabel, tk); fgnd = TkCforegnd; bgnd = TkCbackgnd; if (tk->flag & Tkdisabled) fgnd = TkCdisablefgnd; else if (tk->flag & Tkactive) { fgnd = TkCactivefgnd; bgnd = TkCactivebgnd; } i = tkitmp(e, r.max, bgnd); if(i == nil) return nil; if(tk->flag & Tkactive) draw(i, r, tkgc(e, bgnd), nil, ZP); p = mainr.min; h = tkl->h - 2 * tk->highlightwidth; dx = tk->act.width - tkl->w - tk->ipad.x; dy = tk->act.height - tkl->h - tk->ipad.y; if((tkl->anchor & (Tknorth|Tksouth)) == 0) p.y += dy/2; else if(tkl->anchor & Tksouth) p.y += dy; if((tkl->anchor & (Tkeast|Tkwest)) == 0) p.x += dx/2; else if(tkl->anchor & Tkeast) p.x += dx; if(tk->type == TKcascade) { u.x = mainr.max.x - CheckButton - CheckButtonBW; /* TO DO: CheckButton etc is really the triangle/arrow */ u.y = p.y + ButtonBorder + (h-CheckSpace)/2; tktriangle(u, i, e); } p.x += tk->ipad.x/2; p.y += tk->ipad.y/2; u = ZP; img = nil; if(tkl->img != nil && tkl->img->img != nil) img = tkl->img->img; else if (tkl->bitmap != nil) img = tkl->bitmap; if(img != nil) { s.min.x = p.x + Bitpadx; s.min.y = p.y + Bitpady; s.max.x = s.min.x + Dx(img->r); s.max.y = s.min.y + Dy(img->r); s = rectaddpt(s, u); if(tkchanhastype(img->chan, CGrey)) draw(i, s, tkgc(e, fgnd), img, ZP); else draw(i, s, img, nil, ZP); } else if(tkl->text != nil) { u.x += Textpadx; u.y += Textpady; ct = tkgc(e, fgnd); p.y += (h - tkl->textheight) / 2; tkdrawstring(tk, i, addpt(u, p), tkl->text, tkl->ul, ct, tkl->justify); } if(tkhaskeyfocus(tk)) tkbox(i, focusr, tk->highlightwidth, tkgc(e, TkChighlightfgnd)); tkdrawrelief(i, tk, ZP, bgnd, relief); p.x = tk->act.x + orig.x; p.y = tk->act.y + orig.y; r = rectaddpt(r, p); draw(dst, r, i, nil, ZP); return nil; }
static void tkscalevert(Tk *tk, Image *i) { TkEnv *e; TkScale *tks; char sv[32]; Image *d, *l; Rectangle r, r2, sr; Point p, q; int fh, v, sw, gw, w, h, len, sl; int fgnd; e = tk->env; tks = TKobj(TkScale, tk); fh = e->font->height; fgnd = TkCforegnd; if (tk->flag & Tkdisabled) fgnd = TkCdisablefgnd; r = Rect(0, 0, tk->act.width, tk->act.height); r = rectaddpt(r, Pt(tk->borderwidth, tk->borderwidth)); r = insetrect(r, tk->highlightwidth); r = insetrect(r, ScalePad); if (tks->sv) r.min.x += tks->digwidth + ScalePad; if(tks->label != nil) { p = stringsize(e->font, tks->label); r.max.x -= p.x; string(i, Pt(r.max.x, r.min.y), tkgc(e, fgnd), ZP, e->font, tks->label); r.max.x -= ScalePad; } sr = insetrect(r, ScaleBW); h = Dy(sr); w = Dx(sr); sl = tks->sl + 2*ScaleBW; l = tkgc(e, TkCbackgndlght); d = tkgc(e, TkCbackgnddark); tkbevel(i, r.min, w, h, ScaleBW, d, l); tks->pixmin = sr.min.y; tks->pixmax = sr.max.y; sw = w - 2*ScaleBW; tks->sw = sw/2; h -= sl; if (h <= 0) h = 1; p.x = sr.max.x; p.y = sr.min.y; if(tks->tick > 0){ int j, t, l; t = tks->tick; l = tks->to-tks->from; if (l < 0) l = -l; if (l == 0) l = 1; r2.min = p; r2.max.x = p.x + ScaleBW + ScalePad; for(j = 0; j <= l; j += t){ r2.min.y = p.y+((vlong)j*h)/l+sl/2; r2.max.y = r2.min.y+1; draw(i, r2, tkgc(e, fgnd), nil, ZP); } } v = tks->value-tks->from; len = tks->to-tks->from; if (len != 0) p.y += ((vlong)v*h)/len; p.x = sr.min.x; q = p; if(ScaleBW > 1) { q.x++; gw = sw; } else gw = sw-1; q.y += tks->sl/2 + 1; if(tk->flag & Tkactivated) { r2.min = p; r2.max.x = sr.max.x; r2.max.y = p.y+sl; draw(i, r2, tkgc(e, TkCactivebgnd), nil, ZP); } switch(tks->relief) { case TKsunken: tkbevel(i, p, sw, tks->sl, ScaleBW, d, l); tkbevel(i, q, gw, 0, 1, l, d); break; case TKraised: tkbevel(i, p, sw, tks->sl, ScaleBW, l, d); tkbevel(i, q, gw, 0, 1, d, l); break; } tks->pixpos = p.y; tks->center = p.x + sw/2 + ScaleBW; if(tks->sv != BoolT) return; tkfprint(sv, tks->value); if(tks->digits > 0 && tks->digits < strlen(sv)) sv[tks->digits] = '\0'; p.x = r.min.x - ScalePad - stringwidth(e->font, sv); p.y = q.y; p.y -= fh/2; if (p.y < tks->pixmin) p.y = tks->pixmin; if (p.y + fh > tks->pixmax) p.y = tks->pixmax - fh; string(i, p, tkgc(e, fgnd), ZP, e->font, sv); }
static void tkscalehoriz(Tk *tk, Image *i) { TkEnv *e; char sv[32]; TkScale *tks; Image *d, *l; Rectangle r, r2, sr; Point p, q; int fh, sh, gh, sl, v, w, h, len; int fgnd; e = tk->env; tks = TKobj(TkScale, tk); fh = e->font->height; fgnd = TkCforegnd; if (tk->flag & Tkdisabled) fgnd = TkCdisablefgnd; r = Rect(0, 0, tk->act.width, tk->act.height); r = rectaddpt(r, Pt(tk->borderwidth, tk->borderwidth)); r = insetrect(r, tk->highlightwidth); r = insetrect(r, ScalePad); if(tks->label != nil) { string(i, r.min, tkgc(e, fgnd), ZP, e->font, tks->label); r.min.y += fh + ScalePad; } if(tks->sv == BoolT) r.min.y += fh + ScalePad; sr = insetrect(r, ScaleBW); w = Dx(sr); h = Dy(sr); sl = tks->sl + 2*ScaleBW; l = tkgc(e, TkCbackgndlght); d = tkgc(e, TkCbackgnddark); tkbevel(i, r.min, w, h, ScaleBW, d, l); tks->pixmin = sr.min.x; tks->pixmax = sr.max.x; sh = h - 2*ScaleBW; tks->sw = sh/2; w -= sl; if (w <= 0) w = 1; p.x = sr.min.x; p.y = sr.max.y; if(tks->tick > 0){ int j, t, l; t = tks->tick; l = tks->to-tks->from; if (l < 0) l = -l; if (l == 0) l = 1; r2.min.y = p.y; r2.max.y = p.y + ScaleBW + ScalePad; for(j = 0; j <= l; j += t){ r2.min.x = p.x+((vlong)j*w)/l+sl/2; r2.max.x = r2.min.x+1; draw(i, r2, tkgc(e, fgnd), nil, ZP); } } v = tks->value-tks->from; len = tks->to-tks->from; if (len != 0) p.x += ((vlong)v*w)/len; p.y = sr.min.y; q = p; q.x += tks->sl/2 + 1; if(ScaleBW > 1) { gh = sh; q.y++; } else gh = sh-1; if(tk->flag & Tkactivated) { r2.min = p; r2.max.x = p.x+sl; r2.max.y = sr.max.y; draw(i, r2, tkgc(e, TkCactivebgnd), nil, ZP); } switch(tks->relief) { case TKsunken: tkbevel(i, p, tks->sl, sh, ScaleBW, d, l); tkbevel(i, q, 0, gh, 1, l, d); break; case TKraised: tkbevel(i, p, tks->sl, sh, ScaleBW, l, d); tkbevel(i, q, 0, gh, 1, d, l); break; } tks->pixpos = p.x; tks->center = p.y + sh/2 + ScaleBW; if(tks->sv != BoolT) return; tkfprint(sv, tks->value); if(tks->digits > 0 && tks->digits < strlen(sv)) sv[tks->digits] = '\0'; w = stringwidth(e->font, sv); p.x = q.x; p.x -= w/2; p.y = r.min.y - fh - ScalePad; if(p.x < tks->pixmin) p.x = tks->pixmin; if(p.x+w > tks->pixmax) p.x = tks->pixmax - w; string(i, p, tkgc(e, fgnd), ZP, e->font, sv); }