This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository efm2.

View the commit online.

commit fe0faf5b5632c21140cf7ab3a47ada4a681f1978
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
AuthorDate: Sat Jul 20 11:48:28 2024 +0100

    add start of efm popup menu infra
    
    built in default menu provider using elm mnenus. idea is you can
    provide an external menu provider too (like e_menu's)
    
    check and radio are not fully baked as we dont have icons in the elm
    menu provider - see comments (also icons in general need to be better)
    
    current test menu does nothing... i will need to handle things like
    if a menu is for an icon - cancel menu if icon deleted. need to handle
    popup menus on blank space too.
    
    probably better also to move menu code to another file?
---
 src/efm/efm.c         | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/efm/efm.h         |  59 ++++++++++++---
 src/efm/efm_private.h |  29 ++++++--
 src/efm/efm_structs.h |   8 ++
 src/efm/efm_util.c    | 196 ++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 477 insertions(+), 15 deletions(-)

diff --git a/src/efm/efm.c b/src/efm/efm.c
index 9800b06..8ae520f 100644
--- a/src/efm/efm.c
+++ b/src/efm/efm.c
@@ -7,6 +7,7 @@
 // maximum number of files in a dir on a real system to be fast with: 3,000
 #include "cmd.h"
 #include "efm.h"
+#include "efl_ui_check_eo.legacy.h"
 #include "efm_icon.h"
 #include "efm_graph.h"
 #include "efm_util.h"
@@ -14,6 +15,7 @@
 #include "efm_back_end.h"
 #include "efm_custom.h"
 #include "efm_private.h"
+#include "eina_types.h"
 
 int _log_dom = -1;
 
@@ -804,6 +806,7 @@ _smart_add(Evas_Object *obj)
                                           -100, _cb_key_down, sd);
   evas_object_event_callback_add(sd->o_clip, EVAS_CALLBACK_FOCUS_OUT,
                                  _cb_focus_out, sd);
+  sd->menu_provider.cb = efm_menu_provider_default;
   _efm_list = eina_list_prepend(_efm_list, obj);
 }
 
@@ -817,6 +820,7 @@ _smart_del(Evas_Object *obj)
   Smart_Data_Timer *st;
   ENTRY;
 
+  efm_menu_provider_select(sd->o_smart, -1);
   _efm_list = eina_list_remove(_efm_list, obj);
   e         = evas_object_evas_get(obj);
   evas_event_callback_del_full(e, EVAS_CALLBACK_CANVAS_VIEWPORT_RESIZE,
@@ -1333,6 +1337,7 @@ _reset(Smart_Data *sd)
   const char  *s;
 
   // clear out stuff there so we can start listing again...
+  efm_menu_provider_select(sd->o_smart, -1);
   sd->file_max = 0;
   EINA_LIST_FREE(sd->blocks, block) _block_free(block);
   while (sd->icons)
@@ -1898,3 +1903,198 @@ efm_backend_set(Evas_Object *obj, const char *backend)
   if (!backend) backend = "default";
   eina_stringshare_replace(&(sd->config.backend), backend);
 }
