label.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 Label Label;
  17. struct Label
  18. {
  19. Control Control;
  20. int border;
  21. CFont *font;
  22. CImage *image;
  23. CImage *textcolor;
  24. CImage *bordercolor;
  25. char *text;
  26. int align;
  27. };
  28. enum{
  29. EAlign,
  30. EBorder,
  31. EBordercolor,
  32. EFocus,
  33. EFont,
  34. EHide,
  35. EImage,
  36. ERect,
  37. EReveal,
  38. EShow,
  39. ESize,
  40. ETextcolor,
  41. EValue,
  42. };
  43. static char *cmds[] = {
  44. [EAlign] = "align",
  45. [EBorder] = "border",
  46. [EBordercolor] = "bordercolor",
  47. [EFocus] = "focus",
  48. [EFont] = "font",
  49. [EHide] = "hide",
  50. [EImage] = "image",
  51. [ERect] = "rect",
  52. [EReveal] = "reveal",
  53. [EShow] = "show",
  54. [ESize] = "size",
  55. [ETextcolor] = "textcolor",
  56. [EValue] = "value",
  57. nil
  58. };
  59. static void labelshow(Label*);
  60. static void
  61. labelfree(Control *c)
  62. {
  63. Label *l;
  64. l = (Label*)c;
  65. _putctlfont(l->font);
  66. _putctlimage(l->image);
  67. _putctlimage(l->textcolor);
  68. _putctlimage(l->bordercolor);
  69. }
  70. static void
  71. labelshow(Label *l)
  72. {
  73. Rectangle r;
  74. Point p;
  75. if (l->Control.hidden)
  76. return;
  77. r = l->Control.rect;
  78. draw(l->Control.screen, r, l->image->image, nil, l->image->image->r.min);
  79. if(l->border > 0){
  80. border(l->Control.screen, r, l->border, l->bordercolor->image, l->bordercolor->image->r.min);
  81. r = insetrect(r, l->border);
  82. }
  83. p = _ctlalignpoint(r,
  84. stringwidth(l->font->font, l->text),
  85. l->font->font->height, l->align);
  86. _string(l->Control.screen, p, l->textcolor->image,
  87. ZP, l->font->font, l->text, nil, strlen(l->text),
  88. r, nil, ZP, SoverD);
  89. flushimage(display, 1);
  90. }
  91. static void
  92. labelctl(Control *c, CParse *cp)
  93. {
  94. int cmd;
  95. Rectangle r;
  96. Label *l;
  97. l = (Label*)c;
  98. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  99. switch(cmd){
  100. default:
  101. ctlerror("%q: unrecognized message '%s'", l->Control.name, cp->str);
  102. break;
  103. case EAlign:
  104. _ctlargcount(&l->Control, cp, 2);
  105. l->align = _ctlalignment(cp->args[1]);
  106. break;
  107. case EBorder:
  108. _ctlargcount(&l->Control, cp, 2);
  109. if(cp->iargs[1] < 0)
  110. ctlerror("%q: bad border: %c", l->Control.name, cp->str);
  111. l->border = cp->iargs[1];
  112. break;
  113. case EBordercolor:
  114. _ctlargcount(&l->Control, cp, 2);
  115. _setctlimage(&l->Control, &l->bordercolor, cp->args[1]);
  116. break;
  117. case EFocus:
  118. /* ignore focus change */
  119. break;
  120. case EFont:
  121. _ctlargcount(&l->Control, cp, 2);
  122. _setctlfont(&l->Control, &l->font, cp->args[1]);
  123. break;
  124. case EHide:
  125. _ctlargcount(&l->Control, cp, 1);
  126. l->Control.hidden = 1;
  127. break;
  128. case EImage:
  129. _ctlargcount(&l->Control, cp, 2);
  130. _setctlimage(&l->Control, &l->image, cp->args[1]);
  131. break;
  132. case ERect:
  133. _ctlargcount(&l->Control, cp, 5);
  134. r.min.x = cp->iargs[1];
  135. r.min.y = cp->iargs[2];
  136. r.max.x = cp->iargs[3];
  137. r.max.y = cp->iargs[4];
  138. if(Dx(r)<=0 || Dy(r)<=0)
  139. ctlerror("%q: bad rectangle: %s", l->Control.name, cp->str);
  140. l->Control.rect = r;
  141. break;
  142. case EReveal:
  143. _ctlargcount(&l->Control, cp, 1);
  144. l->Control.hidden = 0;
  145. labelshow(l);
  146. break;
  147. case EShow:
  148. _ctlargcount(&l->Control, cp, 1);
  149. labelshow(l);
  150. /*
  151. _ctlargcount(&l->Control, cp, 2);
  152. _setctlimage(&l->Control, &l->textcolor, cp->args[1]);
  153. */
  154. break;
  155. case ESize:
  156. if (cp->nargs == 3)
  157. r.max = Pt(0x7fffffff, 0x7fffffff);
  158. else{
  159. _ctlargcount(&l->Control, cp, 5);
  160. r.max.x = cp->iargs[3];
  161. r.max.y = cp->iargs[4];
  162. }
  163. r.min.x = cp->iargs[1];
  164. r.min.y = cp->iargs[2];
  165. 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)
  166. ctlerror("%q: bad sizes: %s", l->Control.name, cp->str);
  167. l->Control.size.min = r.min;
  168. l->Control.size.max = r.max;
  169. break;
  170. case ETextcolor:
  171. _ctlargcount(&l->Control, cp, 2);
  172. _setctlimage(&l->Control, &l->textcolor, cp->args[1]);
  173. break;
  174. case EValue:
  175. _ctlargcount(&l->Control, cp, 2);
  176. if(strcmp(cp->args[1], l->text) != 0){
  177. free(l->text);
  178. l->text = ctlstrdup(cp->args[1]);
  179. labelshow(l);
  180. }
  181. break;
  182. }
  183. }
  184. Control*
  185. createlabel(Controlset *cs, char *name)
  186. {
  187. Label *l;
  188. l = (Label*)_createctl(cs, "label", sizeof(Label), name);
  189. l->text = ctlstrdup("");
  190. l->image = _getctlimage("white");
  191. l->textcolor = _getctlimage("black");
  192. l->bordercolor = _getctlimage("black");
  193. l->font = _getctlfont("font");
  194. l->border = 0;
  195. l->Control.ctl = labelctl;
  196. l->Control.exit = labelfree;
  197. return (Control *)l;
  198. }