Files
multirom_m86/checkbox.c
2013-07-27 17:42:34 +02:00

148 lines
3.7 KiB
C

/*
* This file is part of MultiROM.
*
* MultiROM 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 3 of the License, or
* (at your option) any later version.
*
* MultiROM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MultiROM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include "checkbox.h"
#include "input.h"
#include "util.h"
#include "multirom_ui.h"
#define BORDER_SIZE 2
#define BORDER_PADDING 2
#define SELECTED_SIZE (CHECKBOX_SIZE-(BORDER_SIZE+BORDER_PADDING)*2)
#define SELECTED_PADDING (BORDER_SIZE + BORDER_PADDING)
#define TOUCH 15
checkbox *checkbox_create(int x, int y, void (*clicked)(int))
{
checkbox *c = malloc(sizeof(checkbox));
memset(c, 0, sizeof(checkbox));
c->touch_id = -1;
c->clicked = clicked;
c->borders[BORDER_L] = fb_add_rect(0, 0, BORDER_SIZE, CHECKBOX_SIZE, WHITE);
c->borders[BORDER_R] = fb_add_rect(0, 0, BORDER_SIZE, CHECKBOX_SIZE, WHITE);
c->borders[BORDER_T] = fb_add_rect(0, 0, CHECKBOX_SIZE, BORDER_SIZE, WHITE);
c->borders[BORDER_B] = fb_add_rect(0, 0, CHECKBOX_SIZE, BORDER_SIZE, WHITE);
checkbox_set_pos(c, x, y);
if(c->clicked)
add_touch_handler(&checkbox_touch_handler, c);
return c;
}
void checkbox_destroy(checkbox *c)
{
int i;
for(i = 0; i < BORDER_MAX; ++i)
fb_rm_rect(c->borders[i]);
fb_rm_rect(c->selected);
if(c->clicked)
rm_touch_handler(&checkbox_touch_handler, c);
free(c);
}
void checkbox_set_pos(checkbox *c, int x, int y)
{
c->x = x;
c->y = y;
int pos[][2] =
{
// BORDER_L
{ x, y, },
// BORDER_R
{ x + CHECKBOX_SIZE - BORDER_SIZE, y },
// BORDER_T
{ x, y },
// BORDER_B
{ x, y + CHECKBOX_SIZE - BORDER_SIZE }
};
int i;
for(i = 0; i < BORDER_MAX; ++i)
{
c->borders[i]->head.x = pos[i][0];
c->borders[i]->head.y = pos[i][1];
}
if(c->selected)
{
c->selected->head.x = x + SELECTED_PADDING;
c->selected->head.y = y + SELECTED_PADDING;
}
}
void checkbox_select(checkbox *c, int select)
{
if(!((c->selected != NULL) ^ (select != 0)))
return;
if(select)
{
c->selected = fb_add_rect(c->x + SELECTED_PADDING, c->y + SELECTED_PADDING,
SELECTED_SIZE, SELECTED_SIZE, CLR_PRIMARY);
}
else
{
fb_rm_rect(c->selected);
c->selected = NULL;
}
}
int checkbox_touch_handler(touch_event *ev, void *data)
{
checkbox *box = (checkbox*)data;
if(box->touch_id == -1 && (ev->changed & TCHNG_ADDED))
{
if(!in_rect(ev->x, ev->y, box->x-TOUCH, box->y-TOUCH, CHECKBOX_SIZE+TOUCH*2, CHECKBOX_SIZE+TOUCH*2))
return -1;
box->touch_id = ev->id;
box->hover = fb_add_rect(box->x-TOUCH, box->y-TOUCH, CHECKBOX_SIZE+TOUCH*2, CHECKBOX_SIZE+TOUCH*2, CLR_SECONDARY);
fb_draw();
}
if(box->touch_id != ev->id)
return -1;
if(ev->changed & TCHNG_REMOVED)
{
if(in_rect(ev->x, ev->y, box->x-TOUCH, box->y-TOUCH, CHECKBOX_SIZE+TOUCH*2, CHECKBOX_SIZE+TOUCH*2))
{
(*box->clicked)(box->selected == NULL);
checkbox_select(box, (box->selected == NULL));
}
fb_rm_rect(box->hover);
box->hover = NULL;
box->touch_id = -1;
fb_draw();
}
return 0;
}