+
+void
+efm_menu_provider_set(Evas_Object *obj, Efm_Menu_Provider cb, void *data)
+{ // set a func to build/show a menu and handle interaction with it
+  ENTRY;
+
+  sd->menu_provider.cb = cb;
+  sd->menu_provider.data = ""
+}
+
+static Eina_Bool
+_item_find_call(Evas_Object *obj, const Efm_Menu *m, int index)
+{
+  int i;
+
+  for (i = 0; i < m->item_num; i++)
+    {
+      if (m->item[i].index == index)
+        {
+          Efm_Menu_Item_Callback fn = m->item[i].private1;
+
+          if (fn)
+            fn(m->item[i].private2, m->item[i].private3, obj,
+               &(m->item[i]));
+          return EINA_TRUE;
+        }
+      else if (m->item[i].type == EFM_MENU_ITEM_SUBMENU)
+        {
+          if (_item_find_call(obj, m->item[i].sub, index)) return EINA_TRUE;
+        }
+    }
+  return EINA_FALSE;
+}
+
+void
+efm_menu_provider_select(Evas_Object *obj, int index)
+{ // call this to tell efm what was selected, or index -1 for dismissed
+  ENTRY;
+
+  if (!sd->menu_provider.menu) return;
+  if (index == -1)
+    {
+      _efm_menu_del(sd->menu_provider.menu);
+      sd->menu_provider.menu = NULL;
+      sd->menu_provider.menu_data = sd->menu_provider.cb(
+        sd->menu_provider.data, sd->menu_provider.menu_data, obj,
+        NULL, 0, 0);
+    }
+  else
+    {
+      const Efm_Menu *m = sd->menu_provider.menu;
+
+      _item_find_call(obj, m, index);
+   };
+}
+
+void
+_efm_menu_show(Evas_Object *obj, Efm_Menu *m, Evas_Coord x, Evas_Coord y)
+{ // called within efm to ask to show a popup menu, m is NULL to dismiss
+  ENTRY;
+
+  if (!sd->menu_provider.cb) return;
+  sd->menu_provider.menu = m;
+  sd->menu_provider.menu_data
+    = sd->menu_provider.cb(sd->menu_provider.data, sd->menu_provider.menu_data,
+                           obj, sd->menu_provider.menu, x, y);
+}
+
+static void
+_cb_menu_dismissed(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{ // called when the menu is closed
+  efm_menu_provider_select(data, -1);
+}
+
+static void
+_cb_menu_item(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+  Evas_Object *efm = evas_object_data_get(obj, "efm");
+  Efm_Menu_Item *mi  = data;
+
+  efm_menu_provider_select(efm, mi->index);
+}
+
+static void _menu_create_walk(void *data, Evas_Object *obj, const Efm_Menu *m,
+                              Evas_Object *o_menu, Elm_Object_Item *it_parent)
+{
+  int i;
+  Elm_Object_Item *it;
+  Evas_Object     *o, *o_radio = NULL;
+  int             radioval = 0;
+
+  for (i = 0; i < m->item_num; i++)
+   {
+      const Efm_Menu_Item *mi = &(m->item[i]);
+      // XXX: figure out an icon name from mi->icon properly
+      // use elm_object_item_content_set() if needed
+      // e.g.
+      // "std:menu-eject" - native to elm menus (strip std:)
+      // "std:menu/folder" - native to elm menus (strip std:)
+      // "file:/path/to/file.png" - use efm_icon
+      // "/path/to/file.png" - same as above
+      // "icon:/path/to/file" - use efm_icon
+      // "thumb:/path/to/file" - use efm_icon
+      // "video:/path/to/file.mp4" - use efm_icon
+      // "fdo:icon-name" - use efreet to look up icon then use that
+      //
+      // XXX: we have a core problem with elm menus. radio, check OR icon. not
+      // both - maybe use an box or table for menu content and do our own
+      // menu icons ? then we can have a radio/check and icon... to do this
+      // we need to pre-scan all items to see if any have icons at all, and
+      // if any are check or radio - then 0 column, 1 or 2 column for the
+      // box or table and add some padding i guess...
+
+      switch (mi->type)
+        {
+        case EFM_MENU_ITEM_NORMAL:
+          it = elm_menu_item_add(o_menu, it_parent, mi->icon, mi->label,
+                                 _cb_menu_item, mi);
+          o_radio = NULL;
+          break;
+        case EFM_MENU_ITEM_SUBMENU:
+          it = elm_menu_item_add(o_menu, it_parent, mi->icon, mi->label, NULL,
+                                 NULL);
+          _menu_create_walk(data, obj, mi->sub, o_menu, it);
+          o_radio = NULL;
+          break;
+        case EFM_MENU_ITEM_SEPARATOR:
+          elm_menu_item_separator_add(o_menu, it_parent);
+          o_radio = NULL;
+          break;
+        case EFM_MENU_ITEM_CHECK:
+          o = elm_check_add(o_menu);
+          // state change will be handled in cb for original data then rebuild
+          // of menu will reflect that next time it's popped up.
+          it = elm_menu_item_add(o_menu, it_parent, NULL, mi->label,
+                                 _cb_menu_item, mi);
+          elm_check_selected_set(o, mi->selected);
+          elm_object_item_content_set(it, o);
+          o_radio = NULL;
+          break;
+        case EFM_MENU_ITEM_RADIO:
+          o  = elm_radio_add(o_menu);
+          // state change will be handled in cb for original data then rebuild
+          // of menu will reflect that next time it's popped up.
+          it = elm_menu_item_add(o_menu, it_parent, NULL, mi->label,
+                                 _cb_menu_item, mi);
+          if (!o_radio)
+            {
+              o_radio = o;
+              radioval = 0;
+            }
+          else elm_radio_group_add(o, o_radio);
+          elm_radio_state_value_set(o, radioval);
+          if (mi->selected) elm_radio_value_set(o_radio, radioval);
+          elm_object_item_content_set(it, o);
+          radioval++;
+          break;
+        default:
+          break;
+        }
+   }
+}
+
+void *
+efm_menu_provider_default(void *data, void *menu_data, Evas_Object *obj, const Efm_Menu *m,
+                          Evas_Coord x, Evas_Coord y)
+{
+  if (m)
+    {
+      Evas_Object *o, *o_top;
+
+      o_top  = efm_scroller_get(obj);
+      if (o_top) o_top = elm_object_top_widget_get(o_top);
+      else o_top = elm_object_top_widget_get(obj);
+      o      = elm_menu_add(o_top);
+      if (o)
+        {
+          evas_object_data_set(o, "efm", obj);
+          _menu_create_walk(data, obj, m, o, NULL);
+          evas_object_smart_callback_add(o, "dismissed", _cb_menu_dismissed,
+                                         obj);
+          elm_menu_move(o, x, y);
+          evas_object_show(o);
+          elm_menu_open(o);
+          printf("show %p\n", o);
+          return o;
+        }
+    }
+  else
+    {
+      printf("del %p\n", menu_data);
+      if (menu_data) evas_object_del(menu_data);
+    }
+  return NULL;
+}
diff --git a/src/efm/efm.h b/src/efm/efm.h
index 2d34906..03a7e63 100644
--- a/src/efm/efm.h
+++ b/src/efm/efm.h
@@ -34,6 +34,42 @@ typedef enum
   EFM_SORT_MODE_PERMISSIONS = (6 << 0),
 } Efm_Sort_Mode;
 
