From 74353db9442ec97b8f1d092c0462df42e1c9c950 Mon Sep 17 00:00:00 2001 From: "sungwook79.park" Date: Fri, 18 Nov 2016 17:24:12 +0900 Subject: [PATCH] Change emoticon mode form rotary selector to list UI Change-Id: I6bc986252e1d9a3b1ceeb948483993fe72fb0b63 Signed-off-by: sungwook79.park --- inc/w-input-emoticon.h | 3 +- org.tizen.inputdelegator.xml | 2 +- po/en_US.po | 5 + res/edje/w-input-stt.edc | 220 ++++++++++- src/w-input-emoticon.cpp | 915 ++++++++++++++++++++++++++++++++++++++----- src/w-input-selector.cpp | 3 +- 6 files changed, 1039 insertions(+), 109 deletions(-) diff --git a/inc/w-input-emoticon.h b/inc/w-input-emoticon.h index 45ede7b..709fd76 100755 --- a/inc/w-input-emoticon.h +++ b/inc/w-input-emoticon.h @@ -16,6 +16,7 @@ #ifndef W_INPUT_EMOTICON_H_ #define W_INPUT_EMOTICON_H_ -void ise_show_emoticon_popup_rotary(void *data); +void ise_show_emoticon_list(void *data); + #endif /* W_INPUT_EMOTICON_H_ */ diff --git a/org.tizen.inputdelegator.xml b/org.tizen.inputdelegator.xml index e0dd87d..87d0348 100755 --- a/org.tizen.inputdelegator.xml +++ b/org.tizen.inputdelegator.xml @@ -2,7 +2,7 @@ - + w-input-selector.png diff --git a/po/en_US.po b/po/en_US.po index 27d5438..8f90a0a 100644 --- a/po/en_US.po +++ b/po/en_US.po @@ -256,3 +256,8 @@ msgstr "Gear Input" msgid "WDS_WMGR_POP_MAKE_SURE_THE_PS_APP_IS_ACTIVE_ON_YOUR_PHONE" msgstr "Make sure the %s app is active on your phone." +msgid "IDS_IME_HEADER_EMOJIS_ABB" +msgstr "Emojis" + +msgid "IDS_IME_HEADER_RECENT_M_RECETLY_SENT_EMOJIS_ABB" +msgstr "Recent" diff --git a/res/edje/w-input-stt.edc b/res/edje/w-input-stt.edc index 8eda165..b123590 100755 --- a/res/edje/w-input-stt.edc +++ b/res/edje/w-input-stt.edc @@ -1,6 +1,7 @@ #include "w-input-stt-button.edc" #define VOICE_CANDIDATE_AREA_HEIGHT 56 +#define BUTTON_TEXT_SIZE_INC 85 collections { @@ -436,22 +437,31 @@ collections styles { - style { name, "textblock_style"; - base, "font=Tizen:style=Regular font_size=36 align=center color=#FFFFFF text_class=text_class wrap=word ellipsis=1.0"; - tag, "br" "\n"; - tag, "ps" "ps"; - tag, "hilight" "+ font=Tizen:style=Bold"; - tag, "b" "+ font=Tizen:style=Bold"; - tag, "tab" "\t"; - } - style { name, "textblock_style_bottom"; - base, "font=Tizen:style=Regular font_size=36 align=center color=#FFFFFF text_class=text_class wrap=word ellipsis=1.0"; - tag, "br" "\n"; - tag, "ps" "ps"; - tag, "hilight" "+ font=Tizen:style=Bold"; - tag, "b" "+ font=Tizen:style=Bold"; - tag, "tab" "\t"; - } + style { name, "textblock_style"; + base, "font=Tizen:style=Regular font_size=36 align=center color=#FFFFFF text_class=text_class wrap=word ellipsis=1.0"; + tag, "br" "\n"; + tag, "ps" "ps"; + tag, "hilight" "+ font=Tizen:style=Bold"; + tag, "b" "+ font=Tizen:style=Bold"; + tag, "tab" "\t"; + } + style { name, "textblock_style_bottom"; + base, "font=Tizen:style=Regular font_size=36 align=center color=#FFFFFF text_class=text_class wrap=word ellipsis=1.0"; + tag, "br" "\n"; + tag, "ps" "ps"; + tag, "hilight" "+ font=Tizen:style=Bold"; + tag, "b" "+ font=Tizen:style=Bold"; + tag, "tab" "\t"; + } + style { name: "button_general_text_dim"; + base: "font=Tizen:style=Regular font_size="BUTTON_TEXT_SIZE_INC" align=center color=#FFFFFF ellipsis=0.0 wrap=mixed"; + } + style { name: "button_general_text_press"; + base: "font=Tizen:style=Regular font_size="BUTTON_TEXT_SIZE_INC" align=center color=#888888 ellipsis=0.0 wrap=mixed"; + } + style { name: "button_general_text_normal"; + base: "font=Tizen:style=Regular font_size="BUTTON_TEXT_SIZE_INC" align=center color=#FFFFFF ellipsis=0.0 wrap=mixed"; + } } group @@ -1947,6 +1957,184 @@ collections } } + group { name: "elm/button/base/emoticon"; + + script { + public mouse_down = 0; + public multi_down = 0; + } + parts { + part { name: "bg"; + type: SPACER; + scale: 1; + description { state: "default" 0.0; + min: 0 0; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + } + } + part { name: "padding_left_top"; + type: SPACER; + scale: 1; + description { state: "default" 0.0; + align: 0.0 0.0; + rel2.relative: 0.0 0.0; + min: 0 0; + fixed: 1 1; + //visible: 1; + //color: 255 0 0 100; + } + } + part { name: "padding_right_bottom"; + type: SPACER; + scale: 1; + description { state: "default" 0.0; + align: 1.0 1.0; + rel1.relative: 1.0 1.0; + min: 0 0; + fixed: 1 1; + //visible: 1; + //color: 0 255 0 100; + } + } + part { name: "elm.text"; + type: TEXTBLOCK; + mouse_events: 0; + scale: 1; + description { state: "default" 0.0; + fixed: 1 1; + rel1 { + relative: 1.0 1.0; + to: "padding_left_top"; + } + rel2 { + relative: 0.0 0.0; + to: "padding_right_bottom"; + } + text { + max: 1 0; + style: "button_general_text_normal"; + } + } + description { state: "disabled" 0.0; + inherit: "default" 0.0; + text.style: "button_general_text_dim"; + } + description { state: "pressed" 0.0; + inherit: "default" 0.0; + text.style: "button_general_text_press"; + } + } + part { name: "event"; + type: RECT; + scale: 1; + description { state: "default" 0.0; + color: 0 0 0 0; + rel1.to: "bg"; + rel2.to: "bg"; + } + } + } + programs { + program { name: "pressed"; + signal: "mouse,down,1*"; + source: "event"; + script { + if ((get_int(multi_down) == 0) && (get_int(mouse_down) == 0)) + { + set_int(mouse_down, 1); + run_program(PROGRAM:"button_press1"); + } + } + } + program { name: "button_press1"; + script { + new st[31]; + new Float:vl; + get_state(PART:"bg", st, 30, vl); + if (strcmp(st, "disabled")) { + set_state(PART:"bg", "pressed", 0.0); + set_state(PART:"elm.text", "pressed", 0.0); + emit("elm,action,press", ""); + } + } + } + program { name: "unpressed"; + signal: "mouse,up,1"; + source: "event"; + script { + if (get_int(mouse_down) == 1) { + set_int(mouse_down, 0); + run_program(PROGRAM:"button_unpress1"); + } + } + } + program { name: "button_unpress1"; + script { + new st[31]; + new Float:vl; + get_state(PART:"bg", st, 30, vl); + if (strcmp(st, "disabled")) { + set_state(PART:"bg", "default", 0.0); + set_state(PART:"elm.text", "default", 0.0); + emit("elm,action,unpress", ""); + } + } + } + program { name: "touch_snd"; + signal: "mouse,clicked,1"; + source: "event"; + script { + new st[31]; + new Float:vl; + if (get_int(multi_down) == 0) { + get_state(PART:"bg", st, 30, vl); + if (strcmp(st, "disabled")) { + run_program(PROGRAM:"play_sample"); + emit("elm,action,click", ""); + } + } + } + } + program { + name: "play_sample"; + action: RUN_PLUGIN "touch_sound"; + } + program { name: "disable"; + signal: "elm,state,disabled"; + source: "elm"; + action: STATE_SET "disabled" 0.0; + target: "bg"; + target: "elm.text"; + } + program { name: "enable"; + signal: "elm,state,enabled"; + source: "elm"; + action: STATE_SET "default" 0.0; + target: "bg"; + target: "elm.text"; + } + program { name: "multi_down"; + signal: "elm,action,multi,down"; + source: "elm"; + script { + set_int(multi_down, 1); + } + } + program { name: "multi_up"; + signal: "elm,action,multi,up"; + source: "elm"; + script { + set_int(multi_down, 0); + } + } + } + } + #define NAVIFRAME_VIEW_TRANS_TIME 0.4 //time for push and pop #define NAVIFRAME_TITLE_TRANS_TIME 0.5 //Title transition time #define NAVIFRAME_TITLE_EXPAND_TRANS_TIME 0.5 //Title Expansion transition time diff --git a/src/w-input-emoticon.cpp b/src/w-input-emoticon.cpp index aec6abf..e3b9b9d 100755 --- a/src/w-input-emoticon.cpp +++ b/src/w-input-emoticon.cpp @@ -14,155 +14,892 @@ * limitations under the License. */ -#include +#include #include #include +#include + +#include +#include #include "Debug.h" #include "w-input-selector.h" -#define EMOTICON_CNT 27 +#define RECENT_EMOJI_LIST "recent_emoji_list" + +#define EMOTICON_CNT 180 +#define RECENT_CNT 9 + +extern App_Data* app_data; + +static int is_content_reuse_on = 0; + using namespace std; +vector recent_emoji_list; + typedef struct { int code; - const char* name; + char* name; }Emoticon; +static Elm_Object_Item *it_emoticon_empty = NULL; +static Elm_Object_Item *it_emoticon_recent_group = NULL; +static Elm_Object_Item *it_emoticon_emoji_group = NULL; +static Elm_Object_Item *it_last = NULL; + +static Elm_Genlist_Item_Class *itc_emoticon = NULL; + +#define INITAL_ITEM_UNIT 24 +#define LOADING_ITEM_UNIT 27 +static int loading_done_for_item = 0; +Ecore_Timer *lazy_loading_timer_for_items = NULL; + +#define INITAL_CONTENT_UNIT 51 +#define LOADING_CONTENT_UNIT 9 +static int loading_done_for_contents = 0; +Ecore_Timer *lazy_loading_timer_for_contents = NULL; + + +typedef struct emoticon_content +{ + int index; + Evas_Object *content; + int used; +} emoticon_content_s; + +static emoticon_content_s emoticon_contents_pool[EMOTICON_CNT] = { 0, }; +static emoticon_content_s emoticon_recents_pool[RECENT_CNT] = { 0, }; + + Emoticon emoticon_info[EMOTICON_CNT] = { - {0x1f44c, "IDS_IME_BODY_OK_HAND_SIGN_M_EMOTICON_NAME_TTS"}, - {0x1f44d, "IDS_IME_BODY_THUMBS_UP_SIGN_M_EMOTICON_NAME"}, - {0x1f44e, "IDS_IME_BODY_THUMBS_DOWN_SIGN_M_EMOTICON_NAME"}, - {0x1f604, "IDS_IME_BODY_SMILING_FACE_WITH_OPEN_MOUTH_AND_SMILING_EYES_M_EMOTICON_NAME"}, - {0x1f606, "IDS_IME_BODY_SMILING_FACE_WITH_OPEN_MOUTH_AND_TIGHTLY_CLOSED_EYES_M_EMOTICON_NAME"}, - {0x1f60a, "IDS_IME_BODY_SMILING_FACE_WITH_SMILING_EYES_M_EMOTICON_NAME"}, - {0x1f60d, "IDS_IME_BODY_SMILING_FACE_WITH_HEART_SHAPED_EYES_M_EMOTICON_NAME"}, - {0x1f61a, "IDS_IME_BODY_KISSING_FACE_WITH_CLOSED_EYES_M_EMOTICON_NAME"}, - {0x1f61c, "IDS_IME_BODY_FACE_WITH_STUCK_OUT_TONGUE_AND_WINKING_EYE_M_EMOTICON_NAME"}, - {0x1f620, "IDS_IME_BODY_ANGRY_FACE_M_EMOTICON_NAME"}, - {0x1f621, "IDS_IME_BODY_POUTING_FACE_M_EMOTICON_NAME"}, - {0x1f622, "IDS_IME_BODY_CRYING_FACE_M_EMOTICON_NAME"}, - {0x1f624, "IDS_IME_BODY_FACE_WITH_LOOK_OF_TRIUMPH_M_EMOTICON_NAME"}, - {0x1f625, "IDS_IME_BODY_DISAPPOINTED_BUT_RELIEVED_FACE_M_EMOTICON_NAME"}, - {0x1f62a, "IDS_IME_BODY_SLEEPY_FACE_M_EMOTICON_NAME"}, - {0x1f62b, "IDS_IME_BODY_TIRED_FACE_M_EMOTICON_NAME"}, - {0x1f631, "IDS_IME_BODY_FACE_SCREAMING_IN_FEAR_M_EMOTICON_NAME"}, - {0x1f632, "IDS_IME_BODY_ASTONISHED_FACE_M_EMOTICON_NAME"}, - {0x1f637, "IDS_IME_BODY_FACE_WITH_MEDICAL_MASK_M_EMOTICON_NAME"}, - {0x1f495, "IDS_IME_BODY_TWO_HEARTS_M_EMOTICON_NAME"}, - {0x1f43d, "IDS_IME_BODY_PIG_NOSE_M_EMOTICON_NAME"}, - {0x1f415, "IDS_IME_BODY_DOG_M_EMOTICON_NAME"}, - {0x1f408, "IDS_IME_BODY_CAT_M_EMOTICON_NAME"}, - {0x1f414, "IDS_IME_BODY_CHICKEN_M_EMOTICON_NAME"}, - {0x1f433, "IDS_IME_BODY_SPOUTING_WHALE_M_EMOTICON_NAME"}, - {0x1f43c, "IDS_IME_BODY_PANDA_FACE_M_EMOTICON_NAME"}, - {0x1f42f, "IDS_IME_BODY_TIGER_FACE_M_EMOTICON_NAME"}, + {0x1f600, ""}, + {0x1f601, ""}, + {0x1f602, ""}, + {0x1f603, ""}, + {0x1f604, ""}, + {0x1f605, ""}, + {0x1f606, ""}, + {0x1f609, ""}, + {0x1f60a, ""}, + {0x1f60b, ""}, + {0x1f60e, ""}, + {0x1f60d, ""}, + {0x1f618, ""}, + {0x1f617, ""}, + {0x1f619, ""}, + {0x1f61a, ""}, + {0x263a, ""}, + {0x1f642, ""}, + {0x1f917, ""}, + {0x1f607, ""}, + {0x1f914, ""}, + {0x1f610, ""}, + {0x1f611, ""}, + {0x1f636, ""}, + {0x1f644, ""}, + {0x1f60f, ""}, + {0x1f623, ""}, + {0x1f625, ""}, + {0x1f62e, ""}, + {0x1f910, ""}, + {0x1f62f, ""}, + {0x1f634, ""}, + {0x1f62a, ""}, + {0x1f62b, ""}, + {0x1f60c, ""}, + {0x1f913, ""}, + {0x1f61b, ""}, + {0x1f61c, ""}, + {0x1f61d, ""}, + {0x1f641, ""}, + {0x1f612, ""}, + {0x1f613, ""}, + {0x1f614, ""}, + {0x1f615, ""}, + {0x1f616, ""}, + {0x1f643, ""}, + {0x1f637, ""}, + {0x1f912, ""}, + {0x1f915, ""}, + {0x1f911, ""}, + {0x1f632, ""}, + {0x1f61e, ""}, + {0x1f61f, ""}, + {0x1f624, ""}, + {0x1f622, ""}, + {0x1f62d, ""}, + {0x1f626, ""}, + {0x1f627, ""}, + {0x1f628, ""}, + {0x1f629, ""}, + {0x1f62c, ""}, + {0x1f630, ""}, + {0x1f631, ""}, + {0x1f633, ""}, + {0x1f635, ""}, + {0x1f621, ""}, + {0x1f620, ""}, + {0x1f608, ""}, + {0x1f648, ""}, + {0x1f649, ""}, + {0x1f64a, ""}, + {0x1f448, ""}, + {0x1f449, ""}, + {0x261d, ""}, + {0x1f446, ""}, + {0x1f595, ""}, + {0x1f447, ""}, + {0x270c, ""}, + {0x1f596, ""}, + {0x1f918, ""}, + {0x1f591, ""}, + {0x1f590, ""}, + {0x270a, ""}, + {0x270b, ""}, + {0x1f44a, ""}, + {0x1f44c, ""}, + {0x1f44d, ""}, + {0x1f44e, ""}, + {0x1f592, ""}, + {0x1f593, ""}, + {0x1f44b, ""}, + {0x1f44f, ""}, + {0x1f450, ""}, + {0x1f493, ""}, + {0x1f494, ""}, + {0x1f495, ""}, + {0x1f496, ""}, + {0x1f497, ""}, + {0x1f49d, ""}, + {0x1f49e, ""}, + {0x1f49f, ""}, + {0x2763, ""}, + {0x1f35e, ""}, + {0x1f9c0, ""}, + {0x1f356, ""}, + {0x1f357, ""}, + {0x1f354, ""}, + {0x1f35f, ""}, + {0x1f355, ""}, + {0x1f32d, ""}, + {0x1f32e, ""}, + {0x1f32f, ""}, + {0x1f37f, ""}, + {0x1f372, ""}, + {0x1f371, ""}, + {0x1f358, ""}, + {0x1f359, ""}, + {0x1f35a, ""}, + {0x1f35c, ""}, + {0x1f35b, ""}, + {0x1f35d, ""}, + {0x1f360, ""}, + {0x1f362, ""}, + {0x1f363, ""}, + {0x1f364, ""}, + {0x1f365, ""}, + {0x1f361, ""}, + {0x1f366, ""}, + {0x1f368, ""}, + {0x1f367, ""}, + {0x1f369, ""}, + {0x1f36a, ""}, + {0x1f382, ""}, + {0x1f370, ""}, + {0x1f36b, ""}, + {0x1f36c, ""}, + {0x1f36d, ""}, + {0x1f36e, ""}, + {0x1f36f, ""}, + {0x1f37c, ""}, + {0x2615, ""}, + {0x1f375, ""}, + {0x1f376, ""}, + {0x1f37e, ""}, + {0x1f377, ""}, + {0x1f378, ""}, + {0x1f379, ""}, + {0x1f37a, ""}, + {0x1f37b, ""}, + {0x1f383, ""}, + {0x1f384, ""}, + {0x1f388, ""}, + {0x1f389, ""}, + {0x1f38a, ""}, + {0x26bd, ""}, + {0x26be, ""}, + {0x1f3c0, ""}, + {0x1f3c8, ""}, + {0x1f3c9, ""}, + {0x1f3be, ""}, + {0x1f3b1, ""}, + {0x1f3b3, ""}, + {0x26f3, ""}, + {0x26f8, ""}, + {0x1f3a3, ""}, + {0x1f3bf, ""}, + {0x1f3cf, ""}, + {0x1f3d0, ""}, + {0x1f3d1, ""}, + {0x1f3d2, ""}, + {0x1f3d3, ""}, + {0x1f3f8, ""}, + {0x1f3af, ""}, + {0x1f3b2, ""}, + {0x1f3df, ""}, + {0x1f3db, ""}, + {0x1f3e0, ""}, + {0x1f3e2, ""}, + {0x1f3e5, ""}, + {0x1f3eb, ""}, }; -const char * get_emoticon_file_name(int index) -{ - static string path = get_resource_path() + string("images/u00000.png"); - int ipos = path.size()-9; - char str_emoticon_code[10] = {0}; - snprintf(str_emoticon_code, sizeof(str_emoticon_code), "%x", emoticon_info[index].code); - path.erase(ipos, 5); - path.insert(ipos, str_emoticon_code); - return path.c_str(); +static Eina_Bool _custom_back_cb(void *data, Elm_Object_Item *it) +{ + _back_to_genlist_for_selector(); + return EINA_TRUE; } -static Eina_Bool _custom_back_cb(void *data, Elm_Object_Item *it) + +//---------------------------------------------------------------------------------------// + +static Eina_Bool _custom_back_cb2(void *data, Elm_Object_Item *it) { + PRINTFUNC(DLOG_DEBUG, ""); + + if (is_content_reuse_on) { + int i; + + if (lazy_loading_timer_for_items != NULL) { + ecore_timer_del(lazy_loading_timer_for_items); + lazy_loading_timer_for_items = NULL; + } + + if (lazy_loading_timer_for_contents != NULL) { + ecore_timer_del(lazy_loading_timer_for_contents); + lazy_loading_timer_for_contents = NULL; + } + + //Recent EMOTICONS : the recent emoiton need to be updated whenever emoticon view is generated, so deleted here. + for (i=0;i< RECENT_CNT;i++) + { + if (emoticon_recents_pool[i].used == 0 && emoticon_recents_pool[i].content) { + evas_object_del(emoticon_recents_pool[i].content); + } + emoticon_recents_pool[i].content = NULL; + } + } + _back_to_genlist_for_selector(); return EINA_TRUE; } -static Eina_Bool -_rotary_selector_rotary_cb(void *data, Evas_Object *obj, Eext_Rotary_Event_Info *info) + +void get_recent_emoticons(vector &emoticon_list) { - PRINTFUNC(DLOG_DEBUG, "%s", __func__); + int ret = PREFERENCE_ERROR_NONE; + char *str = NULL; + + ret = preference_get_string(RECENT_EMOJI_LIST, &str); + if (PREFERENCE_ERROR_NONE != ret) { + PRINTFUNC(DLOG_ERROR, "preference_get_string error!(%d)", ret); + } + + emoticon_list.clear(); + + PRINTFUNC(DLOG_DEBUG, "str = %s", str); + + if (str != NULL) { + char *tok; + tok = strtok(str, ","); + while (tok != NULL) { + PRINTFUNC(DLOG_DEBUG, "tok = %s", tok); + emoticon_list.push_back(strtol(tok, (char **)NULL, 10)); + tok = strtok(NULL, ","); + } + } - if (info->direction == EEXT_ROTARY_DIRECTION_CLOCKWISE){ - evas_object_smart_callback_call(obj, "item,selected", (void*)data); - eext_rotary_object_event_callback_del(obj, _rotary_selector_rotary_cb); - } + if (str) + free(str); - return ECORE_CALLBACK_PASS_ON; + return; } -static void _rotary_selector_item_clicked(void *data, Evas_Object *obj, void *event_info) +void set_recent_emoticons(vector &emoticon_list, int val) { - PRINTFUNC(DLOG_DEBUG, "%s", __func__); - App_Data* ad = (App_Data*) data; - if (!ad) - return; + int i; + int ret = PREFERENCE_ERROR_NONE; + + if (emoticon_list.size() > 0) { + for (i = 0; i < emoticon_list.size(); i++) { + PRINTFUNC(DLOG_DEBUG, "%d == %d", emoticon_list.at(i), val); - Eext_Object_Item *selected_item = (Eext_Object_Item *)event_info; - Eina_List *rotary_selector_list = (Eina_List *)eext_rotary_selector_items_get(obj); + if (emoticon_list.at(i) == val) { + emoticon_list.erase(emoticon_list.begin()+i); + break; + } + } - int i = 0; - Eina_List *l = rotary_selector_list; - Eext_Object_Item *item = (Eext_Object_Item *)eina_list_data_get(l); + if (emoticon_list.size() >= RECENT_CNT) { + emoticon_list.erase(emoticon_list.end()); + } + } + + emoticon_list.insert(emoticon_list.begin(), val); + + string stored; + char str[10] = {0, }; - for (i = 0; l != NULL; i++) { - if (selected_item == item) - break; + for (i = 0; i < emoticon_list.size(); i++) { + snprintf(str, sizeof(str), "%d", emoticon_list.at(i)); + stored += str; + if (i+1 != emoticon_list.size()) + stored += ","; + } + + PRINTFUNC(DLOG_DEBUG, "%s", stored.c_str()); - l = eina_list_next(l); - item = (Eext_Object_Item *)eina_list_data_get(l); + ret = preference_set_string(RECENT_EMOJI_LIST, stored.c_str()); + if (PREFERENCE_ERROR_NONE != ret) { + PRINTFUNC(DLOG_ERROR, "preference_set_string error!(%d)", ret); } +} + +static void _emoticon_item_clicked_cb(void *data, Evas_Object * obj, void *event_info) +{ + int index = (int)data; + + PRINTFUNC(DLOG_DEBUG, "index = %d", index); + + // store in recents list + set_recent_emoticons(recent_emoji_list, index); int length; - const Eina_Unicode unicode_event[2] = { (unsigned int)emoticon_info[i].code, 0 }; + const Eina_Unicode unicode_event[2] = { emoticon_info[index].code, 0 }; char* utf_8 = eina_unicode_unicode_to_utf8(unicode_event, &length); reply_to_sender_by_callback((const char*)utf_8, "emoticon"); - PRINTFUNC(SECURE_DEBUG, "[%d]%s", i, utf_8); + PRINTFUNC(SECURE_DEBUG, "[%d]%s", index, utf_8); if (utf_8) free(utf_8); - if(ad->reply_type == REPLY_APP_NORMAL) - elm_exit(); + elm_exit(); +} + +Evas_Object* get_emoticon_button(Evas_Object* parent, int index){ + if (parent == NULL) + return NULL; + + Evas_Object* btn = elm_button_add(parent); + elm_object_style_set(btn, "emoticon"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL); + + int length; + const Eina_Unicode unicode_event[2] = { emoticon_info[index].code, 0 }; + char* utf_8 = eina_unicode_unicode_to_utf8(unicode_event, &length); + elm_object_part_text_set(btn, "elm.text", utf_8); + + if (utf_8) + free(utf_8); + + evas_object_layer_set(btn, 32000); + + evas_object_smart_callback_add(btn, "clicked", _emoticon_item_clicked_cb, (void *)index); + + return btn; } -static void _rotary_selector_item_selected(void *data, Evas_Object *obj, void *event_info) +Evas_Object* get_recent_emoticon_button(Evas_Object* parent, int index){ + if (parent == NULL) + return NULL; + + Evas_Object* btn = elm_button_add(parent); + elm_object_style_set(btn, "emoticon"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL); + + int length; + const Eina_Unicode unicode_event[2] = { emoticon_info[recent_emoji_list.at(index)].code, 0 }; + char* utf_8 = eina_unicode_unicode_to_utf8(unicode_event, &length); + elm_object_part_text_set(btn, "elm.text", utf_8); + + evas_object_data_set(btn, "index", (void*) recent_emoji_list.at(index)); + + if (utf_8) + free(utf_8); + + evas_object_layer_set(btn, 32000); + evas_object_smart_callback_add(btn, "clicked", _emoticon_item_clicked_cb, (void*) recent_emoji_list.at(index)); + + return btn; +} + +static void _emoticon_gl_lang_changed(void *data, Evas_Object *obj, void *event_info) { - PRINTFUNC(DLOG_DEBUG, "%s", __func__); + elm_genlist_realized_items_update(obj); } -void ise_show_emoticon_popup_rotary(void *data) +static char * __emoticon_gl_text_get(void *data, Evas_Object *obj, const char *part) +{ + //PRINTFUNC(DLOG_DEBUG,"part = %s", part); + + const char* str = (const char*) data; + if (!str) + return NULL; + + if (!strcmp(part, "elm.text")) { + //PRINTFUNC(DLOG_DEBUG,"str = %s", str); + return strdup(gettext(str)); + } + return NULL; +} + +static void _emoticon_gl_content_unswallowed_cb(void *data, Evas_Object *obj, void *event_info) +{ + Elm_Object_Item *it = (Elm_Object_Item *)event_info; + + const Elm_Genlist_Item_Class *itc = elm_genlist_item_item_class_get(it); + +// PRINTFUNC(DLOG_DEBUG,"%s - stype[%s]", __func__, itc->item_style); + if (!strcmp(itc->item_style, "3button_flat")) { + int index = (int)elm_object_item_data_get(it); + //PRINTFUNC(DLOG_DEBUG,"it = %p", it); + PRINTFUNC(DLOG_DEBUG, "index = %d %d %d", index, index+1, index+2); + + if (index < EMOTICON_CNT) { + emoticon_contents_pool[index].used = 0; + } + if (index + 1 < EMOTICON_CNT) { + emoticon_contents_pool[index+1].used = 0; + } + if (index + 2 < EMOTICON_CNT) { + emoticon_contents_pool[index+2].used = 0; + } + } else if (!strcmp(itc->item_style, "3button_flat_recent")) { + int index = (int)elm_object_item_data_get(it); + //PRINTFUNC(DLOG_DEBUG,"index = %d",index); + + if (index < recent_emoji_list.size()) { + emoticon_recents_pool[index].used = 0; + } + if (index + 1 < recent_emoji_list.size()) { + emoticon_recents_pool[index+1].used = 0; + } + if (index + 2 < recent_emoji_list.size()) { + emoticon_recents_pool[index+2].used = 0; + } + } +} + +static Evas_Object * __emoticon_gl_recent_content_get(void *data, Evas_Object *obj, const char *part) +{ + if (is_content_reuse_on) { + int index = (int)data; + int new_index = 0; + + //PRINTFUNC(DLOG_DEBUG,"%s %d", part, index); + if (!strcmp(part, "elm.icon.1") || (!strcmp(part, "elm.icon.2")) || (!strcmp(part, "elm.icon.3"))) { + if (!strcmp(part, "elm.icon.1")) { + if (index >= recent_emoji_list.size()) return NULL; + new_index = index; + } else if (!strcmp(part, "elm.icon.2")) { + if (index + 1 >= recent_emoji_list.size()) return NULL; + new_index = index + 1; + } else if (!strcmp(part, "elm.icon.3")) { + if (index + 2 >= recent_emoji_list.size()) return NULL; + new_index = index + 2; + } + + Evas_Object* btn = NULL; + btn = (Evas_Object*)emoticon_recents_pool[new_index].content; + emoticon_recents_pool[new_index].used = 1; + return btn; + } else if (!strcmp(part, "base")) { + Evas_Object* btn = elm_button_add(obj); + elm_object_style_set(btn, "ime/transparent"); + return btn; + } + } else { + int index = (int)data; + int new_index = 0; + + // PRINTFUNC(DLOG_DEBUG,"%s %d", part, index); + if (!strcmp(part, "elm.icon.1") || (!strcmp(part, "elm.icon.2")) || (!strcmp(part, "elm.icon.3"))) { + if (!strcmp(part, "elm.icon.1")) { + if (index >= recent_emoji_list.size()) return NULL; + new_index = index; + } else if (!strcmp(part, "elm.icon.2")) { + if (index + 1 >= recent_emoji_list.size()) return NULL; + new_index = index + 1; + } else if (!strcmp(part, "elm.icon.3")) { + if (index + 2 >= recent_emoji_list.size()) return NULL; + new_index = index + 2; + } + return get_recent_emoticon_button(obj, new_index); + } else if (!strcmp(part, "base")) { + Evas_Object* btn = elm_button_add(obj); + elm_object_style_set(btn, "ime/transparent"); + return btn; + } + } + return NULL; +} + +static Evas_Object * __emoticon_gl_emoticon_content_get(void *data, Evas_Object *obj, const char *part) +{ + //PRINTFUNC(DLOG_DEBUG,"%s", __func__); + + if (is_content_reuse_on) { + int index = (int)data; + int new_index = 0; + + if (!strcmp(part, "elm.icon.1") || (!strcmp(part, "elm.icon.2")) || (!strcmp(part, "elm.icon.3"))) { + if (!strcmp(part, "elm.icon.1")) { + if (index >= EMOTICON_CNT) return NULL; + new_index = index; + } else if (!strcmp(part, "elm.icon.2")) { + if (index + 1 >= EMOTICON_CNT) return NULL; + new_index = index + 1; + } else if (!strcmp(part, "elm.icon.3")) { + if (index + 2 >= EMOTICON_CNT) return NULL; + new_index = index + 2; + } + + Evas_Object* btn = NULL; + btn = (Evas_Object*)emoticon_contents_pool[new_index].content; + emoticon_contents_pool[new_index].used = 1; +#if 0 + char utf_8[10] = {0, }; + snprintf(utf_8, sizeof(utf_8), "%d", new_index); + elm_object_part_text_set(btn, "elm.text", strdup(utf_8)); +#else + int length; + const Eina_Unicode unicode_event[2] = { emoticon_info[new_index].code, 0 }; + char* utf_8 = eina_unicode_unicode_to_utf8(unicode_event, &length); + elm_object_part_text_set(btn, "elm.text", utf_8); + evas_object_data_set(btn, "index", (void*)new_index); + + if (utf_8) + free(utf_8); +#endif + return btn; + + } else if (!strcmp(part, "base")) { + Evas_Object* btn = elm_button_add(obj); + elm_object_style_set(btn, "ime/transparent"); + return btn; + } + } else { + int index = (int)data; + int new_index = 0; + + if (!strcmp(part, "elm.icon.1") || (!strcmp(part, "elm.icon.2")) || (!strcmp(part, "elm.icon.3"))) { + if (!strcmp(part, "elm.icon.1")) { + if (index >= EMOTICON_CNT) return NULL; + new_index = index; + } else if (!strcmp(part, "elm.icon.2")) { + if (index + 1 >= EMOTICON_CNT) return NULL; + new_index = index + 1; + } else if (!strcmp(part, "elm.icon.3")) { + if (index + 2 >= EMOTICON_CNT) return NULL; + new_index = index + 2; + } + return get_emoticon_button(obj, new_index); + } else if (!strcmp(part, "base")) { + Evas_Object* btn = elm_button_add(obj); + elm_object_style_set(btn, "ime/transparent"); + return btn; + } + } + return NULL; +} + + +void _create_reusable_recents(Evas_Object *parent) +{ + if (!parent) { + PRINTFUNC(DLOG_ERROR, "parent is null"); + return; + } + + int i; + for (i = 0; i < recent_emoji_list.size(); i++ ) { + emoticon_recents_pool[i].index = i; + emoticon_recents_pool[i].content = get_recent_emoticon_button(parent, i); + emoticon_recents_pool[i].used = 0; + } +} + +static Eina_Bool _lazy_loader_cb_for_contents(void *data) +{ + Evas_Object *gl = (Evas_Object *)data; + if (!gl) { + PRINTFUNC(DLOG_ERROR, "gl is null"); + lazy_loading_timer_for_contents = NULL; + return ECORE_CALLBACK_CANCEL; + } + + if (loading_done_for_contents == EMOTICON_CNT) { + PRINTFUNC(DLOG_DEBUG, "lazy loading contents done"); + lazy_loading_timer_for_contents = NULL; + return ECORE_CALLBACK_CANCEL; + } + + int loading_top = 0; + if (loading_done_for_contents + LOADING_CONTENT_UNIT > EMOTICON_CNT) { + loading_top = EMOTICON_CNT; + } else { + loading_top = loading_done_for_contents + LOADING_CONTENT_UNIT; + } + + PRINTFUNC(DLOG_DEBUG, "_lazy_loader_cb_for_contents loading_done = %d", loading_done_for_contents); + + int i; + for (i = loading_done_for_contents; i < loading_top; i++) { + emoticon_contents_pool[i].index = i; + emoticon_contents_pool[i].used = 0; + + if (emoticon_contents_pool[i].content == NULL) { // reusable + emoticon_contents_pool[i].content = get_emoticon_button(gl, i); + } + } + + loading_done_for_contents = loading_top; + + return ECORE_CALLBACK_RENEW; +} + +void create_reusable_button(Evas_Object *parent) +{ + if (!parent) { + PRINTFUNC(DLOG_ERROR, "parent is null"); + return; + } + loading_done_for_contents = INITAL_CONTENT_UNIT; + + int i; + for (i = 0; i < INITAL_CONTENT_UNIT; i++ ) { + emoticon_contents_pool[i].index = i; + emoticon_contents_pool[i].used = 0; + + if (emoticon_contents_pool[i].content == NULL) { // reusable + emoticon_contents_pool[i].content = get_emoticon_button(parent, i); + } + } + + lazy_loading_timer_for_contents = ecore_timer_add(0.25, _lazy_loader_cb_for_contents, (void *)parent); +} + +static Eina_Bool _lazy_loader_cb_for_items(void *data) +{ + Evas_Object *gl = (Evas_Object *)data; + if (!gl) { + PRINTFUNC(DLOG_ERROR, "gl is null"); + lazy_loading_timer_for_items = NULL; + return ECORE_CALLBACK_CANCEL; + } + + if (loading_done_for_item == EMOTICON_CNT) { + PRINTFUNC(DLOG_DEBUG, "lazy loading item done"); + //elm_genlist_realized_items_update(gl); + elm_genlist_item_class_free(itc_emoticon); + lazy_loading_timer_for_items = NULL; + + return ECORE_CALLBACK_CANCEL; + } + + int loading_top = 0; + if (loading_done_for_item + LOADING_ITEM_UNIT > EMOTICON_CNT) { + loading_top = EMOTICON_CNT; + } else { + loading_top = loading_done_for_item + LOADING_ITEM_UNIT; + } + + if (loading_top > loading_done_for_contents) { + PRINTFUNC(DLOG_DEBUG, "Wait for content loading"); + return ECORE_CALLBACK_RENEW; + } + PRINTFUNC(DLOG_DEBUG, "_lazy_loader_cb_for_items loading_done_for_item = %d", loading_done_for_item); + + int i; + for (i = loading_done_for_item; i < loading_top; i++ ) { + if (i%3 == 0) + elm_genlist_item_append(gl, itc_emoticon, (void*)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, (void *)i); + } + + loading_done_for_item = loading_top; + return ECORE_CALLBACK_RENEW; +} + +void _create_reusable_contents(Evas_Object *gl){ + if (!gl) { + PRINTFUNC(DLOG_ERROR, "gl is null"); + return; + } + int i; + loading_done_for_item = INITAL_ITEM_UNIT; + + for (i = 0; i < INITAL_ITEM_UNIT; i++ ) { + if (i%3 == 0) + elm_genlist_item_append(gl, itc_emoticon, (void*)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, (void *)i); + } + + lazy_loading_timer_for_items = ecore_timer_add(0.1, _lazy_loader_cb_for_items, (void *)gl); +} + +Evas_Object* _create_emoticon_genlist(void* data) { PRINTFUNC(DLOG_DEBUG, "%s", __func__); App_Data* ad = (App_Data*) data; if (!ad) + return NULL; + + Evas_Object* genlist = elm_genlist_add(ad->naviframe); + if (NULL == genlist) + return NULL; + + Evas_Object* circle_object_genlist = eext_circle_object_genlist_add(genlist, ad->circle_surface); + eext_circle_object_genlist_scroller_policy_set(circle_object_genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO); + evas_object_data_set(genlist, "circle", (void *) circle_object_genlist); + eext_rotary_object_event_activated_set(circle_object_genlist, EINA_TRUE); + + evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(genlist); + + Elm_Object_Item *nf_emoticon_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, genlist, "empty"); + + elm_naviframe_item_pop_cb_set(nf_emoticon_item, _custom_back_cb2, ad); + + evas_object_smart_callback_add(genlist, "language,changed", _emoticon_gl_lang_changed, genlist); + + if (is_content_reuse_on) { + evas_object_smart_callback_add(genlist, "content,unswallowed", _emoticon_gl_content_unswallowed_cb, NULL); + } + + return genlist; +} + +void _update_emoticon_items(void *data) +{ + PRINTFUNC(DLOG_DEBUG, "%s", __func__); + Evas_Object* gl = (Evas_Object*) data; + if (!gl) return; + int i; + Elm_Object_Item *it = NULL; + Elm_Object_Item *first_it = NULL; + + Elm_Genlist_Item_Class * itc_dummy = elm_genlist_item_class_new(); + itc_dummy->item_style = "title"; + itc_dummy->func.text_get = NULL; + itc_dummy->func.content_get = NULL; + itc_dummy->func.state_get = NULL; + itc_dummy->func.del = NULL; - Evas_Object *rotary_selector = eext_rotary_selector_add(ad->naviframe); -// uxt_theme_object_replace_color(rotary_selector, "B01153", "AO0117"); - PRINTFUNC(DLOG_DEBUG, "replace color"); - for (int i = 0; i < EMOTICON_CNT; ++i) - { - Evas_Object *img = NULL; - Eext_Object_Item *item = eext_rotary_selector_item_append(rotary_selector); + Elm_Genlist_Item_Class *itc_group = elm_genlist_item_class_new(); - img = elm_image_add(rotary_selector); - elm_image_file_set(img, get_emoticon_file_name(i), NULL); - eext_rotary_selector_item_part_content_set(item, "item,bg_image", EEXT_ROTARY_SELECTOR_ITEM_STATE_NORMAL, img); + itc_group->item_style = "groupindex"; + itc_group->func.text_get = __emoticon_gl_text_get; + itc_group->func.content_get = NULL; + itc_group->func.state_get = NULL; + itc_group->func.del = NULL; - img = elm_image_add(rotary_selector); - elm_image_file_set(img, get_emoticon_file_name(i), NULL); - eext_rotary_selector_item_part_content_set(item, "selector,icon", EEXT_ROTARY_SELECTOR_ITEM_STATE_NORMAL, img); + Elm_Genlist_Item_Class *itc_recent = elm_genlist_item_class_new(); + if (is_content_reuse_on) { +// itc_recent->content_reusable = EINA_TRUE; } + itc_recent->item_style = "3button_flat_recent"; + itc_recent->func.text_get = NULL; + itc_recent->func.content_get = __emoticon_gl_recent_content_get; + itc_recent->func.state_get = NULL; + itc_recent->func.del = NULL; - evas_object_smart_callback_add(rotary_selector, "item,selected", _rotary_selector_item_selected, rotary_selector); - evas_object_smart_callback_add(rotary_selector, "item,clicked", _rotary_selector_item_clicked, (void*)ad); + itc_emoticon = elm_genlist_item_class_new(); + if (is_content_reuse_on) { +// itc_emoticon->content_reusable = EINA_TRUE; + } + itc_emoticon->item_style = "3button_flat"; + itc_emoticon->func.text_get = NULL; + itc_emoticon->func.content_get = __emoticon_gl_emoticon_content_get; + itc_emoticon->func.state_get = NULL; + itc_emoticon->func.del = NULL; - Elm_Object_Item *nf_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, rotary_selector, "empty"); - elm_naviframe_item_pop_cb_set(nf_item, _custom_back_cb, NULL); - eext_rotary_object_event_activated_set(rotary_selector, EINA_TRUE); + // dummy title for empty space + it_emoticon_empty = elm_genlist_item_append(gl, itc_dummy, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL); - PRINTFUNC(DLOG_DEBUG, "%s", __func__); + if (recent_emoji_list.size() > 0) { + if (is_content_reuse_on) { + _create_reusable_recents(gl); + } + + // Group Recents + it_emoticon_recent_group = elm_genlist_item_append(gl, itc_group, (void*)"IDS_IME_HEADER_RECENT_M_RECETLY_SENT_EMOJIS_ABB", NULL, ELM_GENLIST_ITEM_NONE, NULL, (void *)2); + elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + if (first_it == NULL) + first_it = it_emoticon_recent_group; + + PRINTFUNC(DLOG_DEBUG, "size = %d", recent_emoji_list.size()); + + for (i=0;i < recent_emoji_list.size();i=i+3) + { + it = elm_genlist_item_append(gl, itc_recent, (void*)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, (void *)i); + } + } + + // Group Emoticons + it_emoticon_emoji_group = elm_genlist_item_append(gl, itc_group, (void*)"IDS_IME_HEADER_EMOJIS_ABB", NULL, ELM_GENLIST_ITEM_NONE, NULL, (void *)2); + elm_genlist_item_select_mode_set(it, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); + if (first_it == NULL) + first_it = it_emoticon_emoji_group; + + if (is_content_reuse_on) { + _create_reusable_contents(gl); + } else { + // Emoticons + for (i=0;i< EMOTICON_CNT;i=i+3) { + it = elm_genlist_item_append(gl, itc_emoticon, (void*)i, NULL, ELM_GENLIST_ITEM_NONE, NULL, (void *)i); + it_last = it; + } + elm_genlist_item_class_free(itc_emoticon); + } + it = elm_genlist_item_next_get(first_it); + const Elm_Genlist_Item_Class *itc_temp = elm_genlist_item_item_class_get(it); + if (itc_temp == itc_group) { + it = elm_genlist_item_next_get(it); + } + elm_genlist_item_show(it, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE); + + elm_genlist_item_class_free(itc_recent); + elm_genlist_item_class_free(itc_group); + elm_genlist_item_class_free(itc_dummy); +} + +void ise_show_emoticon_list(void *data) +{ + App_Data* ad = (App_Data*) data; + if (!ad) + return; + + it_emoticon_empty = NULL; + it_emoticon_recent_group = NULL; + it_emoticon_emoji_group = NULL; + it_last = NULL; + + get_recent_emoticons(recent_emoji_list); + + Evas_Object* emoticon_list = NULL; + + emoticon_list = _create_emoticon_genlist(ad); + + if (is_content_reuse_on) { + create_reusable_button(ad->naviframe); // button object need to survive even if genlist is deleted. + } + _update_emoticon_items(emoticon_list); } diff --git a/src/w-input-selector.cpp b/src/w-input-selector.cpp index 8eb09bd..828c9a5 100755 --- a/src/w-input-selector.cpp +++ b/src/w-input-selector.cpp @@ -147,8 +147,7 @@ static void _emoticon_clicked_cb(void *data, Evas_Object * obj, void *event_info if(!ad) return; -// ise_show_emoticon_popup(ad); - ise_show_emoticon_popup_rotary(ad); + ise_show_emoticon_list(ad); } static void _keyboard_clicked_cb(void *data, Evas_Object * obj, void *event_info) -- 2.7.4