radiobutton.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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 Radio Radio;
  17. struct Radio
  18. {
  19. Control;
  20. int value;
  21. int lastbut;
  22. Control **buttons;
  23. int nbuttons;
  24. char *eventstr;
  25. };
  26. enum{
  27. EAdd,
  28. EButton,
  29. EFocus,
  30. EFormat,
  31. EHide,
  32. ERect,
  33. EReveal,
  34. EShow,
  35. ESize,
  36. EValue,
  37. };
  38. static char *cmds[] = {
  39. [EAdd] = "add",
  40. [EButton] = "button",
  41. [EFocus] = "focus",
  42. [EFormat] = "format",
  43. [EHide] = "hide",
  44. [ERect] = "rect",
  45. [EReveal] = "reveal",
  46. [EShow] = "show",
  47. [ESize] = "size",
  48. [EValue] = "value",
  49. nil
  50. };
  51. static void radioshow(Radio*);
  52. static void
  53. radiomouse(Control *c, Mouse *m)
  54. {
  55. Radio *r;
  56. int i;
  57. r = (Radio*)c;
  58. for(i=0; i<r->nbuttons; i++)
  59. if(ptinrect(m->xy, r->buttons[i]->rect) && r->buttons[i]->mouse){
  60. (r->buttons[i]->mouse)(r->buttons[i], m);
  61. break;
  62. }
  63. }
  64. static void
  65. radioshow(Radio *r)
  66. {
  67. int i;
  68. if (r->hidden)
  69. return;
  70. for(i=0; i<r->nbuttons; i++){
  71. _ctlprint(r->buttons[i], "value %d", (r->value==i));
  72. _ctlprint(r->buttons[i], "show");
  73. }
  74. }
  75. static void
  76. radioctl(Control *c, CParse *cp)
  77. {
  78. int cmd, i;
  79. Rectangle rect;
  80. Radio *r;
  81. char fmt[256];
  82. r = (Radio*)c;
  83. cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
  84. switch(cmd){
  85. default:
  86. ctlerror("%q: unrecognized message '%s'", r->name, cp->str);
  87. break;
  88. case EAdd:
  89. _ctlargcount(r, cp, 2);
  90. c = controlcalled(cp->args[1]);
  91. if(c == nil)
  92. ctlerror("%q: can't add %s: %r", r->name, cp->args[1]);
  93. snprint(fmt, sizeof fmt, "%%q: %q button %%d", r->name);
  94. _ctlprint(c, "format %q", fmt);
  95. controlwire(c, "event", c->controlset->ctl);
  96. r->buttons = ctlrealloc(r->buttons, (r->nbuttons+1)*sizeof(Control*));
  97. r->buttons[r->nbuttons] = c;
  98. r->nbuttons++;
  99. r->value = -1;
  100. radioshow(r);
  101. break;
  102. case EButton:
  103. if (cp->sender == nil)
  104. ctlerror("%q: senderless buttonevent: %q", r->name, cp->str);
  105. c = controlcalled(cp->sender);
  106. for(i=0; i<r->nbuttons; i++)
  107. if (c == r->buttons[i])
  108. break;
  109. if (i == r->nbuttons)
  110. ctlerror("%q: not my event: %q", r->name, cp->str);
  111. if(cp->iargs[1] == 0){
  112. /* button was turned off; turn it back on */
  113. _ctlprint(c, "value 1");
  114. }else{
  115. r->value = i;
  116. chanprint(r->event, r->format, r->name, i);
  117. radioshow(r);
  118. }
  119. break;
  120. case EFormat:
  121. _ctlargcount(r, cp, 2);
  122. r->format = ctlstrdup(cp->args[1]);
  123. break;
  124. case EHide:
  125. _ctlargcount(r, cp, 1);
  126. r->hidden = 1;
  127. break;
  128. case EFocus:
  129. /* ignore focus change */
  130. break;
  131. case ERect:
  132. _ctlargcount(r, cp, 5);
  133. rect.min.x = cp->iargs[1];
  134. rect.min.y = cp->iargs[2];
  135. rect.max.x = cp->iargs[3];
  136. rect.max.y = cp->iargs[4];
  137. r->rect = rect;
  138. break;
  139. case EReveal:
  140. _ctlargcount(r, cp, 1);
  141. r->hidden = 0;
  142. radioshow(r);
  143. break;
  144. case EShow:
  145. _ctlargcount(r, cp, 1);
  146. radioshow(r);
  147. break;
  148. case ESize:
  149. if (cp->nargs == 3)
  150. rect.max = Pt(0x7fffffff, 0x7fffffff);
  151. else{
  152. _ctlargcount(r, cp, 5);
  153. rect.max.x = cp->iargs[3];
  154. rect.max.y = cp->iargs[4];
  155. }
  156. rect.min.x = cp->iargs[1];
  157. rect.min.y = cp->iargs[2];
  158. if(rect.min.x<=0 || rect.min.y<=0 || rect.max.x<=0 || rect.max.y<=0 || rect.max.x < rect.min.x || rect.max.y < rect.min.y)
  159. ctlerror("%q: bad sizes: %s", r->name, cp->str);
  160. r->size.min = rect.min;
  161. r->size.max = rect.max;
  162. break;
  163. case EValue:
  164. _ctlargcount(r, cp, 2);
  165. r->value = cp->iargs[1];
  166. radioshow(r);
  167. break;
  168. }
  169. }
  170. Control*
  171. createradiobutton(Controlset *cs, char *name)
  172. {
  173. Radio *r;
  174. r = (Radio*)_createctl(cs, "label", sizeof(Radio), name);
  175. r->format = ctlstrdup("%q: value %d");
  176. r->value = -1; /* nobody set at first */
  177. r->mouse = radiomouse;
  178. r->ctl = radioctl;
  179. return (Control*)r;
  180. }