button.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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 <draw.h>
  12. #include <thread.h>
  13. #include <mouse.h>
  14. #include <keyboard.h>
  15. #include <control.h>
  16. typedef struct Button Button;
  17. struct Button
  18. {
  19. Control Control;
  20. CImage *image;
  21. CImage *mask;
  22. CImage *light;
  23. CImage *pale;
  24. CImage *bordercolor;
  25. int pressed;
  26. int lastbut;
  27. int lastshow;
  28. int border;
  29. int align;
  30. int off;
  31. int prepress;
  32. };
  33. enum{
  34. EAlign,
  35. EBorder,
  36. EBordercolor,
  37. EFocus,
  38. EFormat,
  39. EHide,
  40. EImage,
  41. ELight,
  42. EMask,
  43. EPale,
  44. ERect,
  45. EReveal,
  46. EShow,
  47. ESize,
  48. EValue,
  49. };
  50. static char *cmds[] = {
  51. [EAlign] = "align",
  52. [EBorder] = "border",
  53. [EBordercolor] = "bordercolor",
  54. [EFocus] = "focus",
  55. [EFormat] = "format",
  56. [EHide] = "hide",
  57. [EImage] = "image",
  58. [ELight] = "light",
  59. [EMask] = "mask",
  60. [EPale] = "pale",
  61. [ERect] = "rect",
  62. [EReveal] = "reveal",
  63. [EShow] = "show",
  64. [ESize] = "size",
  65. [EValue] = "value",
  66. nil
  67. };
  68. static void
  69. buttonfree(Control *c)
  70. {
  71. Button *b;
  72. b = (Button *)c;
  73. _putctlimage(b->image);
  74. _putctlimage(b->mask);
  75. _putctlimage(b->light);
  76. _putctlimage(b->pale);
  77. _putctlimage(b->bordercolor);
  78. }
  79. static void
  80. buttonshow(Button *b)
  81. {
  82. Rectangle r;
  83. if (b->Control.hidden)
  84. return;
  85. r = b->Control.rect;
  86. if(b->border > 0){
  87. border(b->Control.screen, r, b->border, b->bordercolor->image, ZP);
  88. r = insetrect(b->Control.rect, b->border);
  89. }
  90. draw(b->Control.screen, r, b->image->image, nil, b->image->image->r.min);
  91. if(b->off)
  92. draw(b->Control.screen, r, b->pale->image, b->mask->image, b->mask->image->r.min);
  93. else if(b->pressed)
  94. draw(b->Control.screen, r, b->light->image, b->mask->image, b->mask->image->r.min);
  95. b->lastshow = b->pressed;
  96. flushimage(display, 1);
  97. }
  98. static void
  99. buttonmouse(Control *c, Mouse *m)
  100. {
  101. Button *b;
  102. b = (Button*)c;
  103. if(m->buttons&7) {
  104. if (ptinrect(m->xy,b->Control.rect)) {
  105. if (b->off) {
  106. b->off = 0;
  107. buttonshow(b);
  108. }
  109. } else {
  110. if (!b->off) {
  111. b->off = 1;
  112. buttonshow(b);
  113. }
  114. }
  115. }
  116. if((m->buttons&7) != b->lastbut){
  117. if(m->buttons & 7){
  118. b->prepress = b->pressed;
  119. if (b->pressed)
  120. b->pressed = 0;
  121. else
  122. b->pressed = m->buttons & 7;
  123. buttonshow(b);
  124. }else /* generate event on button up */
  125. if (ptinrect(m->xy,b->Control.rect))
  126. chanprint(b->Control.event, b->Control.format, b->Control.name, b->pressed);
  127. else {
  128. b->off = 0;
  129. b->pressed = b->prepress;
  130. buttonshow(b);
  131. }
  132. }
  133. b->lastbut = m->buttons & 7;
  134. }
  135. static void
  136. buttonctl(Control *c, CParse *cp)
  137. {
  138. int cmd;
  139. Rectangle r;
  140. Button *b;
  141. b = (Button*)c;
  142. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  143. switch(cmd){
  144. default:
  145. ctlerror("%q: unrecognized message '%s'", b->Control.name, cp->str);
  146. break;
  147. case EAlign:
  148. _ctlargcount(&b->Control, cp, 2);
  149. b->align = _ctlalignment(cp->args[1]);
  150. b->lastshow = -1; /* force redraw */
  151. break;
  152. case EBorder:
  153. _ctlargcount(&b->Control, cp, 2);
  154. b->border = cp->iargs[1];
  155. b->lastshow = -1; /* force redraw */
  156. break;
  157. case EBordercolor:
  158. _ctlargcount(&b->Control, cp, 2);
  159. _setctlimage(&b->Control, &b->bordercolor, cp->args[1]);
  160. b->lastshow = -1; /* force redraw */
  161. break;
  162. case EFocus:
  163. /* ignore focus change */
  164. break;
  165. case EFormat:
  166. _ctlargcount(&b->Control, cp, 2);
  167. b->Control.format = ctlstrdup(cp->args[1]);
  168. break;
  169. case EHide:
  170. _ctlargcount(&b->Control, cp, 1);
  171. b->Control.hidden = 1;
  172. break;
  173. case EImage:
  174. _ctlargcount(&b->Control, cp, 2);
  175. _setctlimage(&b->Control, &b->image, cp->args[1]);
  176. b->lastshow = -1; /* force redraw */
  177. break;
  178. case ELight:
  179. _ctlargcount(&b->Control, cp, 2);
  180. _setctlimage(&b->Control, &b->light, cp->args[1]);
  181. b->lastshow = -1; /* force redraw */
  182. break;
  183. case EMask:
  184. _ctlargcount(&b->Control, cp, 2);
  185. _setctlimage(&b->Control, &b->mask, cp->args[1]);
  186. b->lastshow = -1; /* force redraw */
  187. break;
  188. case EPale:
  189. _ctlargcount(&b->Control, cp, 2);
  190. _setctlimage(&b->Control, &b->pale, cp->args[1]);
  191. b->lastshow = -1; /* force redraw */
  192. break;
  193. case ERect:
  194. _ctlargcount(&b->Control, cp, 5);
  195. r.min.x = cp->iargs[1];
  196. r.min.y = cp->iargs[2];
  197. r.max.x = cp->iargs[3];
  198. r.max.y = cp->iargs[4];
  199. if(Dx(r)<0 || Dy(r)<0)
  200. ctlerror("%q: bad rectangle: %s", b->Control.name, cp->str);
  201. b->Control.rect = r;
  202. b->lastshow = -1; /* force redraw */
  203. break;
  204. case EReveal:
  205. _ctlargcount(&b->Control, cp, 1);
  206. b->Control.hidden = 0;
  207. buttonshow(b);
  208. break;
  209. case EShow:
  210. _ctlargcount(&b->Control, cp, 1);
  211. buttonshow(b);
  212. break;
  213. case ESize:
  214. if (cp->nargs == 3)
  215. r.max = Pt(0x7fffffff, 0x7fffffff);
  216. else{
  217. _ctlargcount(&b->Control, cp, 5);
  218. r.max.x = cp->iargs[3];
  219. r.max.y = cp->iargs[4];
  220. }
  221. r.min.x = cp->iargs[1];
  222. r.min.y = cp->iargs[2];
  223. 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)
  224. ctlerror("%q: bad sizes: %s", b->Control.name, cp->str);
  225. b->Control.size.min = r.min;
  226. b->Control.size.max = r.max;
  227. break;
  228. case EValue:
  229. _ctlargcount(&b->Control, cp, 2);
  230. if((cp->iargs[1]!=0) != b->pressed){
  231. b->pressed ^= 1;
  232. buttonshow(b);
  233. }
  234. break;
  235. }
  236. }
  237. Control*
  238. createbutton(Controlset *cs, char *name)
  239. {
  240. Button *b;
  241. b = (Button*)_createctl(cs, "button", sizeof(Button), name);
  242. b->image = _getctlimage("white");
  243. b->mask = _getctlimage("opaque");
  244. b->light = _getctlimage("yellow");
  245. b->pale = _getctlimage("paleyellow");
  246. b->bordercolor = _getctlimage("black");
  247. b->Control.format = ctlstrdup("%q: value %d");
  248. b->lastshow = -1;
  249. b->border = 0;
  250. b->align = Aupperleft;
  251. b->Control.ctl = buttonctl;
  252. b->Control.mouse = buttonmouse;
  253. b->Control.key = nil;
  254. b->Control.exit = buttonfree;
  255. b->off = 0;
  256. b->prepress = 0;
  257. return (Control*)b;
  258. }