discomfitor pushed a commit to branch master.

http://git.enlightenment.org/core/enlightenment.git/commit/?id=57c448739a852f34031ab7920286e835d72a01cc

commit 57c448739a852f34031ab7920286e835d72a01cc
Author: Mike Blumenkrantz <zm...@osg.samsung.com>
Date:   Fri Aug 11 18:48:53 2017 -0400

    add support for external gadget providers in the gadget editor
    
    this allows external gadget managers to add their gadget types into
    existing editor/layouts
---
 src/bin/e_gadget.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++----
 src/bin/e_gadget.h |   7 ++
 2 files changed, 205 insertions(+), 14 deletions(-)

diff --git a/src/bin/e_gadget.c b/src/bin/e_gadget.c
index ca1f2b2a0..f6fca87e3 100644
--- a/src/bin/e_gadget.c
+++ b/src/bin/e_gadget.c
@@ -44,6 +44,11 @@ struct E_Gadget_Config
 {
    EINA_INLIST;
    int id;
+   struct
+   {
+      Eina_Stringshare *domain;
+      Eina_Stringshare *type;
+   } external;
    int zone;
    Eina_Stringshare *type;
    E_Object *e_obj_inherit;
@@ -85,6 +90,13 @@ typedef struct E_Gadget_Sites
    Eina_List *sites;
 } E_Gadget_Sites;
 
+typedef struct E_Gadget_External_Type
+{
+   E_Gadget_External_Create_Cb cb;
+   E_Gadget_External_Wizard_Cb wizard;
+   E_Gadget_External_Name_Cb name;
+} E_Gadget_External_Type;
+
 typedef struct E_Gadget_Type
 {
    E_Gadget_Create_Cb cb;
@@ -110,6 +122,7 @@ static Eina_Bool added;
 static Evas_Object *pointer_site;
 static Eina_List *handlers;
 
+static Eina_Hash *gadget_external_domains;
 static Eina_Hash *gadget_types;
 static E_Gadget_Sites *sites;
 static Ecore_Event_Handler *comp_add_handler;
@@ -145,6 +158,16 @@ _site_recalc_job(E_Gadget_Site *zgs)
    zgs->calc_job = ecore_job_add((Ecore_Cb)_site_recalc_job_cb, zgs);
 }
 
