PageRenderTime 365ms CodeModel.GetById 141ms app.highlight 11ms RepoModel.GetById 150ms app.codeStats 60ms

/src/ftk_popup_menu.c

http://ftk.googlecode.com/
C | 183 lines | 117 code | 37 blank | 29 comment | 18 complexity | 26c7bc92f16ed28a5183bda4bcc7093d MD5 | raw file
  1/*
  2 * File: ftk_popup_menu.c
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   popup menu
  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 * 2010-01-26 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "ftk_log.h"
 33#include "ftk_dialog.h"
 34#include "ftk_list_view.h"
 35#include "ftk_popup_menu.h"
 36#include "ftk_list_render_default.h"
 37
 38typedef struct _PopupMenuPrivInfo
 39{
 40	FtkWidget*     list;
 41	FtkListModel*  model;
 42	FtkListener    listener;
 43	void*          listener_ctx;
 44	FtkWidgetDestroy parent_destroy;
 45}PrivInfo;
 46
 47static Ret ftk_popup_menu_init(FtkWidget* thiz);
 48
 49static void ftk_popup_menu_destroy(FtkWidget* thiz)
 50{
 51	DECL_PRIV2(thiz, priv);
 52
 53	if(priv->parent_destroy != NULL)
 54	{
 55		priv->parent_destroy(thiz);
 56	}
 57
 58	FTK_ZFREE(priv, sizeof(PrivInfo));
 59
 60	return;
 61}
 62static Ret ftk_popup_menu_on_item_clicked(void* ctx, void* list)
 63{
 64	FtkWidget* thiz = (FtkWidget*)ctx;
 65	FtkListItemInfo* info = NULL;
 66	int i = ftk_list_view_get_selected((FtkWidget*)list);
 67	FtkListModel* model = ftk_list_view_get_model((FtkWidget*)list);
 68	ftk_list_model_get_data(model, i, (void**)&info);
 69	
 70	if(info != NULL)
 71	{
 72		DECL_PRIV2(thiz, priv);
 73		if(priv->listener != NULL)
 74		{
 75			priv->listener(priv->listener_ctx, info);
 76		}
 77	}
 78
 79	ftk_widget_unref(thiz);
 80
 81	ftk_logd("%s: %d/%d\n", __func__, i, ftk_list_model_get_total(model));
 82
 83	return RET_OK;
 84}
 85
 86FtkWidget* ftk_popup_menu_create(int x, int y, int w, int h, FtkBitmap* icon, const char* title)
 87{
 88	PrivInfo* priv = NULL;
 89	int has_title = icon != NULL || title != NULL;
 90	FtkWidget* thiz = ftk_dialog_create(x, y, w, h);
 91	
 92	return_val_if_fail(thiz != NULL, NULL);
 93
 94	thiz->priv_subclass[2] = (PrivInfo*)FTK_ZALLOC(sizeof(PrivInfo));
 95	priv = (PrivInfo*)thiz->priv_subclass[2];
 96	if(has_title)
 97	{
 98		ftk_dialog_set_icon(thiz, icon);
 99		ftk_widget_set_text(thiz, title);
100	}
101	else
102	{
103		ftk_dialog_hide_title(thiz);
104	}
105
106	priv->parent_destroy = thiz->destroy;
107	thiz->destroy = ftk_popup_menu_destroy;
108
109	ftk_popup_menu_init(thiz);
110
111	return thiz;
112}
113
114static Ret ftk_popup_menu_init(FtkWidget* thiz)
115{
116	int w = 0;
117	int h = 0;
118	DECL_PRIV2(thiz, priv);
119	FtkWidget* list = NULL;
120	FtkListModel* model = NULL;
121	FtkListRender* render = NULL;
122	
123	return_val_if_fail(thiz != NULL, RET_FAIL);
124
125	w = ftk_widget_width(thiz)  - 2 * FTK_DIALOG_BORDER;
126	h = ftk_widget_height(thiz) - FTK_DIALOG_BORDER - ftk_dialog_get_title_height();
127
128	list = ftk_list_view_create(thiz, 0, 0, w, h);
129	ftk_list_view_set_clicked_listener(list, ftk_popup_menu_on_item_clicked, thiz);
130
131	model = ftk_list_model_default_create(10);
132	render = ftk_list_render_default_create();
133
134	priv->model = model;
135	priv->list = list;
136
137	ftk_window_set_focus(thiz, list);
138	ftk_list_view_init(list, model, render, FTK_POPUP_MENU_ITEM_HEIGHT);
139	ftk_list_model_unref(model);
140
141	return RET_OK;
142}
143
144Ret ftk_popup_menu_add(FtkWidget* thiz, FtkListItemInfo* info)
145{
146	DECL_PRIV2(thiz, priv);
147	return_val_if_fail(priv != NULL && info != NULL, RET_FAIL);
148
149	return ftk_list_model_add(priv->model, info);
150}
151
152Ret ftk_popup_menu_set_clicked_listener(FtkWidget* thiz, FtkListener listener, void* ctx)
153{
154	DECL_PRIV2(thiz, priv);
155	return_val_if_fail(priv != NULL, RET_FAIL);
156
157	priv->listener = listener;
158	priv->listener_ctx = ctx;
159
160	return RET_OK;
161}
162
163int ftk_popup_menu_get_selected(FtkWidget* thiz)
164{
165	DECL_PRIV2(thiz, priv);
166	return_val_if_fail(thiz != NULL, -1);
167
168	return ftk_list_view_get_selected(priv->list);
169}
170
171int ftk_popup_menu_calc_height(int has_title, int visible_items)
172{
173	int height = visible_items * FTK_POPUP_MENU_ITEM_HEIGHT;
174	
175	height += 2 * FTK_DIALOG_BORDER;
176	if(has_title)
177	{
178		height += ftk_dialog_get_title_height();
179	}
180
181	return height;
182}
183