edje: support filtering allowed seats per part

collections.group.parts.part.allowed_seats keeps a list
of seat names to be used for events filter.

So when evas devices of seat type are added, filters
may be applied for each part.

If no seat is listed, every seat may interact with such
part.
This commit is contained in:
Bruno Dilly 2016-12-07 21:10:34 -02:00
parent 65723a190a
commit 9308410479
6 changed files with 199 additions and 0 deletions

View File

@ -313,6 +313,7 @@ static void st_collections_group_parts_part_dragable_y(void);
static void st_collections_group_parts_part_dragable_confine(void);
static void st_collections_group_parts_part_dragable_threshold(void);
static void st_collections_group_parts_part_dragable_events(void);
static void st_collections_group_parts_part_allowed_seats(void);
/* box and table items share these */
static void ob_collections_group_parts_part_box_items_item(void);
@ -789,6 +790,7 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.parts.part.cursor_mode", st_collections_group_parts_part_cursor_mode},
{"collections.group.parts.part.multiline", st_collections_group_parts_part_multiline},
{"collections.group.parts.part.access", st_collections_group_parts_part_access},
{"collections.group.parts.part.allowed_seats", st_collections_group_parts_part_allowed_seats},
IMAGE_SET_STATEMENTS("collections.group.parts.part")
IMAGE_STATEMENTS("collections.group.parts.part.")
{"collections.group.parts.part.font", st_fonts_font}, /* dup */
@ -4418,6 +4420,36 @@ _part_copy(Edje_Part *ep, Edje_Part *ep2)
ep->dragable.count_y = ep2->dragable.count_y;
ep->nested_children_count = ep2->nested_children_count;
if (ep2->allowed_seats)
{
Edje_Part_Allowed_Seat *seat;
unsigned int s;
ep->allowed_seats_count = ep2->allowed_seats_count;
ep->allowed_seats = calloc(ep2->allowed_seats_count,
sizeof(Edje_Part_Allowed_Seat *));
if (!ep->allowed_seats)
{
ERR("Not enough memory.");
exit(-1);
}
for (s = 0; s < ep->allowed_seats_count; s++)
{
seat = mem_alloc(SZ(Edje_Part_Allowed_Seat));
if (ep2->allowed_seats[s]->name)
{
seat->name = strdup(ep2->allowed_seats[s]->name);
if (!seat->name)
{
ERR("Not enough memory.");
exit(-1);
}
}
ep->allowed_seats[s] = seat;
}
}
data_queue_copied_part_lookup(pc, &(ep2->dragable.confine_id), &(ep->dragable.confine_id));
data_queue_copied_part_lookup(pc, &(ep2->dragable.threshold_id), &(ep->dragable.threshold_id));
data_queue_copied_part_lookup(pc, &(ep2->dragable.event_id), &(ep->dragable.event_id));
@ -5827,6 +5859,9 @@ edje_cc_handlers_part_make(int id)
ep->items = NULL;
ep->nested_children_count = 0;
ep->allowed_seats = NULL;
ep->allowed_seats_count = 0;
epp = (Edje_Part_Parser *)ep;
epp->reorder.insert_before = NULL;
epp->reorder.insert_after = NULL;
@ -6022,6 +6057,13 @@ _part_free(Edje_Part_Collection *pc, Edje_Part *ep)
free(ep->items[j]);
free(ep->items);
for (j = 0 ; j < ep->allowed_seats_count; j++)
{
free((void*)(ep->allowed_seats[j]->name));
free(ep->allowed_seats[j]);
}
free(ep->allowed_seats);
free((void*)ep->name);
free((void*)ep->source);
free((void*)ep->source2);
@ -7398,6 +7440,53 @@ st_collections_group_parts_part_dragable_events(void)
}
}
/**
@page edcref
@property
allowed_seats
@parameters
[seat1] [seat2] [seat3] ...
@effect
List of seat names allowed to interact with the part.
If no list is defined all seats are allowed. It's the
default behaviour.
If a seat isn't allowed, no signals will be emitted
related to its actions, as mouse and focus events.
Also it won't be able to focus this part.
@since 1.19
@endproperty
*/
static void
st_collections_group_parts_part_allowed_seats(void)
{
Edje_Part_Allowed_Seat *seat;
Edje_Part *ep;
int n, argc;
check_min_arg_count(1);
ep = current_part;
argc = get_arg_count();
ep->allowed_seats = calloc(argc, sizeof(Edje_Part_Allowed_Seat *));
if (!ep->allowed_seats)
{
ERR("Not enough memory.");
exit(-1);
}
for (n = 0; n < argc; n++)
{
seat = mem_alloc(SZ(Edje_Part_Allowed_Seat));
seat->name = parse_str(n);
ep->allowed_seats[n] = seat;
}
ep->allowed_seats_count = argc;
}
/** @edcsubsection{collections_group_parts_items,
* Group.Parts.Part.Box/Table.Items} */

