box.c 3.2 KB

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