label.c 3.9 KB

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