box.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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 Box Box;
  17. struct Box
  18. {
  19. Control Control;
  20. int border;
  21. CImage *bordercolor;
  22. CImage *image;
  23. int align;
  24. };
  25. enum{
  26. EAlign,
  27. EBorder,
  28. EBordercolor,
  29. EFocus,
  30. EHide,
  31. EImage,
  32. ERect,
  33. EReveal,
  34. EShow,
  35. ESize,
  36. };
  37. static char *cmds[] = {
  38. [EAlign] = "align",
  39. [EBorder] = "border",
  40. [EBordercolor] ="bordercolor",
  41. [EFocus] = "focus",
  42. [EHide] = "hide",
  43. [EImage] = "image",
  44. [ERect] = "rect",
  45. [EReveal] = "reveal",
  46. [EShow] = "show",
  47. [ESize] = "size",
  48. nil
  49. };
  50. static void
  51. boxkey(Control *c, Rune *rp)
  52. {
  53. Box *b;
  54. b = (Box*)c;
  55. chanprint(b->Control.event, "%q: key 0x%x", b->Control.name, rp[0]);
  56. }
  57. static void
  58. boxmouse(Control *c, Mouse *m)
  59. {
  60. Box *b;
  61. b = (Box*)c;
  62. if (ptinrect(m->xy,b->Control.rect))
  63. chanprint(b->Control.event, "%q: mouse %P %d %ld", b->Control.name,
  64. m->xy, m->buttons, m->msec);
  65. }
  66. static void
  67. boxfree(Control *c)
  68. {
  69. _putctlimage(((Box*)c)->image);
  70. }
  71. static void
  72. boxshow(Box *b)
  73. {
  74. Image *i;
  75. Rectangle r;
  76. if(b->Control.hidden)
  77. return;
  78. if(b->border > 0){
  79. border(b->Control.screen, b->Control.rect, b->border, b->bordercolor->image, ZP);
  80. r = insetrect(b->Control.rect, b->border);
  81. }else
  82. r = b->Control.rect;
  83. i = b->image->image;
  84. /* BUG: ALIGNMENT AND CLIPPING */
  85. draw(b->Control.screen, r, i, nil, ZP);
  86. }
  87. static void
  88. boxctl(Control *c, CParse *cp)
  89. {
  90. int cmd;
  91. Rectangle r;
  92. Box *b;
  93. b = (Box*)c;
  94. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  95. switch(cmd){
  96. default:
  97. ctlerror("%q: unrecognized message '%s'", b->Control.name, cp->str);
  98. break;
  99. case EAlign:
  100. _ctlargcount(&b->Control, cp, 2);
  101. b->align = _ctlalignment(cp->args[1]);
  102. break;
  103. case EBorder:
  104. _ctlargcount(&b->Control, cp, 2);
  105. if(cp->iargs[1] < 0)
  106. ctlerror("%q: bad border: %c", b->Control.name, cp->str);
  107. b->border = cp->iargs[1];
  108. break;
  109. case EBordercolor:
  110. _ctlargcount(&b->Control, cp, 2);
  111. _setctlimage(&b->Control, &b->bordercolor, cp->args[1]);
  112. break;
  113. case EFocus:
  114. _ctlargcount(&b->Control, cp, 2);
  115. chanprint(b->Control.event, "%q: focus %s", b->Control.name, cp->args[1]);
  116. break;
  117. case EHide:
  118. _ctlargcount(&b->Control, cp, 1);
  119. b->Control.hidden = 1;
  120. break;
  121. case EImage:
  122. _ctlargcount(&b->Control, cp, 2);
  123. _setctlimage(&b->Control, &b->image, cp->args[1]);
  124. break;
  125. case ERect:
  126. _ctlargcount(&b->Control, cp, 5);
  127. r.min.x = cp->iargs[1];
  128. r.min.y = cp->iargs[2];
  129. r.max.x = cp->iargs[3];
  130. r.max.y = cp->iargs[4];
  131. if(Dx(r)<0 || Dy(r)<0)
  132. ctlerror("%q: bad rectangle: %s", b->Control.name, cp->str);
  133. b->Control.rect = r;
  134. break;
  135. case EReveal:
  136. _ctlargcount(&b->Control, cp, 1);
  137. b->Control.hidden = 0;
  138. boxshow(b);
  139. break;
  140. case EShow:
  141. _ctlargcount(&b->Control, cp, 1);
  142. boxshow(b);
  143. break;
  144. case ESize:
  145. if (cp->nargs == 3)
  146. r.max = Pt(0x7fffffff, 0x7fffffff);
  147. else{
  148. _ctlargcount(&b->Control, cp, 5);
  149. r.max.x = cp->iargs[3];
  150. r.max.y = cp->iargs[4];
  151. }
  152. r.min.x = cp->iargs[1];
  153. r.min.y = cp->iargs[2];
  154. 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)
  155. ctlerror("%q: bad sizes: %s", b->Control.name, cp->str);
  156. b->Control.size.min = r.min;
  157. b->Control.size.max = r.max;
  158. break;
  159. }
  160. }
  161. Control*
  162. createbox(Controlset *cs, char *name)
  163. {
  164. Box *b;
  165. b = (Box *)_createctl(cs, "box", sizeof(Box), name);
  166. b->image = _getctlimage("white");
  167. b->bordercolor = _getctlimage("black");
  168. b->align = Aupperleft;
  169. b->Control.key = boxkey;
  170. b->Control.mouse = boxmouse;
  171. b->Control.ctl = boxctl;
  172. b->Control.exit = boxfree;
  173. return (Control *)b;
  174. }