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