+typedef struct _Efm_Menu      Efm_Menu;
+typedef struct _Efm_Menu_Item Efm_Menu_Item;
+
+typedef enum
+{
+  EFM_MENU_ITEM_NORMAL,
+  EFM_MENU_ITEM_SUBMENU,
+  EFM_MENU_ITEM_SEPARATOR,
+  EFM_MENU_ITEM_CHECK,
+  EFM_MENU_ITEM_RADIO
+} Efm_Menu_Item_Type;
+
+struct _Efm_Menu_Item
+{
+  Efm_Menu_Item_Type type;
+  const char        *label;
+  const char        *icon;
+  int                index;
+  Eina_Bool          selected;
+  Efm_Menu          *sub;
+  void              *private1; // private to efm - ignore
+  void              *private2; // private to efm - ignore
+  void              *private3; // private to efm - ignore
+};
+
+struct _Efm_Menu
+{
+  const char    *title;
+  const char    *title_icon;
+  int            item_num;
+  Efm_Menu_Item *item;
+};
+
+// call this to build a menu or to close it (menu is NULL for close) - return truw if menu is shown
+typedef void *(*Efm_Menu_Provider) (void *data, void *menu_data, Evas_Object *efm, const Efm_Menu *menu, Evas_Coord x, Evas_Coord y);
+
 Evas_Object  *efm_add(Evas_Object *parent);
 void          efm_scroller_set(Evas_Object *obj, Evas_Object *scroller);
 Evas_Object  *efm_scroller_get(Evas_Object *obj);
@@ -44,17 +80,22 @@ void          efm_path_sort_mode_set(Evas_Object *obj, Efm_Sort_Mode mode);
 Efm_Sort_Mode efm_path_sort_mode_get(Evas_Object *obj);
 Evas_Coord    efm_column_min_get(Evas_Object *obj, int col);
 void          efm_column_min_set(Evas_Object *obj, int col, Evas_Coord w);
-void        efm_column_label_set(Evas_Object *obj, int col, const char *label);
-const char *efm_column_label_get(Evas_Object *obj, int col);
-Evas_Coord  efm_iconsize_get(Evas_Object *obj);
-void        efm_iconsize_set(Evas_Object *obj, Evas_Coord sz);
-const char *efm_backend_get(Evas_Object *obj);
-void        efm_backend_set(Evas_Object *obj, const char *backend);
+void          efm_column_label_set(Evas_Object *obj, int col, const char *label);
+const char   *efm_column_label_get(Evas_Object *obj, int col);
+Evas_Coord    efm_iconsize_get(Evas_Object *obj);
+void          efm_iconsize_set(Evas_Object *obj, Evas_Coord sz);
+const char   *efm_backend_get(Evas_Object *obj);
+void          efm_backend_set(Evas_Object *obj, const char *backend);
+void          efm_menu_provider_set(Evas_Object *obj, Efm_Menu_Provider cb, void *data);
+void          efm_menu_provider_select(Evas_Object *obj, int index);
 
 // alweays call path_Set last after setup above like setting icon size etc.
