/lui5/radio.c

https://github.com/drafnel/Vis5d · C · 182 lines · 111 code · 45 blank · 26 comment · 12 complexity · 2254eb519cb09971240d462fa5dafb0d MD5 · raw file

  1. /* radio.c */
  2. /*
  3. * Radio button widget. Exactly one of a set of buttons can be selected
  4. * at once.
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "lui.h"
  10. #define LMARGIN 20
  11. static void draw_radio( LUI_RADIO *r )
  12. {
  13. int x, y, x1, x2, width, height;
  14. int i;
  15. /* background area */
  16. x = LUI_Border;
  17. y = LUI_Border;
  18. width = r->width - 2 * LUI_Border;
  19. height = r->height - 2 * LUI_Border;
  20. XFillRectangle( LUI_Display, r->window, LUI_GC_gray,
  21. x, y, width, height );
  22. /* draw labels */
  23. for (i=0;i<r->numbuttons;i++) {
  24. x = LMARGIN;
  25. y = LUI_Border + 1 + i * (LUI_Font_height+4) + LUI_Font_yoff;
  26. XDrawString( LUI_Display, r->window, LUI_GC_black,
  27. x, y, r->labels[i], strlen(r->labels[i]) );
  28. x1 = LUI_Border + 2;
  29. x2 = r->width - 2*LUI_Border + 1;
  30. y = LUI_Border + i * (LUI_Font_height+4) - 2;
  31. if (i>0) {
  32. XDrawLine( LUI_Display, r->window, LUI_GC_black, x1, y, x2, y );
  33. }
  34. XDrawRectangle( LUI_Display, r->window, LUI_GC_black,
  35. x1, y+3, 11, 11 );
  36. if (r->current==i) {
  37. XFillRectangle( LUI_Display, r->window, LUI_GC_red,
  38. x1+2, y+5, 8, 8 );
  39. }
  40. }
  41. LUI_DrawFrame( r->window, 0, 0, r->width, r->height,
  42. LUI_Border, 1 );
  43. }
  44. static int radio_process( LUI_RADIO *r, XEvent *event )
  45. {
  46. switch (event->type) {
  47. case Expose:
  48. draw_radio( r );
  49. break;
  50. case ButtonPress:
  51. if (event->xbutton.button==Button1) {
  52. int y = event->xbutton.y;
  53. int row = (y - LUI_Border - 1) / (LUI_Font_height+4);
  54. if (row>=0 && row<r->numbuttons) {
  55. r->current = row;
  56. draw_radio( r );
  57. if (r->callback) {
  58. (*r->callback) ( r, row );
  59. }
  60. }
  61. }
  62. break;
  63. default:
  64. printf("Error in radio_process: unexpected event\n");
  65. }
  66. return 1;
  67. }
  68. /*
  69. * Create a new radio button widget.
  70. * Input: parent - parent window
  71. * x, y - position w.r.t parent
  72. * width - width in pixels, height is automatic
  73. * numbuttons - how many buttons
  74. * labels - the button labels
  75. */
  76. LUI_RADIO *LUI_RadioCreate( Window parent, int x, int y, int width,
  77. int numbuttons, char **labels )
  78. {
  79. LUI_RADIO *r;
  80. int height;
  81. height = (LUI_Font_height + 4) * numbuttons + 2 * LUI_Border + 4;
  82. LUI_LayoutCheck( &x, &y, &width, &height );
  83. r = (LUI_RADIO *) malloc( sizeof(LUI_RADIO) );
  84. if (!r) {
  85. return NULL;
  86. }
  87. r->window = XCreateSimpleWindow( LUI_Display, parent,
  88. x, y, width-2, height-2,
  89. 1, LUI_Color_black, LUI_Color_gray );
  90. LUI_EventAdd2( r->window,
  91. ExposureMask | ButtonPressMask,
  92. (LUI_FNCP) radio_process, r );
  93. XMapWindow( LUI_Display, r->window );
  94. r->x = x;
  95. r->y = y;
  96. r->width = width - 2;
  97. r->height = height - 2;
  98. r->numbuttons = numbuttons;
  99. r->labels = labels;
  100. r->current = 0;
  101. r->callback = NULL;
  102. /* MJK 12.04.98 */
  103. /* 24Nov07 Phil McDonald */
  104. LUI_AddWidgetToWindow( parent, r, (LUI_FNCP) LUI_RadioDestroy );
  105. return r;
  106. }
  107. /*
  108. * Specify the callback function for a radio button set.
  109. * The callback function should be declared as:
  110. * int callback( LUI_RADIO *r, int selection )
  111. *
  112. */
  113. void LUI_RadioCallback( LUI_RADIO *r, int (*callback)( LUI_RADIO *, int) )
  114. {
  115. r->callback = callback;
  116. r->context_index = context_index;
  117. }
  118. void LUI_RadioSetCurrent( LUI_RADIO *r, int current )
  119. {
  120. if (r && current>=0 && current<r->numbuttons) {
  121. r->current = current;
  122. draw_radio( r );
  123. }
  124. }
  125. int LUI_RadioGetCurrent( LUI_RADIO *r )
  126. {
  127. return r->current;
  128. }
  129. /*
  130. * Destroy a button.
  131. */
  132. void LUI_RadioDestroy( LUI_RADIO *r )
  133. {
  134. LUI_EventRemove( r->window );
  135. XDestroyWindow( LUI_Display, r->window );
  136. free( r );
  137. }