/src/ftk_entry.c

http://ftk.googlecode.com/ · C · 660 lines · 530 code · 99 blank · 31 comment · 89 complexity · d7a583fcebb1485752c03c56c7a7d06e MD5 · raw file

  1. /*
  2. * File: ftk_entry.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: single line editor
  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. * History:
  26. * ================================================================
  27. * 2009-11-02 Li XianJing <xianjimli@hotmail.com> created
  28. * 2012-5-22 woodysu@gmail.com modified
  29. */
  30. #include "ftk_util.h"
  31. #include "ftk_log.h"
  32. #include "ftk_entry.h"
  33. #include "ftk_globals.h"
  34. #include "ftk_window.h"
  35. #include "ftk_text_buffer.h"
  36. #include "ftk_source_timer.h"
  37. #include "ftk_input_method_preeditor.h"
  38. typedef struct _EntryPrivInfo
  39. {
  40. int caret;
  41. int caret_visible;
  42. int visible_start;
  43. int visible_end;
  44. int selected_end;
  45. int selected_start;
  46. int input_type;
  47. int readonly;
  48. int noborder;
  49. FtkPoint caret_pos;
  50. FtkSource* caret_timer;
  51. FtkTextBuffer* text_buffer;
  52. char* tips;
  53. }PrivInfo;
  54. #define FTK_ENTRY_H_MARGIN 4
  55. #define FTK_ENTRY_V_MARGIN 8
  56. #define TB_TEXT priv->text_buffer->buffer
  57. #define TB_LENGTH (int)(priv->text_buffer->length)
  58. #define HAS_TEXT(priv) (priv != NULL && priv->text_buffer != NULL && TB_LENGTH > 0)
  59. static Ret ftk_entry_on_paint_caret(FtkWidget* thiz);
  60. static Ret ftk_entry_update_caret_pos(FtkWidget* thiz);
  61. static Ret ftk_entry_compute_visible_range(FtkWidget* thiz);
  62. static Ret ftk_entry_set_text_internal(FtkWidget* thiz, const char* text);
  63. static Ret ftk_entry_move_caret(FtkWidget* thiz, int offset)
  64. {
  65. DECL_PRIV0(thiz, priv);
  66. priv->caret_visible = 0;
  67. ftk_entry_update_caret_pos(thiz);
  68. ftk_entry_on_paint_caret(thiz);
  69. if(!HAS_TEXT(priv))
  70. {
  71. priv->caret = 0;
  72. ftk_widget_invalidate(thiz);
  73. return RET_OK;
  74. }
  75. priv->caret += ftk_text_buffer_chars_bytes(priv->text_buffer, priv->caret, offset);
  76. priv->caret = priv->caret < 0 ? 0 : priv->caret;
  77. priv->caret = priv->caret > TB_LENGTH ? TB_LENGTH : priv->caret;
  78. if((priv->caret) < priv->visible_start)
  79. {
  80. priv->visible_start = priv->caret;
  81. priv->visible_end = -1;
  82. }
  83. else if((priv->caret) > priv->visible_end)
  84. {
  85. priv->visible_end = priv->caret;
  86. priv->visible_start = -1;
  87. }
  88. ftk_widget_invalidate(thiz);
  89. return RET_OK;
  90. }
  91. static Ret ftk_entry_get_offset_by_pointer(FtkWidget* thiz, int x)
  92. {
  93. DECL_PRIV0(thiz, priv);
  94. FtkTextLine line = {0};
  95. FtkTextLayout* text_layout = ftk_default_text_layout();
  96. int width = x - FTK_PAINT_X(thiz) - FTK_ENTRY_H_MARGIN + 1;
  97. FtkCanvas* canvas = NULL;
  98. return_val_if_fail(width >= 0, RET_FAIL);
  99. if(!HAS_TEXT(priv))
  100. {
  101. return RET_OK;
  102. }
  103. canvas = ftk_widget_canvas(thiz);
  104. ftk_canvas_reset_gc(canvas, ftk_widget_get_gc(thiz));
  105. ftk_text_layout_init(text_layout, TB_TEXT + priv->visible_start,
  106. priv->visible_end - priv->visible_start, canvas, width);
  107. if(ftk_text_layout_get_visual_line(text_layout, &line) == RET_OK)
  108. {
  109. if(line.len > 0)
  110. {
  111. priv->caret = priv->visible_start + line.pos_v2l[line.len-1] + 1;
  112. }
  113. else
  114. {
  115. priv->caret = priv->visible_start;
  116. }
  117. }
  118. ftk_logd("%s: start=%d caret=%d line.len=%d x=%d width=%d\n",
  119. __func__, priv->visible_start, priv->caret, line.len, x, width);
  120. return ftk_entry_move_caret(thiz, 0);
  121. }
  122. static Ret ftk_entry_handle_mouse_evevnt(FtkWidget* thiz, FtkEvent* event)
  123. {
  124. return ftk_entry_get_offset_by_pointer(thiz, event->u.mouse.x);
  125. }
  126. static Ret ftk_entry_input_str(FtkWidget* thiz, const char* str)
  127. {
  128. int count = 0;
  129. DECL_PRIV0(thiz, priv);
  130. return_val_if_fail(thiz != NULL && str != NULL, RET_FAIL);
  131. count = utf8_count_char(str, strlen(str));
  132. ftk_text_buffer_insert(priv->text_buffer, priv->caret, str, -1);
  133. ftk_entry_move_caret(thiz, count);
  134. if(priv->visible_start >= 0)
  135. {
  136. priv->visible_end = -1;
  137. }
  138. return RET_OK;
  139. }
  140. static Ret ftk_entry_input_char(FtkWidget* thiz, char c)
  141. {
  142. char str[2] = {0};
  143. str[0] = c;
  144. str[1] = '\0';
  145. return ftk_entry_input_str(thiz, str);
  146. }
  147. static Ret ftk_entry_handle_key_event(FtkWidget* thiz, FtkEvent* event)
  148. {
  149. Ret ret = RET_OK;
  150. DECL_PRIV0(thiz, priv);
  151. switch(event->u.key.code)
  152. {
  153. case FTK_KEY_CHOOSE_IME:
  154. {
  155. if(priv->readonly) break;
  156. ftk_input_method_manager_focus_out(ftk_default_input_method_manager(), thiz);
  157. ftk_input_method_chooser();
  158. ftk_input_method_manager_focus_in(ftk_default_input_method_manager(), thiz);
  159. break;
  160. }
  161. case FTK_KEY_HOME:
  162. {
  163. ftk_entry_move_caret(thiz, -priv->caret);
  164. break;
  165. }
  166. case FTK_KEY_END:
  167. {
  168. ftk_entry_move_caret(thiz, TB_LENGTH-priv->caret);
  169. break;
  170. }
  171. case FTK_KEY_LEFT:
  172. {
  173. ftk_entry_move_caret(thiz, -1);
  174. ret = RET_REMOVE;
  175. break;
  176. }
  177. case FTK_KEY_RIGHT:
  178. {
  179. ftk_entry_move_caret(thiz, 1);
  180. ret = RET_REMOVE;
  181. break;
  182. }
  183. case FTK_KEY_UP:
  184. case FTK_KEY_DOWN:break;
  185. case FTK_KEY_DELETE:
  186. {
  187. if(priv->readonly) break;
  188. ftk_text_buffer_delete_chars(priv->text_buffer, priv->caret, 1);
  189. ftk_entry_move_caret(thiz, 0);
  190. break;
  191. }
  192. case FTK_KEY_BACKSPACE:
  193. {
  194. int caret = priv->caret;
  195. if(priv->readonly) break;
  196. ftk_entry_move_caret(thiz, -1);
  197. if(ftk_text_buffer_delete_chars(priv->text_buffer, caret, -1) == RET_OK)
  198. {
  199. }
  200. /*FIXME*/
  201. if(priv->visible_start > 0)
  202. {
  203. if(priv->caret == priv->visible_start)
  204. {
  205. ftk_entry_move_caret(thiz, -1);
  206. ftk_entry_move_caret(thiz, 1);
  207. }
  208. }
  209. break;
  210. }
  211. case FTK_KEY_CLR:
  212. {
  213. if(priv->readonly) break;
  214. ftk_entry_set_text_internal(thiz, "");
  215. break;
  216. }
  217. default:
  218. {
  219. if(priv->readonly) break;
  220. if(event->u.key.code < 0xff && isprint(event->u.key.code))
  221. {
  222. ftk_entry_input_char(thiz, event->u.key.code);
  223. }
  224. break;
  225. }
  226. }
  227. return ret;
  228. }
  229. static Ret ftk_entry_on_event(FtkWidget* thiz, FtkEvent* event)
  230. {
  231. Ret ret = RET_OK;
  232. DECL_PRIV0(thiz, priv);
  233. return_val_if_fail(thiz != NULL && event != NULL, RET_FAIL);
  234. switch(event->type)
  235. {
  236. case FTK_EVT_FOCUS_IN:
  237. {
  238. if(!priv->readonly)
  239. {
  240. ftk_input_method_manager_focus_in(ftk_default_input_method_manager(), thiz);
  241. ftk_input_method_manager_set_current_type(ftk_default_input_method_manager(), (FtkInputType)priv->input_type);
  242. }
  243. ftk_source_ref(priv->caret_timer);
  244. ftk_source_timer_reset(priv->caret_timer);
  245. ftk_main_loop_add_source(ftk_default_main_loop(), priv->caret_timer);
  246. break;
  247. }
  248. case FTK_EVT_FOCUS_OUT:
  249. {
  250. if(!priv->readonly)
  251. {
  252. ftk_input_method_manager_focus_out(ftk_default_input_method_manager(), thiz);
  253. }
  254. ftk_main_loop_remove_source(ftk_default_main_loop(), priv->caret_timer);
  255. break;
  256. }
  257. case FTK_EVT_KEY_DOWN:
  258. case FTK_EVT_KEY_UP:
  259. {
  260. if(event->type == FTK_EVT_KEY_DOWN)
  261. {
  262. ret = ftk_entry_handle_key_event(thiz, event);
  263. }
  264. else
  265. {
  266. ret = event->u.key.code == FTK_KEY_LEFT || event->u.key.code == FTK_KEY_RIGHT
  267. ? RET_REMOVE : RET_OK;
  268. }
  269. break;
  270. }
  271. case FTK_EVT_MOUSE_UP:
  272. {
  273. ret = ftk_entry_handle_mouse_evevnt(thiz, event);
  274. break;
  275. }
  276. case FTK_EVT_IM_PREEDIT:
  277. {
  278. ftk_im_show_preeditor(thiz, &(priv->caret_pos), (FtkCommitInfo*)event->u.extra);
  279. break;
  280. }
  281. case FTK_EVT_IM_COMMIT:
  282. {
  283. ftk_entry_input_str(thiz, (const char*)event->u.extra);
  284. ftk_input_method_manager_focus_ack_commit(ftk_default_input_method_manager());
  285. break;
  286. }
  287. case FTK_EVT_MOUSE_LONG_PRESS:
  288. {
  289. if(priv->readonly) break;
  290. ftk_input_method_manager_focus_out(ftk_default_input_method_manager(), thiz);
  291. ftk_input_method_chooser();
  292. ftk_input_method_manager_focus_in(ftk_default_input_method_manager(), thiz);
  293. break;
  294. }
  295. case FTK_EVT_SET_TEXT:
  296. {
  297. ftk_entry_set_text_internal(thiz, (const char*)event->u.extra);
  298. ret = RET_REMOVE;
  299. break;
  300. }
  301. case FTK_EVT_GET_TEXT:
  302. {
  303. event->u.extra = (void*)ftk_entry_get_text(thiz);
  304. ret = RET_REMOVE;
  305. break;
  306. }
  307. default:break;
  308. }
  309. return ret;
  310. }
  311. static Ret ftk_entry_update_caret_pos(FtkWidget* thiz)
  312. {
  313. FtkGc gc = {0};
  314. DECL_PRIV0(thiz, priv);
  315. FTK_BEGIN_PAINT(x, y, width, height, canvas);
  316. (void)height;
  317. return_val_if_fail(thiz != NULL, RET_FAIL);
  318. if(priv->caret < priv->visible_start || priv->caret > priv->visible_end
  319. || priv->visible_start < 0 || priv->visible_end < 0)
  320. {
  321. return RET_FAIL;
  322. }
  323. (void)width;
  324. gc.mask = FTK_GC_FG;
  325. if(ftk_widget_is_focused(thiz))
  326. {
  327. int extent = 0;
  328. gc.fg = priv->caret_visible ? ftk_widget_get_gc(thiz)->fg : ftk_widget_get_gc(thiz)->bg;
  329. priv->caret_visible = !priv->caret_visible;
  330. if(HAS_TEXT(priv))
  331. {
  332. ftk_canvas_set_gc(canvas, ftk_widget_get_gc(thiz));
  333. extent = ftk_canvas_get_str_extent(canvas, TB_TEXT+priv->visible_start,
  334. priv->caret - priv->visible_start);
  335. //ftk_logd("%s: %d len=%d\n", __func__, extent, priv->caret - priv->visible_start);
  336. }
  337. ftk_canvas_reset_gc(canvas, &gc);
  338. x += extent + FTK_ENTRY_H_MARGIN - 1;
  339. y += FTK_ENTRY_V_MARGIN;
  340. priv->caret_pos.x = x;
  341. priv->caret_pos.y = y;
  342. }
  343. return RET_OK;
  344. }
  345. static Ret ftk_entry_on_paint_caret(FtkWidget* thiz)
  346. {
  347. FtkGc gc = {0};
  348. DECL_PRIV0(thiz, priv);
  349. FTK_BEGIN_PAINT(x, y, width, height, canvas);
  350. return_val_if_fail(thiz != NULL, RET_FAIL);
  351. if(!ftk_window_is_mapped(ftk_widget_toplevel(thiz)))
  352. {
  353. return RET_OK;
  354. }
  355. if(priv->caret < priv->visible_start || priv->caret > priv->visible_end
  356. || priv->visible_start < 0 || priv->visible_end < 0)
  357. {
  358. return RET_FAIL;
  359. }
  360. (void)width;
  361. gc.mask = FTK_GC_FG;
  362. if(ftk_widget_is_focused(thiz))
  363. {
  364. priv->caret_visible = !priv->caret_visible;
  365. gc.fg = priv->caret_visible ? ftk_widget_get_gc(thiz)->fg : ftk_widget_get_gc(thiz)->bg;
  366. x = priv->caret_pos.x;
  367. y = priv->caret_pos.y;
  368. ftk_canvas_reset_gc(canvas, &gc);
  369. ftk_canvas_draw_vline(canvas, x, y, height - (3 * FTK_ENTRY_V_MARGIN)/2 );
  370. FTK_END_PAINT();
  371. }
  372. return RET_OK;
  373. }
  374. static Ret ftk_entry_on_paint(FtkWidget* thiz)
  375. {
  376. FtkGc gc = {0};
  377. DECL_PRIV0(thiz, priv);
  378. int font_height = 0;
  379. FTK_BEGIN_PAINT(x, y, width, height, canvas);
  380. if (!priv->noborder) {
  381. gc.mask = FTK_GC_FG;
  382. gc.fg = ftk_theme_get_border_color(ftk_default_theme(), FTK_ENTRY, ftk_widget_state(thiz));
  383. ftk_canvas_set_gc(canvas, &gc);
  384. ftk_canvas_draw_vline(canvas, x, y + 2, height - 4);
  385. ftk_canvas_draw_vline(canvas, x+width-1, y + 2, height - 4);
  386. ftk_canvas_draw_hline(canvas, x + 2, y, width-4);
  387. ftk_canvas_draw_hline(canvas, x + 1, y + height - 1, width-2);
  388. if(ftk_widget_state(thiz) == FTK_WIDGET_NORMAL)
  389. {
  390. gc.fg.r += 0x60;
  391. gc.fg.g += 0x60;
  392. gc.fg.b += 0x60;
  393. ftk_canvas_set_gc(canvas, &gc);
  394. }
  395. ftk_canvas_draw_hline(canvas, x + 1, y + 1, width-2);
  396. ftk_canvas_draw_vline(canvas, x + 1, y + 1, height - 2);
  397. ftk_canvas_draw_vline(canvas, x + width -2, y + 1, height - 2);
  398. ftk_canvas_draw_hline(canvas, x + 2, y + height - 2, width-4);
  399. }
  400. ftk_canvas_set_gc(canvas, ftk_widget_get_gc(thiz));
  401. if(HAS_TEXT(priv) || priv->tips != NULL)
  402. {
  403. FtkTextLine line = {0};
  404. FtkTextLayout* text_layout = ftk_default_text_layout();
  405. int width = ftk_widget_width(thiz) - 2 * FTK_ENTRY_H_MARGIN;
  406. if(HAS_TEXT(priv))
  407. {
  408. ftk_entry_compute_visible_range(thiz);
  409. ftk_text_layout_init(text_layout, TB_TEXT + priv->visible_start,
  410. priv->visible_end - priv->visible_start, canvas, width);
  411. }
  412. else
  413. {
  414. FtkColor fg = ftk_theme_get_fg_color(ftk_default_theme(), FTK_ENTRY, ftk_widget_state(thiz));
  415. FtkColor bg = ftk_theme_get_bg_color(ftk_default_theme(), FTK_ENTRY, ftk_widget_state(thiz));
  416. gc.fg.r = (fg.r + bg.r) >> 1;
  417. gc.fg.g = (fg.r + bg.g) >> 1;
  418. gc.fg.b = (fg.r + bg.b) >> 1;
  419. ftk_canvas_set_gc(canvas, &gc);
  420. ftk_text_layout_init(text_layout, priv->tips, -1, canvas, width);
  421. }
  422. font_height = ftk_widget_get_font_size(thiz);
  423. x += FTK_ENTRY_H_MARGIN;
  424. y += font_height + FTK_ENTRY_V_MARGIN;
  425. if(ftk_text_layout_get_visual_line(text_layout, &line) == RET_OK)
  426. {
  427. ftk_canvas_draw_string(canvas, x + line.xoffset, y, line.text, line.len, 0);
  428. }
  429. }
  430. ftk_entry_update_caret_pos(thiz);
  431. ftk_entry_on_paint_caret(thiz);
  432. FTK_END_PAINT();
  433. }
  434. static void ftk_entry_destroy(FtkWidget* thiz)
  435. {
  436. if(thiz != NULL)
  437. {
  438. DECL_PRIV0(thiz, priv);
  439. if(ftk_widget_is_focused(thiz))
  440. {
  441. ftk_input_method_manager_focus_out(ftk_default_input_method_manager(), thiz);
  442. }
  443. FTK_FREE(priv->tips);
  444. ftk_source_disable(priv->caret_timer);
  445. ftk_main_loop_remove_source(ftk_default_main_loop(), priv->caret_timer);
  446. ftk_source_unref(priv->caret_timer);
  447. ftk_text_buffer_destroy(priv->text_buffer);
  448. FTK_FREE(priv);
  449. }
  450. return;
  451. }
  452. FtkWidget* ftk_entry_create(FtkWidget* parent, int x, int y, int width, int height)
  453. {
  454. FtkWidget* thiz = (FtkWidget*)FTK_ZALLOC(sizeof(FtkWidget));
  455. return_val_if_fail(thiz != NULL, NULL);
  456. thiz->priv_subclass[0] = (PrivInfo*)FTK_ZALLOC(sizeof(PrivInfo));
  457. if(thiz->priv_subclass[0] != NULL)
  458. {
  459. DECL_PRIV0(thiz, priv);
  460. thiz->on_event = ftk_entry_on_event;
  461. thiz->on_paint = ftk_entry_on_paint;
  462. thiz->destroy = ftk_entry_destroy;
  463. height = ftk_font_desc_get_size(ftk_default_font()) + FTK_ENTRY_V_MARGIN * 2;
  464. ftk_widget_init(thiz, FTK_ENTRY, 0, x, y, width, height, FTK_ATTR_TRANSPARENT|FTK_ATTR_BG_FOUR_CORNER);
  465. priv->input_type = FTK_INPUT_NORMAL;
  466. priv->caret_timer = ftk_source_timer_create(500, (FtkTimer)ftk_entry_on_paint_caret, thiz);
  467. priv->text_buffer = ftk_text_buffer_create(128);
  468. ftk_widget_append_child(parent, thiz);
  469. }
  470. else
  471. {
  472. FTK_FREE(thiz);
  473. }
  474. return thiz;
  475. }
  476. Ret ftk_entry_set_noborder(FtkWidget* thiz, int b)
  477. {
  478. DECL_PRIV0(thiz, priv);
  479. return_val_if_fail(thiz != NULL, RET_FAIL);
  480. priv->noborder = b;
  481. return RET_OK;
  482. }
  483. static Ret ftk_entry_compute_visible_range(FtkWidget* thiz)
  484. {
  485. DECL_PRIV0(thiz, priv);
  486. int width = ftk_widget_width(thiz);
  487. FtkCanvas* canvas = ftk_widget_canvas(thiz);
  488. const char* other_side = NULL;
  489. return_val_if_fail(thiz != NULL && priv->text_buffer != NULL, RET_FAIL);
  490. if(priv->visible_start < 0 || priv->visible_end < 0)
  491. {
  492. other_side = ftk_canvas_calc_str_visible_range(canvas, TB_TEXT,
  493. priv->visible_start, priv->visible_end, width - 2 * FTK_ENTRY_H_MARGIN, NULL);
  494. if(priv->visible_start < 0)
  495. {
  496. priv->visible_start = other_side - TB_TEXT;
  497. }
  498. else if(priv->visible_end < 0)
  499. {
  500. priv->visible_end = other_side - TB_TEXT;
  501. }
  502. }
  503. return RET_OK;
  504. }
  505. static Ret ftk_entry_set_text_internal(FtkWidget* thiz, const char* text)
  506. {
  507. DECL_PRIV0(thiz, priv);
  508. return_val_if_fail(thiz != NULL && text != NULL, RET_FAIL);
  509. ftk_text_buffer_delete(priv->text_buffer, 0, TB_LENGTH);
  510. ftk_text_buffer_insert(priv->text_buffer, 0, text, -1);
  511. priv->visible_start = -1;
  512. priv->visible_end = TB_LENGTH;
  513. priv->caret = priv->visible_end;
  514. ftk_widget_invalidate(thiz);
  515. return RET_OK;
  516. }
  517. Ret ftk_entry_set_tips(FtkWidget* thiz, const char* tips)
  518. {
  519. DECL_PRIV0(thiz, priv);
  520. return_val_if_fail(thiz != NULL, RET_FAIL);
  521. FTK_FREE(priv->tips);
  522. priv->tips = FTK_STRDUP(tips);
  523. return RET_OK;
  524. }
  525. Ret ftk_entry_set_input_type(FtkWidget* thiz, FtkInputType type)
  526. {
  527. DECL_PRIV0(thiz, priv);
  528. return_val_if_fail(thiz != NULL, RET_FAIL);
  529. priv->input_type = type;
  530. return RET_OK;
  531. }
  532. Ret ftk_entry_insert_text(FtkWidget* thiz, size_t pos, const char* text)
  533. {
  534. DECL_PRIV0(thiz, priv);
  535. return_val_if_fail(thiz != NULL && text != NULL, RET_FAIL);
  536. pos = pos < TB_LENGTH ? pos : TB_LENGTH;
  537. ftk_text_buffer_insert(priv->text_buffer, pos, text, -1);
  538. priv->visible_start = -1;
  539. priv->visible_end = TB_LENGTH;
  540. priv->caret = priv->visible_end;
  541. ftk_widget_invalidate(thiz);
  542. return RET_OK;
  543. }
  544. const char* ftk_entry_get_text(FtkWidget* thiz)
  545. {
  546. DECL_PRIV0(thiz, priv);
  547. return_val_if_fail(thiz != NULL, NULL);
  548. return TB_TEXT;
  549. }
  550. Ret ftk_entry_set_text(FtkWidget* thiz, const char* text)
  551. {
  552. ftk_widget_set_text(thiz, text);
  553. return RET_OK;
  554. }
  555. Ret ftk_entry_set_readonly(FtkWidget* thiz, int readonly)
  556. {
  557. DECL_PRIV0(thiz, priv);
  558. return_val_if_fail(thiz != NULL, RET_FAIL);
  559. priv->readonly = readonly;
  560. return RET_OK;
  561. }