/src/ftk_message_box.c

http://ftk.googlecode.com/ · C · 216 lines · 145 code · 39 blank · 32 comment · 16 complexity · cc1502ca84a0d52bd3d4e4b09424c05d MD5 · raw file

  1. /*
  2. * File: ftk_messagebox.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: messagebox
  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. * 2010-01-23 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "ftk_log.h"
  31. #include "ftk_label.h"
  32. #include "ftk_button.h"
  33. #include "ftk_globals.h"
  34. #include "ftk_message_box.h"
  35. static Ret message_box_on_button_clicked(void* ctx, void* obj)
  36. {
  37. *(int*)ctx = ftk_widget_id((FtkWidget*)obj);
  38. ftk_logd("%s: the %dth button is clicked.\n", __func__, ftk_widget_id((FtkWidget*)obj));
  39. return RET_QUIT;
  40. }
  41. #define FTK_BUTTON_DEFAULT_WIDTH 80
  42. #define FTK_BUTTON_DEFAULT_HEIGHT 48
  43. #define FTK_MESSAGE_BOX_MIN_HEIGHT 30
  44. static Ret ftk_message_box_size(int has_title, int has_button, const char* text, int* w, int* h)
  45. {
  46. int start = 0;
  47. int width = 0;
  48. int height = 0;
  49. int font_h = 0;
  50. FtkRect rect = {0};
  51. const char* end = text;
  52. FtkCanvas* canvas = ftk_shared_canvas();
  53. ftk_wnd_manager_get_work_area(ftk_default_wnd_manager(), &rect);
  54. width = rect.width - 2 * (FTK_DIALOG_MARGIN + FTK_LABEL_LEFT_MARGIN + FTK_DIALOG_BORDER);
  55. height = 4 * FTK_V_MARGIN + FTK_DIALOG_BORDER;
  56. height += has_title ? ftk_dialog_get_title_height() : 0;
  57. height += has_button ? FTK_BUTTON_DEFAULT_HEIGHT : 0;
  58. font_h = ftk_font_desc_get_size(ftk_default_font());
  59. while(*end != '\0')
  60. {
  61. height += font_h + FTK_LABEL_TOP_MARGIN;
  62. end = ftk_canvas_calc_str_visible_range(canvas, text, start, -1, width, NULL);
  63. start = end - text;
  64. }
  65. height = height < FTK_MESSAGE_BOX_MIN_HEIGHT ? FTK_MESSAGE_BOX_MIN_HEIGHT : height;
  66. height = height < rect.height ? height : rect.height;
  67. *h = (height + 1) & 0xfffffffe;
  68. *w = (rect.width + 1) & 0xfffffffe;
  69. return RET_OK;
  70. }
  71. static int ftk_count_strings(const char* buttons[FTK_MSGBOX_MAX_BUTTONS])
  72. {
  73. int i = 0;
  74. int buttons_nr = 0;
  75. if(buttons != NULL)
  76. {
  77. for(i = 0; buttons[i] != NULL && i < FTK_MSGBOX_MAX_BUTTONS; i++)
  78. {
  79. buttons_nr++;
  80. }
  81. }
  82. return buttons_nr;
  83. }
  84. int ftk_message_box(FtkBitmap* icon, const char* title, const char* text, const char* buttons[FTK_MSGBOX_MAX_BUTTONS])
  85. {
  86. int i = 0;
  87. int w = 0;
  88. int h = 0;
  89. int id = 0;
  90. int ret = 0;
  91. int width = 0;
  92. int height = 0;
  93. int xoffset = 0;
  94. int yoffset = 0;
  95. int h_margin = 0;
  96. int has_title = icon != NULL || title != NULL;
  97. int buttons_nr = ftk_count_strings(buttons);
  98. FtkWidget* label = NULL;
  99. FtkWidget* button = NULL;
  100. FtkWidget* dialog = NULL;
  101. return_val_if_fail(text != NULL, -1);
  102. ftk_message_box_size(has_title, buttons_nr, text, &width, &height);
  103. dialog = ftk_dialog_create(0, 0, width, height);
  104. ftk_window_set_animation_hint(dialog, "msgbox");
  105. if(has_title)
  106. {
  107. ftk_dialog_set_icon(dialog, icon);
  108. ftk_widget_set_text(dialog, title);
  109. }
  110. else
  111. {
  112. ftk_dialog_hide_title(dialog);
  113. ftk_widget_set_attr(dialog, FTK_ATTR_POPUP);
  114. }
  115. width = ftk_widget_width(dialog);
  116. height = ftk_widget_height(dialog);
  117. /*create label.*/
  118. xoffset = FTK_H_MARGIN;
  119. yoffset = FTK_V_MARGIN;
  120. w = width - 2 * (FTK_DIALOG_BORDER + FTK_H_MARGIN);
  121. h = height - FTK_DIALOG_BORDER - 4 * FTK_V_MARGIN;
  122. h -= has_title ? ftk_dialog_get_title_height() : 0;
  123. h -= buttons_nr > 0 ? FTK_BUTTON_DEFAULT_HEIGHT : 0;
  124. label = ftk_label_create(dialog, xoffset, yoffset, w, h);
  125. ftk_widget_set_text(label, text);
  126. /*create buttons*/
  127. if(buttons_nr > 0)
  128. {
  129. xoffset = 0;
  130. w = FTK_BUTTON_DEFAULT_WIDTH;
  131. h = FTK_BUTTON_DEFAULT_HEIGHT;
  132. w = ((buttons_nr + 1) * w) < width ? w : (width / (buttons_nr + 1));
  133. yoffset = height - h - FTK_V_MARGIN - (has_title ? ftk_dialog_get_title_height() : 0);
  134. h_margin = (width - buttons_nr * w) / (buttons_nr + 1);
  135. for(i = 0; i < buttons_nr; i++)
  136. {
  137. xoffset += h_margin;
  138. button = ftk_button_create(dialog, xoffset, yoffset, w, h);
  139. ftk_widget_set_id(button, i + 1);
  140. ftk_widget_set_text(button, buttons[i]);
  141. ftk_button_set_clicked_listener(button, message_box_on_button_clicked, &id);
  142. xoffset += w;
  143. }
  144. }
  145. else
  146. {
  147. /*if no buttons, quit when timeout.*/
  148. ftk_dialog_quit_after(dialog, 3000);
  149. }
  150. ftk_widget_show_all(dialog, 1);
  151. ret = ftk_dialog_run(dialog);
  152. ftk_widget_unref(dialog);
  153. if(icon != NULL)
  154. {
  155. ftk_bitmap_unref(icon);
  156. }
  157. return ret;
  158. }
  159. int ftk_tips(const char* text)
  160. {
  161. return ftk_message_box(NULL, NULL, text, NULL);
  162. }
  163. int ftk_warning(const char* title, const char* text, const char* buttons[FTK_MSGBOX_MAX_BUTTONS + 1])
  164. {
  165. FtkBitmap* icon = ftk_theme_load_image(ftk_default_theme(), "warning"FTK_STOCK_IMG_SUFFIX);
  166. return ftk_message_box(icon, title, text, buttons);
  167. }
  168. int ftk_question(const char* title, const char* text, const char* buttons[FTK_MSGBOX_MAX_BUTTONS + 1])
  169. {
  170. FtkBitmap* icon = ftk_theme_load_image(ftk_default_theme(), "question"FTK_STOCK_IMG_SUFFIX);
  171. return ftk_message_box(icon, title, text, buttons);
  172. }
  173. int ftk_infomation(const char* title, const char* text, const char* buttons[FTK_MSGBOX_MAX_BUTTONS + 1])
  174. {
  175. FtkBitmap* icon = ftk_theme_load_image(ftk_default_theme(), "info"FTK_STOCK_IMG_SUFFIX);
  176. return ftk_message_box(icon, title, text, buttons);
  177. }