-void        efm_path_set(Evas_Object *obj, const char *path);
-const char *efm_path_get(Evas_Object *obj);
-void        efm_path_parent(Evas_Object *obj);
+void          efm_path_set(Evas_Object *obj, const char *path);
+const char   *efm_path_get(Evas_Object *obj);
+void          efm_path_parent(Evas_Object *obj);
+
+// default menu provider callback for popup menus
+void         *efm_menu_provider_default(void *data, void *menu_data, Evas_Object *obj, const Efm_Menu *m, Evas_Coord x, Evas_Coord y);
 
 #define DBG(...) EINA_LOG_DOM_DBG(_log_dom, __VA_ARGS__)
 #define INF(...) EINA_LOG_DOM_INFO(_log_dom, __VA_ARGS__)
diff --git a/src/efm/efm_private.h b/src/efm/efm_private.h
index 818bd31..bb98e9f 100644
--- a/src/efm/efm_private.h
+++ b/src/efm/efm_private.h
@@ -16,11 +16,30 @@
   Smart_Data *sd = evas_object_smart_data_get(obj); \
   if (!sd) return
 
-void  _listing_done(Smart_Data *sd);
-void  _cb_header_change(void *data);
-void  _reset(Smart_Data *sd);
-void  _redo_detail_sizes(Smart_Data *sd);
-char *_sanitize_dir(const char *path);
+typedef void (*Efm_Menu_Item_Callback)(void *data, void *data2, Evas_Object *efm, const Efm_Menu_Item *menu_item);
+
+void   _listing_done(Smart_Data *sd);
+void   _cb_header_change(void *data);
+void   _reset(Smart_Data *sd);
+void   _redo_detail_sizes(Smart_Data *sd);
+char  *_sanitize_dir(const char *path);
+
+#define MENU_NORM(_lab, _icn, _idx, _cb, _cbdat) \
+  EFM_MENU_ITEM_NORMAL, _lab, _icn, _idx, EINA_FALSE, NULL, (void *)_cb, (void *)_cbdat
+#define MENU_SUB(_lab, _icn, _sub) \
+  EFM_MENU_ITEM_SUBMENU, _lab, _icn, 0, EINA_FALSE, _sub, NULL, NULL
+#define MENU_SEPARATOR() \
+    EFM_MENU_ITEM_SEPARATOR, NULL, NULL, 0, EINA_FALSE, NULL, NULL, NULL
+
+void _efm_menu_show(Evas_Object *obj, Efm_Menu *m, Evas_Coord x, Evas_Coord y);
+
+Efm_Menu *_efm_menu_add(const char *title, const char *icon);
+void      _efm_menu_del(Efm_Menu *m);
+Efm_Menu_Item *_efm_menu_it_normal(Efm_Menu *m, const char *label, const char *icon, Efm_Menu_Item_Callback cb, void *data, void *data2);
+Efm_Menu_Item *_efm_menu_it_separator(Efm_Menu *m);
+Efm_Menu_Item *_efm_menu_it_sub(Efm_Menu *m, const char *label, const char *icon, Efm_Menu *sub);
+Efm_Menu_Item *_efm_menu_it_radio(Efm_Menu *m, const char *label, const char *icon, Eina_Bool on, Efm_Menu_Item_Callback cb, void *data, void *data2);
+Efm_Menu_Item *_efm_menu_it_check(Efm_Menu *m, const char *label, const char *icon, Eina_Bool on, Efm_Menu_Item_Callback cb, void *data, void *data2);
 
 extern Eina_List *_efm_list;
 extern Eina_List *_pending_exe_dels;
diff --git a/src/efm/efm_structs.h b/src/efm/efm_structs.h
index 78edbe8..2b97514 100644
--- a/src/efm/efm_structs.h
+++ b/src/efm/efm_structs.h
@@ -99,6 +99,14 @@ struct _Smart_Data
 
   unsigned long long file_max; // larges file size in dir
 
+  struct
+  {
+    Efm_Menu_Provider  cb;
+    void              *data;
+    Efm_Menu          *menu; // current menu if active
+    void              *menu_data; // some handle to the currently active menu
+  } menu_provider;
+
   Eina_Bool reblocked            : 1;
   Eina_Bool relayout             : 1;
   Eina_Bool focused              : 1;
