PageRenderTime 64ms CodeModel.GetById 20ms app.highlight 23ms RepoModel.GetById 17ms app.codeStats 0ms

/src/ftk_check_button.c

http://ftk.googlecode.com/
C | 326 lines | 248 code | 48 blank | 30 comment | 34 complexity | 79fdf8eaf668b4220f303252993e545c MD5 | raw file
  1/*
  2 * File: ftk_check_button.c    
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   check button widget 
  5 *
  6 * Copyright (c) 2009 - 2010  Li XianJing <xianjimli@hotmail.com>
  7 *
  8 * Licensed under the Academic Free License version 2.1
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with this program; if not, write to the Free Software
 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 23 */
 24
 25/*
 26 * History:
 27 * ================================================================
 28 * 2012-06-01 woodysu@gmail.com modified
 29 * 2009-11-15 Li XianJing <xianjimli@hotmail.com> created
 30 *
 31 */
 32
 33#include "ftk_log.h"
 34#include "ftk_canvas.h"
 35#include "ftk_globals.h"
 36#include "ftk_window.h"
 37#include "ftk_icon_cache.h"
 38#include "ftk_check_button.h"
 39#include "ftk_group_box.h"
 40
 41typedef struct _CheckButtonPrivInfo
 42{
 43	int checked;
 44	int is_radio;
 45	int icon_at_right;
 46	FtkListener listener;
 47	void* listener_ctx;
 48	FtkBitmap* onimg;  
 49	FtkBitmap* offimg; 
 50}PrivInfo;
 51
 52static Ret ftk_check_button_check(FtkWidget* thiz)
 53{
 54	Ret ret = RET_OK;
 55	DECL_PRIV0(thiz, priv);
 56	
 57	if(priv->is_radio && ftk_widget_type(ftk_widget_parent(thiz)) == FTK_GROUP_BOX)
 58	{
 59		ret = ftk_group_box_set_checked(ftk_widget_parent(thiz), thiz);
 60	}
 61	else
 62	{
 63		ret = ftk_check_button_set_checked(thiz, !priv->checked);
 64	}
 65
 66	return ret;
 67}
 68
 69static Ret ftk_check_button_on_event(FtkWidget* thiz, FtkEvent* event)
 70{
 71	Ret ret = RET_OK;
 72	DECL_PRIV0(thiz, priv);
 73	switch(event->type)
 74	{
 75		case FTK_EVT_MOUSE_DOWN:
 76		{
 77			ftk_widget_set_active(thiz, 1);
 78			ftk_window_grab(ftk_widget_toplevel(thiz), thiz);
 79			break;
 80		}
 81		case FTK_EVT_MOUSE_UP:
 82		{
 83			int x = event->u.mouse.x;
 84			int y = event->u.mouse.y;
 85
 86			if(ftk_widget_is_active(thiz))
 87			{
 88				ftk_widget_set_active(thiz, 0);
 89				ftk_window_ungrab(ftk_widget_toplevel(thiz), thiz);
 90				if(FTK_POINT_IN_WIDGET(x, y, thiz))
 91				{
 92					ret = FTK_CALL_LISTENER(priv->listener, priv->listener_ctx, thiz);
 93					ftk_check_button_check(thiz);
 94				}
 95			}
 96			break;
 97		}
 98		case FTK_EVT_KEY_DOWN:
 99		{
100			if(FTK_IS_ACTIVE_KEY(event->u.key.code))
101			{
102				ftk_widget_set_active(thiz, 1);
103			}
104			break;
105		}
106		case FTK_EVT_KEY_UP:
107		{
108			if(FTK_IS_ACTIVE_KEY(event->u.key.code) && ftk_widget_is_active(thiz))
109			{
110				ftk_widget_set_active(thiz, 0);
111				ftk_check_button_check(thiz);
112				ret = FTK_CALL_LISTENER(priv->listener, priv->listener_ctx, thiz);
113			}
114			break;
115		}
116		default:break;
117	}
118
119	return ret;
120}
121
122static const char* check_bg_on_imgs[FTK_WIDGET_STATE_NR] = 
123{
124	"btn_check_on"FTK_STOCK_IMG_SUFFIX,
125	"btn_check_on_selected"FTK_STOCK_IMG_SUFFIX,
126	"btn_check_on_pressed"FTK_STOCK_IMG_SUFFIX,
127	"btn_check_on_disable"FTK_STOCK_IMG_SUFFIX
128};
129
130static const char* check_bg_off_imgs[FTK_WIDGET_STATE_NR] = 
131{
132	"btn_check_off"FTK_STOCK_IMG_SUFFIX,
133	"btn_check_off_selected"FTK_STOCK_IMG_SUFFIX,
134	"btn_check_off_pressed"FTK_STOCK_IMG_SUFFIX,
135	"btn_check_off_disable"FTK_STOCK_IMG_SUFFIX
136};
137
138static const char* radio_bg_on_imgs[FTK_WIDGET_STATE_NR] = 
139{
140	"btn_radio_on"FTK_STOCK_IMG_SUFFIX,
141	"btn_radio_on_selected"FTK_STOCK_IMG_SUFFIX,
142	"btn_radio_on_pressed"FTK_STOCK_IMG_SUFFIX,
143	"btn_radio_on"FTK_STOCK_IMG_SUFFIX
144};
145
146static const char* radio_bg_off_imgs[FTK_WIDGET_STATE_NR] = 
147{
148	"btn_radio_off"FTK_STOCK_IMG_SUFFIX,
149	"btn_radio_off_selected"FTK_STOCK_IMG_SUFFIX,
150	"btn_radio_off_pressed"FTK_STOCK_IMG_SUFFIX,
151	"btn_radio_off"FTK_STOCK_IMG_SUFFIX,
152};
153
154static Ret ftk_check_button_on_paint(FtkWidget* thiz)
155{
156	int dx = 0;
157	int dy = 0;
158	int icon_w = 0;
159	int icon_h = 0;
160
161	FtkBitmap* bitmap = NULL;
162	DECL_PRIV0(thiz, priv);
163	const char** bg_imgs = NULL;
164	FTK_BEGIN_PAINT(x, y, width, height, canvas);
165
166	if (priv->onimg && priv->offimg) { 
167		if (priv->checked)
168			bitmap = priv->onimg;
169		else
170			bitmap = priv->offimg;
171	}
172	else { // orignal code
173		if(priv->is_radio)
174		{
175			bg_imgs = priv->checked ? radio_bg_on_imgs : radio_bg_off_imgs;
176		}
177		else
178		{
179			bg_imgs = priv->checked ? check_bg_on_imgs : check_bg_off_imgs;
180		}
181
182		bitmap = ftk_theme_load_image(ftk_default_theme(), bg_imgs[ftk_widget_state(thiz)]);
183	} 
184	return_val_if_fail(bitmap != NULL, RET_FAIL);
185
186	icon_w = ftk_bitmap_width(bitmap);
187	icon_h = ftk_bitmap_height(bitmap);
188	assert((icon_w) <= width && icon_h <= height);
189
190	dy = (height - icon_h) / 2;
191	dx = priv->icon_at_right ? width - icon_w : 0;
192	ftk_canvas_draw_bitmap_simple(canvas, bitmap, 0, 0, icon_w, icon_h, x + dx, y + dy);
193	if (NULL == priv->onimg) 
194	ftk_bitmap_unref(bitmap);
195
196	if(ftk_widget_get_text(thiz) != NULL)
197	{
198		dy = height/2;
199		dx = priv->icon_at_right ? 2 : icon_w;
200		
201		ftk_canvas_set_gc(canvas, ftk_widget_get_gc(thiz)); 
202		ftk_canvas_draw_string(canvas, x + dx, y + dy, ftk_widget_get_text(thiz), -1, 1);
203	}
204
205	FTK_END_PAINT();
206}
207
208static void ftk_check_button_destroy(FtkWidget* thiz)
209{
210	if(thiz != NULL)
211	{
212		DECL_PRIV0(thiz, priv);
213		ftk_bitmap_unref(priv->onimg);  
214		ftk_bitmap_unref(priv->offimg); 
215		FTK_ZFREE(priv, sizeof(PrivInfo));
216	}
217
218	return;
219}
220
221FtkWidget* ftk_check_button_create_ex(FtkWidget* parent, int x, int y, int width, int height, int radio)
222{
223	FtkWidget* thiz = (FtkWidget*)FTK_ZALLOC(sizeof(FtkWidget));
224	return_val_if_fail(thiz != NULL, NULL);
225
226	thiz->priv_subclass[0] = (PrivInfo*)FTK_ZALLOC(sizeof(PrivInfo));
227	if(thiz->priv_subclass[0] != NULL)
228	{
229		DECL_PRIV0(thiz, priv);
230
231		priv->is_radio = radio;
232		thiz->on_event = ftk_check_button_on_event;
233		thiz->on_paint = ftk_check_button_on_paint;
234		thiz->destroy  = ftk_check_button_destroy;
235
236		ftk_widget_init(thiz, radio ? FTK_RADIO_BUTTON : FTK_CHECK_BUTTON, 0, x, y, width, height, FTK_ATTR_TRANSPARENT);
237		ftk_widget_append_child(parent, thiz);
238	}
239	else
240	{
241		FTK_FREE(thiz);
242	}
243
244	return thiz;
245}
246
247FtkWidget* ftk_check_button_create(FtkWidget* parent, int x, int y, int width, int height)
248{
249	return ftk_check_button_create_ex(parent, x, y, width, height, 0);	
250}
251
252FtkWidget* ftk_check_button_create_radio(FtkWidget* parent, int x, int y, int width, int height)
253{
254	return ftk_check_button_create_ex(parent, x, y, width, height, 1);	
255}
256
257int        ftk_check_button_get_checked(FtkWidget* thiz)
258{
259	DECL_PRIV0(thiz, priv);
260	return_val_if_fail(thiz != NULL, 0);
261
262	return priv->checked;
263}
264
265Ret ftk_check_button_set_image(FtkWidget* thiz, FtkBitmap* onimg, FtkBitmap* offimg)
266{
267	DECL_PRIV0(thiz, priv);
268	return_val_if_fail(thiz != NULL, RET_FAIL);
269
270	ftk_bitmap_unref(priv->onimg);
271	ftk_bitmap_unref(priv->offimg);
272
273	priv->onimg = onimg;
274	ftk_bitmap_ref(priv->onimg);
275	priv->offimg = offimg;
276	ftk_bitmap_ref(priv->offimg);
277
278	return RET_OK;
279}
280
281Ret ftk_check_button_set_icon_position(FtkWidget* thiz, int at_right)
282{
283	DECL_PRIV0(thiz, priv);
284	return_val_if_fail(thiz != NULL, RET_FAIL);
285
286	if(priv->icon_at_right != at_right)
287	{
288		priv->icon_at_right = at_right;
289		ftk_widget_invalidate(thiz);
290	}
291
292	return RET_OK;
293}
294
295Ret        ftk_check_button_set_checked(FtkWidget* thiz, int checked)
296{
297	DECL_PRIV0(thiz, priv);
298	return_val_if_fail(thiz != NULL, RET_FAIL);
299
300	if(priv->checked != checked)
301	{
302		priv->checked = checked;
303		ftk_widget_invalidate(thiz);
304	}
305
306	return RET_OK;
307}
308
309int ftk_check_button_is_checked(FtkWidget* thiz)
310{
311	DECL_PRIV0(thiz, priv);
312	return_val_if_fail(thiz != NULL, RET_FAIL);
313	return priv->checked;
314}
315
316Ret ftk_check_button_set_clicked_listener(FtkWidget* thiz, FtkListener listener, void* ctx)
317{
318	DECL_PRIV0(thiz, priv);
319	return_val_if_fail(thiz != NULL, RET_FAIL);
320
321	priv->listener_ctx = ctx;
322	priv->listener = listener;
323
324	return RET_OK;
325}
326