radiobutton.c 3.7 KB

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