/src/ftk_list_model_default.c

http://ftk.googlecode.com/ · C · 219 lines · 147 code · 43 blank · 29 comment · 45 complexity · 13072a427bc0a177ac0d05a704113e30 MD5 · raw file

  1. /*
  2. * File: ftk_list_model_default.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: default list model
  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-28 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "ftk_list_model_default.h"
  31. typedef struct _ListModelDefaultPrivInfo
  32. {
  33. size_t nr;
  34. size_t alloc_nr;
  35. FtkListItemInfo* items;
  36. }PrivInfo;
  37. static Ret ftk_list_item_reset(FtkListItemInfo* info);
  38. static int ftk_list_model_default_get_total(FtkListModel* thiz)
  39. {
  40. DECL_PRIV(thiz, priv);
  41. return_val_if_fail(priv != NULL, 0);
  42. return priv->nr;
  43. }
  44. static Ret ftk_list_model_default_get_data(FtkListModel* thiz, size_t index, void** ret)
  45. {
  46. DECL_PRIV(thiz, priv);
  47. return_val_if_fail(priv != NULL && index < priv->nr && ret != NULL, RET_FAIL);
  48. *ret = priv->items+index;
  49. return RET_OK;
  50. }
  51. static void ftk_list_model_default_destroy(FtkListModel* thiz)
  52. {
  53. DECL_PRIV(thiz, priv);
  54. if(priv != NULL)
  55. {
  56. size_t i = 0;
  57. for(i = 0; i < priv->nr; i++)
  58. {
  59. ftk_list_item_reset(priv->items+i);
  60. }
  61. FTK_FREE(priv->items);
  62. FTK_ZFREE(thiz, sizeof(FtkListModel) + sizeof(PrivInfo));
  63. }
  64. return;
  65. }
  66. static Ret ftk_list_model_default_extend(FtkListModel* thiz, size_t delta)
  67. {
  68. int alloc_nr = 0;
  69. DECL_PRIV(thiz, priv);
  70. FtkListItemInfo* items = NULL;
  71. if(priv->items != NULL && (priv->nr + delta) < priv->alloc_nr)
  72. {
  73. return RET_OK;
  74. }
  75. alloc_nr = (priv->alloc_nr + delta) + FTK_HALF(priv->alloc_nr + delta) + 2;
  76. items = (FtkListItemInfo*)FTK_REALLOC(priv->items, sizeof(FtkListItemInfo) * alloc_nr);
  77. if(items != NULL)
  78. {
  79. priv->items = items;
  80. priv->alloc_nr = alloc_nr;
  81. }
  82. return (priv->nr + delta) < priv->alloc_nr ? RET_OK : RET_FAIL;
  83. }
  84. static Ret ftk_list_item_reset(FtkListItemInfo* info)
  85. {
  86. return_val_if_fail(info != NULL, RET_FAIL);
  87. if(info->text != NULL)
  88. {
  89. FTK_FREE(info->text);
  90. }
  91. if(info->left_icon != NULL)
  92. {
  93. ftk_bitmap_unref(info->left_icon);
  94. }
  95. if(info->right_icon != NULL)
  96. {
  97. ftk_bitmap_unref(info->right_icon);
  98. }
  99. memset(info, 0x00, sizeof(FtkListItemInfo));
  100. return RET_OK;
  101. }
  102. static Ret ftk_list_item_copy(FtkListModel* thiz, FtkListItemInfo* dst, FtkListItemInfo* src)
  103. {
  104. return_val_if_fail(dst != NULL && src != NULL && thiz != NULL, RET_FAIL);
  105. memcpy(dst, src, sizeof(FtkListItemInfo));
  106. if(src->text != NULL)
  107. {
  108. dst->text = ftk_strdup(src->text);
  109. }
  110. if(dst->left_icon != NULL)
  111. {
  112. ftk_bitmap_ref(dst->left_icon);
  113. }
  114. if(dst->right_icon != NULL)
  115. {
  116. ftk_bitmap_ref(dst->right_icon);
  117. }
  118. return RET_OK;
  119. }
  120. Ret ftk_list_model_default_add(FtkListModel* thiz, void* item)
  121. {
  122. DECL_PRIV(thiz, priv);
  123. FtkListItemInfo* info = (FtkListItemInfo*)item;
  124. return_val_if_fail(thiz != NULL && info != NULL, RET_FAIL);
  125. return_val_if_fail(ftk_list_model_default_extend(thiz, 1) == RET_OK, RET_FAIL);
  126. if(ftk_list_item_copy(thiz, priv->items+priv->nr, info) == RET_OK)
  127. {
  128. priv->nr++;
  129. }
  130. return RET_OK;
  131. }
  132. static Ret ftk_list_model_default_reset(FtkListModel* thiz)
  133. {
  134. size_t i = 0;
  135. DECL_PRIV(thiz, priv);
  136. return_val_if_fail(thiz != NULL, RET_FAIL);
  137. for(i = 0; i < priv->nr; i++)
  138. {
  139. ftk_list_item_reset(priv->items+i);
  140. }
  141. priv->nr = 0;
  142. return RET_OK;
  143. }
  144. Ret ftk_list_model_default_remove(FtkListModel* thiz, size_t index)
  145. {
  146. DECL_PRIV(thiz, priv);
  147. return_val_if_fail(thiz != NULL && index < priv->nr, RET_FAIL);
  148. ftk_list_item_reset(priv->items+index);
  149. if(index < (priv->nr - 1))
  150. {
  151. size_t i = index;
  152. for(; i < priv->nr; i++)
  153. {
  154. memcpy(priv->items+i, priv->items+i+1, sizeof(FtkListItemInfo));
  155. }
  156. }
  157. priv->nr--;
  158. return RET_OK;
  159. }
  160. FtkListModel* ftk_list_model_default_create(size_t init_nr)
  161. {
  162. FtkListModel* thiz = FTK_NEW_PRIV(FtkListModel);
  163. if(thiz != NULL)
  164. {
  165. DECL_PRIV(thiz, priv);
  166. thiz->get_total = ftk_list_model_default_get_total;
  167. thiz->get_data = ftk_list_model_default_get_data;
  168. thiz->add = ftk_list_model_default_add;
  169. thiz->reset = ftk_list_model_default_reset;
  170. thiz->remove = ftk_list_model_default_remove;
  171. thiz->destroy = ftk_list_model_default_destroy;
  172. thiz->ref = 1;
  173. priv->alloc_nr = init_nr;
  174. }
  175. return thiz;
  176. }