View File

@ -37,6 +37,8 @@ Eet_Data_Descriptor *_edje_edd_edje_pack_element = NULL;
Eet_Data_Descriptor *_edje_edd_edje_pack_element_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_allowed_seat = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_allowed_seat_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_variant = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_rectangle = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_snapshot = NULL;
@ -690,6 +692,8 @@ _edje_edd_shutdown(void)
FREED(_edje_edd_edje_pack_element_pointer);
FREED(_edje_edd_edje_part);
FREED(_edje_edd_edje_part_pointer);
FREED(_edje_edd_edje_part_allowed_seat);
FREED(_edje_edd_edje_part_allowed_seat_pointer);
FREED(_edje_edd_edje_part_description_variant);
FREED(_edje_edd_edje_part_description_rectangle);
FREED(_edje_edd_edje_part_description_snapshot);
@ -946,6 +950,11 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_tag, Edje_Style_Tag, "key", key, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_style_tag, Edje_Style_Tag, "value", value, EET_T_STRING);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Allowed_Seat);
_edje_edd_edje_part_allowed_seat =
eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_allowed_seat, Edje_Part_Allowed_Seat, "name", name, EET_T_STRING);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Style);
_edje_edd_edje_style =
eet_data_descriptor_file_new(&eddc);
@ -1766,6 +1775,10 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "nested_children_count", nested_children_count, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "required", required, EET_T_UCHAR);
EDJE_DEFINE_POINTER_TYPE(Part_Allowed_Seat, part_allowed_seat);
EET_DATA_DESCRIPTOR_ADD_VAR_ARRAY(_edje_edd_edje_part, Edje_Part, "allowed_seats", allowed_seats, _edje_edd_edje_part_allowed_seat_pointer);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Limit);
_edje_edd_edje_part_limit = eet_data_descriptor_file_new(&eddc);

View File

@ -15248,6 +15248,19 @@ _edje_generate_source_of_part(Evas_Object *obj, Edje_Part *ep, Eina_Strbuf *buf)
BUF_APPEND(I4 "precise_is_inside: 1;\n");
if (rp->part->access)
BUF_APPEND(I4 "access: 1;\n");
if (rp->part->allowed_seats)
{
Edje_Part_Allowed_Seat *seat;
unsigned int i;
BUF_APPEND(I4 "allowed_seats:");
for (i = 0; i < rp->part->allowed_seats_count; i++)
{
seat = rp->part->allowed_seats[i];
BUF_APPENDF(" %s", seat->name);
}
BUF_APPEND(";\n");
}
if ((str = _edje_part_clip_to_get(ed, rp)))
{

View File

@ -507,6 +507,60 @@ _edje_physics_world_update_cb(void *data, EPhysics_World *world EINA_UNUSED, voi
}
#endif
Eina_Bool
_edje_part_allowed_seat_find(Edje_Real_Part *rp, const char *seat_name)
{
const char *name;
unsigned int i;
for (i = 0; i < rp->part->allowed_seats_count; i++)
{
name = rp->part->allowed_seats[i]->name;
if (!strcmp(seat_name, name))
return EINA_TRUE;
}
return EINA_FALSE;
}
/* It goes throught the list of registered seats and
* set event filters for each of these seats. */
static void
_edje_part_seat_filter_apply(Edje *ed, Edje_Real_Part *rp)
{
Edje_Seat *seat;
Eina_List *l;
Eina_Bool found;
EINA_LIST_FOREACH(ed->seats, l, seat)
{
found = _edje_part_allowed_seat_find(rp, seat->name);
efl_input_seat_event_filter_set(rp->object, seat->device, found);
}
}
/* It goes throught the list of all edje parts and
* set event filters for each of these parts. Should be called when
* a new seat is added.
*/
static void
_edje_seat_event_filter_apply(Edje *ed, Edje_Seat *seat)
{
Edje_Real_Part *rp;
unsigned short i;
Eina_Bool found;
for (i = 0; i < ed->table_parts_size; i++)
{
rp = ed->table_parts[i];
if (!rp->part->allowed_seats)
continue;
found = _edje_part_allowed_seat_find(rp, seat->name);
efl_input_seat_event_filter_set(rp->object, seat->device, found);
}
}
static void
_edje_device_add(Edje *ed, Efl_Input_Device *dev)
{
@ -544,6 +598,7 @@ _edje_device_add(Edje *ed, Efl_Input_Device *dev)
snprintf(sig, sizeof(sig), "seat,added,%s,%s", seat->name,
efl_input_device_name_get(dev));
_edje_emit(ed, sig, "");
_edje_seat_event_filter_apply(ed, seat);
seat_err:
eina_stringshare_del(name);
@ -645,6 +700,8 @@ _edje_device_changed_cb(void *data, const Efl_Event *event)
eina_stringshare_del(seat->name);
free(seat);
_edje_seat_event_filter_apply(ed, s);
return;
}
}
@ -652,6 +709,7 @@ _edje_device_changed_cb(void *data, const Efl_Event *event)
snprintf(sig, sizeof(sig), "seat,renamed,%s,%s", seat->name, name);
eina_stringshare_replace(&seat->name, name);
_edje_emit(ed, sig, "");
_edje_seat_event_filter_apply(ed, seat);
}
static void
@ -1093,6 +1151,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
nested_smart = NULL;
}
if (ep->allowed_seats)
_edje_part_seat_filter_apply(ed, rp);
if (ep->no_render)
efl_canvas_object_no_render_set(rp->object, 1);
@ -2228,6 +2289,14 @@ _edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec, Edje_Part_Collec
for (j = 0; j < ep->items_count; ++j)
free(ep->items[j]);
free(ep->items);
for (j = 0; j < ep->allowed_seats_count; ++j)
{
if (edf->free_strings)
eina_stringshare_del(ep->allowed_seats[j]->name);
free(ep->allowed_seats[j]);
}
free(ep->allowed_seats);
// technically need this - but we ASSUME we use "one_big" so everything gets
// freed in one go lower down when we del the mempool... but what if pool goes
// "over"?

