📄 group.c
字号:
#include <u.h>#include <libc.h>#include <thread.h>#include <draw.h>#include <mouse.h>#include <keyboard.h>#include <control.h>#include "group.h"static int debug = 0;static int debugm = 0;static int debugr = 0;enum{ EAdd, EBorder, EBordercolor, EFocus, EHide, EImage, ERect, ERemove, EReveal, ESeparation, EShow, ESize,};static char *cmds[] = { [EAdd] = "add", [EBorder] = "border", [EBordercolor] = "bordercolor", [EFocus] = "focus", [EHide] = "hide", [EImage] = "image", [ERect] = "rect", [ERemove] = "remove", [EReveal] = "reveal", [ESeparation] = "separation", [EShow] = "show", [ESize] = "size",};static void boxboxresize(Group*, Rectangle);static void columnresize(Group*, Rectangle);static void groupctl(Control *c, CParse *cp);static void groupfree(Control*);static void groupmouse(Control *, Mouse *);static void groupsize(Control *c);static void removegroup(Group*, int);static void rowresize(Group*, Rectangle);static void stackresize(Group*, Rectangle);static voidgroupinit(Group *g){ g->bordercolor = _getctlimage("black"); g->image = _getctlimage("white"); g->border = 0; g->mansize = 0; g->separation = 0; g->selected = -1; g->lastkid = -1; g->kids = nil; g->separators = nil; g->nkids = 0; g->nseparators = 0; g->ctl = groupctl; g->mouse = groupmouse; g->exit = groupfree;}static voidgroupctl(Control *c, CParse *cp){ int cmd, i, n; Rectangle r; Group *g; g = (Group*)c; cmd = _ctllookup(cp->args[0], cmds, nelem(cmds)); switch(cmd){ case EAdd: for (i = 1; i < cp->nargs; i++){ c = controlcalled(cp->args[i]); if (c == nil) ctlerror("%q: no such control: %s", g->name, cp->args[i]); _ctladdgroup(g, c); } if (g->setsize) g->setsize((Control*)g); break; case EBorder: _ctlargcount(g, cp, 2); if(cp->iargs[1] < 0) ctlerror("%q: bad border: %c", g->name, cp->str); g->border = cp->iargs[1]; break; case EBordercolor: _ctlargcount(g, cp, 2); _setctlimage(g, &g->bordercolor, cp->args[1]); break; case EFocus: /* ignore focus change */ break; case EHide: _ctlargcount(g, cp, 1); for (i = 0; i < g->nkids; i++) if (g->kids[i]->ctl) _ctlprint(g->kids[i], "hide"); g->hidden = 1; break; case EImage: _ctlargcount(g, cp, 2); _setctlimage(g, &g->image, cp->args[1]); break; case ERect: _ctlargcount(g, 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", g->name, cp->str); g->rect = r; r = insetrect(r, g->border); if (g->nkids == 0) return; switch(g->type){ case Ctlboxbox: boxboxresize(g, r); break; case Ctlcolumn: columnresize(g, r); break; case Ctlrow: rowresize(g, r); break; case Ctlstack: stackresize(g, r); break; } break; case ERemove: _ctlargcount(g, cp, 2); for (n = 0; n < g->nkids; n++) if (strcmp(cp->args[1], g->kids[n]->name) == 0) break; if (n == g->nkids) ctlerror("%s: remove nonexistent control: %q", g->name, cp->args[1]); removegroup(g, n); if (g->setsize) g->setsize((Control*)g); break; case EReveal: g->hidden = 0; if (debugr) fprint(2, "reveal %s\n", g->name); if (g->type == Ctlstack){ if (cp->nargs == 2){ if (cp->iargs[1] < 0 || cp->iargs[1] >= g->nkids) ctlerror("%s: control out of range: %q", g->name, cp->str); g->selected = cp->iargs[1]; }else _ctlargcount(g, cp, 1); for (i = 0; i < g->nkids; i++) if (g->kids[i]->ctl){ if (g->selected == i){ if (debugr) fprint(2, "reveal %s: reveal kid %s\n", g->name, g->kids[i]->name); _ctlprint(g->kids[i], "reveal"); }else{ if (debugr) fprint(2, "reveal %s: hide kid %s\n", g->name, g->kids[i]->name); _ctlprint(g->kids[i], "hide"); } } break; } _ctlargcount(g, cp, 1); if (debug) fprint(2, "reveal %s: border %R/%d\n", g->name, g->rect, g->border); border(g->screen, g->rect, g->border, g->bordercolor->image, g->bordercolor->image->r.min); r = insetrect(g->rect, g->border); if (debug) fprint(2, "reveal %s: draw %R\n", g->name, r); draw(g->screen, r, g->image->image, nil, g->image->image->r.min); for (i = 0; i < g->nkids; i++) if (g->kids[i]->ctl) _ctlprint(g->kids[i], "reveal"); break; case EShow: _ctlargcount(g, cp, 1); if (g->hidden) break; // pass it on to the kiddies if (debug) fprint(2, "show %s: border %R/%d\n", g->name, g->rect, g->border); border(g->screen, g->rect, g->border, g->bordercolor->image, g->bordercolor->image->r.min); r = insetrect(g->rect, g->border); if (debug) fprint(2, "show %s: draw %R\n", g->name, r); draw(g->screen, r, g->image->image, nil, g->image->image->r.min); for (i = 0; i < g->nkids; i++) if (g->kids[i]->ctl){ if (debug) fprint(2, "show %s: kid %s: %q\n", g->name, g->kids[i]->name, cp->str); _ctlprint(g->kids[i], "show"); } flushimage(display, 1); break; case ESize: r.max = Pt(_Ctlmaxsize, _Ctlmaxsize); if (g->type == Ctlboxbox) _ctlargcount(g, cp, 5); switch(cp->nargs){ default: ctlerror("%s: args of %q", g->name, cp->str); case 1: /* recursively set size */ g->mansize = 0; if (g->setsize) g->setsize((Control*)g); break; case 5: _ctlargcount(g, cp, 5); r.max.x = cp->iargs[3]; r.max.y = cp->iargs[4]; /* fall through */ case 3: 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", g->name, cp->str); g->size = r; g->mansize = 1; break; } break; case ESeparation: if (g->type != Ctlstack){ _ctlargcount(g, cp, 2); if(cp->iargs[1] < 0) ctlerror("%q: illegal value: %c", g->name, cp->str); g->separation = cp->iargs[1]; break; } // fall through for Ctlstack default: ctlerror("%q: unrecognized message '%s'", g->name, cp->str); break; }}static voidgroupfree(Control *c){ Group *g; g = (Group*)c; _putctlimage(g->bordercolor); free(g->kids);}static voidgroupmouse(Control *c, Mouse *m){ Group *g; int i, lastkid; g = (Group*)c; if (g->type == Ctlstack){ i = g->selected; if (i >= 0 && g->kids[i]->mouse && ( ( ((m->buttons == 0) || (g->lastbut == 0)) && ptinrect(m->xy, g->kids[i]->rect) ) || ( ((m->buttons != 0) || (g->lastbut != 0)) && (g->lastkid == i) ) ) ) { if (debugm) fprint(2, "groupmouse %s mouse kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n", g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut, ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0); (g->kids[i]->mouse)(g->kids[i], m); g->lastkid = i; g->lastbut = m->buttons; } else { if (debugm) fprint(2, "groupmouse %s skip kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n", g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut, ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0); } return; } lastkid = -1; for(i=0; i<g->nkids; i++) { if(g->kids[i]->mouse && ( ( ((m->buttons == 0) || (g->lastbut == 0)) && ptinrect(m->xy, g->kids[i]->rect) ) || ( ((m->buttons != 0) || (g->lastbut != 0)) && (g->lastkid == i) ) ) ) { if (debugm) fprint(2, "groupmouse %s mouse kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n", g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut, ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0); (g->kids[i]->mouse)(g->kids[i], m); lastkid = i; } else { if (debugm) fprint(2, "groupmouse %s skip kid %s i=%d lastkid=%d buttons=%d lastbut=%d inrect=%d\n", g->name, g->kids[i]->name, i, g->lastkid, m->buttons, g->lastbut, ptinrect(m->xy, g->kids[i]->rect) ? 1 : 0); } } g->lastkid = lastkid; g->lastbut = m->buttons;#ifdef notdef if(m->buttons == 0){ /* buttons now up */ g->lastbut = 0; return; } if(g->lastbut == 0 && m->buttons != 0){ /* button went down, start tracking border */ switch(g->stacking){ default: return; case Vertical: p = Pt(m->xy.x, middle_of_border.y); p0 = Pt(g->r.min.x, m->xy.y); p1 = Pt(g->r.max.x, m->xy.y); break; case Horizontal: p = Pt(middle_of_border.x, m->xy.y); p0 = Pt(m->xy.x, g->r.min.y); p1 = Pt(m->xy.x, g->r.max.y); break; } // setcursor(); oi = nil; } else if (g->lastbut != 0 && s->m.buttons != 0){ /* button is down, keep tracking border */ if(!eqpt(s->m.xy, p)){ p = onscreen(s->m.xy); r = canonrect(Rpt(p0, p)); if(Dx(r)>5 && Dy(r)>5){ i = allocwindow(wscreen, r, Refnone, 0xEEEEEEFF); /* grey */ freeimage(oi); if(i == nil) goto Rescue; oi = i; border(i, r, Selborder, red, ZP); flushimage(display, 1); } } } else if (g->lastbut != 0 && s->m.buttons == 0){ /* button went up, resize kiddies */ } g->lastbut = s->m.buttons;#endif}static voidactivategroup(Control *c, int act){ int i; Group *g; g = (Group*)c; for (i = 0; i < g->nkids; i++) if (act) activate(g->kids[i]); else deactivate(g->kids[i]);}Control *createrow(Controlset *cs, char *name){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -