Files
commandergenius/project/jni/application/lbreakout2/gui/gui_radiogroup.c

245 lines
8.9 KiB
C

/***************************************************************************
gui_radiogroup.c - description
-------------------
begin : Wed Oct 16 2002
copyright : (C) 2002 by Michael Speck
email : kulkanie@gmx.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <stdlib.h>
#include <string.h>
#include "gui_widget.h"
#include "gui_radiogroup.h"
extern GuiTheme *gui_theme;
extern SDL_Surface *stk_display;
/*
====================================================================
LOCALS
====================================================================
*/
/*
====================================================================
Default event handler
====================================================================
*/
static void default_event_handler(
GuiWidget *widget, GuiEvent *event )
{
int px, py, i;
switch ( event->type ) {
case GUI_DESTROY:
if ( widget->spec.radiogroup.checks )
free( widget->spec.radiogroup.checks );
break;
case GUI_DRAW:
/* display surface */
stk_surface_blit(
widget->surface, 0, 0, -1, -1,
stk_display,
widget->screen_region.x,
widget->screen_region.y );
/* add checkers */
px = widget->screen_region.x +
widget->spec.radiogroup.x;
py = widget->screen_region.y +
widget->spec.radiogroup.y;
for ( i = 0; i < widget->spec.radiogroup.size;
i++, py += widget->spec.radiogroup.offset ) {
if ( widget->spec.radiogroup.checks[i] )
stk_surface_blit(
gui_theme->checkbox,
gui_theme->checkbox_size, 0,
gui_theme->checkbox_size,
gui_theme->checkbox_size,
stk_display, px, py );
}
break;
case GUI_CLICKED:
gui_radiogroup_toggle( widget,
(event->button.y - widget->screen_region.y -
widget->border) / widget->spec.radiogroup.offset );
break;
}
}
/*
====================================================================
PUBLICS
====================================================================
*/
/*
====================================================================
Create a radiogroup or a checkbox which is nothing but a
single entried radiogroup.
'caption': checkbox caption
'items': items - the widget does not modify the pointers
'checked': is True if checkbox checked else False.
Radiogroup selections can be set with gui_radiogroup_select().
====================================================================
*/
GuiWidget* gui_checkbox_create(
GuiWidget *parent, int x, int y, int width, int height, int with_frame,
void (*user_event_handler)(GuiWidget*,GuiEvent*),
char *caption, int checked )
{
GuiWidget *widget;
char *items[1];
items[0] = caption;
/* this is just a single itemed radiogroup */
widget = gui_radiogroup_create(
parent, x, y, width, height, with_frame, user_event_handler,
1, items, 0, 1 );
gui_radiogroup_set_checked( widget, 0, checked );
return widget;
}
GuiWidget* gui_radiogroup_create(
GuiWidget *parent, int x, int y, int width, int height, int with_frame,
void (*user_event_handler)(GuiWidget*,GuiEvent*),
int item_count, char **items, int min, int max )
{
int px, py, i, j, gap = 4;
GuiWidget *widget = gui_widget_create(
parent, GUI_RADIOGROUP, x, y, width, height,
default_event_handler, user_event_handler );
/* events */
gui_widget_enable_event( widget, GUI_CLICKED );
/* create surface, wallpaper and frame it */
widget->surface = stk_surface_create(
SDL_SWSURFACE, width, height );
SDL_SetColorKey( widget->surface, 0,0 );
stk_surface_apply_wallpaper( widget->surface, 0,0,-1,-1,
gui_theme->widget_wallpaper, -1 );
if ( with_frame )
widget->border = stk_surface_apply_frame(
widget->surface, 0, 0, -1, -1,
gui_theme->widget_frame );
/* size w/o border */
widget->width -= 2 * widget->border;
widget->height -= 2 * widget->border;
/* various */
widget->spec.radiogroup.size = item_count;
widget->spec.radiogroup.min = min;
widget->spec.radiogroup.max = max;
widget->spec.radiogroup.single_check = -1;
/* compute offset of single items */
widget->spec.radiogroup.offset =
(height - 2 * widget->border) /
item_count;
/* position of first checkbox */
widget->spec.radiogroup.x = widget->border + gap;
widget->spec.radiogroup.y = widget->border +
(widget->spec.radiogroup.offset -
gui_theme->checkbox_size) / 2;
/* add empty checkboxes and labels */
gui_theme->label_font->align = STK_FONT_ALIGN_CENTER_Y;
px = widget->spec.radiogroup.x;
py = widget->spec.radiogroup.y;
for ( i = 0, j = 0; i < widget->spec.radiogroup.size;
i++, py += widget->spec.radiogroup.offset, j++ ) {
stk_surface_blit(
gui_theme->checkbox, 0, 0,
gui_theme->checkbox_size,
gui_theme->checkbox_size,
widget->surface, px, py );
stk_font_write( gui_theme->label_font,
widget->surface, px + gui_theme->checkbox_size + gap,
py + gui_theme->checkbox_size/2, -1, items[j] );
}
/* create empty checkers */
widget->spec.radiogroup.checks = calloc( item_count, sizeof( int ) );
if ( widget->spec.radiogroup.checks == 0 )
GUI_ABORT( "Out Of Memory" );
return widget;
}
/*
====================================================================
Set or check if a checkbox in the radiogroup is set.
Stores refresh rects if visible.
====================================================================
*/
void gui_radiogroup_set_checked(
GuiWidget *widget, int id, int check )
{
if ( widget->type != GUI_RADIOGROUP )
return;
if ( id >= widget->spec.radiogroup.size || id < 0 )
return;
/* if there is at maximum one item selectable
we clear the selection to simplify usage */
if ( widget->spec.radiogroup.max == 1 ) {
memset( widget->spec.radiogroup.checks, 0,
widget->spec.radiogroup.size * sizeof( int ) );
widget->spec.radiogroup.check_count = 0;
widget->spec.radiogroup.single_check = -1;
}
if ( check ) {
/* select item if possible */
if ( widget->spec.radiogroup.check_count ==
widget->spec.radiogroup.max )
return;
/* if only one selection is allowed unselect old checker */
widget->spec.radiogroup.checks[id] = 1;
widget->spec.radiogroup.single_check = id;
widget->spec.radiogroup.check_count++;
}
else {
/* unselect item if possible */
if ( widget->spec.radiogroup.check_count ==
widget->spec.radiogroup.min )
return;
if ( widget->spec.radiogroup.checks[id] == 0 )
return;
widget->spec.radiogroup.checks[id] = 0;
widget->spec.radiogroup.single_check = -1;
widget->spec.radiogroup.check_count--;
}
if ( widget->visible )
gui_widget_draw( widget );
}
void gui_radiogroup_toggle( GuiWidget *widget, int id )
{
if ( widget->type != GUI_RADIOGROUP )
return;
if ( id >= widget->spec.radiogroup.size || id < 0 )
return;
gui_radiogroup_set_checked(
widget, id, !widget->spec.radiogroup.checks[id] );
}
int gui_radiogroup_is_checked( GuiWidget *widget, int id )
{
if ( widget->type != GUI_RADIOGROUP )
return 0;
if ( id >= widget->spec.radiogroup.size || id < 0 )
return 0;
return widget->spec.radiogroup.checks[id];
}
/*
====================================================================
For radiogroups with at max one items this returns the currently
checked id or -1.
====================================================================
*/
int gui_radiogroup_get_checked( GuiWidget *widget )
{
if ( widget->type != GUI_RADIOGROUP )
return -1;
if ( widget->spec.radiogroup.max != 1 )
return -1;
return widget->spec.radiogroup.single_check;
}