cedric pushed a commit to branch master. http://git.enlightenment.org/core/elementary.git/commit/?id=52e9c80dfa042c5b321c5251c2fd1f09cdd0477a
commit 52e9c80dfa042c5b321c5251c2fd1f09cdd0477a Author: woochan lee <wc0917....@samsung.com> Date: Tue Aug 4 15:55:18 2015 +0200 index: add index item priority APIs for support multilingual Summary: I add the APIs for supporting multi language on index. "elm_index_item_priority_set()" API can give the priority value for each item. it will be grouping with each priority items when index start to draw the item. It can get a 0 or 1 (default : -1) -1 priority item show always even priority changed. "elm_index_priority_set()" API can changed the current priority in manually. priority will be up automatically when user send move event into last of priority 1 group item. otherwise, priority will be down automatically when user send move event into first of priority 0 group item. "elm_index_priority_get()" API can get a current index priority. @feature Test Plan: I added the test application in test_index with give the name as "test_index3" (It's for only show how to handle the priority APIs and show the how does it works for multi language so it doesn't operate with genlist.) You can check the how it works and how APIs works for it as well. Reviewers: eunue, seoz, woohyun, Hermet Subscribers: SanghyeonLee, eagleeye Differential Revision: https://phab.enlightenment.org/D2729 Signed-off-by: Cedric BAIL <ced...@osg.samsung.com> --- src/bin/test.c | 2 + src/bin/test_index.c | 93 +++++++++++++++++++++++++ src/lib/elm_index.c | 165 +++++++++++++++++++++++++++++++++++++++++++-- src/lib/elm_index.eo | 29 ++++++++ src/lib/elm_index_item.eo | 20 ++++++ src/lib/elm_widget_index.h | 3 + 6 files changed, 305 insertions(+), 7 deletions(-) diff --git a/src/bin/test.c b/src/bin/test.c index 04fb02d..96827d5 100644 --- a/src/bin/test.c +++ b/src/bin/test.c @@ -153,6 +153,7 @@ void test_scroller3(void *data, Evas_Object *obj, void *event_info); void test_spinner(void *data, Evas_Object *obj, void *event_info); void test_index(void *data, Evas_Object *obj, void *event_info); void test_index2(void *data, Evas_Object *obj, void *event_info); +void test_index3(void *data, Evas_Object *obj, void *event_info); void test_index_horizontal(void *data, Evas_Object *obj, void *event_info); void test_photocam(void *data, Evas_Object *obj, void *event_info); void test_photocam_remote(void *data, Evas_Object *obj, void *event_info); @@ -723,6 +724,7 @@ add_tests: //------------------------------// ADD_TEST(NULL, "Selectors", "Index", test_index); ADD_TEST(NULL, "Selectors", "Index 2", test_index2); + ADD_TEST(NULL, "Selectors", "Index 3", test_index3); ADD_TEST(NULL, "Selectors", "Index Horizontal", test_index_horizontal); ADD_TEST(NULL, "Selectors", "FileSelector", test_fileselector); ADD_TEST(NULL, "Selectors", "FileSelector Entry", test_fileselector_entry); diff --git a/src/bin/test_index.c b/src/bin/test_index.c index 6c13245..cd05954 100644 --- a/src/bin/test_index.c +++ b/src/bin/test_index.c @@ -434,6 +434,99 @@ test_index2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in evas_object_show(win); } +/***** Index 3 Mode ******/ + +static void +_index_priority_change_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *index = data; + int priority; + + priority = elm_index_priority_get(index); + + if (priority == 0) + elm_index_priority_set(index, 1); + else + elm_index_priority_set(index, 0); + + printf("Priority changed to : %d\n", elm_index_priority_get(index)); +} + +void +test_index3(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Evas_Object *win, *bx, *index, *bt; + Elm_Object_Item *it; + int i, j, len; + char *str; + char buf[PATH_MAX] = {0, }; + + win = elm_win_util_standard_add("Index-priority", "Index priority for multilingual"); + elm_win_autodel_set(win, EINA_TRUE); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + index = elm_index_add(win); + evas_object_size_hint_weight_set(index, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(index, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_index_autohide_disabled_set(index, EINA_TRUE); + elm_index_omit_enabled_set(index, EINA_TRUE); + + bt = elm_button_add(win); + elm_object_text_set(bt, "Priority Change"); + evas_object_smart_callback_add(bt, "clicked", _index_priority_change_cb, index); + elm_box_pack_end(bx, bt); + evas_object_show(bt); + + elm_box_pack_end(bx, index); + + evas_object_show(index); + + //1. Special character & Numbers + elm_index_item_append(index, "#", NULL, NULL); + + //2. Local language + str = "ㄱㄴㄷㄹㅁㅂㅅㅇㅈㅊㅍㅎ"; + len = strlen(str); + + i = 0; + while (i < len) + { + j = i; + eina_unicode_utf8_next_get(str, &i); + snprintf(buf, i - j + 1, "%s", str + j); + buf[i - j + 1] = 0; + + it = elm_index_item_append(index, buf, NULL, NULL); + elm_index_item_priority_set(it, 0); + } + + //3. English + str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + len = strlen(str); + + i = 0; + while (i < len) + { + j = i; + eina_unicode_utf8_next_get(str, &i); + snprintf(buf, i - j + 1, "%s", str + j); + buf[i - j + 1] = 0; + + it = elm_index_item_append(index, buf, NULL, NULL); + elm_index_item_priority_set(it, 1); + } + + elm_index_level_go(index, 0); + + evas_object_resize(win, 300, 300); + evas_object_show(win); +} + /***** Index Horizontal Mode ******/ static void diff --git a/src/lib/elm_index.c b/src/lib/elm_index.c index 272fd8c..bb49068 100644 --- a/src/lib/elm_index.c +++ b/src/lib/elm_index.c @@ -128,11 +128,15 @@ static void _omit_calc(void *data, int num_of_items, int max_num_of_items) { Elm_Index_Data *sd = data; - int max_group_num, num_of_extra_items, i, g, size, sum, *group_pos, *omit_info; + int max_group_num, num_of_extra_items, i, g, size, sum, start, *group_pos, *omit_info; Elm_Index_Omit *o; if ((max_num_of_items < 3) || (num_of_items <= max_num_of_items)) return; + if (sd->group_num > 0) + start = sd->show_group + sd->default_num; + else start = 0; + max_group_num = (max_num_of_items - 1) / 2; num_of_extra_items = num_of_items - max_num_of_items; @@ -185,7 +189,7 @@ _omit_calc(void *data, int num_of_items, int max_num_of_items) ERR("failed to allocate memory!"); break; } - o->offset = sum; + o->offset = sum + start; o->count = omit_info[i]; sd->omit = eina_list_append(sd->omit, o); } @@ -205,7 +209,7 @@ _index_box_auto_fill(Evas_Object *obj, Eina_List *l; Eina_Bool rtl; Elm_Object_Item *eo_item; - Elm_Index_Item_Data *head = NULL; + Elm_Index_Item_Data *head = NULL, *last_it = NULL; Evas_Coord mw, mh, ih; Evas_Object *o; Elm_Index_Omit *om; @@ -244,11 +248,13 @@ _index_box_auto_fill(Evas_Object *obj, EINA_LIST_FOREACH(sd->items, l, eo_item) { ELM_INDEX_ITEM_DATA_GET(eo_item, it); - if (it->level == level) num_of_items++; + if (it->level == level && it->priority == sd->show_group) num_of_items++; } if (mh != 0) max_num_of_items = ih / mh; + if (sd->group_num) + max_num_of_items -= (sd->group_num + sd->default_num - 1); _omit_calc(sd, num_of_items, max_num_of_items); } @@ -261,6 +267,29 @@ _index_box_auto_fill(Evas_Object *obj, if (it->level != level) continue; + /** when index has more than one group, + * one group is shown completely and other groups are represented by one item + */ + if (it->priority != -1) + { + // for groups of higher priority, the first item represents the group + if (it->priority < sd->show_group) + { + if (last_it && (last_it->priority == it->priority)) continue; + } + // for groups of lower priority, the last item represents the group + else if (it->priority > sd->show_group) + { + l = eina_list_next(l); + if (l) + { + ELM_INDEX_ITEM_DATA_GET(eina_list_data_get(l), next_it); + l = eina_list_prev(l); + if (next_it->priority == it->priority) continue; + } + } + } + if ((om) && (i == om->offset)) { skip = om->count; @@ -338,12 +367,56 @@ _index_box_auto_fill(Evas_Object *obj, if ((it->level == 0) && (_elm_config->access_mode == ELM_ACCESS_MODE_ON)) eo_do(eo_item, elm_wdg_item_access_register()); + + last_it = it; } evas_object_smart_calculate(sd->bx[level]); sd->level_active[level] = EINA_TRUE; } +static void +_priority_change_job(void *data) +{ + ELM_INDEX_DATA_GET(data, sd); + Elm_Object_Item *selected_it; + + sd->show_group = sd->next_group; + _index_box_clear(data, 0); + _index_box_auto_fill(data, 0); + + selected_it = elm_index_selected_item_get(data, sd->level); + if (selected_it) + elm_index_item_selected_set(selected_it, EINA_FALSE); +} + +static void +_priority_up_cb(void *data) +{ + _priority_change_job(data); +} + +static void +_priority_down_cb(void *data) +{ + _priority_change_job(data); +} + +static void +_index_priority_change(void *data, Elm_Index_Item_Data *it) +{ + ELM_INDEX_DATA_GET(data, sd); + + if ((it->priority != -1) && (it->priority != sd->show_group)) + { + sd->next_group = it->priority; + if (it->priority < sd->show_group) + _priority_up_cb(data); + else + _priority_down_cb(data); + } +} + EOLIAN static Eina_Bool _elm_index_elm_widget_theme_apply(Eo *obj, Elm_Index_Data *sd) { @@ -479,6 +552,7 @@ _item_new(Evas_Object *obj, it->func = func; WIDGET_ITEM_DATA_SET(EO_OBJ(it), data); it->level = sd->level; + it->priority = -1; return eo_item; } @@ -509,9 +583,14 @@ _delay_change_cb(void *data) sd->delay = NULL; item = elm_index_selected_item_get(data, sd->level); - if (item) eo_do(data, eo_event_callback_call - (ELM_INDEX_EVENT_DELAY_CHANGED, item)); + if (item) + { + eo_do(data, eo_event_callback_call + (ELM_INDEX_EVENT_DELAY_CHANGED, item)); + ELM_INDEX_ITEM_DATA_GET(item, it); + _index_priority_change(data, it); + } return ECORE_CALLBACK_CANCEL; } @@ -926,6 +1005,18 @@ _index_resize_cb(void *data EINA_UNUSED, } } +static int +_sort_cb(const void *d1, const void *d2) +{ + Elm_Object_Item *eo_it1 = (Elm_Object_Item *)d1, *eo_it2 = (Elm_Object_Item *)d2; + + ELM_INDEX_ITEM_DATA_GET(eo_it1, it1); + ELM_INDEX_ITEM_DATA_GET(eo_it2, it2); + if (it1->priority <= it2->priority) return -1; + else return 1; +} + + EOLIAN static void _elm_index_evas_object_smart_add(Eo *obj, Elm_Index_Data *priv) { @@ -1398,7 +1489,31 @@ _elm_index_item_clear(Eo *obj, Elm_Index_Data *sd) EOLIAN static void _elm_index_level_go(Eo *obj, Elm_Index_Data *sd, int level) { - (void) level; + Elm_Object_Item *eo_it; + Eina_List *l; + int prev; + + sd->items = eina_list_sort(sd->items, 0, EINA_COMPARE_CB(_sort_cb)); + + if (level == 0) + { + sd->default_num = 0; + sd->group_num = 0; + sd->show_group = -1; + prev = -1; + EINA_LIST_FOREACH(sd->items, l, eo_it) + { + ELM_INDEX_ITEM_DATA_GET(eo_it, it); + if (it->priority == -1) sd->default_num++; + if (it->priority != prev) + { + if (prev == -1) sd->show_group = it->priority; + sd->group_num++; + prev = it->priority; + } + } + } + _index_box_clear(obj, 0); _index_box_auto_fill(obj, 0); if (sd->level == 1) @@ -1485,6 +1600,42 @@ _elm_index_omit_enabled_get(Eo *obj EINA_UNUSED, Elm_Index_Data *sd) return sd->omit_enabled; } +EOLIAN static void +_elm_index_item_priority_set(Eo *eo_it EINA_UNUSED, Elm_Index_Item_Data *it, int priority) +{ + if (priority < -1) + { + WRN("priority value should be greater than or equal to -1."); + return; + } + + it->priority = priority; +} + +EOLIAN static void +_elm_index_priority_set(Eo *obj, Elm_Index_Data *sd, int priority) +{ + if (priority < -1) + { + WRN("priority value should be greater than or equal to -1."); + return; + } + if (priority != sd->show_group) + { + sd->next_group = priority; + if (priority > sd->show_group) + _priority_up_cb((void *)obj); + else + _priority_down_cb((void *)obj); + } +} + +EOLIAN static int +_elm_index_priority_get(Eo *obj EINA_UNUSED, Elm_Index_Data *sd) +{ + return sd->show_group; +} + static void _elm_index_class_constructor(Eo_Class *klass) { diff --git a/src/lib/elm_index.eo b/src/lib/elm_index.eo index 8da401c..05c897c 100644 --- a/src/lib/elm_index.eo +++ b/src/lib/elm_index.eo @@ -52,6 +52,35 @@ class Elm.Index (Elm.Layout, Evas.Clickable_Interface, Evas.Selectable_Interface enabled: bool; /*@ @c EINA_TRUE to enable omit feature, @c EINA_FALSE to disable */ } } + @property priority { + set { + /*@ + Set priority group of index. Priority group will be shown as many items as it can, + and other group will be shown one character only. + + @see elm_index_priority_get() + + @since 1.16 + + @ingroup Index */ + } + get { + /*@ + Get current priority group of index. + + @return priority value in index + + @see elm_index_priority_set() + + @since 1.16 + + @ingroup Index */ + } + values { + priority: int; /*@ @c priority target priority value in index */ + } + } + @property horizontal { set { /*@ diff --git a/src/lib/elm_index_item.eo b/src/lib/elm_index_item.eo index 6fd0621..3cfe709 100644 --- a/src/lib/elm_index_item.eo +++ b/src/lib/elm_index_item.eo @@ -25,6 +25,26 @@ class Elm.Index_Item(Elm.Widget_Item) selected: bool; /*@ EINA_TRUE if selected EINA_FALSE otherwise */ } } + @property priority { + set { + /*@ + Sets the priority of an item. + + The priority is @c -1 by default, which means that the item doesn't belong to a group. + The value of the priority starts from @c 0. + + In elm_index_level_go, the items are sorted in ascending order according to priority. + Items of the same priority make a group and the primary group is shown by default. + + @see elm_index_item_priority_get() + + @ingroup Index + */ + } + values { + priority: int; /*@ The priority */ + } + } letter_get @const { /*@ Get the letter (string) set on a given index widget item. diff --git a/src/lib/elm_widget_index.h b/src/lib/elm_widget_index.h index 7bdba82..f48330d 100644 --- a/src/lib/elm_widget_index.h +++ b/src/lib/elm_widget_index.h @@ -40,6 +40,8 @@ struct _Elm_Index_Data Eina_Bool level_active[2]; /**< a flag for the activeness of a level. activeness means the box is filled with contents. */ + int group_num, default_num; + int show_group, next_group; Eina_Bool mouse_down : 1; Eina_Bool horizontal : 1; @@ -60,6 +62,7 @@ struct _Elm_Index_Item_Data Eina_List *omitted; Elm_Index_Item_Data *head; + int priority; Eina_Bool selected : 1; /**< a flag that remembers an item is selected. this is set true when mouse down/move occur above an item and when elm_index_item_selected_set() API is called. */ }; --