File Manager / src / view /

genlist-widget.c

  1. /*
  2. * Copyright 2014 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17.  
  18. #include "view/genlist-widget.h"
  19. #include "view/navi-path-widget.h"
  20. #include "view/list-view.h"
  21. #include "utils/ui-utils.h"
  22. #include "utils/logger.h"
  23. #include "utils/model-utils.h"
  24. #include "utils/config.h"
  25. #include "utils/common-utils.h"
  26. #include "utils/app-types.h"
  27. #include "main-app.h"
  28.  
  29. #define MIN_FILE_TYPE_ICON_SIZE ELM_SCALE_SIZE(80)
  30.  
  31. static const char *const LABEL_TEXT_SELECT_ALL = "Select All";
  32.  
  33. static void _genlist_widget_destroy(genlist_widget *widget);
  34. static void _genlist_widget_set_items_style(genlist_widget *widget);
  35. static void _genlist_widget_reset_all_checkboxes(genlist_widget *widget);
  36. static void _genlist_widget_check_state_sel_all(genlist_widget *widget);
  37. static void _genlist_widget_item_edit_sel(genlist_widget *widget, Evas_Object *checkbox);
  38. static void _genlist_widget_sel_all_item_sel(genlist_widget *widget);
  39.  
  40. static void _genlist_widget_delete_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
  41. static void _genlist_widget_item_sel_cb(void *data, Evas_Object *obj, void *event_info);
  42. static void _genlist_widget_sel_all_checkbox_change_cb(void *data, Evas_Object *obj, void *event_info);
  43. static void _genlist_widget_sel_all_layout_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info);
  44. static void _genlist_widget_item_checkbox_sel_cb(void *data, Evas_Object *obj, void *event_info);
  45.  
  46. static Evas_Object *_genlist_widget_edit_icon_get(void *data, Evas_Object *obj, const char *part);
  47. static Evas_Object *_genlist_widget_main_icon_get(const char *icon_name, Evas_Object *parent);
  48. static Evas_Object *_genlist_widget_default_node_icon_get(void *data, Evas_Object *obj, const char *part);
  49. static Evas_Object *_genlist_widget_default_storage_icon_get(void *data, Evas_Object *obj, const char *part);
  50. static char *_genlist_widget_node_label_get(void *data, Evas_Object *obj, const char *part);
  51. static char *_genlist_widget_storage_label_get(void *data, Evas_Object *obj, const char *part);
  52.  
  53. genlist_widget *genlist_widget_add(view_data *view)
  54. {
  55. RETVM_IF(!view, NULL, "View object is NULL");
  56.  
  57. genlist_widget *widget = calloc(1, sizeof(genlist_widget));
  58. RETVM_IF(!widget, NULL, "Fail allocate memory");
  59.  
  60. widget->view = view;
  61.  
  62. widget->box = elm_box_add(widget->view->navi_layout);
  63. if (!widget->box) {
  64. ERR("Fail to create box");
  65. _genlist_widget_destroy(widget);
  66. return NULL;
  67. }
  68. evas_object_size_hint_weight_set(widget->box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  69. evas_object_size_hint_align_set(widget->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
  70.  
  71. widget->sel_all_layout = elm_layout_add(widget->box);
  72. if (!widget->sel_all_layout) {
  73. ERR("Fail to create select all layout object");
  74. evas_object_del(widget->box);
  75. _genlist_widget_destroy(widget);
  76. return NULL;
  77. }
  78. elm_layout_theme_set(widget->sel_all_layout, "genlist", "item", "select_all/default");
  79. evas_object_size_hint_weight_set(widget->sel_all_layout, EVAS_HINT_EXPAND, EVAS_HINT_FILL);
  80. evas_object_size_hint_align_set(widget->sel_all_layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
  81. evas_object_event_callback_add(widget->sel_all_layout, EVAS_CALLBACK_MOUSE_DOWN,
  82. _genlist_widget_sel_all_layout_down_cb, widget);
  83. evas_object_show(widget->sel_all_layout);
  84.  
  85. widget->sel_all_checkbox = elm_check_add(widget->sel_all_layout);
  86. if (!widget->sel_all_checkbox) {
  87. ERR("Fail to create select all checkbox object");
  88. evas_object_del(widget->box);
  89. _genlist_widget_destroy(widget);
  90. return NULL;
  91. }
  92. evas_object_propagate_events_set(widget->sel_all_checkbox, EINA_FALSE);
  93. elm_check_state_pointer_set(widget->sel_all_checkbox, &widget->view->edit.is_all_selected);
  94. evas_object_smart_callback_add(widget->sel_all_checkbox, "changed",
  95. _genlist_widget_sel_all_checkbox_change_cb, widget);
  96. elm_object_part_content_set(widget->sel_all_layout, "elm.icon", widget->sel_all_checkbox);
  97. elm_object_part_text_set(widget->sel_all_layout, "elm.text.main", LABEL_TEXT_SELECT_ALL);
  98. evas_object_show(widget->sel_all_layout);
  99.  
  100. widget->genlist = ui_utils_genlist_add(widget->view->navi_layout, _genlist_widget_delete_cb, widget);
  101. if (!widget->genlist) {
  102. ERR("Fail to create genlist");
  103. evas_object_del(widget->box);
  104. _genlist_widget_destroy(widget);
  105. return NULL;
  106. }
  107. _genlist_widget_set_items_style(widget);
  108.  
  109. elm_box_pack_end(widget->box, widget->genlist);
  110. evas_object_show(widget->box);
  111.  
  112. elm_object_part_content_set(widget->view->navi_layout, "content", widget->box);
  113. evas_object_data_set(widget->genlist, "data_list", widget);
  114.  
  115. return widget;
  116. }
  117.  
  118. void genlist_widget_content_set(genlist_widget *widget, const Eina_List *file_list)
  119. {
  120. RETM_IF(!widget, "Widget is NULL");
  121.  
  122. const Eina_List *list = NULL;
  123. void *item = NULL;
  124.  
  125. _genlist_widget_set_items_style(widget);
  126.  
  127. EINA_LIST_FOREACH(file_list, list, item)
  128. {
  129. Elm_Object_Item *node_item = elm_genlist_item_append(widget->genlist, &itc, item, NULL,
  130. ELM_GENLIST_ITEM_NONE, _genlist_widget_item_sel_cb, widget);
  131.  
  132. elm_object_item_data_set(node_item, item);
  133. }
  134. }
  135.  
  136. int genlist_widget_update(genlist_widget *widget)
  137. {
  138. RETVM_IF(!widget->view, RESULT_TYPE_INVALID_ARG, "View object is NULL");
  139.  
  140. app_data *app = widget->view->app;
  141.  
  142. _genlist_widget_set_items_style(widget);
  143. _genlist_widget_reset_all_checkboxes(widget);
  144.  
  145. if (app->status.curr_mode == MODE_EDIT) {
  146. evas_object_show(widget->sel_all_layout);
  147. elm_box_pack_start(widget->box, widget->sel_all_layout);
  148. } else {
  149. evas_object_hide(widget->sel_all_layout);
  150. elm_box_unpack(widget->box, widget->sel_all_layout);
  151. }
  152.  
  153. return RESULT_TYPE_OK;
  154. }
  155.  
  156. void genlist_widget_clear(genlist_widget *widget)
  157. {
  158. elm_genlist_clear(widget->genlist);
  159. }
  160.  
  161. static void _genlist_widget_destroy(genlist_widget *widget)
  162. {
  163. free(widget);
  164. }
  165.  
  166. static void _genlist_widget_set_items_style(genlist_widget *widget)
  167. {
  168. app_data *app = widget->view->app;
  169. itc.item_style = "type1";
  170.  
  171. itc.func.text_get = (app->status.is_mainview)
  172. ? _genlist_widget_storage_label_get
  173. : _genlist_widget_node_label_get;
  174.  
  175. if (app->status.curr_mode == MODE_EDIT) {
  176. itc.func.content_get = _genlist_widget_edit_icon_get;
  177. } else {
  178. itc.func.content_get = (app->status.is_mainview)
  179. ? _genlist_widget_default_storage_icon_get
  180. : _genlist_widget_default_node_icon_get;
  181. }
  182.  
  183. elm_genlist_realized_items_update(widget->genlist);
  184. }
  185.  
  186. static void _genlist_widget_reset_all_checkboxes(genlist_widget *widget)
  187. {
  188. Elm_Object_Item *item = elm_genlist_first_item_get(widget->genlist);
  189. while (item) {
  190. node_info *node = elm_object_item_data_get(item);
  191. node->is_selected = EINA_FALSE;
  192.  
  193. Evas_Object *checkbox = elm_object_item_part_content_get(item, "elm.swallow.end");
  194. elm_check_state_set(checkbox, EINA_FALSE);
  195. item = elm_genlist_item_next_get(item);
  196. }
  197.  
  198. elm_check_state_set(widget->sel_all_checkbox, EINA_FALSE);
  199. widget->view->edit.checked_count = 0;
  200. }
  201.  
  202. static void _genlist_widget_check_state_sel_all(genlist_widget *widget)
  203. {
  204. Eina_Bool check_sel_all = EINA_FALSE;
  205. if (widget->view->edit.checked_count == list_view_items_count_get(widget->view)) {
  206. check_sel_all = EINA_TRUE;
  207. }
  208. elm_check_state_set(widget->sel_all_checkbox, check_sel_all);
  209. }
  210.  
  211. static void _genlist_widget_item_edit_sel(genlist_widget *widget, Evas_Object *checkbox)
  212. {
  213. Eina_Bool checked = elm_check_state_get(checkbox);
  214. (checked) ? ++widget->view->edit.checked_count
  215. : --widget->view->edit.checked_count;
  216. }
  217.  
  218. static void _genlist_widget_sel_all_item_sel(genlist_widget *widget)
  219. {
  220. Eina_Bool checked = elm_check_state_get(widget->sel_all_checkbox);
  221. Elm_Object_Item *item = elm_genlist_first_item_get(widget->genlist);
  222. while (item) {
  223. node_info *node = elm_object_item_data_get(item);
  224.  
  225. if (node->is_selected != checked) {
  226. node->is_selected = checked;
  227.  
  228. (checked) ? ++widget->view->edit.checked_count
  229. : --widget->view->edit.checked_count;
  230.  
  231. Evas_Object *checkbox = elm_object_item_part_content_get(item, "elm.swallow.end");
  232. elm_check_state_set(checkbox, checked);
  233. }
  234.  
  235. item = elm_genlist_item_next_get(item);
  236. }
  237.  
  238. int res = list_view_select_all(widget->view, checked);
  239. RETM_IF(res != RESULT_TYPE_OK, "Failed to %s all files", (checked ? "select" : "unselect"));
  240. }
  241.  
  242. static void _genlist_widget_delete_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
  243. {
  244. _genlist_widget_destroy(data);
  245. }
  246.  
  247. static void _genlist_widget_item_sel_cb(void *data, Evas_Object *obj, void *event_info)
  248. {
  249. RETM_IF(!data, "Data is NULL");
  250.  
  251. genlist_widget *widget = data;
  252. app_data *app = widget->view->app;
  253.  
  254. elm_genlist_item_selected_set(event_info, EINA_FALSE);
  255.  
  256. if (app->status.curr_mode != MODE_EDIT) {
  257. if (app->status.is_mainview) {
  258. storage_info *storage = elm_object_item_data_get(event_info);
  259. list_view_add(app, widget->view->navi, storage->root_path, NULL);
  260. } else {
  261. node_info *pNode = elm_object_item_data_get(event_info);
  262. if (pNode->type == FILE_TYPE_DIR) {
  263. list_view_add(app, widget->view->navi, widget->view->curr_path, pNode->name);
  264. } else {
  265. model_utils_launch_file(pNode);
  266. }
  267. }
  268. } else {
  269. Evas_Object *checkbox = elm_object_item_part_content_get(event_info, "elm.swallow.end");
  270. Eina_Bool checked = elm_check_state_get(checkbox);
  271. elm_check_state_set(checkbox, !checked);
  272.  
  273. _genlist_widget_item_edit_sel(widget, checkbox);
  274. _genlist_widget_check_state_sel_all(widget);
  275.  
  276. int res = list_view_update(widget->view->navi_item, UPDATE_TYPE_CTRL_BAR_STATE);
  277. RETM_IF(res != RESULT_TYPE_OK, "Fail to update view");
  278. }
  279. }
  280.  
  281. static void _genlist_widget_sel_all_layout_down_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
  282. {
  283. RETM_IF(!data, "Data is NULL");
  284.  
  285. genlist_widget *widget = data;
  286. Eina_Bool checked = elm_check_state_get(widget->sel_all_checkbox);
  287. elm_check_state_set(widget->sel_all_checkbox, !checked);
  288. _genlist_widget_sel_all_checkbox_change_cb(data, widget->sel_all_checkbox, NULL);
  289. }
  290.  
  291. static void _genlist_widget_sel_all_checkbox_change_cb(void *data, Evas_Object *obj, void *event_info)
  292. {
  293. RETM_IF(!data, "Data is NULL");
  294.  
  295. genlist_widget *widget = data;
  296. _genlist_widget_sel_all_item_sel(widget);
  297.  
  298. int res = list_view_update(widget->view->navi_item, UPDATE_TYPE_CTRL_BAR_STATE);
  299. RETM_IF(res != RESULT_TYPE_OK, "Fail to update view");
  300. }
  301.  
  302. static void _genlist_widget_item_checkbox_sel_cb(void *data, Evas_Object *obj, void *event_info)
  303. {
  304. RETM_IF(!data, "Data is NULL");
  305.  
  306. genlist_widget *widget = data;
  307. _genlist_widget_item_edit_sel(widget, obj);
  308. _genlist_widget_check_state_sel_all(widget);
  309.  
  310. int res = list_view_update(widget->view->navi_item, UPDATE_TYPE_CTRL_BAR_STATE);
  311. RETM_IF(res != RESULT_TYPE_OK, "Fail to update view");
  312. }
  313.  
  314. static Evas_Object *_genlist_widget_edit_icon_get(void *data, Evas_Object *obj, const char *part)
  315. {
  316. RETVM_IF(!data, NULL, "Data is NULL");
  317. Evas_Object *eo = NULL;
  318.  
  319. genlist_widget *widget = evas_object_data_get(obj, "data_list");
  320. node_info *pNode = data;
  321.  
  322. if (!strcmp(part, "elm.swallow.icon")) {
  323. eo = _genlist_widget_default_node_icon_get(data, obj, part);
  324. RETVM_IF(!eo, NULL, "Failed to create icon");
  325. } else if (!strcmp(part, "elm.swallow.end")) {
  326. eo = elm_check_add(obj);
  327. elm_check_state_set(eo, pNode->is_selected);
  328. elm_check_state_pointer_set(eo, &pNode->is_selected);
  329. elm_object_focus_set(eo, EINA_FALSE);
  330. evas_object_propagate_events_set(eo, EINA_FALSE);
  331. evas_object_smart_callback_add(eo, "changed", _genlist_widget_item_checkbox_sel_cb, widget);
  332. }
  333.  
  334. return eo;
  335. }
  336.  
  337. static Evas_Object *_genlist_widget_main_icon_get(const char *icon_name, Evas_Object *parent)
  338. {
  339. Evas_Object *icon = elm_image_add(parent);
  340. elm_object_focus_set(icon, EINA_FALSE);
  341. elm_image_file_set(icon, ui_utils_get_resource(icon_name), NULL);
  342. evas_object_size_hint_min_set(icon, MIN_FILE_TYPE_ICON_SIZE, MIN_FILE_TYPE_ICON_SIZE);
  343. evas_object_show(icon);
  344. return icon;
  345. }
  346.  
  347. static Evas_Object *_genlist_widget_default_node_icon_get(void *data, Evas_Object *obj, const char *part)
  348. {
  349. RETVM_IF(!data, NULL, "Data is NULL");
  350. node_info *pNode = data;
  351. Evas_Object *eo = NULL;
  352. const char *icon_name = model_utils_get_default_icon_name(pNode->type);
  353.  
  354. if (!strcmp(part, "elm.swallow.icon")) {
  355. eo = _genlist_widget_main_icon_get(icon_name, obj);
  356. RETVM_IF(!eo, NULL, "Failed to create icon");
  357. }
  358.  
  359. return eo;
  360. }
  361.  
  362. static Evas_Object *_genlist_widget_default_storage_icon_get(void *data, Evas_Object *obj, const char *part)
  363. {
  364. RETVM_IF(!data, NULL, "Data is NULL");
  365. Evas_Object *eo = NULL;
  366.  
  367. if (!strcmp(part, "elm.swallow.icon")) {
  368. eo = _genlist_widget_main_icon_get(FM_ICON_FOLDER, obj);
  369. RETVM_IF(!eo, NULL, "Failed to create icon");
  370. }
  371.  
  372. return eo;
  373. }
  374.  
  375. static char *_genlist_widget_node_label_get(void *data, Evas_Object *obj, const char *part)
  376. {
  377. RETVM_IF(!data, NULL, "Data is NULL");
  378. node_info *pNode = data;
  379.  
  380. if (!strcmp(part, "elm.text")) {
  381. return elm_entry_utf8_to_markup(pNode->name);
  382. }
  383.  
  384. return NULL;
  385. }
  386.  
  387. static char *_genlist_widget_storage_label_get(void *data, Evas_Object *obj, const char *part)
  388. {
  389. RETVM_IF(!data, NULL, "Data is NULL");
  390. storage_info *pStorage = data;
  391.  
  392. if (!strcmp(part, "elm.text")) {
  393. return elm_entry_utf8_to_markup(pStorage->root_name);
  394. }
  395.  
  396. return NULL;
  397. }
  398.