PageRenderTime 315ms CodeModel.GetById 141ms app.highlight 73ms RepoModel.GetById 98ms app.codeStats 0ms

/src/ftk_input_method_preeditor_default.c

http://ftk.googlecode.com/
C | 296 lines | 211 code | 56 blank | 29 comment | 19 complexity | c2a7df526f2583e5deff34818411bcac MD5 | raw file
  1/*
  2 * File: ftk_input_method_preeditor.h    
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   default implementation of input candidate selector.
  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-02-11 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "ftk_button.h"
 33#include "ftk_window.h"
 34#include "ftk_globals.h"
 35#include "ftk_list_view.h"
 36#include "ftk_text_buffer.h"
 37#include "ftk_list_model_default.h"
 38#include "ftk_list_render_default.h"
 39#include "ftk_input_method_preeditor.h"
 40
 41typedef struct _InputMethodPreeditorPrivInfo
 42{
 43	FtkWidget* widget;
 44	FtkWidget* editor;
 45	FtkListModel* model;
 46	FtkWidget* raw_text_button;
 47	FtkTextBuffer* text_buffer;
 48}PrivInfo;
 49
 50#define IDC_RAW_TEXT    1000
 51#define IDC_CANDIDATES  1001
 52#define FTK_IM_PREEDITOR_WIDTH       120
 53#define FTK_IM_PREEDITOR_ITEM_HEIGHT 20
 54#define FTK_ROW_HEIGHT (FTK_FONT_SIZE + 2 * FTK_V_MARGIN)
 55
 56static Ret ftk_popup_on_raw_text_clicked(void* ctx, void* button)
 57{
 58	PrivInfo* priv = (PrivInfo*)ctx;
 59	FtkEvent event;
 60	
 61	ftk_event_init(&event,   FTK_EVT_IM_COMMIT);
 62	event.widget   = priv->editor;
 63	event.u.extra  = (char*)ftk_widget_get_text((FtkWidget*)button);
 64
 65	ftk_widget_event(priv->editor, &event);
 66	ftk_widget_show_all(ftk_widget_toplevel((FtkWidget*)button), 0);
 67	ftk_widget_set_text((FtkWidget*)button, "");
 68
 69	return RET_OK;
 70}
 71
 72static Ret ftk_popup_on_item_clicked(void* ctx, void* list)
 73{
 74	PrivInfo* priv = (PrivInfo*)ctx;
 75	FtkListItemInfo* info = NULL;
 76	FtkListModel* model = priv->model;
 77	int i = ftk_list_view_get_selected((FtkWidget*)list);
 78	
 79	ftk_list_model_get_data(model, i, (void**)&info);
 80	if(info != NULL)
 81	{
 82		FtkEvent event;
 83		
 84		ftk_event_init(&event,   FTK_EVT_IM_COMMIT);
 85		event.widget   = priv->editor;
 86		event.u.extra  = (void*)info->text;
 87
 88		ftk_widget_event(priv->editor, &event);
 89	}
 90	ftk_widget_show_all(ftk_widget_toplevel((FtkWidget*)list), 0);
 91
 92	return RET_OK;
 93}
 94
 95static Ret ftk_input_method_preeditor_default_resize(FtkImPreeditor* thiz, int candidate_nr, FtkPoint* caret)
 96{
 97	int x = 0;
 98	int y = 0;
 99	int w = 0;
100	int h = 0;
101	DECL_PRIV(thiz, priv);
102	FtkRect work_rect = {0};
103	FtkWidget* widget = priv->widget;
104
105	w = FTK_IM_PREEDITOR_WIDTH;
106	h = (candidate_nr + 1) * FTK_IM_PREEDITOR_ITEM_HEIGHT + 2 * FTK_V_MARGIN;
107	ftk_wnd_manager_get_work_area(ftk_default_wnd_manager(), &work_rect);
108
109	if((caret->y + h + FTK_ROW_HEIGHT) <= (work_rect.y + work_rect.height))
110	{
111		y = caret->y + FTK_ROW_HEIGHT;
112	}
113	else
114	{
115		y = caret->y - h;
116	}
117
118	if((caret->x + w) <= (work_rect.x + work_rect.width))
119	{
120		x = caret->x;
121	}
122	else
123	{
124		x = work_rect.x + work_rect.width - w;
125	}
126
127	ftk_widget_move_resize(widget, x, y, w, h);
128	ftk_widget_move_resize(ftk_widget_lookup(widget, IDC_RAW_TEXT), 0, 
129		0, w, FTK_IM_PREEDITOR_ITEM_HEIGHT);
130	ftk_widget_move_resize(ftk_widget_lookup(widget, IDC_CANDIDATES), 0, 
131		FTK_IM_PREEDITOR_ITEM_HEIGHT, w, h - FTK_IM_PREEDITOR_ITEM_HEIGHT);
132
133	return RET_OK;
134}
135
136static Ret ftk_input_method_preeditor_default_reset(FtkImPreeditor* thiz)
137{
138	DECL_PRIV(thiz, priv);
139	return_val_if_fail(thiz != NULL, RET_FAIL);
140
141	ftk_list_model_reset(priv->model);
142	ftk_text_buffer_reset(priv->text_buffer);
143	ftk_widget_set_text(priv->raw_text_button, "          ");
144
145	return RET_OK;
146}
147
148static Ret ftk_input_method_preeditor_default_set_editor(FtkImPreeditor* thiz, FtkWidget* editor)
149{
150	DECL_PRIV(thiz, priv);
151	return_val_if_fail(thiz != NULL && editor != NULL, RET_FAIL);
152
153	priv->editor = editor;
154
155	return RET_OK;
156}
157
158static Ret ftk_input_method_preeditor_default_set_raw_text(FtkImPreeditor* thiz, const char* text)
159{
160	DECL_PRIV(thiz, priv);
161	
162	return_val_if_fail(priv != NULL, RET_FAIL);
163
164	ftk_widget_set_text(priv->raw_text_button, text);
165
166	return RET_OK;
167}
168
169static Ret ftk_input_method_preeditor_default_add_candidate(FtkImPreeditor* thiz, const char* text)
170{
171	FtkListItemInfo info = {0};
172	DECL_PRIV(thiz, priv);
173
174	return_val_if_fail(priv != NULL && text != NULL, RET_FAIL);
175	
176	info.user_data = thiz;
177	info.type = FTK_LIST_ITEM_NORMAL;
178	info.text = ftk_text_buffer_append_string(priv->text_buffer, text);
179
180	return ftk_list_model_add(priv->model, &info);
181}
182
183static void ftk_input_method_preeditor_default_destroy(FtkImPreeditor* thiz)
184{
185	DECL_PRIV(thiz, priv);
186	if(thiz != NULL)
187	{
188		ftk_list_model_unref(priv->model);
189		ftk_text_buffer_destroy(priv->text_buffer);
190		FTK_FREE(thiz);
191	}
192
193	return;
194}
195
196static Ret ftk_input_method_preeditor_default_hide(FtkImPreeditor* thiz)
197{
198	DECL_PRIV(thiz, priv);
199	return_val_if_fail(thiz != NULL, RET_FAIL);
200
201	ftk_widget_show_all(priv->widget, 0);
202
203	return RET_OK;
204}
205
206static Ret ftk_input_method_preeditor_default_show(FtkImPreeditor* thiz, FtkPoint* caret)
207{
208	DECL_PRIV(thiz, priv);
209	int candidate_nr = 0;
210	return_val_if_fail(thiz != NULL, RET_FAIL);
211
212	ftk_wnd_manager_restack(ftk_default_wnd_manager(), priv->widget, FTK_MAX_WINDOWS);
213	
214	candidate_nr = ftk_list_model_get_total(priv->model);
215	candidate_nr = FTK_MIN(candidate_nr, FTK_IM_PREEDITOR_MAX_ROW);
216	ftk_input_method_preeditor_default_resize(thiz, candidate_nr, caret);
217	ftk_widget_show_all(priv->widget, 1);
218
219	return RET_OK;
220}
221
222FtkImPreeditor* ftk_input_method_preeditor_default_create(void)
223{
224	int x = 0;
225	int y = 0;
226	FtkGc gc = {0};
227	FtkWidget* list  = NULL;
228	FtkWidget* button = NULL;
229	FtkWidget* popup = NULL;
230	FtkListModel* model = NULL;
231	FtkListRender* render = NULL;
232	FtkImPreeditor* thiz = NULL;
233	int w = FTK_IM_PREEDITOR_WIDTH;
234	int h = FTK_IM_PREEDITOR_ITEM_HEIGHT * FTK_IM_PREEDITOR_MAX_ROW;
235
236	model = ftk_list_model_default_create(10);
237	return_val_if_fail(model != NULL, NULL);
238
239	popup = ftk_window_create(FTK_WINDOW_MISC, 0, x, y, w, h);
240	ftk_window_set_animation_hint(popup, "im_preeditor");
241	ftk_widget_set_text(popup, "im preeditor");
242	render = ftk_list_render_default_create();
243	button = ftk_button_create(popup, 0, 0, w, FTK_IM_PREEDITOR_ITEM_HEIGHT);
244	ftk_widget_set_id(button, IDC_RAW_TEXT);
245	ftk_widget_unset_attr(button, FTK_ATTR_TRANSPARENT);
246
247	gc.mask = FTK_GC_BG | FTK_GC_FG | FTK_GC_FONT;
248	gc.font = ftk_default_font();
249	gc.bg = ftk_theme_get_bg_color(ftk_default_theme(), FTK_BUTTON, FTK_WIDGET_NORMAL);
250	gc.fg = ftk_theme_get_fg_color(ftk_default_theme(), FTK_BUTTON, FTK_WIDGET_NORMAL);
251	ftk_widget_reset_gc(button, FTK_WIDGET_NORMAL, &gc);
252	
253	gc.bg = ftk_theme_get_bg_color(ftk_default_theme(), FTK_BUTTON, FTK_WIDGET_FOCUSED);
254	gc.fg = ftk_theme_get_fg_color(ftk_default_theme(), FTK_BUTTON, FTK_WIDGET_FOCUSED);
255	ftk_widget_reset_gc(button, FTK_WIDGET_FOCUSED, &gc);
256	
257	gc.bg = ftk_theme_get_bg_color(ftk_default_theme(), FTK_BUTTON, FTK_WIDGET_ACTIVE);
258	gc.fg = ftk_theme_get_fg_color(ftk_default_theme(), FTK_BUTTON, FTK_WIDGET_ACTIVE);
259	ftk_widget_reset_gc(button, FTK_WIDGET_ACTIVE, &gc);
260
261	list = ftk_list_view_create(popup, 0, FTK_IM_PREEDITOR_ITEM_HEIGHT, 
262		w, h - FTK_IM_PREEDITOR_ITEM_HEIGHT);
263	ftk_widget_set_id(list, IDC_CANDIDATES);
264	ftk_window_set_focus(popup, list);
265
266	ftk_list_view_init(list, model, render, FTK_IM_PREEDITOR_ITEM_HEIGHT);
267
268	thiz = FTK_NEW_PRIV(FtkImPreeditor);
269
270	if(thiz != NULL)
271	{
272		DECL_PRIV(thiz, priv);
273		thiz->hide          = ftk_input_method_preeditor_default_hide;
274		thiz->show          = ftk_input_method_preeditor_default_show;
275		thiz->reset         = ftk_input_method_preeditor_default_reset;
276		thiz->set_editor    = ftk_input_method_preeditor_default_set_editor;
277		thiz->set_raw_text  = ftk_input_method_preeditor_default_set_raw_text;
278		thiz->add_candidate = ftk_input_method_preeditor_default_add_candidate;
279		thiz->destroy       = ftk_input_method_preeditor_default_destroy;
280
281		priv->model = model;
282		priv->widget = popup;
283		priv->raw_text_button = button;
284		priv->text_buffer = ftk_text_buffer_create(1024);
285
286		ftk_button_set_clicked_listener(button, ftk_popup_on_raw_text_clicked, priv);
287		ftk_list_view_set_clicked_listener(list, ftk_popup_on_item_clicked, priv);
288	}
289	else
290	{
291		ftk_widget_unref(popup);
292	}
293
294	return thiz;
295}
296