Ctxpopup example

In this example we have a list with two items, when either item is clicked a ctxpopup for it will be shown. Our two ctxpopups are quite different, the one for the first item is a vertical and it's items contain both labels and icons, the one for the second item is horizontal and it's items have icons but not labels.

We will begin examining our example code by looking at the callback we'll use when items in the ctxpopup are clicked. It's very simple, all it does is print the label present in the ctxpopup item:

//Compile with:
//gcc -o ctxpopup_example_01 ctxpopup_example_01.c -g `pkg-config --cflags --libs elementary`
#include <Elementary.h>
static int list_mouse_down = 0;
static void
_dismissed_cb(void *data EINA_UNUSED, Evas_Object *obj,
void *event_info EINA_UNUSED)
{
evas_object_del(obj);
}
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition: eina_types.h:339
evas_object_del
EVAS_API void evas_object_del(Evas_Object *obj)
Marks the given Evas object for deletion (when Evas will free its memory).
Definition: evas_object_main.c:928
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition: Evas_Common.h:185

Next we examine a function that creates ctxpopup items, it was created to avoid repeating the same code whenever we needed to add an item to our ctxpopup. Our function creates an icon from the standard set of icons, and then creates the item, with the label received as an argument. We also set the callback to be called when the item is clicked:

static void
_ctxpopup_item_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info)
{
printf("ctxpopup item selected: %s\n", elm_object_item_text_get(event_info));
}

Finally we have the function that will create the ctxpopup for the first item in our list. This one is somewhat more complex though, so let's go through it in parts. First we declare our variable and add the ctxpopup:

Elm_Object_Item *item_new(Evas_Object *ctxpopup, const char * label, const char *icon)
{
Evas_Object *ic = elm_icon_add(ctxpopup);
elm_icon_standard_set(ic, icon);
elm_image_resizable_set(ic, EINA_FALSE, EINA_FALSE);
return elm_ctxpopup_item_append(ctxpopup, label, ic, _ctxpopup_item_cb, NULL);
}
static void
_list_item_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
{
Evas_Object *ctxpopup;
Elm_Object_Item *it;
Evas_Coord x,y;
if (list_mouse_down > 0) return;
ctxpopup = elm_ctxpopup_add(obj);
Evas_Coord
int Evas_Coord
Type used for coordinates (in pixels, int).
Definition: Evas_Common.h:116
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:533
elm_ctxpopup_item_append
Elm_Widget_Item * elm_ctxpopup_item_append(Elm_Ctxpopup *obj, const char *label, Efl_Canvas_Object *icon, Evas_Smart_Cb func, const void *data)
Add a new item to a ctxpopup object.
Definition: elm_ctxpopup_eo.legacy.c:105
elm_ctxpopup_add
Evas_Object * elm_ctxpopup_add(Evas_Object *parent)
Add a new Ctxpopup object to the parent.
Definition: elc_ctxpopup.c:1109
Elm_Object_Item
Eo Elm_Object_Item
An Elementary Object item handle.
Definition: elm_object_item.h:6
elm_icon_add
Evas_Object * elm_icon_add(Evas_Object *parent)
Add a new icon object to the parent.
Definition: elm_icon.c:613
elm_icon_standard_set
Eina_Bool elm_icon_standard_set(Evas_Object *obj, const char *name)
Set the icon by icon standards names.
Definition: elm_icon.c:885
elm_image_resizable_set
void elm_image_resizable_set(Evas_Object *obj, Eina_Bool up, Eina_Bool down)
Control if the object is (up/down) resizable.
Definition: efl_ui_image.c:2656

Next we create a bunch of items for our ctxpopup, marking two of them as disabled just so we can see what that will look like:

evas_object_smart_callback_add(ctxpopup, "dismissed", _dismissed_cb, NULL);
item_new(ctxpopup, "Go to home folder", "home");
item_new(ctxpopup, "Save file", "file");
item_new(ctxpopup, "Delete file", "delete");
it = item_new(ctxpopup, "Navigate to folder", "folder");
elm_object_item_disabled_set(it, EINA_TRUE);
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
elm_object_item_disabled_set
void elm_object_item_disabled_set(Elm_Widget_Item *obj, Eina_Bool disable)
Control the disabled state of a widget item.
Definition: elm_widget_item_eo.legacy.c:111
evas_object_smart_callback_add
EVAS_API void evas_object_smart_callback_add(Evas_Object *eo_obj, const char *event, Evas_Smart_Cb func, const void *data)
Add (register) a callback function to the smart event specified by event on the smart object obj.
Definition: evas_object_smart.c:1040
item_new(ctxpopup, "Edit entry", "edit");
it = item_new(ctxpopup, "Set date and time", "clock");
elm_object_item_disabled_set(it, EINA_TRUE);

Then we ask evas where the mouse pointer was so that we can have our ctxpopup appear in the right place, set a maximum size for the ctxpopup, move it and show it:

evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x, &y);
evas_object_move(ctxpopup, x, y);
evas_object_show(ctxpopup);
evas_pointer_canvas_xy_get
EVAS_API void evas_pointer_canvas_xy_get(const Evas_Canvas *obj, int *x, int *y)
This function returns the current known default pointer coordinates.
Definition: evas_canvas_eo.legacy.c:75
evas_object_show
EVAS_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
evas_object_move
EVAS_API void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
Move the given Evas object to the given location inside its canvas' viewport.
Definition: evas_object_main.c:1171
evas_object_evas_get
EVAS_API Evas * evas_object_evas_get(const Eo *eo_obj)
Get the Evas to which this object belongs to.
Definition: evas_object_main.c:2662

