diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index 188e169a07..c4968377aa 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -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} */ diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index 6c4ef6aec1..0af3b130fb 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -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); diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c index de88db33e4..291b5afaf0 100644 --- a/src/lib/edje/edje_edit.c +++ b/src/lib/edje/edje_edit.c @@ -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))) { diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index e530926c33..bdbf698ca7 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -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"? diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index 1a2d7dbdea..13dc7961dd 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -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); diff --git a/src/lib/edje/edje_program.c b/src/lib/edje/edje_program.c index ef4cf40d05..7ab1498814 100644 --- a/src/lib/edje/edje_program.c +++ b/src/lib/edje/edje_program.c @@ -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); }