View File

@ -377,6 +377,7 @@ typedef struct _Edje_Part_Box_Animation Edje_Part_Box_Animation;
typedef struct _Edje_Part_Limit Edje_Part_Limit;
typedef struct _Edje_Part_Description_Vector Edje_Part_Description_Vector;
typedef struct _Edje_Part_Description_Spec_Svg Edje_Part_Description_Spec_Svg;
typedef struct _Edje_Part_Allowed_Seat Edje_Part_Allowed_Seat;
typedef struct _Edje_Real_Part_Vector Edje_Real_Part_Vector;
typedef struct _Edje_Vector_Data Edje_Vector_Data;
@ -1195,6 +1196,8 @@ struct _Edje_Part
unsigned int items_count;
Edje_3D_Vec scale_3d;
Edje_Part_Api api;
Edje_Part_Allowed_Seat **allowed_seats;
unsigned int allowed_seats_count;
unsigned char type; /* what type (image, rect, text) */
#ifdef HAVE_EPHYSICS
unsigned char physics_body; /* body (none, rigid box, soft circle, ...) */
@ -1628,6 +1631,12 @@ struct _Edje_Part_Description_Vector
Edje_Part_Description_Spec_Svg vg;
};
struct _Edje_Part_Allowed_Seat
{
const char *name;
};
/*----------*/
struct _Edje_Signal_Source_Char
@ -2495,6 +2504,7 @@ void _edje_part_focus_set(Edje *ed, const char *seat_name, Edje_Real_Part *rp);
Eina_Stringshare *_edje_seat_name_get(Edje *ed, Efl_Input_Device *device);
Efl_Input_Device *_edje_seat_get(Edje *ed, Eina_Stringshare *name);
Eina_Bool _edje_part_allowed_seat_find(Edje_Real_Part *rp, const char *seat_name);
const Edje_Signals_Sources_Patterns *_edje_signal_callback_patterns_ref(const Edje_Signal_Callback_Group *gp);
void _edje_signal_callback_patterns_unref(const Edje_Signals_Sources_Patterns *essp);

View File

@ -662,6 +662,10 @@ _edje_part_focus_set(Edje *ed, const char *seat_name, Edje_Real_Part *rp)
if (focused_part != rp)
{
if ((rp->part->allowed_seats) &&
(!_edje_part_allowed_seat_find(rp, sname)))
goto not_allowed;
if (focused_part)
_edje_seat_name_emit(ed, sname, "focus,part,out",
focused_part->part->name);
@ -670,6 +674,7 @@ _edje_part_focus_set(Edje *ed, const char *seat_name, Edje_Real_Part *rp)
_edje_seat_name_emit(ed, sname, "focus,part,in", rp->part->name);
}
not_allowed:
eina_stringshare_del(sname);
}