elementary: efl_ui_list focus manager fix

fixed focus changed with keyboard
fixed scroll in focus
fixed focus in example
This commit is contained in:
Larry Jr 2018-01-19 15:27:26 -02:00 committed by Felipe Magno de Almeida
parent f80061e184
commit 7e0f98a794
6 changed files with 113 additions and 20 deletions

View File

@ -59,7 +59,10 @@ static void
_focused(void *data, const Efl_Event *event)
{
Priv_Data *priv = (Priv_Data*)data;
priv->selected = efl_ui_focus_manager_focus_get(event->object);
Evas_Object *focused = efl_ui_focus_manager_focus_get(event->object);
if (focused)
priv->selected = focused;
}
static void

View File

@ -1,15 +1,15 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#define ELM_ACCESS_PROTECTED
#define ELM_ACCESS_WIDGET_ACTION_PROTECTED
#define EFL_ACCESS_PROTECTED
#define EFL_ACCESS_WIDGET_ACTION_PROTECTED
#define EFL_ACCESS_SELECTION_PROTECTED
#define EFL_UI_SCROLL_MANAGER_PROTECTED
#define EFL_UI_SCROLLBAR_PROTECTED
#define EFL_UI_SCROLLBAR_BETA
#define EFL_GFX_SIZE_HINT_PROTECTED
#define EFL_UI_LIST_PROTECTED
#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
#include <Elementary.h>
#include "efl_ui_list_private.h"
@ -165,6 +165,24 @@ _efl_model_properties_has(Efl_Model *model, Eina_Stringshare *propfind)
return ret;
}
static void
_list_element_focused(void *data EINA_UNUSED, const Efl_Event *ev)
{
Eina_Rect geom;
Eina_Position2D pos;
Efl_Ui_Focus_Object *focused = efl_ui_focus_manager_focus_get(ev->object);
if (!focused) return;
EFL_UI_LIST_DATA_GET(ev->object, pd);
geom = efl_ui_focus_object_focus_geometry_get(focused);
pos = efl_ui_scrollable_content_pos_get(pd->scrl_mgr);
geom.x += pos.x;
geom.y += pos.y;
efl_ui_scrollable_scroll(pd->scrl_mgr, geom, EINA_TRUE);
}
static void
_on_item_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *o EINA_UNUSED, void *event_info)
{
@ -709,6 +727,11 @@ _efl_ui_list_efl_object_constructor(Eo *obj, Efl_Ui_List_Data *pd)
efl_composite_attach(obj, manager);
_efl_ui_focus_manager_redirect_events_add(manager, obj);
efl_event_callback_add(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, _list_element_focused, NULL);
efl_ui_focus_composition_custom_manager_set(obj, obj);
efl_ui_focus_composition_logical_mode_set(obj, EINA_TRUE);
pd->style = eina_stringshare_add(elm_widget_style_get(obj));
pd->factory = NULL;
@ -847,7 +870,7 @@ _efl_ui_list_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, Efl_Ui_Lis
static Eina_Bool
_key_action_move(Evas_Object *obj EINA_UNUSED, const char *params EINA_UNUSED)
{
return EINA_FALSE;
return EINA_FALSE;
}
static Eina_Bool
@ -863,8 +886,6 @@ _key_action_escape(Evas_Object *obj, const char *params EINA_UNUSED)
return EINA_TRUE;
}
ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_list, Efl_Ui_List_Data)
void
_efl_ui_list_item_select_set(Efl_Ui_List_LayoutItem *item, Eina_Bool selected)
{
@ -944,6 +965,30 @@ _efl_ui_list_efl_ui_list_model_min_size_set(Eo *obj, Efl_Ui_List_Data *pd, Eina_
efl_event_callback_call(pd->pan_obj, EFL_UI_PAN_EVENT_CONTENT_CHANGED, NULL);
}
EOLIAN static void
_efl_ui_list_efl_ui_focus_composition_prepare(Eo *obj, Efl_Ui_List_Data *pd)
{
Eina_List *order = efl_ui_list_relayout_elements_get(pd->relayout);
efl_ui_focus_composition_elements_set(obj, order);
}
EOLIAN Eina_List*
_efl_ui_list_efl_access_children_get(Eo *obj, Efl_Ui_List_Data *pd)
{
Eina_List *ret = NULL, *ret2 = NULL;
ret = efl_ui_list_relayout_elements_get(pd->relayout);
ret2 = efl_access_children_get(efl_super(obj, EFL_UI_LIST_CLASS));
return eina_list_merge(ret, ret2);
}
EOLIAN static Eina_Bool
_efl_ui_list_efl_ui_widget_focus_state_apply(Eo *obj, Efl_Ui_List_Data *pd EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State *configured_state, Efl_Ui_Widget *redirect EINA_UNUSED)
{
return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj);
}
EOLIAN static Efl_Ui_List_LayoutItem *
_efl_ui_list_efl_ui_list_model_realize(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_List_LayoutItem *item)
{
@ -954,10 +999,17 @@ _efl_ui_list_efl_ui_list_model_realize(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_Lis
evas_object_smart_member_add(item->layout, pd->pan_obj);
evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item);
if (_elm_config->atspi_mode)
{
efl_access_added(item->layout);
efl_access_children_changed_added_signal_emit(obj, item->layout);
}
evt.child = item->children;
evt.layout = item->layout;
evt.index = efl_ui_list_item_index_get((Efl_Ui_List_Item *)item);
efl_event_callback_call(obj, EFL_UI_LIST_EVENT_ITEM_REALIZED, &evt);
efl_ui_focus_composition_dirty(obj);
evas_object_show(item->layout);
return item;
@ -970,6 +1022,12 @@ _efl_ui_list_efl_ui_list_model_unrealize(Eo *obj, Efl_Ui_List_Data *pd, Efl_Ui_L
EINA_SAFETY_ON_NULL_RETURN(item->layout);
evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item);
if (elm_object_focus_allow_get(item->layout))
{
if (elm_object_focus_get(item->layout))
elm_object_focus_set(item->layout, EINA_FALSE);
efl_ui_focus_manager_calc_unregister(obj, item->layout);
}
evas_object_hide(item->layout);
evas_object_move(item->layout, -9999, -9999);
@ -1001,6 +1059,8 @@ _efl_ui_list_efl_ui_list_model_size_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Data *p
return pd->item_count;
}
ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_list, Efl_Ui_List_Data)
/* Internal EO APIs and hidden overrides */
#define EFL_UI_LIST_EXTRA_OPS \

