diff options
author | Pankaj Mittal <m.pankaj@samsung.com> | 2016-06-21 16:04:31 +0200 |
---|---|---|
committer | Marcel Hollerbach <marcel-hollerbach@t-online.de> | 2016-06-21 19:03:09 +0200 |
commit | 1a5321c7cc502c39e81936e7b67590aa8560a495 (patch) | |
tree | 020961a514b88f0a7a2ebcfc1cd79547718b3556 | |
parent | d72098a81711d603e5c8b89484bf69c9b886caba (diff) | |
download | efl-devs/bu5hm4n/focus_secure.tar.gz |
focus: next/prev(Tab Order) implementationdevs/bu5hm4n/focus_secure
Summary:
This feature is being used when user presses TAB or SHIFT+TAB key for focus movement.
The idea is to use existing nodes of graph instead of creating new one, and adding links
for creating required ordering.
@feature
Reviewers: yashu21985, atulfokk, singh.amitesh, cedric
Subscribers: alok25, bu5hm4n, cedric, jpeg
Differential Revision: https://phab.enlightenment.org/D4026
-rw-r--r-- | src/lib/elementary/efl_ui_focus_manager.c | 62 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_win.c | 15 |
2 files changed, 71 insertions, 6 deletions
diff --git a/src/lib/elementary/efl_ui_focus_manager.c b/src/lib/elementary/efl_ui_focus_manager.c index bb65db8395..b3fc1dc1b0 100644 --- a/src/lib/elementary/efl_ui_focus_manager.c +++ b/src/lib/elementary/efl_ui_focus_manager.c @@ -27,10 +27,13 @@ struct _Border { }; typedef struct _Node Node; + struct _Node { Elm_Widget *focusable; Border directions[NODE_DIRECTIONS_COUNT]; Efl_Ui_Focus_Manager *manager; + Node *next; + Node *prev; }; typedef struct { @@ -40,6 +43,8 @@ typedef struct { Efl_Ui_Focus_Manager *redirect; Eina_List *dirty; + + Node *last_node; } Efl_Ui_Focus_Manager_Data; static Efl_Ui_Focus_Direction @@ -124,6 +129,38 @@ node_item_free(Node *item) //CALCULATING STUFF +// Append current Object to Focus Chain +static void +efl_ui_focus_chain_append(Efl_Ui_Focus_Manager_Data *pd, Node *prev, Node *current) +{ + if (!current) + { + CRI("Appending NULL Object!!"); + return; + } + if (prev) + { + prev->next = current; + current->prev = prev; + } + pd->last_node = current; +} +// Remove current Object to Focus Chain +static void +efl_ui_focus_chain_remove(Efl_Ui_Focus_Manager_Data *pd, Node *current) +{ + if (!current) + { + CRI("Removing NULL Object!!"); + return; + } + if (current->prev) + current->prev->next = current->next; + if (current->next) + current->next->prev = current->prev; + else + pd->last_node = current->prev; +} static inline int _distance(Eina_Rectangle node, Eina_Rectangle op, Dimension dim) { @@ -446,6 +483,9 @@ _efl_ui_focus_manager_register(Eo *obj, Efl_Ui_Focus_Manager_Data *pd, Evas_Obje //mark dirty dirty_add(pd, node); + //update next/prev links + efl_ui_focus_chain_append(pd, pd->last_node, node); + //listen to events eo_event_callback_array_add(child, focusable_node(), obj); @@ -483,7 +523,6 @@ _efl_ui_focus_manager_listener(Eo *obj, Efl_Ui_Focus_Manager_Data *pd, Eo_Base * return EINA_TRUE; } - EOLIAN static void _efl_ui_focus_manager_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data *pd, Evas_Object *child) { @@ -525,6 +564,11 @@ _efl_ui_focus_manager_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Data //remove from known listeners eina_hash_del_by_key(pd->listener_hash, &child); } + else + { + //update next/prev links + efl_ui_focus_chain_remove(pd, node); + } eina_hash_del_by_key(pd->node_hash, &child); } @@ -725,6 +769,20 @@ _efl_ui_focus_manager_request_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Dat _debug_node(upper); #endif + //for Handling Tab and SHIFT + tab movements. + if (direction == EFL_UI_FOCUS_DIRECTION_NEXT) + { + if (upper->next) + return upper->next->focusable; + return NULL; + } + else if (direction == EFL_UI_FOCUS_DIRECTION_PREV) + { + if (upper->prev) + return upper->prev->focusable; + return NULL; + } + //we are searcing which of the partners is lower to the history EINA_LIST_REVERSE_FOREACH(pd->focus_stack, node, candidate) { @@ -746,4 +804,4 @@ _efl_ui_focus_manager_request_move(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Dat } -#include "efl_ui_focus_manager.eo.c"
\ No newline at end of file +#include "efl_ui_focus_manager.eo.c" diff --git a/src/lib/elementary/efl_ui_win.c b/src/lib/elementary/efl_ui_win.c index c0a7e7eb04..8b9725454f 100644 --- a/src/lib/elementary/efl_ui_win.c +++ b/src/lib/elementary/efl_ui_win.c @@ -1625,7 +1625,6 @@ static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { const char *dir = params; - if (!getenv("FOCUS_WORK")) { _elm_widget_focus_auto_show(obj); @@ -1643,7 +1642,6 @@ _key_action_move(Evas_Object *obj, const char *params) elm_widget_focus_cycle(obj, ELM_FOCUS_DOWN); else return EINA_FALSE; - return EINA_TRUE; } else @@ -3948,9 +3946,16 @@ _focus_movement(void *data, Evas *e, Evas_Object *obj, void *event_info) r = efl_ui_focus_manager_move(data, EFL_UI_FOCUS_DIRECTION_UP); else if (!strcmp(down->keyname, "Down")) r = efl_ui_focus_manager_move(data, EFL_UI_FOCUS_DIRECTION_DOWN); + else if (!strcmp(down->keyname, "Tab")) + { + const Evas_Modifier *m = evas_key_modifier_get(e); + if (evas_key_modifier_is_set(m, "Shift")) + r = efl_ui_focus_manager_move(data, EFL_UI_FOCUS_DIRECTION_PREV); + else + r = efl_ui_focus_manager_move(data, EFL_UI_FOCUS_DIRECTION_NEXT); + } } - static Eo * _elm_win_finalize_internal(Eo *obj, Efl_Ui_Win_Data *sd, const char *name, Elm_Win_Type type) { @@ -4564,7 +4569,9 @@ _elm_win_finalize_internal(Eo *obj, Efl_Ui_Win_Data *sd, const char *name, Elm_W evas_object_key_grab(sd->edje, "Left", 0, 0, EINA_TRUE); evas_object_key_grab(sd->edje, "Up", 0, 0, EINA_TRUE); evas_object_key_grab(sd->edje, "Down", 0, 0, EINA_TRUE); - + evas_object_key_grab(sd->edje, "Tab", 0, 0, EINA_TRUE); + evas_object_key_grab(sd->edje, "Shift_L", 0, 0, EINA_TRUE); + evas_object_key_grab(sd->edje, "Shift_R", 0, 0, EINA_TRUE); evas_object_event_callback_add (sd->edje, EVAS_CALLBACK_KEY_DOWN, _focus_movement, obj); } |