box.c 3.2 KB

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