View File

@ -7,7 +7,7 @@ struct Efl.Ui.List.Item_Event
index: int;
}
class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Efl.Ui.Scrollable.Interactive, Efl.Ui.Scrollbar,
Efl.Access.Widget.Action, Efl.Access.Selection,
Efl.Access.Widget.Action, Efl.Access.Selection, Efl.Ui.Focus.Composition, Efl.Ui.Focus.Manager.Sub,
Efl.Ui.Clickable, Efl.Ui.Selectable, Efl.Ui.List.Model)
{
methods {
@ -77,19 +77,10 @@ class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Efl.Ui.Scrollable.Interactive, Ef
Efl.Ui.List.Model.min_size { get; set; }
// Widget
// Elm.Widget.focus_next_manager_is;
// Elm.Widget.focus_direction_manager_is;
// Elm.Widget.focus_register;
// Elm.Widget.focus_next;
// Elm.Widget.on_focus_update;
// Elm.Widget.activate;
// Elm.Widget.focused_item { get; }
// Elm.Widget.focused_object { get; }
Efl.Ui.Widget.focus_manager_create;
Efl.Ui.Widget.widget_event;
// Efl.Ui.Focus.Manager.focus {set; }
//Efl.Ui.Layout.sizing_eval;
Efl.Ui.Widget.focus_state_apply;
Efl.Ui.Focus.Composition.prepare;
Efl.Ui.View.model { get; set; }
Efl.Ui.Scrollable.Interactive.viewport_geometry { get; }
@ -101,6 +92,7 @@ class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Efl.Ui.Scrollable.Interactive, Ef
// Elm.Interface.Atspi_Accessible.children { get; }
// Elm.Interface.Atspi_Widget.Action.elm_actions { get; }
// Efl.Access.Widget.Action.elm_actions { get; }
Efl.Access.children { get; }
Efl.Access.Selection.selected_children_count { get; }
Efl.Access.Selection.selected_child { get; }
Efl.Access.Selection.selected_child_deselect;

View File

@ -414,7 +414,7 @@ static void
_calc_range(Efl_Ui_List_Precise_Layouter_Data *pd)
{
Efl_Ui_List_SegArray_Node *node;
Evas_Coord ch;
Evas_Coord ch, ny;
Eina_Rect vgmt;
Eina_Position2D spos;
Efl_Ui_List_Precise_Layouter_Node_Data *nodedata;
@ -423,6 +423,11 @@ _calc_range(Efl_Ui_List_Precise_Layouter_Data *pd)
vgmt = efl_ui_scrollable_viewport_geometry_get(pd->modeler);
spos = efl_ui_scrollable_content_pos_get(pd->modeler);
ny = spos.y - (vgmt.h / 2);
if (ny < 0) spos.y = 0;
else spos.y = ny;
vgmt.h *= 2;
ch = 0;
Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
EINA_ACCESSOR_FOREACH(nodes, i, node)
@ -518,6 +523,32 @@ _efl_ui_list_precise_layouter_efl_object_constructor(Eo *obj EINA_UNUSED, Efl_Ui
return obj;
}
EOLIAN static Eina_List *
_efl_ui_list_precise_layouter_efl_ui_list_relayout_elements_get(Eo *obj EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd)
{
Eina_List *elements_order = NULL;
Efl_Ui_List_LayoutItem* layout_item;
Efl_Ui_List_SegArray_Node *items_node;
int i, j = 0;
Eina_Accessor *nodes = efl_ui_list_segarray_node_accessor_get(pd->segarray);
EINA_ACCESSOR_FOREACH(nodes, i, items_node)
{
Efl_Ui_List_Precise_Layouter_Node_Data *nodedata = items_node->layout_data;
if (!nodedata || !nodedata->realized)
continue;
for(j = 0; j != items_node->length;++j)
{
layout_item = (Efl_Ui_List_LayoutItem *)items_node->pointers[j];
if (layout_item->layout)
elements_order = eina_list_append(elements_order, layout_item->layout);
}
}
return elements_order;
}
EOLIAN static void
_efl_ui_list_precise_layouter_efl_ui_list_relayout_model_set(Eo *obj EINA_UNUSED, Efl_Ui_List_Precise_Layouter_Data *pd, Efl_Model *model)
{

View File

@ -4,5 +4,6 @@ class Efl.Ui.List.Precise_Layouter (Efl.Object, Efl.Ui.List.Relayout)
Efl.Object.constructor;
Efl.Ui.List.Relayout.layout_do;
Efl.Ui.List.Relayout.model { set; }
Efl.Ui.List.Relayout.elements { get; }
}
}

View File

@ -19,5 +19,11 @@ interface Efl.Ui.List.Relayout (Efl.Interface)
model: Efl.Model; [[Efl model]]
}
}
@property elements {
get {}
values {
elements: list<Efl.Gfx>; [[The order to use]]
}
}
}
}