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 <cedric@osg.samsung.com>
This commit is contained in:
woochan lee 2015-08-04 15:55:18 +02:00 committed by Cedric BAIL
parent a249d77d1d
commit e22bf93a67
6 changed files with 305 additions and 7 deletions

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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 {
/*@

View File

@ -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.

View File

@ -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. */
};