And last we mark the list item as not selected:

elm_list_item_selected_set(event_info, EINA_FALSE);
}

Our next function is the callback that will create the ctxpopup for the second list item, it is very similar to the previous function. A couple of interesting things to note is that we ask our ctxpopup to be horizontal, and that we pass NULL as the label for every item:

static void
_list_item_cb2(void *data EINA_UNUSED, Evas_Object *obj, void *event_info)
{
Evas_Object *ctxpopup;
Elm_Object_Item *it;
Evas_Coord x,y;
if (list_mouse_down > 0) return;
ctxpopup = elm_ctxpopup_add(obj);
evas_object_smart_callback_add(ctxpopup, "dismissed", _dismissed_cb, NULL);
elm_ctxpopup_horizontal_set(ctxpopup, EINA_TRUE);
item_new(ctxpopup, NULL, "home");
item_new(ctxpopup, NULL, "file");
item_new(ctxpopup, NULL, "delete");
item_new(ctxpopup, NULL, "folder");
it = item_new(ctxpopup, NULL, "edit");
elm_object_item_disabled_set(it, EINA_TRUE);
item_new(ctxpopup, NULL, "clock");
evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x, &y);
evas_object_move(ctxpopup, x, y);
evas_object_show(ctxpopup);
elm_list_item_selected_set(event_info, EINA_FALSE);
}
elm_ctxpopup_horizontal_set
void elm_ctxpopup_horizontal_set(Elm_Ctxpopup *obj, Eina_Bool horizontal)
Change the ctxpopup's orientation to horizontal or vertical.
Definition: elm_ctxpopup_eo.legacy.c:27

And with all of that in place we can now get to our main function where we create the window, the list, the list items and run the main loop:

