summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorAmitesh Singh <amitesh.sh@samsung.com>2014-02-18 23:40:48 +0900
committerDaniel Juyung Seo <seojuyung2@gmail.com>2014-02-26 01:26:22 +0900
commitf79ef2608d9bf633ccca2077bfd3fb1885a7da2d (patch)
tree85060cc64ca63d4528e0ad54ca28a79f28564143 /src/lib
parenteea1d9b3dc972be583259b8cccda91f644563723 (diff)
list: implemented widget item focus feature.
@feature Summary: # Added "item,focused" and "item,unfocused" smart callbacks. # Added elm_object_focused_item_get() in elm_widget # Added elm_object_item_focus_set and elm_object_item_focus_get() APIs for # Added one argument in existing _focus_highlight_geometry_get(...,is_next) This is required to find out previous and current widget item. # Added a elm_win function _focus_highlight_start() which starts the focus Test Plan: elementary_test->List Focus , List Horizontal Focus Reviewers: seoz, woohyun Reviewers Comments: SeoZ - there are some known bugs. we will actively fix them in a near future. CC: nirajkr Differential Revision: https://phab.enlightenment.org/D532
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/elm_focus.h45
-rw-r--r--src/lib/elm_list.c331
-rw-r--r--src/lib/elm_main.c19
-rw-r--r--src/lib/elm_widget.c151
-rw-r--r--src/lib/elm_widget.h63
-rw-r--r--src/lib/elm_widget_list.h5
-rw-r--r--src/lib/elm_win.c19
-rw-r--r--src/lib/elm_win_eo.h4
8 files changed, 566 insertions, 71 deletions
diff --git a/src/lib/elm_focus.h b/src/lib/elm_focus.h
index 44c241765..ea84cda40 100644
--- a/src/lib/elm_focus.h
+++ b/src/lib/elm_focus.h
@@ -317,3 +317,48 @@ EAPI Eina_Bool elm_object_focus_highlight_style_set(Evas_Object *obj, const c
317 */ 317 */
318EAPI const char *elm_object_focus_highlight_style_get(const Evas_Object *obj); 318EAPI const char *elm_object_focus_highlight_style_get(const Evas_Object *obj);
319 319
320/**
321 * Get the focused object item
322 *
323 * This returns the focused object item.
324 *
325 * @param obj The container object
326 * @return The focused item, or @c NULL if none
327 *
328 * The focused item can be unfocused with function
329 * elm_object_item_focus_set().
330 *
331 * see @elm_object_item_focus_set()
332 * see @elm_object_item_focus_get()
333 *
334 * @ingroup Focus
335 * @since 1.10
336 */
337EAPI Elm_Object_Item *elm_object_focused_item_get(const Evas_Object *obj);
338
339/**
340 * Set the object item focused
341 *
342 * @param it The object item
343 * @param focused The focused state
344 *
345 * @see elm_object_item_focus_get()
346 *
347 * @ingroup Focus
348 * @since 1.10
349 */
350EAPI void elm_object_item_focus_set(Elm_Object_Item *it, Eina_Bool focused);
351
352/**
353 * Get whether the @p it is focused or not.
354 *
355 * @param it The object item
356 * @return @c EINA_TRUE means item is focused. @c EINA_FALSE indicates
357 * it's not. If @p obj is @c NULL, @c EINA_FALSE is returned.
358 *
359 * @see elm_object_item_focus_set()
360 *
361 * @ingroup Focus
362 * @since 1.10
363 */
364EAPI Eina_Bool elm_object_item_focus_get(const Elm_Object_Item *it);
diff --git a/src/lib/elm_list.c b/src/lib/elm_list.c
index c91497808..12b66958b 100644
--- a/src/lib/elm_list.c
+++ b/src/lib/elm_list.c
@@ -29,6 +29,8 @@ static const char SIG_EDGE_RIGHT[] = "edge,right";
29static const char SIG_SWIPE[] = "swipe"; 29static const char SIG_SWIPE[] = "swipe";
30static const char SIG_HIGHLIGHTED[] = "highlighted"; 30static const char SIG_HIGHLIGHTED[] = "highlighted";
31static const char SIG_UNHIGHLIGHTED[] = "unhighlighted"; 31static const char SIG_UNHIGHLIGHTED[] = "unhighlighted";
32static const char SIG_ITEM_FOCUSED[] = "item,focused";
33static const char SIG_ITEM_UNFOCUSED[] = "item,unfocused";
32static const Evas_Smart_Cb_Description _smart_callbacks[] = { 34static const Evas_Smart_Cb_Description _smart_callbacks[] = {
33 {SIG_ACTIVATED, ""}, 35 {SIG_ACTIVATED, ""},
34 {SIG_CLICKED_DOUBLE, ""}, 36 {SIG_CLICKED_DOUBLE, ""},
@@ -42,6 +44,8 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = {
42 {SIG_SWIPE, ""}, 44 {SIG_SWIPE, ""},
43 {SIG_HIGHLIGHTED, ""}, 45 {SIG_HIGHLIGHTED, ""},
44 {SIG_UNHIGHLIGHTED, ""}, 46 {SIG_UNHIGHLIGHTED, ""},
47 {SIG_ITEM_FOCUSED, ""},
48 {SIG_ITEM_UNFOCUSED, ""},
45 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */ 49 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
46 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */ 50 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
47 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */ 51 {SIG_LAYOUT_FOCUSED, ""}, /**< handled by elm_layout */
@@ -97,12 +101,10 @@ _item_multi_select_up(Elm_List_Smart_Data *sd)
97 { 101 {
98 elm_list_item_selected_set(sd->last_selected_item, EINA_FALSE); 102 elm_list_item_selected_set(sd->last_selected_item, EINA_FALSE);
99 sd->last_selected_item = prev; 103 sd->last_selected_item = prev;
100 elm_list_item_show(sd->last_selected_item);
101 } 104 }
102 else 105 else
103 { 106 {
104 elm_list_item_selected_set(prev, EINA_TRUE); 107 elm_list_item_selected_set(prev, EINA_TRUE);
105 elm_list_item_show(prev);
106 } 108 }
107 return EINA_TRUE; 109 return EINA_TRUE;
108} 110}
@@ -122,12 +124,10 @@ _item_multi_select_down(Elm_List_Smart_Data *sd)
122 { 124 {
123 elm_list_item_selected_set(sd->last_selected_item, EINA_FALSE); 125 elm_list_item_selected_set(sd->last_selected_item, EINA_FALSE);
124 sd->last_selected_item = next; 126 sd->last_selected_item = next;
125 elm_list_item_show(sd->last_selected_item);
126 } 127 }
127 else 128 else
128 { 129 {
129 elm_list_item_selected_set(next, EINA_TRUE); 130 elm_list_item_selected_set(next, EINA_TRUE);
130 elm_list_item_show(next);
131 } 131 }
132 return EINA_TRUE; 132 return EINA_TRUE;
133} 133}
@@ -164,7 +164,6 @@ _item_single_select_up(Elm_List_Smart_Data *sd)
164 _all_items_unselect(sd); 164 _all_items_unselect(sd);
165 165
166 elm_list_item_selected_set(prev, EINA_TRUE); 166 elm_list_item_selected_set(prev, EINA_TRUE);
167 elm_list_item_show(prev);
168 167
169 return EINA_TRUE; 168 return EINA_TRUE;
170} 169}
@@ -189,7 +188,6 @@ _item_single_select_down(Elm_List_Smart_Data *sd)
189 _all_items_unselect(sd); 188 _all_items_unselect(sd);
190 189
191 elm_list_item_selected_set(next, EINA_TRUE); 190 elm_list_item_selected_set(next, EINA_TRUE);
192 elm_list_item_show(next);
193 191
194 return EINA_TRUE; 192 return EINA_TRUE;
195} 193}
@@ -197,9 +195,10 @@ _item_single_select_down(Elm_List_Smart_Data *sd)
197static Eina_Bool 195static Eina_Bool
198_elm_list_item_focus_set(Elm_List_Item *it, Elm_Focus_Direction dir, Eina_Bool h_mode) 196_elm_list_item_focus_set(Elm_List_Item *it, Elm_Focus_Direction dir, Eina_Bool h_mode)
199{ 197{
198 ELM_LIST_DATA_GET(WIDGET(it), sd);
200 if (!it) return EINA_FALSE; 199 if (!it) return EINA_FALSE;
201 200
202 if (!it->sd->focus_on_selection_enabled) return EINA_FALSE; 201 if (!sd->focus_on_selection_enabled) return EINA_FALSE;
203 202
204 int focus_objs = 0; 203 int focus_objs = 0;
205 Evas_Object *focus_chain[2]; 204 Evas_Object *focus_chain[2];
@@ -255,6 +254,70 @@ _elm_list_item_focus_set(Elm_List_Item *it, Elm_Focus_Direction dir, Eina_Bool h
255 return EINA_TRUE; 254 return EINA_TRUE;
256} 255}
257 256
257static Eina_Bool
258_item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
259{
260 ELM_LIST_DATA_GET_OR_RETURN_VAL(obj, sd, EINA_FALSE);
261 Elm_List_Item *it = NULL;
262
263 sd->prev_focused_item = sd->focused_item;
264 if (!sd->h_mode)
265 {
266 if ((dir == ELM_FOCUS_UP) || (dir == ELM_FOCUS_DOWN))
267 {
268 Eina_List *l = eina_list_data_find_list(sd->items, sd->focused_item);
269 if (sd->focused_item)
270 {
271 if (dir == ELM_FOCUS_DOWN)
272 it = (Elm_List_Item *)eina_list_data_get(eina_list_next(l));
273 else it = (Elm_List_Item *)eina_list_data_get(eina_list_prev(l));
274 if (!it)
275 return EINA_FALSE;
276 }
277 else
278 {
279 if (dir == ELM_FOCUS_DOWN)
280 it = (Elm_List_Item *)eina_list_data_get(sd->items);
281 else it = (Elm_List_Item *)eina_list_data_get(eina_list_last(sd->items));
282 }
283 if (elm_object_item_disabled_get((Elm_Object_Item *)it))
284 return EINA_TRUE;
285 elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
286 return EINA_TRUE;
287 }
288 else if ((dir == ELM_FOCUS_LEFT) || (dir == ELM_FOCUS_RIGHT))
289 return EINA_FALSE;
290 }
291 else
292 {
293 if ((dir == ELM_FOCUS_LEFT) || (dir == ELM_FOCUS_RIGHT))
294 {
295 Eina_List *l = eina_list_data_find_list(sd->items, sd->focused_item);
296 if (sd->focused_item)
297 {
298 if (dir == ELM_FOCUS_RIGHT)
299 it = (Elm_List_Item *)eina_list_data_get(eina_list_next(l));
300 else it = (Elm_List_Item *)eina_list_data_get(eina_list_prev(l));
301 if (!it)
302 return EINA_FALSE;
303 }
304 else
305 {
306 if (dir == ELM_FOCUS_RIGHT)
307 it = (Elm_List_Item *)eina_list_data_get(sd->items);
308 else it = (Elm_List_Item *)eina_list_data_get(eina_list_last(sd->items));
309 }
310 if (elm_object_item_disabled_get((Elm_Object_Item *)it))
311 return EINA_TRUE;
312 elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
313 return EINA_TRUE;
314 }
315 else if ((dir == ELM_FOCUS_UP) || (dir == ELM_FOCUS_DOWN))
316 return EINA_FALSE;
317 }
318 return EINA_FALSE;
319}
320
258static void 321static void
259_elm_list_smart_event(Eo *obj, void *_pd, va_list *list) 322_elm_list_smart_event(Eo *obj, void *_pd, va_list *list)
260{ 323{
@@ -295,17 +358,23 @@ _elm_list_smart_event(Eo *obj, void *_pd, va_list *list)
295 it = (Elm_List_Item *)elm_list_selected_item_get(obj); 358 it = (Elm_List_Item *)elm_list_selected_item_get(obj);
296 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_LEFT, sd->h_mode); 359 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_LEFT, sd->h_mode);
297 360
298 if ((sd->h_mode && !focused) && 361 if ((sd->h_mode && !focused))
299 (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && 362 {
300 (_item_multi_select_up(sd))) 363 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
301 || (_item_single_select_up(sd)))) 364 _item_multi_select_up(sd);
365 else
366 _item_single_select_up(sd);
367 }
368 if (_item_focused_next(obj, ELM_FOCUS_LEFT))
302 { 369 {
303 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; 370 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
304 if (ret) *ret = EINA_TRUE; 371 if (ret) *ret = EINA_TRUE;
305 return;
306 } 372 }
307 else 373 else
308 x -= step_x; 374 {
375 if (ret) *ret = EINA_FALSE;
376 }
377 return;
309 } 378 }
310 else if ((!strcmp(ev->key, "Right")) || 379 else if ((!strcmp(ev->key, "Right")) ||
311 ((!strcmp(ev->key, "KP_Right")) && !ev->string)) 380 ((!strcmp(ev->key, "KP_Right")) && !ev->string))
@@ -313,17 +382,23 @@ _elm_list_smart_event(Eo *obj, void *_pd, va_list *list)
313 it = (Elm_List_Item *)elm_list_selected_item_get(obj); 382 it = (Elm_List_Item *)elm_list_selected_item_get(obj);
314 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_RIGHT, sd->h_mode); 383 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_RIGHT, sd->h_mode);
315 384
316 if ((sd->h_mode && !focused) && 385 if (sd->h_mode && !focused)
317 (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && 386 {
318 (_item_multi_select_down(sd))) 387 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
319 || (_item_single_select_down(sd)))) 388 _item_multi_select_down(sd);
389 else
390 _item_single_select_down(sd);
391 }
392 if (_item_focused_next(obj, ELM_FOCUS_RIGHT))
320 { 393 {
321 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; 394 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
322 if (ret) *ret = EINA_TRUE; 395 if (ret) *ret = EINA_TRUE;
323 return;
324 } 396 }
325 else 397 else
326 x += step_x; 398 {
399 if (ret) *ret = EINA_FALSE;
400 }
401 return;
327 } 402 }
328 else if ((!strcmp(ev->key, "Up")) || 403 else if ((!strcmp(ev->key, "Up")) ||
329 ((!strcmp(ev->key, "KP_Up")) && !ev->string)) 404 ((!strcmp(ev->key, "KP_Up")) && !ev->string))
@@ -331,17 +406,23 @@ _elm_list_smart_event(Eo *obj, void *_pd, va_list *list)
331 it = (Elm_List_Item *)elm_list_selected_item_get(obj); 406 it = (Elm_List_Item *)elm_list_selected_item_get(obj);
332 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_UP, sd->h_mode); 407 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_UP, sd->h_mode);
333 408
334 if ((!sd->h_mode && !focused) && 409 if (!sd->h_mode && !focused)
335 (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && 410 {
336 (_item_multi_select_up(sd))) 411 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
337 || (_item_single_select_up(sd)))) 412 _item_multi_select_up(sd);
413 else
414 _item_single_select_up(sd);
415 }
416 if (_item_focused_next(obj, ELM_FOCUS_UP))
338 { 417 {
339 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; 418 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
340 if (ret) *ret = EINA_TRUE; 419 if (ret) *ret = EINA_TRUE;
341 return;
342 } 420 }
343 else 421 else
344 y -= step_y; 422 {
423 if (ret) *ret = EINA_FALSE;
424 }
425 return;
345 } 426 }
346 else if ((!strcmp(ev->key, "Down")) || 427 else if ((!strcmp(ev->key, "Down")) ||
347 ((!strcmp(ev->key, "KP_Down")) && !ev->string)) 428 ((!strcmp(ev->key, "KP_Down")) && !ev->string))
@@ -349,17 +430,23 @@ _elm_list_smart_event(Eo *obj, void *_pd, va_list *list)
349 it = (Elm_List_Item *)elm_list_selected_item_get(obj); 430 it = (Elm_List_Item *)elm_list_selected_item_get(obj);
350 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_DOWN, sd->h_mode); 431 Eina_Bool focused = _elm_list_item_focus_set(it, ELM_FOCUS_DOWN, sd->h_mode);
351 432
352 if ((!sd->h_mode && !focused) && 433 if (!sd->h_mode && !focused)
353 (((evas_key_modifier_is_set(ev->modifiers, "Shift")) && 434 {
354 (_item_multi_select_down(sd))) 435 if (evas_key_modifier_is_set(ev->modifiers, "Shift"))
355 || (_item_single_select_down(sd)))) 436 _item_multi_select_down(sd);
437 else
438 _item_single_select_down(sd);
439 }
440 if (_item_focused_next(obj, ELM_FOCUS_DOWN))
356 { 441 {
357 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; 442 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
358 if (ret) *ret = EINA_TRUE; 443 if (ret) *ret = EINA_TRUE;
359 return;
360 } 444 }
361 else 445 else
362 y += step_y; 446 {
447 if (ret) *ret = EINA_FALSE;
448 }
449 return;
363 } 450 }
364 else if ((!strcmp(ev->key, "Home")) || 451 else if ((!strcmp(ev->key, "Home")) ||
365 ((!strcmp(ev->key, "KP_Home")) && !ev->string)) 452 ((!strcmp(ev->key, "KP_Home")) && !ev->string))
@@ -920,6 +1007,52 @@ _elm_list_smart_theme(Eo *obj, void *_pd, va_list *list)
920} 1007}
921 1008
922static void 1009static void
1010_elm_list_item_focused(Elm_List_Item *it)
1011{
1012 ELM_LIST_DATA_GET(WIDGET(it), sd);
1013 Evas_Coord x, y, w, h, sx, sy, sw, sh;
1014 const char *focus_raise;
1015
1016 if ((sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) ||
1017 (it == (Elm_List_Item *)sd->focused_item))
1018 return;
1019 evas_object_geometry_get(VIEW(it), &x, &y, &w, &h);
1020 evas_object_geometry_get(sd->hit_rect, &sx, &sy, &sw, &sh);
1021 if ((x < sx) || (y < sy)|| ((x + w) > (sx + sw)) || ((y + h) > (sy + sh)))
1022 elm_list_item_bring_in((Elm_Object_Item *)it);
1023 sd->focused_item = (Elm_Object_Item *)it;
1024 ((Elm_Widget_Item *)it)->focused = EINA_TRUE;
1025 if (elm_widget_focus_highlight_enabled_get(WIDGET(it)))
1026 {
1027 edje_object_signal_emit
1028 (VIEW(it), "elm,state,focused", "elm");
1029 }
1030 focus_raise = edje_object_data_get(VIEW(it), "focusraise");
1031 if ((focus_raise) && (!strcmp(focus_raise, "on")))
1032 evas_object_raise(VIEW(it));
1033 evas_object_smart_callback_call
1034 (WIDGET(it), SIG_ITEM_FOCUSED, it);
1035}
1036
1037static void
1038_elm_list_item_unfocused(Elm_List_Item *it)
1039{
1040 ELM_LIST_DATA_GET(WIDGET(it), sd);
1041
1042 if (!sd->focused_item) return;
1043 sd->prev_focused_item = (Elm_Object_Item *)it;
1044 if (sd->select_mode == ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY)
1045 return;
1046 if (elm_widget_focus_highlight_enabled_get(WIDGET(sd->focused_item)))
1047 edje_object_signal_emit
1048 (VIEW(sd->focused_item), "elm,state,unfocused", "elm");
1049 if (it == (Elm_List_Item *)sd->focused_item)
1050 sd->focused_item = NULL;
1051 evas_object_smart_callback_call
1052 (WIDGET(it), SIG_ITEM_UNFOCUSED, it);
1053}
1054
1055static void
923_elm_list_smart_on_focus(Eo *obj, void *_pd, va_list *list) 1056_elm_list_smart_on_focus(Eo *obj, void *_pd, va_list *list)
924{ 1057{
925 Eina_Bool *ret = va_arg(*list, Eina_Bool *); 1058 Eina_Bool *ret = va_arg(*list, Eina_Bool *);
@@ -933,6 +1066,22 @@ _elm_list_smart_on_focus(Eo *obj, void *_pd, va_list *list)
933 if (elm_widget_focus_get(obj) && sd->selected && !sd->last_selected_item) 1066 if (elm_widget_focus_get(obj) && sd->selected && !sd->last_selected_item)
934 sd->last_selected_item = eina_list_data_get(sd->selected); 1067 sd->last_selected_item = eina_list_data_get(sd->selected);
935 1068
1069 if (elm_widget_focus_get(obj))
1070 {
1071 if (sd->last_focused_item)
1072 _elm_list_item_focused((Elm_List_Item *)sd->last_focused_item);
1073 else if (sd->last_selected_item)
1074 _elm_list_item_focused((Elm_List_Item *)sd->last_selected_item);
1075 else
1076 _elm_list_item_focused((Elm_List_Item *)elm_list_first_item_get(obj));
1077 _elm_widget_focus_highlight_start(obj);
1078 }
1079 else
1080 {
1081 sd->prev_focused_item = sd->focused_item;
1082 sd->last_focused_item = sd->focused_item;
1083 _elm_list_item_unfocused((Elm_List_Item *)sd->focused_item);
1084 }
936 if (ret) *ret = EINA_TRUE; 1085 if (ret) *ret = EINA_TRUE;
937} 1086}
938 1087
@@ -1033,7 +1182,7 @@ call:
1033 1182
1034 if (it->func) it->func((void *)it->base.data, WIDGET(it), it); 1183 if (it->func) it->func((void *)it->base.data, WIDGET(it), it);
1035 evas_object_smart_callback_call(obj, SIG_SELECTED, it); 1184 evas_object_smart_callback_call(obj, SIG_SELECTED, it);
1036 it->sd->last_selected_item = (Elm_Object_Item *)it; 1185 sd->last_selected_item = (Elm_Object_Item *)it;
1037 1186
1038 _elm_list_unwalk(obj, sd); 1187 _elm_list_unwalk(obj, sd);
1039 evas_object_unref(obj); 1188 evas_object_unref(obj);
@@ -1086,7 +1235,7 @@ _item_unselect(Elm_List_Item *it)
1086 evas_object_ref(obj); 1235 evas_object_ref(obj);
1087 _elm_list_walk(sd); 1236 _elm_list_walk(sd);
1088 1237
1089 if (it->sd->focus_on_selection_enabled) 1238 if (sd->focus_on_selection_enabled)
1090 { 1239 {
1091 if (it->icon) elm_object_focus_set(it->icon, EINA_FALSE); 1240 if (it->icon) elm_object_focus_set(it->icon, EINA_FALSE);
1092 if (it->end) elm_object_focus_set(it->end, EINA_FALSE); 1241 if (it->end) elm_object_focus_set(it->end, EINA_FALSE);
@@ -1322,6 +1471,7 @@ _mouse_up_cb(void *data,
1322 evas_object_ref(obj); 1471 evas_object_ref(obj);
1323 _elm_list_walk(sd); 1472 _elm_list_walk(sd);
1324 1473
1474 elm_object_item_focus_set((Elm_Object_Item *)it, EINA_TRUE);
1325 if (sd->multi && 1475 if (sd->multi &&
1326 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) || 1476 ((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
1327 (evas_key_modifier_is_set(ev->modifiers, "Control")))) 1477 (evas_key_modifier_is_set(ev->modifiers, "Control"))))
@@ -1544,6 +1694,39 @@ _item_signal_emit_hook(Elm_Object_Item *it,
1544 edje_object_signal_emit(VIEW(it), emission, source); 1694 edje_object_signal_emit(VIEW(it), emission, source);
1545} 1695}
1546 1696
1697static void
1698_item_focus_set_hook(Elm_Object_Item *it, Eina_Bool focused)
1699{
1700 ELM_LIST_ITEM_CHECK_OR_RETURN(it);
1701 Evas_Object *obj = WIDGET(it);
1702 ELM_LIST_DATA_GET(obj, sd);
1703
1704 if (focused)
1705 {
1706 if (!elm_object_focus_get(obj))
1707 elm_object_focus_set(obj, EINA_TRUE);
1708 if (sd->focused_item)
1709 _elm_list_item_unfocused((Elm_List_Item *)sd->focused_item);
1710 if (it != sd->focused_item) _elm_list_item_focused((Elm_List_Item *)it);
1711 }
1712 else
1713 _elm_list_item_unfocused((Elm_List_Item *)it);
1714 _elm_widget_focus_highlight_start(obj);
1715}
1716
1717static Eina_Bool
1718_item_focus_get_hook(Elm_Object_Item *it)
1719{
1720 ELM_LIST_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1721 Evas_Object *obj = WIDGET(it);
1722 ELM_LIST_CHECK(obj) EINA_FALSE;
1723 ELM_LIST_DATA_GET(obj, sd);
1724
1725 if (it == sd->focused_item)
1726 return EINA_TRUE;
1727 return EINA_FALSE;
1728}
1729
1547static char * 1730static char *
1548_access_info_cb(void *data, Evas_Object *obj EINA_UNUSED) 1731_access_info_cb(void *data, Evas_Object *obj EINA_UNUSED)
1549{ 1732{
@@ -1669,10 +1852,7 @@ _item_new(Evas_Object *obj,
1669{ 1852{
1670 Elm_List_Item *it; 1853 Elm_List_Item *it;
1671 1854
1672 ELM_LIST_DATA_GET(obj, sd);
1673
1674 it = elm_widget_item_new(obj, Elm_List_Item); 1855 it = elm_widget_item_new(obj, Elm_List_Item);
1675 it->sd = sd;
1676 it->label = eina_stringshare_add(label); 1856 it->label = eina_stringshare_add(label);
1677 it->icon = icon; 1857 it->icon = icon;
1678 it->end = end; 1858 it->end = end;
@@ -1720,6 +1900,8 @@ _item_new(Evas_Object *obj,
1720 elm_widget_item_text_get_hook_set(it, _item_text_get_hook); 1900 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1721 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook); 1901 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1722 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook); 1902 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1903 elm_widget_item_focus_set_hook_set(it, _item_focus_set_hook);
1904 elm_widget_item_focus_get_hook_set(it, _item_focus_get_hook);
1723 1905
1724 return it; 1906 return it;
1725} 1907}
@@ -2807,6 +2989,81 @@ _focus_on_selection_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
2807} 2989}
2808 2990
2809static void 2991static void
2992_elm_list_item_coordinates_adjust(Elm_List_Item *it,
2993 Evas_Coord *x,
2994 Evas_Coord *y,
2995 Evas_Coord *w,
2996 Evas_Coord *h)
2997{
2998 ELM_LIST_DATA_GET(WIDGET(it), sd);
2999
3000 Evas_Coord ix, iy, iw, ih, vx, vy, vw, vh;
3001
3002 evas_object_geometry_get(sd->hit_rect, &vx, &vy, &vw, &vh);
3003 evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih);
3004 *x = ix;
3005 *y = iy;
3006 *w = iw;
3007 *h = ih;
3008 if (!sd->h_mode)
3009 {
3010 //TODO: Enhance it later. declare a macro in elm_macros.h
3011 if ((ix < vx) || (ix + iw) > (vx + vw) || (iy + ih) > (vy + vh))
3012 *y = iy - ih;
3013 else if (iy < vy)
3014 *y = iy + ih;
3015 }
3016 else
3017 {
3018 //TODO: Enhance it later. declare a macro in elm_macros.h
3019 if ((iy < vy) || (ix + iw) > (vx + vw) || (iy + ih) > (vy + vh))
3020 *x = ix - iw;
3021 else if (ix < vx)
3022 *x = ix + iw;
3023 }
3024}
3025
3026static void
3027_elm_list_focus_highlight_geometry_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
3028{
3029 Evas_Coord *x = va_arg(*list, Evas_Coord *);
3030 Evas_Coord *y = va_arg(*list, Evas_Coord *);
3031 Evas_Coord *w = va_arg(*list, Evas_Coord *);
3032 Evas_Coord *h = va_arg(*list, Evas_Coord *);
3033 Eina_Bool *is_next = va_arg(*list, Eina_Bool *);
3034
3035 Elm_List_Smart_Data *sd = _pd;
3036
3037 if (is_next && *is_next)
3038 {
3039 if (sd->focused_item)
3040 {
3041 _elm_list_item_coordinates_adjust((Elm_List_Item *)sd->focused_item, x, y, w, h);
3042 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(sd->focused_item), x, y, w, h);
3043 }
3044 }
3045 else
3046 {
3047 if (sd->prev_focused_item)
3048 {
3049 _elm_list_item_coordinates_adjust((Elm_List_Item *)sd->prev_focused_item, x, y, w, h);
3050 elm_widget_focus_highlight_focus_part_geometry_get(VIEW(sd->prev_focused_item), x, y, w, h);
3051 }
3052 }
3053}
3054
3055static void
3056_elm_list_focused_item_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
3057{
3058 Elm_Object_Item **ret = va_arg(*list, Elm_Object_Item **);
3059 Elm_List_Smart_Data *sd = _pd;
3060 if (ret) *ret = NULL;
3061
3062 if (!elm_object_focus_get(obj)) return;
3063 if (ret) *ret = sd->focused_item;
3064}
3065
3066static void
2810_class_constructor(Eo_Class *klass) 3067_class_constructor(Eo_Class *klass)
2811{ 3068{
2812 const Eo_Op_Func_Description func_desc[] = { 3069 const Eo_Op_Func_Description func_desc[] = {
@@ -2828,6 +3085,8 @@ _class_constructor(Eo_Class *klass)
2828 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_SUB_OBJECT_DEL), _elm_list_smart_sub_object_del), 3085 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_SUB_OBJECT_DEL), _elm_list_smart_sub_object_del),
2829 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_DIRECTION_MANAGER_IS), _elm_list_smart_focus_direction_manager_is), 3086 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_DIRECTION_MANAGER_IS), _elm_list_smart_focus_direction_manager_is),
2830 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_ACCESS), _elm_list_smart_access), 3087 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_ACCESS), _elm_list_smart_access),
3088 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET), _elm_list_focus_highlight_geometry_get),
3089 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUSED_ITEM_GET), _elm_list_focused_item_get),
2831 3090
2832 EO_OP_FUNC(ELM_OBJ_LAYOUT_ID(ELM_OBJ_LAYOUT_SUB_ID_SIZING_EVAL), _elm_list_smart_sizing_eval), 3091 EO_OP_FUNC(ELM_OBJ_LAYOUT_ID(ELM_OBJ_LAYOUT_SUB_ID_SIZING_EVAL), _elm_list_smart_sizing_eval),
2833 3092
diff --git a/src/lib/elm_main.c b/src/lib/elm_main.c
index 90981b0b7..e49ade833 100644
--- a/src/lib/elm_main.c
+++ b/src/lib/elm_main.c
@@ -1720,6 +1720,13 @@ elm_object_orientation_mode_disabled_get(const Evas_Object *obj)
1720 return elm_widget_orientation_mode_disabled_get(obj); 1720 return elm_widget_orientation_mode_disabled_get(obj);
1721} 1721}
1722 1722
1723EAPI Elm_Object_Item *
1724elm_object_focused_item_get(const Evas_Object *obj)
1725{
1726 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
1727 return elm_widget_focused_item_get(obj);
1728}
1729
1723EAPI void 1730EAPI void
1724elm_object_item_access_info_set(Elm_Object_Item *it, const char *txt) 1731elm_object_item_access_info_set(Elm_Object_Item *it, const char *txt)
1725{ 1732{
@@ -1934,3 +1941,15 @@ elm_object_item_track_get(const Elm_Object_Item *it)
1934{ 1941{
1935 return elm_widget_item_track_get((Elm_Widget_Item *)it); 1942 return elm_widget_item_track_get((Elm_Widget_Item *)it);
1936} 1943}
1944
1945EAPI void
1946elm_object_item_focus_set(Elm_Object_Item *item, Eina_Bool focused)
1947{
1948 elm_widget_item_focus_set(item, focused);
1949}
1950
1951EAPI Eina_Bool
1952elm_object_item_focus_get(const Elm_Object_Item *item)
1953{
1954 return elm_widget_item_focus_get(item);
1955}
diff --git a/src/lib/elm_widget.c b/src/lib/elm_widget.c
index 5f52f17e4..464352a67 100644
--- a/src/lib/elm_widget.c
+++ b/src/lib/elm_widget.c
@@ -83,6 +83,25 @@ _elm_scrollable_is(const Evas_Object *obj)
83 eo_isa(obj, ELM_SCROLLABLE_INTERFACE); 83 eo_isa(obj, ELM_SCROLLABLE_INTERFACE);
84} 84}
85 85
86void
87_elm_widget_focus_highlight_start(const Evas_Object *obj)
88{
89 Evas_Object *top = elm_widget_top_get(obj);
90
91 if (top && eo_isa(top, ELM_OBJ_WIN_CLASS))
92 _elm_win_focus_highlight_start(top);
93}
94
95EAPI Eina_Bool
96elm_widget_focus_highlight_enabled_get(const Evas_Object *obj)
97{
98 const Evas_Object *win = elm_widget_top_get(obj);
99
100 if (win && eo_isa(win, ELM_OBJ_WIN_CLASS))
101 return elm_win_focus_highlight_enabled_get(win);
102 return EINA_FALSE;
103}
104
86/** 105/**
87 * @internal 106 * @internal
88 * 107 *
@@ -4861,46 +4880,78 @@ _elm_widget_newest_focus_order_get(Eo *obj, void *_pd, va_list *list)
4861} 4880}
4862 4881
4863EAPI void 4882EAPI void
4864elm_widget_focus_highlight_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) 4883elm_widget_focus_highlight_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h, Eina_Bool is_next)
4865{ 4884{
4866 ELM_WIDGET_CHECK(obj); 4885 ELM_WIDGET_CHECK(obj);
4867 eo_do(obj, elm_wdg_focus_highlight_geometry_get(x, y, w, h)); 4886 eo_do(obj, elm_wdg_focus_highlight_geometry_get(x, y, w, h, &is_next));
4868} 4887}
4869 4888
4870static void 4889EAPI void
4871_elm_widget_focus_highlight_geometry_get(Eo *obj, void *_pd, va_list *list) 4890elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj,
4891 Evas_Coord *x,
4892 Evas_Coord *y,
4893 Evas_Coord *w,
4894 Evas_Coord *h)
4872{ 4895{
4873 Evas_Coord *x = va_arg(*list, Evas_Coord *);
4874 Evas_Coord *y = va_arg(*list, Evas_Coord *);
4875 Evas_Coord *w = va_arg(*list, Evas_Coord *);
4876 Evas_Coord *h = va_arg(*list, Evas_Coord *);
4877
4878 Evas_Coord tx = 0, ty = 0, tw = 0, th = 0; 4896 Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
4879 const char *target_hl_part = NULL; 4897 const char *target_hl_part = NULL;
4880 Evas_Object *edje_obj = NULL; 4898 const Evas_Object *edje_obj = NULL;
4881 Elm_Widget_Smart_Data *sd = _pd;
4882 4899
4883 evas_object_geometry_get(obj, x, y, w, h); 4900 if (obj && eo_isa(obj, EDJE_OBJ_CLASS))
4884 if (sd->resize_obj && eo_isa(sd->resize_obj, EDJE_OBJ_CLASS))
4885 { 4901 {
4886 edje_obj = sd->resize_obj; 4902 edje_obj = obj;
4887 if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part"))) 4903 if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part")))
4888 return; 4904 return;
4889 } 4905 }
4890 else if (sd->resize_obj && eo_isa(sd->resize_obj, ELM_OBJ_LAYOUT_CLASS)) 4906 else if (obj && eo_isa(obj, ELM_OBJ_LAYOUT_CLASS))
4891 { 4907 {
4892 edje_obj = elm_layout_edje_get(sd->resize_obj); 4908 edje_obj = elm_layout_edje_get(obj);
4893 if (!(target_hl_part = elm_layout_data_get(sd->resize_obj, "focus_part"))) 4909 if (!(target_hl_part = elm_layout_data_get(obj, "focus_part")))
4894 return; 4910 return;
4895 } 4911 }
4896 else return; 4912 else
4913 return;
4897 4914
4898 edje_object_part_geometry_get(edje_obj, target_hl_part, 4915 edje_object_part_geometry_get(edje_obj, target_hl_part,
4899 &tx, &ty, &tw, &th); 4916 &tx, &ty, &tw, &th);
4900 *x += tx; 4917 *x += tx;
4901 *y += ty; 4918 *y += ty;
4902 if (tw != *w) *w = tw; 4919 if (tw != *w) *w = tw;
4903 if (th != *h) *h = th; 4920 if (th != *h) *h = th;
4921}
4922
4923static void
4924_elm_widget_focus_highlight_geometry_get(Eo *obj, void *_pd, va_list *list)
4925{
4926 Evas_Coord *x = va_arg(*list, Evas_Coord *);
4927 Evas_Coord *y = va_arg(*list, Evas_Coord *);
4928 Evas_Coord *w = va_arg(*list, Evas_Coord *);
4929 Evas_Coord *h = va_arg(*list, Evas_Coord *);
4930 Eina_Bool *is_next = va_arg(*list, Eina_Bool *);
4931 (void)is_next;
4932
4933 Elm_Widget_Smart_Data *sd = _pd;
4934
4935 evas_object_geometry_get(obj, x, y, w, h);
4936 elm_widget_focus_highlight_focus_part_geometry_get(sd->resize_obj, x, y, w, h);
4937}
4938
4939EAPI Elm_Object_Item *
4940elm_widget_focused_item_get(const Evas_Object *obj)
4941{
4942 ELM_WIDGET_CHECK(obj) NULL;
4943 Elm_Object_Item *ret = NULL;
4944 eo_do(obj, elm_wdg_focused_item_get(&ret));
4945
4946 return ret;
4947}
4948
4949static void
4950_elm_widget_focused_item_get(Eo *obj EINA_UNUSED, void *_pd EINA_UNUSED, va_list *list EINA_UNUSED)
4951{
4952 Elm_Object_Item **ret = va_arg(*list, Elm_Object_Item **);
4953
4954 if (ret) *ret = NULL;
4904} 4955}
4905 4956
4906EAPI void 4957EAPI void
@@ -5297,6 +5348,42 @@ _elm_widget_item_style_get_hook_set(Elm_Widget_Item *item,
5297 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item); 5348 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5298 item->style_get_func = func; 5349 item->style_get_func = func;
5299} 5350}
5351
5352/**
5353 * @internal
5354 *
5355 * Set the function to set the focus on widget item.
5356 *
5357 * @param item a valid #Elm_Widget_Item to be notified
5358 * @see elm_widget_item_focus_set_hook_set() convenience macro.
5359 * @ingroup Widget
5360 */
5361EAPI void
5362_elm_widget_item_focus_set_hook_set(Elm_Widget_Item *item, Elm_Widget_Focus_Set_Cb func)
5363{
5364 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5365 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5366 item->focus_set_func = func;
5367}
5368
5369/**
5370 * @internal
5371 *
5372 * Set the function to set the focus on widget item.
5373 *
5374 * @param item a valid #Elm_Widget_Item to be notified
5375 * @see elm_widget_item_focus_get_hook_set() convenience macro.
5376 * @ingroup Widget
5377 */
5378EAPI void
5379_elm_widget_item_focus_get_hook_set(Elm_Widget_Item *item,
5380 Elm_Widget_Focus_Get_Cb func)
5381{
5382 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5383 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5384 item->focus_get_func = func;
5385}
5386
5300/** 5387/**
5301 * @internal 5388 * @internal
5302 * 5389 *
@@ -5455,6 +5542,20 @@ _elm_widget_item_disable_hook_set(Elm_Widget_Item *item,
5455} 5542}
5456 5543
5457EAPI void 5544EAPI void
5545_elm_widget_item_focus_set(Elm_Widget_Item *item, Eina_Bool focused)
5546{
5547 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5548 item->focus_set_func(item, focused);
5549}
5550
5551EAPI Eina_Bool
5552_elm_widget_item_focus_get(const Elm_Widget_Item *item)
5553{
5554 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5555 return item->focus_get_func(item);
5556}
5557
5558EAPI void
5458_elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item, 5559_elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item,
5459 const char *part, 5560 const char *part,
5460 const char *domain, 5561 const char *domain,
@@ -6658,6 +6759,7 @@ _class_constructor(Eo_Class *klass)
6658 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_CAN_FOCUS_CHILD_LIST_GET), _elm_widget_can_focus_child_list_get), 6759 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_CAN_FOCUS_CHILD_LIST_GET), _elm_widget_can_focus_child_list_get),
6659 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_NEWEST_FOCUS_ORDER_GET), _elm_widget_newest_focus_order_get), 6760 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_NEWEST_FOCUS_ORDER_GET), _elm_widget_newest_focus_order_get),
6660 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET), _elm_widget_focus_highlight_geometry_get), 6761 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET), _elm_widget_focus_highlight_geometry_get),
6762 EO_OP_FUNC(ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUSED_ITEM_GET), _elm_widget_focused_item_get),
6661 6763
6662 EO_OP_FUNC_SENTINEL 6764 EO_OP_FUNC_SENTINEL
6663 }; 6765 };
@@ -6811,6 +6913,7 @@ static const Eo_Op_Description op_desc[] = {
6811 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_CAN_FOCUS_CHILD_LIST_GET, "Get the list of focusable child objects."), 6913 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_CAN_FOCUS_CHILD_LIST_GET, "Get the list of focusable child objects."),
6812 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_NEWEST_FOCUS_ORDER_GET, "Get the newest focused object and its order."), 6914 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_NEWEST_FOCUS_ORDER_GET, "Get the newest focused object and its order."),
6813 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET, "Get the focus highlight geometry of widget."), 6915 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET, "Get the focus highlight geometry of widget."),
6916 EO_OP_DESCRIPTION(ELM_WIDGET_SUB_ID_FOCUSED_ITEM_GET, "Get the focused widget item."),
6814 6917
6815 EO_OP_DESCRIPTION_SENTINEL 6918 EO_OP_DESCRIPTION_SENTINEL
6816}; 6919};
diff --git a/src/lib/elm_widget.h b/src/lib/elm_widget.h
index 35e96e632..a127dd500 100644
--- a/src/lib/elm_widget.h
+++ b/src/lib/elm_widget.h
@@ -467,6 +467,8 @@ typedef Eina_Bool (*Elm_Widget_Del_Pre_Cb)(void *data);
467typedef void (*Elm_Widget_Item_Signal_Cb)(void *data, Elm_Widget_Item *item, const char *emission, const char *source); 467typedef void (*Elm_Widget_Item_Signal_Cb)(void *data, Elm_Widget_Item *item, const char *emission, const char *source);
468typedef void (*Elm_Widget_Style_Set_Cb)(void *data, const char *style); 468typedef void (*Elm_Widget_Style_Set_Cb)(void *data, const char *style);
469typedef const char *(*Elm_Widget_Style_Get_Cb)(const void *data); 469typedef const char *(*Elm_Widget_Style_Get_Cb)(const void *data);
470typedef void (*Elm_Widget_Focus_Set_Cb)(void *data, Eina_Bool focused);
471typedef Eina_Bool (*Elm_Widget_Focus_Get_Cb)(const void *data);
470 472
471#define ELM_ACCESS_DONE -1 /* sentence done - send done event here */ 473#define ELM_ACCESS_DONE -1 /* sentence done - send done event here */
472#define ELM_ACCESS_CANCEL -2 /* stop reading immediately */ 474#define ELM_ACCESS_CANCEL -2 /* stop reading immediately */
@@ -510,6 +512,8 @@ Eina_Bool _elm_access_auto_highlight_get(void);
510void _elm_access_widget_item_access_order_set(Elm_Widget_Item *item, Eina_List *objs); 512void _elm_access_widget_item_access_order_set(Elm_Widget_Item *item, Eina_List *objs);
511const Eina_List *_elm_access_widget_item_access_order_get(const Elm_Widget_Item *item); 513const Eina_List *_elm_access_widget_item_access_order_get(const Elm_Widget_Item *item);
512void _elm_access_widget_item_access_order_unset(Elm_Widget_Item *item); 514void _elm_access_widget_item_access_order_unset(Elm_Widget_Item *item);
515void _elm_widget_focus_highlight_start(const Evas_Object *obj);
516void _elm_win_focus_highlight_start(Evas_Object *obj);
513 517
514EAPI void _elm_access_clear(Elm_Access_Info *ac); 518EAPI void _elm_access_clear(Elm_Access_Info *ac);
515EAPI void _elm_access_text_set(Elm_Access_Info *ac, int type, const char *text); 519EAPI void _elm_access_text_set(Elm_Access_Info *ac, int type, const char *text);
@@ -578,6 +582,8 @@ struct _Elm_Widget_Item
578 Elm_Widget_Disable_Cb disable_func; 582 Elm_Widget_Disable_Cb disable_func;
579 Elm_Widget_Style_Set_Cb style_set_func; 583 Elm_Widget_Style_Set_Cb style_set_func;
580 Elm_Widget_Style_Get_Cb style_get_func; 584 Elm_Widget_Style_Get_Cb style_get_func;
585 Elm_Widget_Focus_Set_Cb focus_set_func;
586 Elm_Widget_Focus_Get_Cb focus_get_func;
581 Evas_Object *access_obj; 587 Evas_Object *access_obj;
582 const char *access_info; 588 const char *access_info;
583 Eina_List *access_order; 589 Eina_List *access_order;
@@ -589,6 +595,7 @@ struct _Elm_Widget_Item
589 Eina_Bool disabled : 1; 595 Eina_Bool disabled : 1;
590 Eina_Bool on_deletion : 1; 596 Eina_Bool on_deletion : 1;
591 Eina_Bool on_translate : 1; 597 Eina_Bool on_translate : 1;
598 Eina_Bool focused : 1;
592}; 599};
593 600
594struct _Elm_Object_Item 601struct _Elm_Object_Item
@@ -659,6 +666,8 @@ EAPI void elm_widget_parent2_set(Evas_Object *obj, Evas_Object *pare
659EAPI void elm_widget_focus_steal(Evas_Object *obj); 666EAPI void elm_widget_focus_steal(Evas_Object *obj);
660EAPI Evas_Object *elm_widget_newest_focus_order_get(const Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only); 667EAPI Evas_Object *elm_widget_newest_focus_order_get(const Evas_Object *obj, unsigned int *newest_focus_order, Eina_Bool can_focus_only);
661EAPI void elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode); 668EAPI void elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode);
669EAPI Eina_Bool elm_widget_focus_highlight_enabled_get(const Evas_Object *obj);
670EAPI void elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
662EAPI const Elm_Widget_Smart_Class *elm_widget_smart_class_get(void); 671EAPI const Elm_Widget_Smart_Class *elm_widget_smart_class_get(void);
663 672
664/** 673/**
@@ -734,9 +743,10 @@ EAPI Evas_Object *elm_widget_content_part_unset(Evas_Object *obj, const char
734EAPI void elm_widget_access_info_set(Evas_Object *obj, const char *txt); 743EAPI void elm_widget_access_info_set(Evas_Object *obj, const char *txt);
735EAPI const char *elm_widget_access_info_get(const Evas_Object *obj); 744EAPI const char *elm_widget_access_info_get(const Evas_Object *obj);
736EAPI void elm_widget_orientation_set(Evas_Object *obj, int rotation); 745EAPI void elm_widget_orientation_set(Evas_Object *obj, int rotation);
746EAPI Elm_Object_Item *elm_widget_focused_item_get(const Evas_Object *obj);
737EAPI void elm_widget_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled); 747EAPI void elm_widget_orientation_mode_disabled_set(Evas_Object *obj, Eina_Bool disabled);
738EAPI Eina_Bool elm_widget_orientation_mode_disabled_get(const Evas_Object *obj); 748EAPI Eina_Bool elm_widget_orientation_mode_disabled_get(const Evas_Object *obj);
739EAPI void elm_widget_focus_highlight_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); 749EAPI void elm_widget_focus_highlight_geometry_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h, Eina_Bool is_next);
740EAPI Elm_Widget_Item *_elm_widget_item_new(Evas_Object *parent, size_t alloc_size); 750EAPI Elm_Widget_Item *_elm_widget_item_new(Evas_Object *parent, size_t alloc_size);
741EAPI void _elm_widget_item_free(Elm_Widget_Item *item); 751EAPI void _elm_widget_item_free(Elm_Widget_Item *item);
742EAPI Evas_Object *_elm_widget_item_widget_get(const Elm_Widget_Item *item); 752EAPI Evas_Object *_elm_widget_item_widget_get(const Elm_Widget_Item *item);
@@ -768,7 +778,8 @@ EAPI const char *_elm_widget_item_part_text_get(const Elm_Widget_Item *item
768EAPI void _elm_widget_item_part_text_custom_set(Elm_Widget_Item *item, const char *part, const char *label); 778EAPI void _elm_widget_item_part_text_custom_set(Elm_Widget_Item *item, const char *part, const char *label);
769EAPI const char *_elm_widget_item_part_text_custom_get(Elm_Widget_Item *item, const char *part); 779EAPI const char *_elm_widget_item_part_text_custom_get(Elm_Widget_Item *item, const char *part);
770EAPI void _elm_widget_item_part_text_custom_update(Elm_Widget_Item *item); 780EAPI void _elm_widget_item_part_text_custom_update(Elm_Widget_Item *item);
771 781EAPI void _elm_widget_item_focus_set(Elm_Widget_Item *item, Eina_Bool focused);
782EAPI Eina_Bool _elm_widget_item_focus_get(const Elm_Widget_Item *item);
772EAPI void _elm_widget_item_style_set(Elm_Widget_Item *item, const char *style); 783EAPI void _elm_widget_item_style_set(Elm_Widget_Item *item, const char *style);
773EAPI const char *_elm_widget_item_style_get(Elm_Widget_Item *item); 784EAPI const char *_elm_widget_item_style_get(Elm_Widget_Item *item);
774 785
@@ -788,6 +799,8 @@ EAPI void _elm_widget_item_disable_hook_set(Elm_Widget_Item *item, E
788EAPI void _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, Elm_Widget_Del_Pre_Cb func); 799EAPI void _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, Elm_Widget_Del_Pre_Cb func);
789EAPI void _elm_widget_item_style_set_hook_set(Elm_Widget_Item *item, Elm_Widget_Style_Set_Cb func); 800EAPI void _elm_widget_item_style_set_hook_set(Elm_Widget_Item *item, Elm_Widget_Style_Set_Cb func);
790EAPI void _elm_widget_item_style_get_hook_set(Elm_Widget_Item *item, Elm_Widget_Style_Get_Cb func); 801EAPI void _elm_widget_item_style_get_hook_set(Elm_Widget_Item *item, Elm_Widget_Style_Get_Cb func);
802EAPI void _elm_widget_item_focus_get_hook_set(Elm_Widget_Item *item, Elm_Widget_Focus_Get_Cb func);
803EAPI void _elm_widget_item_focus_set_hook_set(Elm_Widget_Item *item, Elm_Widget_Focus_Set_Cb func);
791EAPI void _elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item, const char *part, const char *domain, const char *label); 804EAPI void _elm_widget_item_domain_translatable_part_text_set(Elm_Widget_Item *item, const char *part, const char *domain, const char *label);
792EAPI const char * _elm_widget_item_translatable_part_text_get(const Elm_Widget_Item *item, const char *part); 805EAPI const char * _elm_widget_item_translatable_part_text_get(const Elm_Widget_Item *item, const char *part);
793EAPI void _elm_widget_item_translate(Elm_Widget_Item *item); 806EAPI void _elm_widget_item_translate(Elm_Widget_Item *item);
@@ -1042,6 +1055,21 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out
1042 */ 1055 */
1043#define elm_widget_item_style_get(item) \ 1056#define elm_widget_item_style_get(item) \
1044 _elm_widget_item_style_get((Elm_Widget_Item *)item) 1057 _elm_widget_item_style_get((Elm_Widget_Item *)item)
1058
1059/**
1060 * Convenience function to query focus set hook.
1061 * @see _elm_widget_item_focus_set_hook_set()
1062 */
1063#define elm_widget_item_focus_set_hook_set(item, func) \
1064 _elm_widget_item_focus_set_hook_set((Elm_Widget_Item *)item, (Elm_Widget_Focus_Set_Cb)func)
1065
1066/**
1067 * Convenience function to query focus get hook.
1068 * @see _elm_widget_item_focus_get_hook_set()
1069 */
1070#define elm_widget_item_focus_get_hook_set(item, func) \
1071 _elm_widget_item_focus_get_hook_set((Elm_Widget_Item *)item, (Elm_Widget_Focus_Get_Cb)func)
1072
1045/** 1073/**
1046 * Convenience function to query track_cancel. 1074 * Convenience function to query track_cancel.
1047 * @see _elm_widget_item_del_pre_hook_set() 1075 * @see _elm_widget_item_del_pre_hook_set()
@@ -1077,6 +1105,20 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out
1077#define elm_widget_item_part_text_custom_update(item) \ 1105#define elm_widget_item_part_text_custom_update(item) \
1078 _elm_widget_item_part_text_custom_update((Elm_Widget_Item *)item) 1106 _elm_widget_item_part_text_custom_update((Elm_Widget_Item *)item)
1079 1107
1108/**
1109 * Convenience function to set the focus on widget item.
1110 * @see _elm_widget_item_focus_set()
1111 */
1112#define elm_widget_item_focus_set(item, focused) \
1113 _elm_widget_item_focus_set((Elm_Widget_Item *)item, focused)
1114
1115/**
1116 * Convenience function to query focus set hook.
1117 * @see _elm_widget_item_focus_get()
1118 */
1119#define elm_widget_item_focus_get(item) \
1120 _elm_widget_item_focus_get((const Elm_Widget_Item *)item)
1121
1080#define ELM_WIDGET_CHECK_OR_RETURN(obj, ...) \ 1122#define ELM_WIDGET_CHECK_OR_RETURN(obj, ...) \
1081 do { \ 1123 do { \
1082 if (!obj || !evas_object_smart_data_get(obj)) \ 1124 if (!obj || !evas_object_smart_data_get(obj)) \
@@ -1275,6 +1317,7 @@ enum
1275 ELM_WIDGET_SUB_ID_CAN_FOCUS_CHILD_LIST_GET, 1317 ELM_WIDGET_SUB_ID_CAN_FOCUS_CHILD_LIST_GET,
1276 ELM_WIDGET_SUB_ID_NEWEST_FOCUS_ORDER_GET, 1318 ELM_WIDGET_SUB_ID_NEWEST_FOCUS_ORDER_GET,
1277 ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET, 1319 ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET,
1320 ELM_WIDGET_SUB_ID_FOCUSED_ITEM_GET,
1278#if 0 1321#if 0
1279 ELM_WIDGET_SUB_ID_THEME_APPLY, /* API + virtual*/ 1322 ELM_WIDGET_SUB_ID_THEME_APPLY, /* API + virtual*/
1280 ELM_WIDGET_SUB_ID_THEME_SPECIFIC, 1323 ELM_WIDGET_SUB_ID_THEME_SPECIFIC,
@@ -2681,9 +2724,19 @@ typedef void * (*list_data_get_func_type)(const Eina_List * l);
2681 * @param[in] x 2724 * @param[in] x
2682 * @param[in] y 2725 * @param[in] y
2683 * @param[in] w 2726 * @param[in] w
2684 * @param[in] z 2727 * @param[in] h
2728 * @param[in] is_next
2685 * 2729 *
2686 */ 2730 */
2687#define elm_wdg_focus_highlight_geometry_get(x, y, w, h) ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET), EO_TYPECHECK(Evas_Coord *, x), EO_TYPECHECK(Evas_Coord *, y), EO_TYPECHECK(Evas_Coord *, w), EO_TYPECHECK(Evas_Coord *, h) 2731#define elm_wdg_focus_highlight_geometry_get(x, y, w, h, is_next) ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUS_HIGHLIGHT_GEOMETRY_GET), EO_TYPECHECK(Evas_Coord *, x), EO_TYPECHECK(Evas_Coord *, y), EO_TYPECHECK(Evas_Coord *, w), EO_TYPECHECK(Evas_Coord *, h), EO_TYPECHECK(Eina_Bool *, is_next)
2688 2732/**
2733 * @def elm_wdg_focused_item_get
2734 * @since 1.10
2735 *
2736 * Get the focused widget item.
2737 *
2738 * @param[out] ret
2739 *
2740 */
2741#define elm_wdg_focused_item_get(ret) ELM_WIDGET_ID(ELM_WIDGET_SUB_ID_FOCUSED_ITEM_GET), EO_TYPECHECK(Elm_Object_Item **, ret)
2689#endif 2742#endif
diff --git a/src/lib/elm_widget_list.h b/src/lib/elm_widget_list.h
index cfc9b1e2f..06562da29 100644
--- a/src/lib/elm_widget_list.h
+++ b/src/lib/elm_widget_list.h
@@ -27,6 +27,9 @@ struct _Elm_List_Smart_Data
27 27
28 Eina_List *items, *selected, *to_delete; 28 Eina_List *items, *selected, *to_delete;
29 Elm_Object_Item *last_selected_item; 29 Elm_Object_Item *last_selected_item;
30 Elm_Object_Item *focused_item; /**< a focused item by keypad arrow or mouse. This is set to NULL if widget looses focus. */
31 Elm_Object_Item *prev_focused_item; /**< a previous focused item by keypad arrow or mouse. */
32 Elm_Object_Item *last_focused_item; /**< This records the last focused item when widget looses focus. This is required to set the focus on last focused item when widgets gets focus. */
30 Evas_Coord minw[2], minh[2]; 33 Evas_Coord minw[2], minh[2];
31 Elm_Object_Select_Mode select_mode; 34 Elm_Object_Select_Mode select_mode;
32 Elm_Object_Multi_Select_Mode multi_select_mode; /**< select mode for multiple selection */ 35 Elm_Object_Multi_Select_Mode multi_select_mode; /**< select mode for multiple selection */
@@ -57,8 +60,6 @@ struct _Elm_List_Item
57{ 60{
58 ELM_WIDGET_ITEM; 61 ELM_WIDGET_ITEM;
59 62
60 Elm_List_Smart_Data *sd;
61
62 Ecore_Timer *swipe_timer; 63 Ecore_Timer *swipe_timer;
63 Ecore_Timer *long_timer; 64 Ecore_Timer *long_timer;
64 Evas_Object *icon, *end; 65 Evas_Object *icon, *end;
diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c
index 7995382c7..53a707b09 100644
--- a/src/lib/elm_win.c
+++ b/src/lib/elm_win.c
@@ -711,8 +711,8 @@ _elm_win_focus_highlight_anim_setup(Elm_Win_Smart_Data *sd,
711 Evas_Object *target = sd->focus_highlight.cur.target; 711 Evas_Object *target = sd->focus_highlight.cur.target;
712 712
713 evas_object_geometry_get(sd->obj, NULL, NULL, &w, &h); 713 evas_object_geometry_get(sd->obj, NULL, NULL, &w, &h);
714 elm_widget_focus_highlight_geometry_get(target, &tx, &ty, &tw, &th); 714 elm_widget_focus_highlight_geometry_get(target, &tx, &ty, &tw, &th, EINA_TRUE);
715 elm_widget_focus_highlight_geometry_get(previous, &px, &py, &pw, &ph); 715 elm_widget_focus_highlight_geometry_get(previous, &px, &py, &pw, &ph, EINA_FALSE);
716 evas_object_move(obj, tx, ty); 716 evas_object_move(obj, tx, ty);
717 evas_object_resize(obj, tw, th); 717 evas_object_resize(obj, tw, th);
718 evas_object_clip_unset(obj); 718 evas_object_clip_unset(obj);
@@ -738,7 +738,7 @@ _elm_win_focus_highlight_simple_setup(Elm_Win_Smart_Data *sd,
738 Evas_Coord x, y, w, h; 738 Evas_Coord x, y, w, h;
739 739
740 clip = evas_object_clip_get(target); 740 clip = evas_object_clip_get(target);
741 elm_widget_focus_highlight_geometry_get(target, &x, &y, &w, &h); 741 elm_widget_focus_highlight_geometry_get(target, &x, &y, &w, &h, EINA_TRUE);
742 742
743 evas_object_move(obj, x, y); 743 evas_object_move(obj, x, y);
744 evas_object_resize(obj, w, h); 744 evas_object_resize(obj, w, h);
@@ -5823,6 +5823,18 @@ _window_id_get(Eo *obj EINA_UNUSED, void *_pd, va_list *list)
5823 *ret = 0; 5823 *ret = 0;
5824} 5824}
5825 5825
5826void
5827_elm_win_focus_highlight_start(Evas_Object *obj)
5828{
5829 ELM_WIN_DATA_GET(obj, sd);
5830
5831 if (!elm_win_focus_highlight_enabled_get(obj)) return;
5832 sd->focus_highlight.cur.visible = EINA_TRUE;
5833 sd->focus_highlight.cur.in_theme = EINA_FALSE;
5834 sd->focus_highlight.geometry_changed = EINA_TRUE;
5835 _elm_win_focus_highlight_reconfigure(sd);
5836}
5837
5826EAPI Ecore_Window 5838EAPI Ecore_Window
5827elm_win_window_id_get(const Evas_Object *obj) 5839elm_win_window_id_get(const Evas_Object *obj)
5828{ 5840{
@@ -5963,7 +5975,6 @@ _class_constructor(Eo_Class *klass)
5963 EO_OP_FUNC(ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE_SET), _wm_manual_rotation_done_set), 5975 EO_OP_FUNC(ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE_SET), _wm_manual_rotation_done_set),
5964 EO_OP_FUNC(ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE_GET), _wm_manual_rotation_done_get), 5976 EO_OP_FUNC(ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE_GET), _wm_manual_rotation_done_get),
5965 EO_OP_FUNC(ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE), _wm_manual_rotation_done), 5977 EO_OP_FUNC(ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE), _wm_manual_rotation_done),
5966
5967 EO_OP_FUNC_SENTINEL 5978 EO_OP_FUNC_SENTINEL
5968 }; 5979 };
5969 5980
diff --git a/src/lib/elm_win_eo.h b/src/lib/elm_win_eo.h
index ae679092d..8ade15a58 100644
--- a/src/lib/elm_win_eo.h
+++ b/src/lib/elm_win_eo.h
@@ -1372,3 +1372,7 @@ enum
1372 * @see elm_win_wm_rotation_manual_rotation_done 1372 * @see elm_win_wm_rotation_manual_rotation_done
1373 */ 1373 */
1374#define elm_obj_win_wm_manual_rotation_done() ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE) 1374#define elm_obj_win_wm_manual_rotation_done() ELM_OBJ_WIN_ID(ELM_OBJ_WIN_SUB_ID_WM_MANUAL_ROTATION_DONE)
1375
1376/**
1377 * @}
1378 */