button.c 5.8 KB
Newer Older
B
bernard.xiong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * File      : button.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2009-10-16     Bernard      first version
 */
#include <rtgui/dc.h>
#include <rtgui/widgets/button.h>
#include <rtgui/rtgui_theme.h>

static void _rtgui_button_constructor(rtgui_button_t *button)
{
	/* init widget and set event handler */
	RTGUI_WIDGET(button)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
	rtgui_widget_set_event_handler(RTGUI_WIDGET(button), rtgui_button_event_handler);

	/* un-press button */
25
	button->flag = 0;
B
bernard.xiong 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

	/* set flag and on_button event handler */
	button->pressed_image = RT_NULL;
	button->unpressed_image = RT_NULL;
	button->on_button = RT_NULL;

	/* set gc */
	RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(button)) = default_foreground;
	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(button)) = RTGUI_RGB(212, 208, 200);
	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(button)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
}

static void _rtgui_button_destructor(rtgui_button_t *button)
{
	if (button->pressed_image != RT_NULL)
	{
		rtgui_image_destroy(button->pressed_image);
		button->pressed_image = RT_NULL;
	}

	if (button->unpressed_image != RT_NULL)
	{
		rtgui_image_destroy(button->unpressed_image);
		button->unpressed_image = RT_NULL;
	}
}

rtgui_type_t *rtgui_button_type_get(void)
{
	static rtgui_type_t *button_type = RT_NULL;

	if (!button_type)
	{
		button_type = rtgui_type_create("button", RTGUI_LABEL_TYPE,
			sizeof(rtgui_button_t), 
			RTGUI_CONSTRUCTOR(_rtgui_button_constructor), 
			RTGUI_DESTRUCTOR(_rtgui_button_destructor));
	}

	return button_type;
}

rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
	struct rtgui_button* btn;

	RT_ASSERT(widget != RT_NULL);

	btn = (struct rtgui_button*) widget;
	switch (event->type)
	{
	case RTGUI_EVENT_PAINT:
78
#ifndef RTGUI_USING_SMALL_SIZE		
B
bernard.xiong 已提交
79
		if (widget->on_draw != RT_NULL ) widget->on_draw(widget, event);
80 81 82
		else
#endif			
			rtgui_theme_draw_button(btn);
B
bernard.xiong 已提交
83 84
		break;

85 86 87 88
	case RTGUI_EVENT_KBD:
		{
			struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*) event;

B
bernard.xiong 已提交
89
			if (RTGUI_WIDGET_IS_HIDE(widget)) RT_FALSE;
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
			if ((ekbd->key == RTGUIK_RETURN) || (ekbd->key == RTGUIK_SPACE))
			{
				if (RTGUI_KBD_IS_DOWN(ekbd))
				{
					btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
				}
				else
				{
					btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
				}

				/* draw button */
				rtgui_theme_draw_button(btn);

				if ((btn->flag & RTGUI_BUTTON_FLAG_PRESS) && (btn->on_button != RT_NULL))
				{
					/* call on button handler */
					btn->on_button(widget, event);
				}
			}
		}
		break;

B
bernard.xiong 已提交
113
	case RTGUI_EVENT_MOUSE_BUTTON:
B
bernard.xiong 已提交
114
		if (RTGUI_WIDGET_IS_HIDE(widget)) RT_FALSE;