+static E_Gadget_External_Type *
+_gadget_external_type_get(const char *domain, const char *type)
+{
+   Eina_Hash *h;
+   if (!gadget_external_domains) return NULL;
+   h = eina_hash_find(gadget_external_domains, domain);
+   if (!h) return NULL;
+   return eina_hash_find(h, type);
+}
+
 static Eina_Bool
 _editor_site_visible(void)
 {
@@ -179,6 +202,8 @@ _gadget_free(E_Gadget_Config *zgc)
 {
    evas_object_del(zgc->display);
    eina_stringshare_del(zgc->type);
+   eina_stringshare_del(zgc->external.type);
+   eina_stringshare_del(zgc->external.domain);
    eina_stringshare_del(zgc->style.name);
    free(zgc);
 }
@@ -430,17 +455,29 @@ _gadget_object_hints(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj EINA_UNUS
 static Eina_Bool
 _gadget_object_create(E_Gadget_Config *zgc)
 {
-   E_Gadget_Type *t;
+   E_Gadget_Type *t = NULL;
+   E_Gadget_External_Type *te = NULL;
    Evas_Object *g;
 
-   t = eina_hash_find(gadget_types, zgc->type);
-   if (!t) return EINA_TRUE; //can't create yet
+   if (zgc->external.domain)
+     {
+        te = _gadget_external_type_get(zgc->external.domain, 
zgc->external.type);
+        if (!te) return EINA_TRUE; //can't create yet
+     }
+   else
+     {
+        t = eina_hash_find(gadget_types, zgc->type);
+        if (!t) return EINA_TRUE; //can't create yet
+     }
 
    if (!zgc->id)
      {
-        if (t->wizard)
+        if ((t && t->wizard) || (te && te->wizard))
           {
-             zgc->cfg_object = t->wizard(_gadget_wizard_end, zgc, 
zgc->site->layout);
+             if (t)
+               zgc->cfg_object = t->wizard(_gadget_wizard_end, zgc, 
zgc->site->layout);
+             else
+               zgc->cfg_object = te->wizard(_gadget_wizard_end, zgc, 
zgc->external.type, zgc->site->layout);
              if (!zgc->cfg_object)
                {
                   added = 1;
@@ -464,7 +501,10 @@ _gadget_object_create(E_Gadget_Config *zgc)
     * a gadget should return NULL for any demo instance where it
     * should not be shown
     */
-   g = t->cb(zgc->site->layout, &zgc->id, zgc->site->orient);
+   if (t)
+     g = t->cb(zgc->site->layout, &zgc->id, zgc->site->orient);
+   else
+     g = te->cb(zgc->site->layout, zgc->external.type, &zgc->id, 
zgc->site->orient);
    if (zgc->id < 0)
      {
         if (!g) return EINA_FALSE;
@@ -508,6 +548,8 @@ _gadget_object_finalize(E_Gadget_Config *zgc)
    zgc->site->gadgets = eina_list_remove(zgc->site->gadgets, zgc);
    zgc->site->gadget_list = eina_inlist_remove(zgc->site->gadget_list, 
EINA_INLIST_GET(zgc));
    eina_stringshare_del(zgc->type);
+   eina_stringshare_del(zgc->external.type);
+   eina_stringshare_del(zgc->external.domain);
    free(zgc);
 }
 
@@ -892,13 +934,19 @@ _gadget_mouse_resize(E_Gadget_Config *zgc, int t 
EINA_UNUSED, Ecore_Event_Mouse_
 }
 
 static void
-_gadget_util_add(E_Gadget_Site *zgs, const char *type, int id)
+_gadget_util_add(E_Gadget_Site *zgs, const char *domain, const char *type, int 
id)
 {
    E_Gadget_Config *zgc;
 
    zgc = E_NEW(E_Gadget_Config, 1);
    zgc->id = id;
-   zgc->type = eina_stringshare_add(type);
+   if (domain)
+     {
+        zgc->external.domain = eina_stringshare_add(domain);
+        zgc->external.type = eina_stringshare_add(type);
+     }
+   else
+     zgc->type = eina_stringshare_add(type);
    zgc->x = zgc->y = -1;
    zgc->site = zgs;
    zgc->zone = -1;
@@ -947,7 +995,10 @@ _gadget_act_move(E_Object *obj, const char *params 
EINA_UNUSED, E_Binding_Event_
    _editor_pointer_site_init(zgc->site->orient, NULL, NULL, 1);
    e_gadget_site_owner_setup(pointer_site, zgc->site->anchor, NULL);
    ZGS_GET(pointer_site);
-   _gadget_util_add(zgs, zgc->type, zgc->id);
+   if (zgc->external.domain)
+     _gadget_util_add(zgs, zgc->external.domain, zgc->external.type, zgc->id);
+   else
+     _gadget_util_add(zgs, NULL, zgc->type, zgc->id);
    z = eina_list_data_get(zgs->gadgets);
    evas_object_geometry_get(g, NULL, NULL, &w, &h);
    evas_object_resize(pointer_site, w, h);
@@ -1671,7 +1722,19 @@ e_gadget_site_gadget_add(Evas_Object *obj, const char 
*type, Eina_Bool demo)
    id -= demo;
    EINA_SAFETY_ON_NULL_RETURN(gadget_types);
    ZGS_GET(obj);
-   _gadget_util_add(zgs, type, id);
+   _gadget_util_add(zgs, NULL, type, id);
+}
+
+E_API void
+e_gadget_site_gadget_external_add(Evas_Object *obj, const char *domain, const 
char *type, Eina_Bool demo)
+{
+   int id = 0;
+
+   demo = !!demo;
+   id -= demo;
+   EINA_SAFETY_ON_NULL_RETURN(gadget_types);
+   ZGS_GET(obj);
+   _gadget_util_add(zgs, domain, type, id);
 }
 
 E_API Evas_Object *
@@ -1715,7 +1778,7 @@ e_gadget_type_get(Evas_Object *g)
    EINA_SAFETY_ON_NULL_RETURN_VAL(g, NULL);
    zgc = evas_object_data_get(g, "__e_gadget");
    EINA_SAFETY_ON_NULL_RETURN_VAL(zgc, NULL);
-   return zgc->type;
+   return zgc->external.type ?: zgc->type;
 }
 
 E_API void
@@ -1759,6 +1822,82 @@ e_gadget_type_del(const char *type)
    eina_hash_del_by_key(gadget_types, type);
 }
 
+E_API void
+e_gadget_external_type_add(const char *domain, const char *type, 
E_Gadget_External_Create_Cb callback, E_Gadget_External_Wizard_Cb wizard)
+{
+   E_Gadget_External_Type *te;
+   Eina_List *l, *ll;
+   E_Gadget_Site *zgs;
+   E_Gadget_Config *zgc;
+   Eina_Hash *h = NULL;
+
+   if (gadget_external_domains)
+     {
+        h = eina_hash_find(gadget_external_domains, domain);
+        if (h)
+          EINA_SAFETY_ON_TRUE_RETURN(!!eina_hash_find(h, type));
+     }
+   else
+     gadget_external_domains = 
eina_hash_string_superfast_new((Eina_Free_Cb)eina_hash_free);
+   if (!h)
+     {
+        h = eina_hash_string_superfast_new(free);
+        eina_hash_add(gadget_external_domains, domain, h);
+     }
+   te = E_NEW(E_Gadget_External_Type, 1);
+   te->cb = callback;
+   te->wizard = wizard;
+   eina_hash_add(h, type, te);
+   EINA_LIST_FOREACH(sites->sites, l, zgs)
+     if (zgs->layout)
+       EINA_LIST_FOREACH(zgs->gadgets, ll, zgc)
+         if (eina_streq(domain, zgc->external.domain) && eina_streq(type, 
zgc->external.type))
+           _gadget_object_create(zgc);
+}
+
+E_API void
+e_gadget_external_type_name_cb_set(const char *domain, const char *type, 
E_Gadget_External_Name_Cb name)
+{
+   E_Gadget_External_Type *te;
+
+   te = _gadget_external_type_get(domain, type);
+   EINA_SAFETY_ON_NULL_RETURN(te);
+   te->name = name;
+}
+
+E_API void
+e_gadget_external_type_del(const char *domain, const char *type)
+{
+   Eina_List *l, *ll;
+   E_Gadget_Site *zgs;
+   E_Gadget_Config *zgc;
+
+   if (!gadget_external_domains) return;
+   if (!sites) return;
+
+   EINA_LIST_FOREACH(sites->sites, l, zgs)
+     {
+        EINA_LIST_FOREACH(zgs->gadgets, ll, zgc)
+          if (eina_streq(domain, zgc->external.domain))
+            {
+               if ((!type) || eina_streq(type, zgc->external.type))
+                 evas_object_del(zgc->gadget);
+            }
+     }
+   if (type)
+     {
+        Eina_Hash *h;
+
+        h = eina_hash_find(gadget_external_domains, domain);
+        EINA_SAFETY_ON_NULL_RETURN(h);
+        eina_hash_del_by_key(h, type);
+        if (!eina_hash_population(h))
+          eina_hash_del_by_key(gadget_external_domains, domain);
+     }
+   else
+     eina_hash_del_by_key(gadget_external_domains, domain);
+}
+
 E_API Eina_Iterator *
 e_gadget_type_iterator_get(void)
 {
@@ -2042,6 +2181,8 @@ e_gadget_init(void)
    E_CONFIG_VAL(edd_gadget, E_Gadget_Config, id, INT);
    E_CONFIG_VAL(edd_gadget, E_Gadget_Config, zone, INT);
    E_CONFIG_VAL(edd_gadget, E_Gadget_Config, type, STR);
+   E_CONFIG_VAL(edd_gadget, E_Gadget_Config, external.domain, STR);
+   E_CONFIG_VAL(edd_gadget, E_Gadget_Config, external.type, STR);
    E_CONFIG_VAL(edd_gadget, E_Gadget_Config, style.name, STR);
    E_CONFIG_VAL(edd_gadget, E_Gadget_Config, x, DOUBLE);
    E_CONFIG_VAL(edd_gadget, E_Gadget_Config, y, DOUBLE);
@@ -2133,6 +2274,7 @@ e_gadget_shutdown(void)
    e_action_predef_name_del(_("Gadgets"), _("Gadget menu"));
    move_act = resize_act = configure_act = menu_act = NULL;
    E_FREE_FUNC(gadget_types, eina_hash_free);
+   E_FREE_FUNC(gadget_external_domains, eina_hash_free);
 }
 
 //////////////////////////////////////////////////////
@@ -2328,17 +2470,23 @@ _editor_gadget_new(void *data, Evas_Object *obj, void 
*event_info)
 {
    Gadget_Item *gi = data;
    E_Gadget_Site_Orient orient;
+   E_Gadget_Config *zgc;
+
+   zgc = evas_object_data_get(gi->gadget, "__e_gadget");
 
    evas_object_hide(desktop_editor);
    evas_object_pass_events_set(desktop_editor, 1);
    orient = e_gadget_site_orient_get(gi->site);
    _editor_pointer_site_init(orient, gi->site, gi->editor, 0);
    e_comp_object_util_del_list_append(gi->editor, pointer_site);
-   
-   e_gadget_site_gadget_add(pointer_site, e_gadget_type_get(gi->gadget), 1);
+
+   if (zgc->external.domain)
+     e_gadget_site_gadget_external_add(pointer_site, zgc->external.domain, 
e_gadget_type_get(gi->gadget), 1);
+   else
+     e_gadget_site_gadget_add(pointer_site, e_gadget_type_get(gi->gadget), 1);
    ZGS_GET(pointer_site);
    {
-      E_Gadget_Config *zgc = eina_list_data_get(zgs->gadgets);
+      zgc = eina_list_data_get(zgs->gadgets);
       zgc->moving = 1;
    }
    elm_object_disabled_set(gi->editor, 1);
@@ -2379,7 +2527,19 @@ _editor_text_get(void *data, Evas_Object *obj 
EINA_UNUSED, const char *part EINA
 {
    char buf[1024];
    Gadget_Item *gi = data;
+   E_Gadget_Config *zgc;
 
+   zgc = evas_object_data_get(gi->gadget, "__e_gadget");
+   if (zgc->external.domain)
+     {
+        E_Gadget_External_Type *te;
+
+        te = _gadget_external_type_get(zgc->external.domain, 
zgc->external.type);
+        if (te->name)
+          return te->name(zgc->external.type);
+        ERR("No name cb for external gadget provider!");
+        return strdup(_("ERROR: NO NAME PROVIDED"));
+     }
    strncpy(buf, e_gadget_type_get(gi->gadget), sizeof(buf) - 1);
    buf[0] = toupper(buf[0]);
    return strdup(buf);
@@ -2440,6 +2600,30 @@ e_gadget_editor_add(Evas_Object *parent, Evas_Object 
*site)
      }
    eina_iterator_free(it);
 
+   if (gadget_external_domains)
+     {
+        Eina_Hash_Tuple *tup;
+
+        it = eina_hash_iterator_tuple_new(gadget_external_domains);
+        EINA_ITERATOR_FOREACH(it, tup)
+          {
+             const char *domain = tup->key;
+             Eina_Hash *h = tup->data;
+             E_Gadget_Config *zgc;
+             Eina_Iterator *typeit = eina_hash_iterator_key_new(h);
+
+             EINA_ITERATOR_FOREACH(typeit, type)
+               {
+                  e_gadget_site_gadget_external_add(tempsite, domain, type, 1);
+                  ZGS_GET(tempsite);
+                  zgc = eina_list_last_data_get(zgs->gadgets);
+                  if (!zgc->gadget) _gadget_remove(zgc);
+               }
+             eina_iterator_free(typeit);
+          }
+        eina_iterator_free(it);
+     }
+
    gadgets = e_gadget_site_gadgets_list(tempsite);
    EINA_LIST_FREE(gadgets, g)
      {
diff --git a/src/bin/e_gadget.h b/src/bin/e_gadget.h
index 90252b6b8..fd92b79fe 100644
--- a/src/bin/e_gadget.h
+++ b/src/bin/e_gadget.h
@@ -90,10 +90,13 @@
 #include "e_gadget_types.h"
 
 typedef Evas_Object *(*E_Gadget_Create_Cb)(Evas_Object *parent, int *id, 
E_Gadget_Site_Orient orient);
+typedef Evas_Object *(*E_Gadget_External_Create_Cb)(Evas_Object *parent, const 
char *type, int *id, E_Gadget_Site_Orient orient);
 typedef Evas_Object *(*E_Gadget_Configure_Cb)(Evas_Object *gadget);
 typedef void (*E_Gadget_Wizard_End_Cb)(void *data, int id);
 typedef Evas_Object *(*E_Gadget_Wizard_Cb)(E_Gadget_Wizard_End_Cb cb, void 
*data, Evas_Object *site);
+typedef Evas_Object *(*E_Gadget_External_Wizard_Cb)(E_Gadget_Wizard_End_Cb cb, 
void *data, const char *type, Evas_Object *site);
 typedef void (*E_Gadget_Style_Cb)(Evas_Object *owner, Eina_Stringshare *name, 
Evas_Object *g);
+typedef char *(*E_Gadget_External_Name_Cb)(const char *type);
 
 EINTERN void e_gadget_init(void);
 EINTERN void e_gadget_shutdown(void);
@@ -108,6 +111,7 @@ E_API E_Gadget_Site_Orient 
e_gadget_site_orient_get(Evas_Object *obj);
 E_API E_Gadget_Site_Gravity e_gadget_site_gravity_get(Evas_Object *obj);
 E_API void e_gadget_site_gravity_set(Evas_Object *obj, E_Gadget_Site_Gravity 
gravity);
 E_API void e_gadget_site_gadget_add(Evas_Object *obj, const char *type, 
Eina_Bool demo);
+E_API void e_gadget_site_gadget_external_add(Evas_Object *obj, const char 
*domain, const char *type, Eina_Bool demo);
 E_API Eina_List *e_gadget_site_gadgets_list(Evas_Object *obj);
 
 E_API void e_gadget_configure_cb_set(Evas_Object *g, E_Gadget_Configure_Cb cb);
@@ -117,6 +121,9 @@ E_API Eina_Stringshare *e_gadget_type_get(Evas_Object *g);
 
 E_API void e_gadget_type_add(const char *type, E_Gadget_Create_Cb callback, 
E_Gadget_Wizard_Cb wizard);
 E_API void e_gadget_type_del(const char *type);
+E_API void e_gadget_external_type_add(const char *domain, const char *type, 
E_Gadget_External_Create_Cb callback, E_Gadget_External_Wizard_Cb wizard);
+E_API void e_gadget_external_type_del(const char *domain, const char *type);
+E_API void e_gadget_external_type_name_cb_set(const char *domain, const char 
*type, E_Gadget_External_Name_Cb name);
 E_API Eina_Iterator *e_gadget_type_iterator_get(void);
 /* delete a gadget and its config */
 E_API void e_gadget_del(Evas_Object *g);

-- 


Reply via email to