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)
{
}
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339
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

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);
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;
if (list_mouse_down > 0) return;
ctxpopup = elm_ctxpopup_add(obj);
int Evas_Coord
Type used for coordinates (in pixels, int).
Definition Evas_Common.h:116
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition eina_types.h:533
Evas_Object * elm_ctxpopup_add(Evas_Object *parent)
Add a new Ctxpopup object to the parent.
Definition elc_ctxpopup.c:1109
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
Eina_Bool elm_icon_standard_set(Evas_Object *obj, const char *name)
Set the icon by icon standards names.
Definition elm_icon.c:876
Evas_Object * elm_icon_add(Evas_Object *parent)
Add a new icon object to the parent.
Definition elm_icon.c:604
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:2637

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");
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
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_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");

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_object_move(ctxpopup, x, y);
evas_object_show(ctxpopup);
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_API void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition evas_object_main.c:1814
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_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;
if (list_mouse_down > 0) return;
ctxpopup = elm_ctxpopup_add(obj);
evas_object_smart_callback_add(ctxpopup, "dismissed", _dismissed_cb, NULL);
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");
item_new(ctxpopup, NULL, "clock");
evas_object_move(ctxpopup, x, y);
evas_object_show(ctxpopup);
elm_list_item_selected_set(event_info, EINA_FALSE);
}
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;
win = elm_win_util_standard_add("Contextual Popup", "Contextual Popup");
evas_object_smart_callback_add(win, "delete,request", _win_del, NULL);
list = elm_list_add(win);
_list_mouse_down, NULL);
_list_mouse_up, NULL);
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);
elm_list_go(list);
evas_object_resize(win, 400, 400);
return 0;
}
#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
Mouse Button Up Event.
Definition Evas_Common.h:423
@ EVAS_CALLBACK_MOUSE_DOWN
Mouse Button Down Event.
Definition Evas_Common.h:422
#define ELM_MAIN()
macro to be used after the elm_main() function
Definition elm_general.h:556
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
void elm_run(void)
Run Elementary's main loop.
Definition elm_main.c:1357
@ ELM_POLICY_QUIT_LAST_WINDOW_CLOSED
quit when the application's last window is closed
Definition elm_general.h:248
@ ELM_POLICY_QUIT
under which circumstances the application should quit automatically.
Definition elm_general.h:227
@ 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
void elm_list_go(Elm_List *obj)
Starts the list.
Definition elm_list_eo.legacy.c:111
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
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
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
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:9587
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:9002
void elm_win_autodel_set(Eo *obj, Eina_Bool autodel)
Set the window's autodel state.
Definition efl_ui_win.c:6199
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_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_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: