/* radio.c */
/*
* Radio button widget. Exactly one of a set of buttons can be selected
* at once.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lui.h"
#define LMARGIN 20
static void draw_radio( LUI_RADIO *r )
{
int x, y, x1, x2, width, height;
int i;
/* background area */
x = LUI_Border;
y = LUI_Border;
width = r->width - 2 * LUI_Border;
height = r->height - 2 * LUI_Border;
XFillRectangle( LUI_Display, r->window, LUI_GC_gray,
x, y, width, height );
/* draw labels */
for (i=0;i<r->numbuttons;i++) {
x = LMARGIN;
y = LUI_Border + 1 + i * (LUI_Font_height+4) + LUI_Font_yoff;
XDrawString( LUI_Display, r->window, LUI_GC_black,
x, y, r->labels[i], strlen(r->labels[i]) );
x1 = LUI_Border + 2;
x2 = r->width - 2*LUI_Border + 1;
y = LUI_Border + i * (LUI_Font_height+4) - 2;
if (i>0) {
XDrawLine( LUI_Display, r->window, LUI_GC_black, x1, y, x2, y );
}
XDrawRectangle( LUI_Display, r->window, LUI_GC_black,
x1, y+3, 11, 11 );
if (r->current==i) {
XFillRectangle( LUI_Display, r->window, LUI_GC_red,
x1+2, y+5, 8, 8 );
}
}
LUI_DrawFrame( r->window, 0, 0, r->width, r->height,
LUI_Border, 1 );
}
static int radio_process( LUI_RADIO *r, XEvent *event )
{
switch (event->type) {
case Expose:
draw_radio( r );
break;
case ButtonPress:
if (event->xbutton.button==Button1) {
int y = event->xbutton.y;
int row = (y - LUI_Border - 1) / (LUI_Font_height+4);
if (row>=0 && row<r->numbuttons) {
r->current = row;
draw_radio( r );
if (r->callback) {
(*r->callback) ( r, row );
}
}
}
break;
default:
printf("Error in radio_process: unexpected event\n");
}
return 1;
}
/*
* Create a new radio button widget.
* Input: parent - parent window
* x, y - position w.r.t parent
* width - width in pixels, height is automatic
* numbuttons - how many buttons
* labels - the button labels
*/
LUI_RADIO *LUI_RadioCreate( Window parent, int x, int y, int width,
int numbuttons, char **labels )
{
LUI_RADIO *r;
int height;
height = (LUI_Font_height + 4) * numbuttons + 2 * LUI_Border + 4;
LUI_LayoutCheck( &x, &y, &width, &height );
r = (LUI_RADIO *) malloc( sizeof(LUI_RADIO) );
if (!r) {
return NULL;
}
r->window = XCreateSimpleWindow( LUI_Display, parent,
x, y, width-2, height-2,
1, LUI_Color_black, LUI_Color_gray );
LUI_EventAdd2( r->window,
ExposureMask | ButtonPressMask,
(LUI_FNCP) radio_process, r );
XMapWindow( LUI_Display, r->window );
r->x = x;
r->y = y;
r->width = width - 2;
r->height = height - 2;
r->numbuttons = numbuttons;
r->labels = labels;
r->current = 0;
r->callback = NULL;
/* MJK 12.04.98 */
/* 24Nov07 Phil McDonald */
LUI_AddWidgetToWindow( parent, r, (LUI_FNCP) LUI_RadioDestroy );
return r;
}
/*
* Specify the callback function for a radio button set.
* The callback function should be declared as:
* int callback( LUI_RADIO *r, int selection )
*
*/
void LUI_RadioCallback( LUI_RADIO *r, int (*callback)( LUI_RADIO *, int) )
{
r->callback = callback;
r->context_index = context_index;
}
void LUI_RadioSetCurrent( LUI_RADIO *r, int current )
{
if (r && current>=0 && current<r->numbuttons) {
r->current = current;
draw_radio( r );
}
}
int LUI_RadioGetCurrent( LUI_RADIO *r )
{
return r->current;
}
/*
* Destroy a button.
*/
void LUI_RadioDestroy( LUI_RADIO *r )
{
LUI_EventRemove( r->window );
XDestroyWindow( LUI_Display, r->window );
free( r );
}
syntax highlighted by Code2HTML, v. 0.9.1