diff --git a/src/efm/efm_util.c b/src/efm/efm_util.c
index ca84986..5c55f85 100644
--- a/src/efm/efm_util.c
+++ b/src/efm/efm_util.c
@@ -6,6 +6,7 @@
 #include "efm_dnd.h"
 #include "efm_back_end.h"
 #include "efm_private.h"
+#include "eina_binbuf.h"
 
 // util funcs for the efm view
 static inline int
@@ -862,7 +863,6 @@ _icon_select_update(Icon *icon)
 
 static Eina_Bool
 _cb_dnd_over_open_timer(void *data)
-
 {
   Smart_Data *sd = data;
 
@@ -996,6 +996,51 @@ _select_range(Icon *icon_from, Icon *icon_to)
   }
 }
 
+static void
+_cb_ic_item1(void *data, void *data2, Evas_Object *efm, const Efm_Menu_Item *menu_item)
+{
+  printf("ic1");
+}
+
+static void
+_cb_ic_item2(void *data, void *data2, Evas_Object *efm, const Efm_Menu_Item *menu_item)
+{
+  printf("ic2");
+}
+
+static void
+_cb_ic_item3(void *data, void *data2, Evas_Object *efm, const Efm_Menu_Item *menu_item)
+{
+  printf("ic3");
+}
+
+static void
+_cb_ic_item4(void *data, void *data2, Evas_Object *efm, const Efm_Menu_Item *menu_item)
+{
+  printf("ic4");
+}
+
+static void
+_cb_ic_item5(void *data, void *data2, Evas_Object *efm,
+             const Efm_Menu_Item *menu_item)
+{
+  printf("ic5");
+}
+
+static void
+_cb_ic_item6(void *data, void *data2, Evas_Object *efm,
+             const Efm_Menu_Item *menu_item)
+{
+  printf("ic6");
+}
+
+static void
+_cb_ic_item7(void *data, void *data2, Evas_Object *efm,
+             const Efm_Menu_Item *menu_item)
+{
+  printf("ic7");
+}
+
 static void
 _cb_icon_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
                   void *event_info)
