forked from enlightenment/efl
genlist: implement item focus
this implements item-content focus for genlist. feel free to notify me if there are any crashes or something simular. ref T6181
This commit is contained in:
parent
d30985b4e2
commit
b364293b0c
|
@ -8,6 +8,7 @@
|
|||
#define EFL_ACCESS_SELECTION_PROTECTED
|
||||
#define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
|
||||
#define ELM_WIDGET_ITEM_PROTECTED
|
||||
#define EFL_UI_FOCUS_COMPOSITION_PROTECTED
|
||||
|
||||
#include <Elementary.h>
|
||||
#include <Elementary_Cursor.h>
|
||||
|
@ -15,6 +16,8 @@
|
|||
#include "elm_priv.h"
|
||||
#include "elm_widget_genlist.h"
|
||||
#include "elm_interface_scrollable.h"
|
||||
#include "efl_ui_focus_parent_provider_gen.eo.h"
|
||||
#include "efl_ui_focus_composition_adapter.eo.h"
|
||||
#include "elm_genlist_item.eo.h"
|
||||
#include "elm_genlist_pan.eo.h"
|
||||
#include "elm_genlist.eo.h"
|
||||
|
@ -403,6 +406,8 @@ _item_content_realize(Elm_Gen_Item *it,
|
|||
Eina_List *source;
|
||||
const char *key;
|
||||
|
||||
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
|
||||
|
||||
if (!parts)
|
||||
{
|
||||
EINA_LIST_FREE(*contents, content)
|
||||
|
@ -437,6 +442,7 @@ _item_content_realize(Elm_Gen_Item *it,
|
|||
|
||||
if (content != old)
|
||||
{
|
||||
eina_hash_add(sd->content_item_map, &content, it->base->eo_obj);
|
||||
// FIXME: Genlist item doesn't update its size when the size of
|
||||
// content is changed, so deferred calculation for content should
|
||||
// be performed before realization.
|
||||
|
@ -472,6 +478,7 @@ out:
|
|||
{
|
||||
*contents = eina_list_remove(*contents, old);
|
||||
evas_object_del(old);
|
||||
eina_hash_del_by_key(sd->content_item_map, &old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1684,6 +1691,7 @@ _item_cache_find(Elm_Gen_Item *it)
|
|||
static Eina_List *
|
||||
_content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
|
||||
{
|
||||
ELM_GENLIST_DATA_GET_FROM_ITEM(it, pd);
|
||||
Evas_Object *content = NULL;
|
||||
EINA_LIST_FREE(it->contents, content)
|
||||
{
|
||||
|
@ -1691,6 +1699,7 @@ _content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
|
|||
elm_widget_disabled_set(content, EINA_FALSE);
|
||||
|
||||
*cache = eina_list_append(*cache, content);
|
||||
eina_hash_del_by_key(pd->content_item_map, &content);
|
||||
}
|
||||
|
||||
return *cache;
|
||||
|
@ -5786,16 +5795,50 @@ elm_genlist_add(Evas_Object *parent)
|
|||
return elm_legacy_add(MY_CLASS, parent);
|
||||
}
|
||||
|
||||
static void
|
||||
_genlist_element_focused(void *data, const Efl_Event *ev)
|
||||
{
|
||||
ELM_GENLIST_DATA_GET(data, pd);
|
||||
Elm_Widget *focused = efl_ui_focus_manager_focus_get(ev->object);
|
||||
Elm_Widget_Item *item;
|
||||
|
||||
if (!focused) return;
|
||||
|
||||
if (efl_isa(focused, EFL_UI_FOCUS_COMPOSITION_ADAPTER_CLASS))
|
||||
item = efl_parent_get(focused);
|
||||
else
|
||||
item = efl_ui_focus_parent_provider_find_logical_parent(pd->provider, focused);
|
||||
|
||||
if (efl_isa(item, ELM_GENLIST_ITEM_CLASS))
|
||||
{
|
||||
_elm_genlist_item_focused(item);
|
||||
_all_items_deselect(pd);
|
||||
elm_genlist_item_selected_set(item, EINA_TRUE);
|
||||
elm_genlist_item_bring_in(item, ELM_GENLIST_ITEM_SCROLLTO_MIDDLE);
|
||||
}
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_elm_genlist_efl_object_constructor(Eo *obj, Elm_Genlist_Data *sd)
|
||||
{
|
||||
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
||||
|
||||
sd->content_item_map = eina_hash_pointer_new(NULL);
|
||||
sd->provider = efl_add(EFL_UI_FOCUS_PARENT_PROVIDER_GEN_CLASS, obj,
|
||||
efl_ui_focus_parent_provider_gen_container_set(efl_added, obj),
|
||||
efl_ui_focus_parent_provider_gen_content_item_map_set(efl_added, sd->content_item_map));
|
||||
|
||||
efl_ui_focus_composition_custom_manager_set(obj, obj);
|
||||
efl_ui_focus_composition_logical_mode_set(obj, EINA_TRUE);
|
||||
|
||||
sd->obj = obj;
|
||||
|
||||
efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
|
||||
evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
|
||||
efl_access_role_set(obj, EFL_ACCESS_ROLE_LIST);
|
||||
|
||||
efl_event_callback_add(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, _genlist_element_focused, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -5924,17 +5967,7 @@ _item_select(Elm_Gen_Item *it)
|
|||
|
||||
if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
|
||||
{
|
||||
Evas_Object *swallow_obj;
|
||||
Eina_List *l;
|
||||
EINA_LIST_FOREACH(it->contents, l, swallow_obj)
|
||||
{
|
||||
if (elm_widget_is(swallow_obj) && elm_object_focus_get(swallow_obj))
|
||||
{
|
||||
elm_object_focus_set(obj, EINA_FALSE);
|
||||
elm_object_focus_set(obj, EINA_TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
efl_ui_focus_manager_focus_set(obj, it->base->eo_obj);
|
||||
}
|
||||
|
||||
evas_object_unref(obj);
|
||||
|
@ -6191,6 +6224,8 @@ _elm_genlist_item_new(Elm_Genlist_Data *sd,
|
|||
it->item->expanded_depth = depth;
|
||||
sd->item_count++;
|
||||
|
||||
efl_ui_focus_composition_dirty(sd->obj);
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
|
@ -8702,6 +8737,54 @@ _elm_genlist_efl_access_selection_child_deselect(Eo *obj EINA_UNUSED, Elm_Genlis
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Object*
|
||||
_elm_genlist_efl_object_provider_find(Eo *obj, Elm_Genlist_Data *pd, const Efl_Object *klass)
|
||||
{
|
||||
if (klass == EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE)
|
||||
return pd->provider;
|
||||
return efl_provider_find(efl_super(obj, ELM_GENLIST_CLASS), klass);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_elm_genlist_efl_ui_focus_composition_prepare(Eo *obj, Elm_Genlist_Data *pd)
|
||||
{
|
||||
Elm_Gen_Item *item;
|
||||
Eina_List *order = NULL;
|
||||
|
||||
EINA_INLIST_FOREACH(pd->items, item)
|
||||
{
|
||||
if (item->base->disabled)
|
||||
continue;
|
||||
|
||||
order = eina_list_append(order, item->base->eo_obj);
|
||||
}
|
||||
|
||||
efl_ui_focus_composition_elements_set(obj, order);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_elm_genlist_item_efl_ui_focus_object_prepare_logical(Eo *obj, Elm_Gen_Item *pd)
|
||||
{
|
||||
Eina_List *n;
|
||||
Elm_Widget *wid;
|
||||
|
||||
_item_realize(pd, pd->item->order_num_in, EINA_FALSE);
|
||||
|
||||
EINA_LIST_FOREACH(pd->contents, n, wid)
|
||||
{
|
||||
if (efl_isa(wid, ELM_WIDGET_CLASS))
|
||||
_elm_widget_full_eval(wid);
|
||||
}
|
||||
|
||||
efl_ui_focus_object_prepare_logical(efl_super(obj, ELM_GENLIST_ITEM_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_elm_genlist_elm_widget_focus_state_apply(Eo *obj, Elm_Genlist_Data *pd EINA_UNUSED, Elm_Widget_Focus_State current_state, Elm_Widget_Focus_State *configured_state, Elm_Widget *redirect EINA_UNUSED)
|
||||
{
|
||||
return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj);
|
||||
}
|
||||
|
||||
/* Standard widget overrides */
|
||||
|
||||
ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(elm_genlist, Elm_Genlist_Data)
|
||||
|
|
|
@ -2,7 +2,7 @@ import elm_general;
|
|||
import elm_list;
|
||||
import elm_genlist_item;
|
||||
|
||||
class Elm.Genlist (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
||||
class Elm.Genlist (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
||||
Elm.Interface.Atspi_Widget_Action, Efl.Access.Selection,
|
||||
Efl.Ui.Selectable)
|
||||
{
|
||||
|
@ -301,7 +301,7 @@ class Elm.Genlist (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
|||
|
||||
This returns a list of the realized items in the genlist.
|
||||
The list contains genlist item pointers. The list must be
|
||||
freed by the caller when done with \@ref eina_list_free. The
|
||||
freed by the caller when done with \@ref eina_list_free. The
|
||||
item pointers in the list are only valid so long as those
|
||||
items are not deleted or the genlist is not deleted.
|
||||
]]
|
||||
|
@ -331,7 +331,7 @@ class Elm.Genlist (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
|||
[[Get the last item in the genlist
|
||||
|
||||
This returns the last item in the list.
|
||||
|
||||
|
||||
If filter is set to genlist, it returns
|
||||
last filtered item in the list.
|
||||
]]
|
||||
|
@ -532,6 +532,7 @@ class Elm.Genlist (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
|||
Efl.Gfx.position { set; }
|
||||
Efl.Gfx.size { set; }
|
||||
Efl.Canvas.Group.group_member_add;
|
||||
Efl.Object.provider_find;
|
||||
Elm.Widget.theme_apply;
|
||||
Elm.Widget.widget_sub_object_add;
|
||||
Elm.Widget.on_access_update;
|
||||
|
@ -554,6 +555,8 @@ class Elm.Genlist (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
|||
Efl.Access.Selection.is_child_selected;
|
||||
Efl.Access.Selection.all_children_select;
|
||||
Efl.Access.Selection.clear;
|
||||
Efl.Ui.Focus.Composition.prepare;
|
||||
Elm.Widget.focus_state_apply;
|
||||
}
|
||||
events {
|
||||
item,focused; [[Called when genlist item got focus]]
|
||||
|
@ -568,11 +571,11 @@ class Elm.Genlist (Efl.Ui.Layout, Elm.Interface_Scrollable, Efl.Ui.Clickable,
|
|||
edge,bottom; [[Called when bottom edge is reached]]
|
||||
edge,left; [[Called when left edge is reached]]
|
||||
edge,right; [[Called when right edge is reached]]
|
||||
moved; [[Called when genlist item moved]]
|
||||
moved; [[Called when genlist item moved]]
|
||||
moved,before; [[Called when genlist item moved before]]
|
||||
moved,after; [[Called when genlist item moved after]]
|
||||
swipe; [[Called when swipe is detected]]
|
||||
multi,pinch,in; [[Called when multitouch pinch in detected]]
|
||||
multi,pinch,in; [[Called when multitouch pinch in detected]]
|
||||
multi,pinch,out; [[Called when multitouch pinch out detected]]
|
||||
multi,swipe,down; [[Called when multitouch swipe down detected]]
|
||||
multi,swipe,up; [[Called when multitouch swipe up detected]]
|
||||
|
|
|
@ -38,7 +38,7 @@ enum Elm.Genlist.Item.Scrollto_Type
|
|||
bottom = (1 << 3) [[To the bottom of viewport.]]
|
||||
}
|
||||
|
||||
class Elm.Genlist.Item(Elm.Widget.Item)
|
||||
class Elm.Genlist.Item(Elm.Widget.Item.Static_Focus)
|
||||
{
|
||||
[[Elementary genlist item class]]
|
||||
legacy_prefix: elm_genlist_item;
|
||||
|
@ -223,7 +223,7 @@ class Elm.Genlist.Item(Elm.Widget.Item)
|
|||
@property select_mode {
|
||||
get {
|
||||
[[Get the genlist item's select mode.
|
||||
|
||||
|
||||
It's ELM_OBJECT_SELECT_MODE_MAX on failure.
|
||||
]]
|
||||
}
|
||||
|
@ -461,5 +461,6 @@ class Elm.Genlist.Item(Elm.Widget.Item)
|
|||
Elm.Widget.Item.cursor_unset;
|
||||
Efl.Access.name { get; }
|
||||
Efl.Access.state_set { get; }
|
||||
Efl.Ui.Focus.Object.prepare_logical;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,9 @@ struct _Elm_Genlist_Data
|
|||
Ecore_Idle_Enterer *queue_filter_enterer;
|
||||
Eina_Hash *size_caches;
|
||||
|
||||
Eina_Hash *content_item_map;
|
||||
Eo *provider;
|
||||
|
||||
Eina_Bool filter;
|
||||
Eina_Bool focus_on_selection_enabled : 1;
|
||||
Eina_Bool tree_effect_enabled : 1;
|
||||
|
|
Loading…
Reference in New Issue