tabs.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <thread.h>
  12. #include <draw.h>
  13. #include <mouse.h>
  14. #include <keyboard.h>
  15. #include <control.h>
  16. #include "group.h"
  17. typedef struct Tab Tab;
  18. struct Tab {
  19. Control Control;
  20. int border;
  21. int selected;
  22. int separation;
  23. char *_format;
  24. CImage *bordercolor;
  25. CImage *image;
  26. Control *tabrow;
  27. Control *tabstack;
  28. Control *tabcolumn;
  29. int ntabs;
  30. int nbuttons;
  31. Control **buttons;
  32. };
  33. enum{
  34. EAdd,
  35. EBorder,
  36. EBordercolor,
  37. EButton,
  38. EFocus,
  39. EFormat,
  40. EHide,
  41. EImage,
  42. ERect,
  43. EReveal,
  44. ESeparation,
  45. ESeparatorcolor,
  46. EShow,
  47. ESize,
  48. EValue,
  49. };
  50. static char *cmds[] = {
  51. [EAdd] = "add",
  52. [EBorder] = "border",
  53. [EBordercolor] = "bordercolor",
  54. [EButton] = "button",
  55. [EFocus] = "focus",
  56. [EFormat] = "format",
  57. [EHide] = "hide",
  58. [EImage] = "image",
  59. [ERect] = "rect",
  60. [EReveal] = "reveal",
  61. [ESeparation] = "separation",
  62. [ESeparatorcolor] = "separatorcolor",
  63. [EShow] = "show",
  64. [ESize] = "size",
  65. [EValue] = "value",
  66. };
  67. static void
  68. tabshow(Tab *t)
  69. {
  70. int i;
  71. Rectangle r;
  72. Group *g;
  73. if (t->Control.hidden)
  74. return;
  75. for(i=0; i<t->nbuttons; i++){
  76. _ctlprint(t->buttons[i], "value %d", (t->selected==i));
  77. }
  78. _ctlprint(t->tabstack, "reveal %d", t->selected);
  79. _ctlprint(t->tabcolumn, "show");
  80. if (t->selected < 0)
  81. return;
  82. g = (Group*)t->tabcolumn;
  83. if (g->nseparators == 0){
  84. return;
  85. }
  86. r = g->separators[0];
  87. r.min.x = t->buttons[t->selected]->rect.min.x;
  88. r.max.x = t->buttons[t->selected]->rect.max.x;
  89. draw(t->Control.screen, r, t->image->image, nil, t->image->image->r.min);
  90. flushimage(display, 1);
  91. }
  92. static void
  93. tabsize(Control *c)
  94. {
  95. Tab *t = (Tab*)c;
  96. if (t->tabcolumn && t->tabcolumn->setsize)
  97. t->tabcolumn->setsize((Control*)t->tabcolumn);
  98. }
  99. static void
  100. tabctl(Control *c, CParse *cp)
  101. {
  102. int cmd, i;
  103. Control *cbut, *cwin;
  104. Tab *t;
  105. Rectangle r;
  106. t = (Tab*)c;
  107. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  108. switch(cmd){
  109. case EAdd:
  110. if ((cp->nargs & 1) == 0)
  111. ctlerror("%q: arg count: %s", t->Control.name, cp->args[1]);
  112. for (i = 1; i < cp->nargs; i += 2){
  113. cbut = controlcalled(cp->args[i]);
  114. if (cbut == nil)
  115. ctlerror("%q: no such control: %s", t->Control.name, cp->args[i]);
  116. cwin = controlcalled(cp->args[i+1]);
  117. if (cwin == nil)
  118. ctlerror("%q: no such control: %s", t->Control.name, cp->args[i+1]);
  119. _ctladdgroup(t->tabrow, cbut);
  120. _ctlprint(t->tabstack, "add %q", cp->args[i+1]);
  121. _ctlprint(cbut, "format '%%s: %q button %%d'", t->Control.name);
  122. controlwire(cbut, "event", t->Control.controlset->ctl);
  123. t->buttons = ctlrealloc(t->buttons, (t->nbuttons+1)*sizeof(Control*));
  124. t->buttons[t->nbuttons] = cbut;
  125. t->nbuttons++;
  126. t->selected = -1;
  127. }
  128. _ctlprint(t->tabcolumn, "size");
  129. t->Control.size = t->tabcolumn->size;
  130. break;
  131. case EBorder:
  132. _ctlargcount(&t->Control, cp, 2);
  133. if(cp->iargs[1] < 0)
  134. ctlerror("%q: bad border: %c", t->Control.name, cp->str);
  135. t->border = cp->iargs[1];
  136. break;
  137. case EBordercolor:
  138. _ctlargcount(&t->Control, cp, 2);
  139. _setctlimage(&t->Control, &t->bordercolor, cp->args[1]);
  140. break;
  141. case EButton:
  142. _ctlargcount(&t->Control, cp, 2);
  143. if (cp->sender == nil)
  144. ctlerror("%q: senderless buttonevent: %q", t->Control.name, cp->str);
  145. cbut = controlcalled(cp->sender);
  146. for(i=0; i<t->nbuttons; i++)
  147. if (cbut == t->buttons[i])
  148. break;
  149. if (i == t->nbuttons)
  150. ctlerror("%q: not my event: %q", t->Control.name, cp->str);
  151. if(cp->iargs[1] == 0){
  152. /* button was turned off; turn it back on */
  153. _ctlprint(cbut, "value 1");
  154. }else{
  155. t->selected = i;
  156. if (t->_format)
  157. chanprint(t->Control.event, t->_format, t->Control.name, i);
  158. tabshow(t);
  159. }
  160. break;
  161. case EFocus:
  162. /* ignore focus change */
  163. break;
  164. case EFormat:
  165. _ctlargcount(&t->Control, cp, 2);
  166. t->_format = ctlstrdup(cp->args[1]);
  167. break;
  168. case EImage:
  169. _ctlargcount(&t->Control, cp, 2);
  170. _setctlimage(&t->Control, &t->image, cp->args[1]);
  171. break;
  172. case ESeparation:
  173. t->tabrow->ctl(t->tabrow, cp);
  174. t->tabcolumn->ctl(t->tabcolumn, cp);
  175. break;
  176. case ERect:
  177. _ctlargcount(&t->Control, cp, 5);
  178. r.min.x = cp->iargs[1];
  179. r.min.y = cp->iargs[2];
  180. r.max.x = cp->iargs[3];
  181. r.max.y = cp->iargs[4];
  182. if(Dx(r)<=0 || Dy(r)<=0)
  183. ctlerror("%q: bad rectangle: %s", t->Control.name, cp->str);
  184. t->Control.rect = r;
  185. r = insetrect(r, t->border);
  186. _ctlprint(t->tabcolumn, "rect %R", r);
  187. break;
  188. case EReveal:
  189. _ctlargcount(&t->Control, cp, 1);
  190. case EHide:
  191. case ESize:
  192. t->tabcolumn->ctl(t->tabcolumn, cp);
  193. break;
  194. case EShow:
  195. tabshow(t);
  196. break;
  197. case EValue:
  198. _ctlargcount(&t->Control, cp, 2);
  199. if (cp->iargs[1] < 0 || cp->iargs[1] >= t->nbuttons)
  200. ctlerror("%q: illegal value '%s'", t->Control.name, cp->str);
  201. t->selected = cp->iargs[1];
  202. tabshow(t);
  203. break;
  204. default:
  205. ctlerror("%q: unrecognized message '%s'", t->Control.name, cp->str);
  206. break;
  207. }
  208. }
  209. static void
  210. tabfree(Control*c)
  211. {
  212. Tab *t = (Tab*)c;
  213. t->nbuttons = 0;
  214. free(t->buttons);
  215. t->buttons = 0;
  216. }
  217. static void
  218. activatetab(Control *c, int act)
  219. {
  220. Tab *t;
  221. t = (Tab*)c;
  222. if (act)
  223. activate(t->tabcolumn);
  224. else
  225. deactivate(t->tabcolumn);
  226. }
  227. Control *
  228. createtab(Controlset *cs, char *name)
  229. {
  230. char s[128];
  231. Tab *t;
  232. t = (Tab*)_createctl(cs, "tab", sizeof(Tab), name);
  233. t->selected = -1;
  234. t->nbuttons = 0;
  235. t->Control.ctl = tabctl;
  236. t->Control.mouse = nil;
  237. t->Control.exit = tabfree;
  238. snprint(s, sizeof s, "_%s-row", name);
  239. t->tabrow = createrow(cs, s);
  240. snprint(s, sizeof s, "_%s-stack", name);
  241. t->tabstack = createstack(cs, s);
  242. snprint(s, sizeof s, "_%s-column", name);
  243. t->tabcolumn = createcolumn(cs, s);
  244. ctlprint(t->tabcolumn, "add %q %q", t->tabrow->name, t->tabstack->name);
  245. t->bordercolor = _getctlimage("black");
  246. t->image = _getctlimage("white");
  247. t->Control.setsize = tabsize;
  248. t->Control.activate = activatetab;
  249. return (Control*)t;
  250. }