bdilly pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9308410479b398169ec81daa6b77ef522a0f84ee

commit 9308410479b398169ec81daa6b77ef522a0f84ee
Author: Bruno Dilly <bdi...@profusion.mobi>
Date:   Wed Dec 7 21:10:34 2016 -0200

    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.
---
 src/bin/edje/edje_cc_handlers.c | 89 +++++++++++++++++++++++++++++++++++++++++
 src/lib/edje/edje_data.c        | 13 ++++++
 src/lib/edje/edje_edit.c        | 13 ++++++
 src/lib/edje/edje_load.c        | 69 ++++++++++++++++++++++++++++++++
 src/lib/edje/edje_private.h     | 10 +++++
 src/lib/edje/edje_program.c     |  5 +++
 6 files changed, 199 insertions(+)

diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index 188e169..c496837 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 6c4ef6a..0af3b13 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 de88db3..291b5af 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 e530926..bdbf698 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 1a2d7db..13dc796 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 ef4cf40..7ab1498 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);
 }
 

-- 


Reply via email to