@@ -1055,7 +1100,43 @@ _cb_icon_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
       if (((dx * dx) + (dy * dy)) > (5 * 5)) dragged = EINA_TRUE;
       if (!dragged)
         {
+          Efm_Menu *m1, *m2;
+
           printf("XXX: right mouse\n");
+          m1 = _efm_menu_add("Submenu", "mail-reply-all");
+          _efm_menu_it_normal(m1, "Item 1", "menu/folder", _cb_ic_item1,
+                              icon, NULL);
+          _efm_menu_it_normal(m1, "Item 2", "system-lock-screen",
+                              _cb_ic_item2, icon, NULL);
+          _efm_menu_it_separator(m1);
+          _efm_menu_it_normal(m1, "Item 3 - much longer label", "media-eject",
+                              _cb_ic_item3, icon, NULL);
+          _efm_menu_it_normal(m1, "Item 4", "media-eject", _cb_ic_item4,
+                              icon, NULL);
+          m2 = _efm_menu_add("Main Menu", "mail-reply-all");
+          _efm_menu_it_normal(m2, "Item 5", "system-run", _cb_ic_item5, icon,
+                              NULL);
+          _efm_menu_it_separator(m1);
+          _efm_menu_it_check(m2, "Check 1", "system-run", EINA_FALSE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_check(m2, "Check 2", "system-run", EINA_TRUE,
+                             _cb_ic_item7, icon, NULL);
+          _efm_menu_it_separator(m1);
+          _efm_menu_it_radio(m2, "Radio 1", "system-run", EINA_FALSE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_radio(m2, "Radio 2", "system-run", EINA_TRUE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_radio(m2, "Radio 3", "system-run", EINA_FALSE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_separator(m2);
+          _efm_menu_it_radio(m2, "Radio 1", "system-run", EINA_FALSE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_radio(m2, "Radio 2", "system-run", EINA_FALSE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_radio(m2, "Radio 3", "system-run", EINA_TRUE,
+                             _cb_ic_item6, icon, NULL);
+          _efm_menu_it_sub(m2, "Submenu here", "system-lock-screen", m1);
+          _efm_menu_show(icon->sd->o_smart, m2, icon->down_x, icon->down_y);
         }
       icon->sd->last_focused = icon;
       icon->drag             = EINA_FALSE;
@@ -2435,3 +2516,116 @@ _cb_reblock(void *data)
   sd->reblocked = EINA_TRUE;
   evas_object_smart_changed(sd->o_smart);
 }
+
+Efm_Menu *
+_efm_menu_add(const char *title, const char *icon)
+{
+  Efm_Menu *m = calloc(1, sizeof(Efm_Menu));
+
+  eina_stringshare_replace(&(m->title), title);
+  eina_stringshare_replace(&(m->title_icon), icon);
+  return m;
+}
+
+void
+_efm_menu_del(Efm_Menu *m)
+{
+  Efm_Menu_Item *mi;
+  int            i;
+
+  if (!m) return;
+  eina_stringshare_replace(&(m->title), NULL);
+  eina_stringshare_replace(&(m->title_icon), NULL);
+  for (i = 0; i < m->item_num; i++)
+    {
+      mi = &(m->item[i]);
+      eina_stringshare_replace(&(mi->label), NULL);
+      eina_stringshare_replace(&(mi->icon), NULL);
+      _efm_menu_del(mi->sub);
+    }
+  free(m->item);
+  free(m);  
+}
+
+static int
+_m_index(void)
+{
+  static int mindex = 1;
+  int        i      = mindex;
+
+  mindex++;
+  if (mindex > 0x0fffffff) mindex = 1; // wrap at 28 bit - we're good here
+  // as long as all indexes in a single menu tree instance (menu + all subs)
+  // are unique per item you can select with a callback. so that's about
+  // 268 million items we need to be unique for... good enough
+  return i;
+}
+
+static Efm_Menu_Item *
+_mi_add(Efm_Menu *m, Efm_Menu_Item_Type type, const char *label, const char *icon,
+        Efm_Menu_Item_Callback cb, void *data, void *data2)
+{
+  Efm_Menu_Item *mi;
+
+  m->item_num++;
+  mi = realloc(m->item, (m->item_num * sizeof(Efm_Menu_Item)));
+  if (!mi)
+    {
+      m->item_num--;
+      return NULL;
+    }
+  m->item = mi;
+  mi      = &(m->item[m->item_num - 1]);
+  memset(mi, 0, sizeof(Efm_Menu_Item));
+  mi->type = type;
+  mi->index = _m_index();
+  eina_stringshare_replace(&(mi->label), label);
+  eina_stringshare_replace(&(mi->icon), icon);
+  mi->private1 = cb;
+  mi->private2 = data;
+  mi->private2 = data2;
+  return mi;
+}
+
+Efm_Menu_Item *
+_efm_menu_it_normal(Efm_Menu *m, const char *label, const char *icon,
+                    Efm_Menu_Item_Callback cb, void *data, void *data2)
+{
+  return _mi_add(m, EFM_MENU_ITEM_NORMAL, label, icon, cb, data, data2);
+}
+
+Efm_Menu_Item *
+_efm_menu_it_separator(Efm_Menu *m)
+{
+  return _mi_add(m, EFM_MENU_ITEM_SEPARATOR, NULL, NULL, NULL, NULL, NULL);
+}
+
+Efm_Menu_Item *
+_efm_menu_it_sub(Efm_Menu *m, const char *label, const char *icon,
+                 Efm_Menu *sub)
+{
+  Efm_Menu_Item *mi = _mi_add(m, EFM_MENU_ITEM_SUBMENU, label, icon, NULL, NULL, NULL);
+
+  if (mi) mi->sub = sub;
+  return mi;
+}
+
+Efm_Menu_Item *
+_efm_menu_it_radio(Efm_Menu *m, const char *label, const char *icon,
+                   Eina_Bool on, Efm_Menu_Item_Callback cb, void *data, void *data2)
+{
+  Efm_Menu_Item *mi = _mi_add(m, EFM_MENU_ITEM_RADIO, label, icon, cb, data, data2);
+
+  if (mi) mi->selected = on;
+  return mi;
+}
+
+Efm_Menu_Item *
+_efm_menu_it_check(Efm_Menu *m, const char *label, const char *icon,
+                   Eina_Bool on, Efm_Menu_Item_Callback cb, void *data, void *data2)
+{
+  Efm_Menu_Item *mi = _mi_add(m, EFM_MENU_ITEM_CHECK, label, icon, cb, data, data2);
+
+  if (mi) mi->selected = on;
+  return mi;
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to