B
bernard.xiong 已提交
115 116 117 118 119 120 121 122 123
		{
			struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;

			if (btn->flag & RTGUI_BUTTON_TYPE_PUSH)
			{
				/* it's a push button */
				if (emouse->button & RTGUI_MOUSE_BUTTON_UP)
				{
					if (btn->flag & RTGUI_BUTTON_FLAG_PRESS)
124
					{
B
bernard.xiong 已提交
125
						btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
126
					}
B
bernard.xiong 已提交
127
					else
128
					{
B
bernard.xiong 已提交
129
						btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
130
					}
B
bernard.xiong 已提交
131 132

					/* draw button */
133
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
134
					if (widget->on_draw != RT_NULL ) widget->on_draw(widget, event);
135 136 137
					else 
#endif
						rtgui_theme_draw_button(btn);
B
bernard.xiong 已提交
138

139 140 141 142 143 144
					if (btn->on_button != RT_NULL)
					{
						/* call on button handler */
						btn->on_button(widget, event);
					}

145
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
146 147 148 149
					/* invokes call back */
					if (widget->on_mouseclick != RT_NULL &&
						emouse->button & RTGUI_MOUSE_BUTTON_UP)
						return widget->on_mouseclick(widget, event);
150
#endif
B
bernard.xiong 已提交
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
				}
			}
			else
			{
				if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT)
				{
					/* it's a normal button */
					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
					{
						btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
					}
					else
					{
						btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
					}

					/* draw button */
168
#ifndef RTGUI_USING_SMALL_SIZE					
B
bernard.xiong 已提交
169
					if (widget->on_draw != RT_NULL ) widget->on_draw(widget, event);
170 171 172
					else
#endif
						rtgui_theme_draw_button(btn);
B
bernard.xiong 已提交
173

174
#ifndef RTGUI_USING_SMALL_SIZE
B
bernard.xiong 已提交
175 176 177 178
					/* invokes call back */
					if (widget->on_mouseclick != RT_NULL &&
						emouse->button & RTGUI_MOUSE_BUTTON_UP)
						return widget->on_mouseclick(widget, event);
179
#endif
180 181 182 183 184 185

					if (!(btn->flag & RTGUI_BUTTON_FLAG_PRESS) && (btn->on_button != RT_NULL))
					{
						/* call on button handler */
						btn->on_button(widget, event);
					}
B
bernard.xiong 已提交
186 187 188 189 190 191 192 193 194 195 196
				}

			}

			return RT_TRUE;
		}
	}

	return RT_FALSE;
}

197
rtgui_button_t* rtgui_button_create(char* text)
B
bernard.xiong 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
{
    struct rtgui_button* btn;

    btn = (struct rtgui_button*) rtgui_widget_create (RTGUI_BUTTON_TYPE);
    if (btn != RT_NULL)
    {
		rtgui_rect_t rect;

		/* set default rect */
		rtgui_font_get_metrics(rtgui_font_default(), text, &rect);
		rect.x2 += (RTGUI_BORDER_DEFAULT_WIDTH << 1);
		rect.y2 += (RTGUI_BORDER_DEFAULT_WIDTH << 1);
		rtgui_widget_set_rect(RTGUI_WIDGET(btn), &rect);
		rtgui_label_set_text(RTGUI_LABEL(btn), text);
    }

    return btn;
}

217
rtgui_button_t* rtgui_pushbutton_create(char* text)
B
bernard.xiong 已提交
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
{
	rtgui_button_t* btn;

	btn = rtgui_button_create(text);
	if (btn != RT_NULL) btn->flag |= RTGUI_BUTTON_TYPE_PUSH;

	return btn;
}

void rtgui_button_destroy(rtgui_button_t* btn)
{
	rtgui_widget_destroy(RTGUI_WIDGET(btn));
}

void rtgui_button_set_pressed_image(rtgui_button_t* btn, rtgui_image_t* image)
{
	RT_ASSERT(btn != RT_NULL);

	btn->pressed_image = image;
}

void rtgui_button_set_unpressed_image(rtgui_button_t* btn, rtgui_image_t* image)
{
	RT_ASSERT(btn != RT_NULL);

	btn->unpressed_image = image;
}

246 247 248 249 250 251 252
void rtgui_button_set_onbutton(rtgui_button_t* btn, rtgui_onbutton_func_t func)
{
	RT_ASSERT(btn != RT_NULL);

	btn->on_button = func;
}