static void
_list_mouse_down(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
list_mouse_down++;
}
static void
_list_mouse_up(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
list_mouse_down--;
}
static void
_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
list_mouse_down = 0;
}
EAPI_MAIN int
elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
Evas_Object *win, *list;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_util_standard_add("Contextual Popup", "Contextual Popup");
evas_object_smart_callback_add(win, "delete,request", _win_del, NULL);
elm_win_autodel_set(win, EINA_TRUE);
list = elm_list_add(win);
evas_object_event_callback_add(list, EVAS_CALLBACK_MOUSE_DOWN,
_list_mouse_down, NULL);
evas_object_event_callback_add(list, EVAS_CALLBACK_MOUSE_UP,
_list_mouse_up, NULL);
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, list);
elm_list_mode_set(list, ELM_LIST_COMPRESS);
elm_list_item_append(list, "Ctxpopup with icons and labels", NULL, NULL,
_list_item_cb, NULL);
elm_list_item_append(list, "Ctxpopup with icons only", NULL, NULL,
_list_item_cb2, NULL);
evas_object_show(list);
elm_list_go(list);
evas_object_resize(win, 400, 400);
evas_object_show(win);
elm_run();
return 0;
}
ELM_MAIN()
EVAS_HINT_EXPAND
#define EVAS_HINT_EXPAND
Use with evas_object_size_hint_weight_set(), evas_object_size_hint_weight_get(), evas_object_size_hin...
Definition: Evas_Common.h:297
EVAS_CALLBACK_MOUSE_UP
@ EVAS_CALLBACK_MOUSE_UP
Mouse Button Up Event.
Definition: Evas_Common.h:423
EVAS_CALLBACK_MOUSE_DOWN
@ EVAS_CALLBACK_MOUSE_DOWN
Mouse Button Down Event.
Definition: Evas_Common.h:422
ELM_MAIN
#define ELM_MAIN()
macro to be used after the elm_main() function
Definition: elm_general.h:556
elm_policy_set
Eina_Bool elm_policy_set(unsigned int policy, int value)
Set a new policy's value (for a given policy group/identifier).
Definition: elm_main.c:1380
elm_run
void elm_run(void)
Run Elementary's main loop.
Definition: elm_main.c:1357
ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
@ ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
quit when the application's last window is closed
Definition: elm_general.h:248
ELM_POLICY_QUIT
@ ELM_POLICY_QUIT
under which circumstances the application should quit automatically.
Definition: elm_general.h:227
ELM_LIST_COMPRESS
@ ELM_LIST_COMPRESS
The list won't set any of its size hints to inform how a possible container should resize it.
Definition: elm_general.h:432
elm_list_go
void elm_list_go(Elm_List *obj)
Starts the list.
Definition: elm_list_eo.legacy.c:111
elm_list_add
Evas_Object * elm_list_add(Evas_Object *parent)
Add a new list widget to the given parent Elementary (container) object.
Definition: elm_list.c:2513
elm_list_mode_set
void elm_list_mode_set(Elm_List *obj, Elm_List_Mode mode)
Control which mode to use for the list object.
Definition: elm_list_eo.legacy.c:63
elm_list_item_append
Elm_Widget_Item * elm_list_item_append(Elm_List *obj, const char *label, Efl_Canvas_Object *icon, Efl_Canvas_Object *end, Evas_Smart_Cb func, const void *data)
Append a new item to the list object.
Definition: elm_list_eo.legacy.c:129
elm_win_resize_object_add
void elm_win_resize_object_add(Eo *obj, Evas_Object *subobj)
Add subobj as a resize object of window obj.
Definition: efl_ui_win.c:8992
elm_win_autodel_set
void elm_win_autodel_set(Eo *obj, Eina_Bool autodel)
Set the window's autodel state.
Definition: efl_ui_win.c:6189
elm_win_util_standard_add
Evas_Object * elm_win_util_standard_add(const char *name, const char *title)
Adds a window object with standard setup.
Definition: efl_ui_win.c:9576
Evas
Eo Evas
An opaque handle to an Evas canvas.
Definition: Evas_Common.h:163
evas_object_event_callback_add
EVAS_API void evas_object_event_callback_add(Evas_Object *eo_obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
Add (register) a callback function to a given Evas object event.
Definition: evas_callbacks.c:478
evas_object_size_hint_weight_set
EVAS_API void evas_object_size_hint_weight_set(Evas_Object *obj, double x, double y)
Sets the hints for an object's weight.
Definition: evas_object_main.c:2638
evas_object_resize
EVAS_API void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Changes the size of the given Evas object.
Definition: evas_object_main.c:1236

The example will initially look like this:

Note
  This doesn't show the ctxpopup tough, since it will only appear when we click one of the list items.

Here is what our first ctxpopup will look like:

And here the second ctxpopup: