123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- #include <lib9.h>
- #include <kernel.h>
- #include "draw.h"
- #include "tk.h"
- #include "label.h"
- #define O(t, e) ((long)(&((t*)0)->e))
- TkOption tklabelopts[] =
- {
- "text", OPTtext, O(TkLabel, text), nil,
- "label", OPTtext, O(TkLabel, text), nil,
- "underline", OPTdist, O(TkLabel, ul), nil,
- "justify", OPTflag, O(TkLabel, justify), tkjustify,
- "anchor", OPTflag, O(TkLabel, anchor), tkanchor,
- "bitmap", OPTbmap, O(TkLabel, bitmap), nil,
- "image", OPTimag, O(TkLabel, img), nil,
- nil
- };
- char*
- tklabel(TkTop *t, char *arg, char **ret)
- {
- Tk *tk;
- char *e;
- TkLabel *tkl;
- TkName *names;
- TkOptab tko[3];
- tk = tknewobj(t, TKlabel, sizeof(Tk)+sizeof(TkLabel));
- if(tk == nil)
- return TkNomem;
- tkl = TKobj(TkLabel, tk);
- tkl->ul = -1;
- tkl->justify = Tkleft;
- tko[0].ptr = tk;
- tko[0].optab = tkgeneric;
- tko[1].ptr = tkl;
- tko[1].optab = tklabelopts;
- tko[2].ptr = nil;
- names = nil;
- e = tkparse(t, arg, tko, &names);
- if(e != nil) {
- tkfreeobj(tk);
- return e;
- }
- tksizelabel(tk);
- tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd));
- 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*
- tklabelcget(Tk *tk, char *arg, char **val)
- {
- 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;
- return tkgencget(tko, arg, val, tk->env->top);
- }
- 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;
- }
- void
- tksizelabel(Tk *tk)
- {
- Point p;
- int w, h;
- TkLabel *tkl;
-
- tkl = TKobj(TkLabel, tk);
- if(tkl->anchor == 0)
- tkl->anchor = Tkcenter;
- w = 0;
- h = 0;
- tkl->textheight = 0;
- if(tkl->img != nil) {
- w = tkl->img->w + 2*Bitpadx;
- h = tkl->img->h + 2*Bitpady;
- } else if(tkl->bitmap != nil) {
- w = Dx(tkl->bitmap->r) + 2*Bitpadx;
- h = Dy(tkl->bitmap->r) + 2*Bitpady;
- } else if(tkl->text != nil) {
- p = tkstringsize(tk, tkl->text);
- w = p.x + 2*Textpadx;
- h = p.y + 2*Textpady;
- if(tkl->ul != -1 && tkl->ul > strlen(tkl->text))
- tkl->ul = strlen(tkl->text); /* underline all */
- tkl->textheight = p.y;
- }
- if(tk->type == TKcascade) {
- w += CheckButton + 2*CheckButtonBW;
- if(h < CheckButton)
- h = CheckButton;
- }
- w += 2*tk->highlightwidth;
- h += 2*tk->highlightwidth;
- tkl->w = w;
- tkl->h = h;
- if((tk->flag & Tksetwidth) == 0)
- tk->req.width = w;
- if((tk->flag & Tksetheight) == 0)
- tk->req.height = h;
- }
- int
- tklabelmargin(Tk *tk)
- {
- TkLabel *tkl;
- Image *img;
- switch(tk->type){
- case TKseparator:
- return 0;
- case TKlabel:
- case TKcascade:
- tkl = TKobj(TkLabel, tk);
- img = nil;
- if (tkl->img != nil)
- img = tkl->img->img;
- else if (tkl->bitmap != nil)
- img = tkl->bitmap;
- if (img != nil)
- return Bitpadx;
- return Textpadx;
- default:
- fprint(2, "label margin: type %d\n", tk->type);
- return 0;
- }
- }
- void
- tkfreelabel(Tk *tk)
- {
- Image *i;
- int locked;
- Display *d;
- TkLabel *tkl;
- tkl = TKobj(TkLabel, tk);
- if(tkl->text != nil)
- free(tkl->text);
- if(tkl->command != nil)
- free(tkl->command);
- if(tkl->value != nil)
- free(tkl->value);
- if(tkl->variable != nil) {
- tkfreevar(tk->env->top, tkl->variable, tk->flag & Tkswept);
- free(tkl->variable);
- }
- if(tkl->img != nil)
- tkimgput(tkl->img);
- i = tkl->bitmap;
- if(i != nil) {
- d = i->display;
- locked = lockdisplay(d);
- freeimage(i);
- if(locked)
- unlockdisplay(d);
- }
- if(tkl->menu != nil)
- free(tkl->menu);
- }
- 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]);
- }
- /*
- * 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;
- }
- void
- tklabelgetimgs(Tk *tk, Image **image, Image **mask)
- {
- TkLabel *tkl;
- tkl = TKobj(TkLabel, tk);
- *mask = nil;
- if (tkl->img != nil)
- *image = tkl->img->img;
- else
- *image = tkl->bitmap;
- }
- static
- TkCmdtab tklabelcmd[] =
- {
- "cget", tklabelcget,
- "configure", tklabelconf,
- nil
- };
- TkMethod labelmethod = {
- "label",
- tklabelcmd,
- tkfreelabel,
- tkdrawlabel,
- nil,
- tklabelgetimgs
- };
|