123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <thread.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <control.h>
- typedef struct Textbutton Textbutton;
- struct Textbutton
- {
- Control;
- CFont *font;
- CImage *image;
- CImage *mask;
- CImage *light;
- CImage *bordercolor;
- CImage *textcolor;
- CImage *pressedtextcolor;
- CImage *paletextcolor;
- int pressed;
- int lastbut;
- int lastshow;
- char **line;
- int nline;
- int align;
- int border;
- int off;
- int showoff;
- int prepress;
- };
- enum{
- EAlign,
- EBorder,
- EBordercolor,
- EFocus,
- EFont,
- EFormat,
- EHide,
- EImage,
- ELight,
- EMask,
- EPaletextcolor,
- EPressedtextcolor,
- ERect,
- EReveal,
- EShow,
- ESize,
- EText,
- ETextcolor,
- EValue,
- };
- static char *cmds[] = {
- [EAlign] = "align",
- [EBorder] = "border",
- [EBordercolor] = "bordercolor",
- [EFocus] = "focus",
- [EFont] = "font",
- [EFormat] = "format",
- [EHide] = "hide",
- [EImage] = "image",
- [ELight] = "light",
- [EMask] = "mask",
- [EPaletextcolor] ="paletextcolor",
- [EPressedtextcolor] ="pressedtextcolor",
- [ERect] = "rect",
- [EReveal] = "reveal",
- [EShow] = "show",
- [ESize] = "size",
- [EText] = "text",
- [ETextcolor] = "textcolor",
- [EValue] = "value",
- nil
- };
- static void textbuttonshow(Textbutton*);
- static void
- textbuttonmouse(Control *c, Mouse *m)
- {
- Textbutton *t;
- t = (Textbutton *)c;
- if(m->buttons&7) {
- if (ptinrect(m->xy,t->rect)) {
- if (t->off) {
- t->off = 0;
- textbuttonshow(t);
- }
- } else {
- if (!t->off) {
- t->off = 1;
- textbuttonshow(t);
- }
- }
- }
- if((m->buttons&7) != t->lastbut){
- if(m->buttons & 7){
- t->prepress = t->pressed;
- if (t->pressed)
- t->pressed = 0;
- else
- t->pressed = 1;
- textbuttonshow(t);
- }else{ /* generate event on button up */
- if (ptinrect(m->xy,t->rect))
- chanprint(t->event, t->format, t->name, t->pressed);
- else {
- t->off = 0;
- t->pressed = t->prepress;
- textbuttonshow(t);
- }
- }
- }
- t->lastbut = m->buttons & 7;
- }
- static void
- textbuttonfree(Control *c)
- {
- int i;
- Textbutton *t;
- t = (Textbutton*)c;
- _putctlfont(t->font);
- _putctlimage(t->image);
- _putctlimage(t->light);
- _putctlimage(t->mask);
- _putctlimage(t->textcolor);
- _putctlimage(t->bordercolor);
- _putctlimage(t->paletextcolor);
- _putctlimage(t->pressedtextcolor);
- for(i=0; i<t->nline; i++)
- free(t->line[i]);
- free(t->line);
- }
- static void
- textbuttonshow(Textbutton *t)
- {
- Rectangle r, clipr;
- int i, dx, dy, w;
- Font *f;
- Point p, q;
- Image *im;
- if(t->hidden || (t->lastshow == t->pressed && t->showoff == t->off))
- return;
- f = t->font->font;
- draw(t->screen, t->rect, t->image->image, nil, t->image->image->r.min);
- if(t->border > 0)
- border(t->screen, t->rect, t->border, t->bordercolor->image, ZP);
- /* text goes here */
- dx = 0;
- for(i=0; i<t->nline; i++){
- w = stringwidth(f, t->line[i]);
- if(dx < w)
- dx = w;
- }
- dy = t->nline*f->height;
- clipr = insetrect(t->rect, t->border);
- p = _ctlalignpoint(clipr, dx, dy, t->align);
- im = t->textcolor->image;
- if(t->off)
- im = t->paletextcolor->image;
- else if(t->pressed)
- im = t->pressedtextcolor->image;
- for(i=0; i<t->nline; i++){
- r.min = p;
- r.max.x = p.x+dx;
- r.max.y = p.y+f->height;
- q = _ctlalignpoint(r, stringwidth(f, t->line[i]), f->height, t->align%3);
- _string(t->screen, q, im,
- ZP, f, t->line[i], nil, strlen(t->line[i]),
- clipr, nil, ZP, SoverD);
- p.y += f->height;
- }
- if(t->off || t->pressed)
- draw(t->screen, t->rect, t->light->image, t->mask->image, t->mask->image->r.min);
- t->lastshow = t->pressed;
- t->showoff = t->off;
- flushimage(display, 1);
- }
- static void
- textbuttonctl(Control *c, CParse *cp)
- {
- int cmd, i;
- Rectangle r;
- Textbutton *t;
- t = (Textbutton*)c;
- cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
- switch(cmd){
- default:
- ctlerror("%q: unrecognized message '%s'", t->name, cp->str);
- break;
- case EAlign:
- _ctlargcount(t, cp, 2);
- t->align = _ctlalignment(cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EBorder:
- _ctlargcount(t, cp, 2);
- t->border = cp->iargs[1];
- t->lastshow = -1; /* force redraw */
- break;
- case EBordercolor:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->bordercolor, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EFocus:
- break;
- case EFont:
- _ctlargcount(t, cp, 2);
- _setctlfont(t, &t->font, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EFormat:
- _ctlargcount(t, cp, 2);
- t->format = ctlstrdup(cp->args[1]);
- break;
- case EHide:
- _ctlargcount(t, cp, 1);
- t->hidden = 1;
- break;
- case EImage:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->image, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case ELight:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->light, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EMask:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->mask, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EPaletextcolor:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->paletextcolor, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EPressedtextcolor:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->pressedtextcolor, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case ERect:
- _ctlargcount(t, cp, 5);
- r.min.x = cp->iargs[1];
- r.min.y = cp->iargs[2];
- r.max.x = cp->iargs[3];
- r.max.y = cp->iargs[4];
- if(Dx(r)<=0 || Dy(r)<=0)
- ctlerror("%q: bad rectangle: %s", t->name, cp->str);
- t->rect = r;
- t->lastshow = -1; /* force redraw */
- break;
- case EReveal:
- _ctlargcount(t, cp, 1);
- t->hidden = 0;
- t->lastshow = -1; /* force redraw */
- textbuttonshow(t);
- break;
- case EShow:
- _ctlargcount(t, cp, 1);
- t->lastshow = -1; /* force redraw */
- textbuttonshow(t);
- break;
- case ESize:
- if (cp->nargs == 3)
- r.max = Pt(0x7fffffff, 0x7fffffff);
- else{
- _ctlargcount(t, cp, 5);
- r.max.x = cp->iargs[3];
- r.max.y = cp->iargs[4];
- }
- r.min.x = cp->iargs[1];
- r.min.y = cp->iargs[2];
- if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)
- ctlerror("%q: bad sizes: %s", t->name, cp->str);
- t->size.min = r.min;
- t->size.max = r.max;
- break;
- case EText:
- /* free existing text */
- for(i=0; i<t->nline; i++)
- free(t->line[i]);
- t->nline = cp->nargs-1;
- t->line = ctlrealloc(t->line, t->nline*sizeof(char*));
- for(i=0; i<t->nline; i++)
- t->line[i] = ctlstrdup(cp->args[i+1]);
- t->lastshow = -1; /* force redraw */
- textbuttonshow(t);
- break;
- case ETextcolor:
- _ctlargcount(t, cp, 2);
- _setctlimage(t, &t->textcolor, cp->args[1]);
- t->lastshow = -1; /* force redraw */
- break;
- case EValue:
- _ctlargcount(t, cp, 2);
- if((cp->iargs[1]!=0) != t->pressed){
- t->pressed ^= 1;
- textbuttonshow(t);
- }
- break;
- }
- }
- Control*
- createtextbutton(Controlset *cs, char *name)
- {
- Textbutton *t;
- t = (Textbutton *)_createctl(cs, "textbutton", sizeof(Textbutton), name);
- t->line = ctlmalloc(sizeof(char*));
- t->nline = 0;
- t->image = _getctlimage("white");
- t->light = _getctlimage("yellow");
- t->mask = _getctlimage("opaque");
- t->bordercolor = _getctlimage("black");
- t->textcolor = _getctlimage("black");
- t->pressedtextcolor = _getctlimage("black");
- t->paletextcolor = _getctlimage("paleyellow");
- t->font = _getctlfont("font");
- t->format = ctlstrdup("%q: value %d");
- t->lastshow = -1;
- t->mouse = textbuttonmouse;
- t->ctl = textbuttonctl;
- t->exit = textbuttonfree;
- t->prepress = 0;
- t->off = 0;
- t->showoff = -1;
- return (Control *)t;
- }
|