--- /dev/null
+/*
+ * gcc -o anchorblock_example_01 anchorblock_example_01.c `pkg-config --cflags --libs elementary`
+ */
+#include <Elementary.h>
+
+static void _anchorblock_clicked_cb(void *data, Evas_Object *obj, void *ev);
+static void _anchorview_clicked_cb(void *data, Evas_Object *obj, void *ev);
+
+int
+elm_main(int argc, char *argv[])
+{
+ Evas_Object *win, *box, *o, *frame;
+ const char *anchortext =
+ "Example of some markup text, a long one at that, using anchors in"
+ "different ways, like <a href=random>some random text</a>.<br>"
+ "Something more useful is to have actions over urls, either in direct"
+ "form: <a href=url:http://www.enlightenment.org>"
+ "http://www.enlightenment.org</a> or with "
+ "<a href=url:http://www.enlightenment.org>more random text</a>.<br>"
+ "In any case, the href part of the anchor is what you will receive on"
+ "the callback, so it's a good idea to keep anything needed to identify"
+ "whatever is linked at in there.<br>"
+ "Playing to be a phone, we can also identify contacts from our address"
+ "list, like this dude here <a href=contact:42>Thomas Anderson</a>, or"
+ "phone numbers <a href=tel:+61432123>+61 432 1234</a>.";
+
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+ win = elm_win_add(NULL, "Anchortwins example", ELM_WIN_BASIC);
+ elm_win_title_set(win, "Anchortwins example");
+ elm_win_autodel_set(win, EINA_TRUE);
+ evas_object_resize(win, 320, 300);
+ evas_object_show(win);
+
+ o = elm_bg_add(win);
+ evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(win, o);
+ evas_object_show(o);
+
+ box = elm_box_add(win);
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_win_resize_object_add(win, box);
+ evas_object_show(box);
+
+ frame = elm_frame_add(win);
+ elm_frame_label_set(frame, "Anchorblock");
+ evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(frame);
+ elm_box_pack_end(box, frame);
+
+ o = elm_anchorblock_add(win);
+ elm_anchorblock_hover_style_set(o, "popout");
+ elm_anchorblock_hover_parent_set(o, win);
+ elm_anchorblock_text_set(o, anchortext);
+ evas_object_smart_callback_add(o, "anchor,clicked", _anchorblock_clicked_cb,
+ NULL);
+ evas_object_show(o);
+ elm_frame_content_set(frame, o);
+
+ frame = elm_frame_add(win);
+ elm_frame_label_set(frame, "Anchorview");
+ evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(frame);
+ elm_box_pack_end(box, frame);
+
+ o = elm_anchorview_add(win);
+ elm_anchorview_hover_parent_set(o, frame);
+ elm_anchorview_bounce_set(o, EINA_FALSE, EINA_TRUE);
+ elm_anchorview_text_set(o, anchortext);
+ evas_object_smart_callback_add(o, "anchor,clicked", _anchorview_clicked_cb,
+ NULL);
+ evas_object_show(o);
+ elm_frame_content_set(frame, o);
+
+ elm_run();
+
+ return 0;
+}
+ELM_MAIN();
+
+static void _anchor_buttons_create(Evas_Object *ao, Elm_Entry_Anchorblock_Info *info, Evas_Smart_Cb btn_end_cb);
+
+static void
+_btn_anchorblock_end_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ elm_anchorblock_hover_end((Evas_Object *)data);
+}
+
+static void
+_anchorblock_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Elm_Entry_Anchorblock_Info *info = event_info;
+ _anchor_buttons_create(obj, info, _btn_anchorblock_end_cb);
+}
+
+static void
+_btn_anchorview_end_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ elm_anchorview_hover_end((Evas_Object *)data);
+}
+
+static void
+_anchorview_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ /* should be an Elm_Entry_Anchorview_Info, but since both of them are
+ * the same, it simplifies code in this example to use one only */
+ Elm_Entry_Anchorblock_Info *info = event_info;
+ _anchor_buttons_create(obj, info, _btn_anchorview_end_cb);
+}
+
+static void
+_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *lbl = elm_button_label_get(obj);
+ printf("%s: %s\n", lbl, (char *)data);
+ eina_stringshare_del(data);
+}
+
+static void
+_anchor_buttons_create(Evas_Object *ao, Elm_Entry_Anchorblock_Info *info, Evas_Smart_Cb btn_end_cb)
+{
+ Evas_Object *btn, *secondary = NULL, *box = NULL;
+ char *p;
+ const char *str;
+
+ btn = elm_button_add(ao);
+ evas_object_show(btn);
+
+ p = strchr(info->name, ':');
+ if (!p)
+ {
+ elm_button_label_set(btn, "Nothing to see here");
+ evas_object_smart_callback_add(btn, "clicked", btn_end_cb, ao);
+ elm_hover_content_set(info->hover, "middle", btn);
+ return;
+ }
+
+ str = eina_stringshare_add(p + 1);
+ if (!strncmp(info->name, "tel:", 4))
+ {
+ Evas_Object *o;
+ elm_button_label_set(btn, "Call");
+
+ secondary = elm_button_add(ao);
+ elm_button_label_set(secondary, "Send SMS");
+ evas_object_show(secondary);
+ evas_object_smart_callback_add(secondary, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(secondary, "clicked", _btn_clicked_cb,
+ str);
+
+ box = elm_box_add(ao);
+ evas_object_show(box);
+
+ o = elm_button_add(ao);
+ elm_button_label_set(o, "Add to contacts");
+ elm_box_pack_end(box, o);
+ evas_object_show(o);
+ evas_object_smart_callback_add(o, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(o, "clicked", _btn_clicked_cb, str);
+
+ o = elm_button_add(ao);
+ elm_button_label_set(o, "Send MMS");
+ elm_box_pack_end(box, o);
+ evas_object_show(o);
+ evas_object_smart_callback_add(o, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(o, "clicked", _btn_clicked_cb, str);
+ }
+ else if (!strncmp(info->name, "contact:", 8))
+ {
+ Evas_Object *o;
+ elm_button_label_set(btn, "Call");
+
+ secondary = elm_button_add(ao);
+ elm_button_label_set(secondary, "Send SMS");
+ evas_object_show(secondary);
+ evas_object_smart_callback_add(secondary, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(secondary, "clicked", _btn_clicked_cb,
+ str);
+
+ box = elm_box_add(ao);
+ evas_object_show(box);
+
+ o = elm_button_add(ao);
+ elm_button_label_set(o, "Send MMS");
+ elm_box_pack_end(box, o);
+ evas_object_show(o);
+ evas_object_smart_callback_add(o, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(o, "clicked", _btn_clicked_cb, str);
+ }
+ else if (!strncmp(info->name, "mailto:", 7))
+ {
+ Evas_Object *o;
+ elm_button_label_set(btn, "Send E-Mail");
+
+ secondary = elm_button_add(ao);
+ elm_button_label_set(secondary, "Add to contacts");
+ evas_object_show(secondary);
+ evas_object_smart_callback_add(secondary, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(secondary, "clicked", _btn_clicked_cb,
+ str);
+ }
+ else if (!strncmp(info->name, "url:", 4))
+ {
+ Evas_Object *o;
+ elm_button_label_set(btn, "Launch in browser");
+
+ box = elm_box_add(ao);
+ evas_object_show(box);
+
+ o = elm_button_add(ao);
+ elm_button_label_set(o, "Send as mail to...");
+ elm_box_pack_end(box, o);
+ evas_object_show(o);
+ evas_object_smart_callback_add(o, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(o, "clicked", _btn_clicked_cb, str);
+
+ o = elm_button_add(ao);
+ elm_button_label_set(o, "Send as SMS to...");
+ elm_box_pack_end(box, o);
+ evas_object_show(o);
+ evas_object_smart_callback_add(o, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(o, "clicked", _btn_clicked_cb, str);
+ }
+
+ evas_object_smart_callback_add(btn, "clicked", btn_end_cb, ao);
+ evas_object_smart_callback_add(btn, "clicked", _btn_clicked_cb, str);
+ elm_hover_content_set(info->hover, "middle", btn);
+
+ if (secondary)
+ {
+ if (info->hover_right)
+ elm_hover_content_set(info->hover, "right", secondary);
+ else if (info->hover_left)
+ elm_hover_content_set(info->hover, "left", secondary);
+ else
+ evas_object_del(secondary);
+ }
+
+ if (box)
+ {
+ if (info->hover_bottom)
+ elm_hover_content_set(info->hover, "bottom", box);
+ else if (info->hover_top)
+ elm_hover_content_set(info->hover, "top", box);
+ else
+ evas_object_del(box);
+ }
+}
* in convenient packages that do more than basic stuff */
/* anchorview */
+ /**
+ * @defgroup Anchorview Anchorview
+ *
+ * Anchorview is for displaying text that contains markup with anchors
+ * like <c>\<a href=1234\>something\</\></c> in it.
+ *
+ * Besides being styled differently, the anchorview widget provides the
+ * necessary functionality so that clicking on these anchors brings up a
+ * popup with user defined content such as "call", "add to contacts" or
+ * "open web page". This popup is provided using the @ref Hover widget.
+ *
+ * This widget is very similar to @ref Anchorblock, so refer to that
+ * widget for an example. The only difference Anchorview has is that the
+ * widget is already provided with scrolling functionality, so if the
+ * text set to it is too large to fit in the given space, it will scroll,
+ * whereas the @ref Anchorblock widget will keep growing to ensure all the
+ * text can be displayed.
+ *
+ * This widget emits the following signals:
+ * @li "anchor,clicked": will be called when an anchor is clicked. The
+ * @p event_info parameter on the callback will be a pointer of type
+ * ::Elm_Entry_Anchorview_Info.
+ *
+ * See @ref Anchorblock for an example on how to use both of them.
+ *
+ * @see Anchorblock
+ * @see Entry
+ * @see Hover
+ *
+ * @{
+ */
+ /**
+ * @typedef Elm_Entry_Anchorview_Info
+ *
+ * The info sent in the callback for "anchor,clicked" signals emitted by
+ * the Anchorview widget.
+ */
typedef struct _Elm_Entry_Anchorview_Info Elm_Entry_Anchorview_Info;
+ /**
+ * @struct _Elm_Entry_Anchorview_Info
+ *
+ * The info sent in the callback for "anchor,clicked" signals emitted by
+ * the Anchorview widget.
+ */
struct _Elm_Entry_Anchorview_Info
{
- const char *name;
- int button;
- Evas_Object *hover;
+ const char *name; /**< Name of the anchor, as indicated in its href
+ attribute */
+ int button; /**< The mouse button used to click on it */
+ Evas_Object *hover; /**< The hover object to use for the popup */
struct {
Evas_Coord x, y, w, h;
- } anchor, hover_parent;
- Eina_Bool hover_left : 1;
- Eina_Bool hover_right : 1;
- Eina_Bool hover_top : 1;
- Eina_Bool hover_bottom : 1;
+ } anchor, /**< Geometry selection of text used as anchor */
+ hover_parent; /**< Geometry of the object used as parent by the
+ hover */
+ Eina_Bool hover_left : 1; /**< Hint indicating if there's space
+ for content on the left side of
+ the hover. Before calling the
+ callback, the widget will make the
+ necessary calculations to check
+ which sides are fit to be set with
+ content, based on the position the
+ hover is activated and its distance
+ to the edges of its parent object
+ */
+ Eina_Bool hover_right : 1; /**< Hint indicating content fits on
+ the right side of the hover.
+ See @ref hover_left */
+ Eina_Bool hover_top : 1; /**< Hint indicating content fits on top
+ of the hover. See @ref hover_left */
+ Eina_Bool hover_bottom : 1; /**< Hint indicating content fits
+ below the hover. See @ref
+ hover_left */
};
+ /**
+ * Add a new Anchorview object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ */
EAPI Evas_Object *elm_anchorview_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
+ /**
+ * Set the text to show in the anchorview
+ *
+ * Sets the text of the anchorview to @p text. This text can include markup
+ * format tags, including <c>\<a href=anchorname\></c> to begin a segment of
+ * text that will be specially styled and react to click events, ended with
+ * either of \</a\> or \</\>. When clicked, the anchor will emit an
+ * "anchor,clicked" signal that you can attach a callback to with
+ * evas_object_smart_callback_add(). The name of the anchor given in the
+ * event info struct will be the one set in the href attribute, in this
+ * case, anchorname.
+ *
+ * Other markup can be used to style the text in different ways, but it's
+ * up to the style defined in the theme which tags do what.
+ */
EAPI void elm_anchorview_text_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
+ /**
+ * Get the markup text set for the anchorview
+ *
+ * Retrieves the text set on the anchorview, with markup tags included.
+ *
+ * @param obj The anchorview object
+ * @return The markup text set or @c NULL if nothing was set or an error
+ * occurred
+ */
EAPI const char *elm_anchorview_text_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
-
+ /**
+ * Set the parent of the hover popup
+ *
+ * Sets the parent object to use by the hover created by the anchorview
+ * when an anchor is clicked. See @ref Hover for more details on this.
+ * If no parent is set, the same anchorview object will be used.
+ *
+ * @param obj The anchorview object
+ * @param parent The object to use as parent for the hover
+ */
EAPI void elm_anchorview_hover_parent_set(Evas_Object *obj, Evas_Object *parent) EINA_ARG_NONNULL(1);
+ /**
+ * Get the parent of the hover popup
+ *
+ * Get the object used as parent for the hover created by the anchorview
+ * widget. See @ref Hover for more details on this.
+ *
+ * @param obj The anchorview object
+ * @return The object used as parent for the hover, NULL if none is set.
+ */
EAPI Evas_Object *elm_anchorview_hover_parent_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Set the style that the hover should use
+ *
+ * When creating the popup hover, anchorview will request that it's
+ * themed according to @p style.
+ *
+ * @param obj The anchorview object
+ * @param style The style to use for the underlying hover
+ *
+ * @see elm_object_style_set()
+ */
EAPI void elm_anchorview_hover_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1);
+ /**
+ * Get the style that the hover should use
+ *
+ * Get the style the hover created by anchorview will use.
+ *
+ * @param obj The anchorview object
+ * @return The style to use by the hover. NULL means the default is used.
+ *
+ * @see elm_object_style_set()
+ */
EAPI const char *elm_anchorview_hover_style_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Ends the hover popup in the anchorview
+ *
+ * When an anchor is clicked, the anchorview widget will create a hover
+ * object to use as a popup with user provided content. This function
+ * terminates this popup, returning the anchorview to its normal state.
+ *
+ * @param obj The anchorview object
+ */
EAPI void elm_anchorview_hover_end(Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Set bouncing behaviour when the scrolled content reaches an edge
+ *
+ * Tell the internal scroller object whether it should bounce or not
+ * when it reaches the respective edges for each axis.
+ *
+ * @param obj The anchorview object
+ * @param h_bounce Whether to bounce or not in the horizontal axis
+ * @param v_bounce Whether to bounce or not in the vertical axis
+ *
+ * @see elm_scroller_bounce_set()
+ */
EAPI void elm_anchorview_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce) EINA_ARG_NONNULL(1);
+ /**
+ * Get the set bouncing behaviour of the internal scroller
+ *
+ * Get whether the internal scroller should bounce when the edge of each
+ * axis is reached scrolling.
+ *
+ * @param obj The anchorview object
+ * @param h_bounce Pointer where to store the bounce state of the horizontal
+ * axis
+ * @param v_bounce Pointer where to store the bounce state of the vertical
+ * axis
+ *
+ * @see elm_scroller_bounce_get()
+ */
EAPI void elm_anchorview_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce) EINA_ARG_NONNULL(1);
+ /**
+ * Appends a custom item provider to the given anchorview
+ *
+ * Appends the given function to the list of items providers. This list is
+ * called, one function at a time, with the given @p data pointer, the
+ * anchorview object and, in the @p item parameter, the item name as
+ * referenced in its href string. Following functions in the list will be
+ * called in order until one of them returns something different to NULL,
+ * which should be an Evas_Object which will be used in place of the item
+ * element.
+ *
+ * Items in the markup text take the form \<item relsize=16x16 vsize=full
+ * href=item/name\>\</item\>
+ *
+ * @param obj The anchorview object
+ * @param func The function to add to the list of providers
+ * @param data User data that will be passed to the callback function
+ *
+ * @see elm_entry_item_provider_append()
+ */
EAPI void elm_anchorview_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data) EINA_ARG_NONNULL(1, 2);
+ /**
+ * Prepend a custom item provider to the given anchorview
+ *
+ * Like elm_anchorview_item_provider_append(), but it adds the function
+ * @p func to the beginning of the list, instead of the end.
+ *
+ * @param obj The anchorview object
+ * @param func The function to add to the list of providers
+ * @param data User data that will be passed to the callback function
+ */
EAPI void elm_anchorview_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data) EINA_ARG_NONNULL(1, 2);
+ /**
+ * Remove a custom item provider from the list of the given anchorview
+ *
+ * Removes the function and data pairing that matches @p func and @p data.
+ * That is, unless the same function and same user data are given, the
+ * function will not be removed from the list. This allows us to add the
+ * same callback several times, with different @p data pointers and be
+ * able to remove them later without conflicts.
+ *
+ * @param obj The anchorview object
+ * @param func The function to remove from the list
+ * @param data The data matching the function to remove from the list
+ */
EAPI void elm_anchorview_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data) EINA_ARG_NONNULL(1, 2);
- /* smart callbacks called:
- * "anchor,clicked" - achor called was clicked | event_info = Elm_Entry_Anchorview_Info
+ /**
+ * @}
*/
/* anchorblock */
+ /**
+ * @defgroup Anchorblock Anchorblock
+ *
+ * Anchorblock is for displaying text that contains markup with anchors
+ * like <c>\<a href=1234\>something\</\></c> in it.
+ *
+ * Besides being styled differently, the anchorblock widget provides the
+ * necessary functionality so that clicking on these anchors brings up a
+ * popup with user defined content such as "call", "add to contacts" or
+ * "open web page". This popup is provided using the @ref Hover widget.
+ *
+ * This widget emits the following signals:
+ * @li "anchor,clicked": will be called when an anchor is clicked. The
+ * @p event_info parameter on the callback will be a pointer of type
+ * ::Elm_Entry_Anchorblock_Info.
+ *
+ * @see Anchorview
+ * @see Entry
+ * @see Hover
+ *
+ * Since examples are usually better than plain words, we might as well
+ * try one. This exampel will show both Anchorblock and @ref Anchorview,
+ * since both are very similar and it's easier to show them once and side
+ * by side, so the difference is more clear.
+ *
+ * We'll show the relevant snippets of the code here, but the full example
+ * can be found here... sorry, @ref anchorblock_example_01.c "here".
+ *
+ * As for the actual example, it's just a simple window with an anchorblock
+ * and an anchorview, both containing the same text. After including
+ * Elementary.h and declaring some functions we'll need, we jump to our
+ * elm_main (see ELM_MAIN) and create our window.
+ * @dontinclude anchorblock_example_01.c
+ * @skip int
+ * @until const char
+ * @until ;
+ *
+ * With the needed variables declared, we'll create the window and a box to
+ * hold our widgets, but we don't need to go through that here.
+ *
+ * In order to make clear where the anchorblock ends and the anchorview
+ * begins, they'll be each inside a @ref Frame. After creating the frame,
+ * the anchorblock follows.
+ * @skip elm_frame_add
+ * @until elm_frame_content_set
+ *
+ * Nothing out of the ordinary there. What's worth mentioning is the call
+ * to elm_anchorblock_hover_parent_set(). We are telling our widget that
+ * when an anchor is clicked, the hover for the popup will cover the entire
+ * window. This affects the area that will be obscured by the hover and
+ * where clicking will dismiss it, as well as the calculations it does to
+ * inform the best locations where to insert the popups content.
+ * Other than that, the code is pretty standard. We also need to set our
+ * callback for when an anchor is clicked, since it's our task to populate
+ * the popup. There's no default for it.
+ *
+ * The anchorview is no different, we only change a few things so it looks
+ * different.
+ * @until elm_frame_content_set
+ *
+ * Then we run, so stuff works and close our main function in the usual way.
+ * @until ELM_MAIN
+ *
+ * Now, a little note. Normally you would use either one of anchorblock or
+ * anchorview, set your one callback to clicks and do your stuff in there.
+ * In this example, however, there are a few tricks to make it easier to
+ * show both widgets in one go (and to save me some typing). So we have
+ * two callbacks, one per widget, that will call a common function to do
+ * the rest. The trick is using ::Elm_Entry_Anchorblock_Info for the
+ * anchorview too, since both are equal, and passing a callback to use
+ * for our buttons to end the hover, because each widget has a different
+ * function for it.
+ * @until _anchorview_clicked_cb
+ * @until }
+ *
+ * The meat of our popup is in the following function. We check what kind
+ * of menu we need to show, based on the name set to the anchor in the
+ * markup text. If there's no type (something went wrong, no valid contact
+ * in the address list) we are just putting a button that does nothing, but
+ * it's perfectly reasonable to just end the hover and call it quits.
+ *
+ * Our popup will consist of one main button in the middle of our hover,
+ * and possibly a secondary button and a list of other options. We'll create
+ * first our main button and check what kind of popup we need afterwards.
+ * @skip static void
+ * @skip static void
+ * @until eina_stringshare_add
+ * @until }
+ *
+ * Each button has two callbacks, one is our hack to close the hover
+ * properly based on which widget it belongs to, the other a simple
+ * printf that will show the action with the anchors own data. This is
+ * not how you would usually do it. Instead, the common case is to have
+ * one callback for the button that will know which function to call to end
+ * things, but since we are doing it this way it's worth noting that
+ * smart callbacks will be called in reverse in respect to the order they
+ * were added, and since our @c btn_end_cb will close the hover, and thus
+ * delete our buttons, the other callback wouldn't be called if we had
+ * added it before.
+ *
+ * After our telephone popup, there are a few others that are practically
+ * the same, so they won't be shown here.
+ *
+ * Once we are done with that, it's time to place our actions into our
+ * hover. Main button goes in the middle without much questioning, and then
+ * we see if we have a secondary button and a box of extra options.
+ * Because I said so, secondary button goes on either side and box of
+ * options either on top or below the main one, but to choose which
+ * exactly, we use the hints our callback info has, which saves us from
+ * having to do the math and see which side has more space available, with
+ * a little special case where we delete our extra stuff if there's nowhere
+ * to place it.
+ * @skip url:
+ * @skip }
+ * @skip evas_object_smart
+ * @until evas_object_del(box)
+ * @until }
+ * @until }
+ */
+ /**
+ * @example anchorblock_example_01.c
+ */
+ /**
+ * @addtogroup Anchorblock
+ * @{
+ */
+ /**
+ * @typedef Elm_Entry_Anchorblock_Info
+ *
+ * The info sent in the callback for "anchor,clicked" signals emitted by
+ * the Anchorblock widget.
+ */
typedef struct _Elm_Entry_Anchorblock_Info Elm_Entry_Anchorblock_Info;
+ /**
+ * @struct _Elm_Entry_Anchorblock_Info
+ *
+ * The info sent in the callback for "anchor,clicked" signals emitted by
+ * the Anchorblock widget.
+ */
struct _Elm_Entry_Anchorblock_Info
{
- const char *name;
- int button;
- Evas_Object *hover;
+ const char *name; /**< Name of the anchor, as indicated in its href
+ attribute */
+ int button; /**< The mouse button used to click on it */
+ Evas_Object *hover; /**< The hover object to use for the popup */
struct {
Evas_Coord x, y, w, h;
- } anchor, hover_parent;
- Eina_Bool hover_left : 1;
- Eina_Bool hover_right : 1;
- Eina_Bool hover_top : 1;
- Eina_Bool hover_bottom : 1;
+ } anchor, /**< Geometry selection of text used as anchor */
+ hover_parent; /**< Geometry of the object used as parent by the
+ hover */
+ Eina_Bool hover_left : 1; /**< Hint indicating if there's space
+ for content on the left side of
+ the hover. Before calling the
+ callback, the widget will make the
+ necessary calculations to check
+ which sides are fit to be set with
+ content, based on the position the
+ hover is activated and its distance
+ to the edges of its parent object
+ */
+ Eina_Bool hover_right : 1; /**< Hint indicating content fits on
+ the right side of the hover.
+ See @ref hover_left */
+ Eina_Bool hover_top : 1; /**< Hint indicating content fits on top
+ of the hover. See @ref hover_left */
+ Eina_Bool hover_bottom : 1; /**< Hint indicating content fits
+ below the hover. See @ref
+ hover_left */
};
+ /**
+ * Add a new Anchorblock object
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ */
EAPI Evas_Object *elm_anchorblock_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
+ /**
+ * Set the text to show in the anchorblock
+ *
+ * Sets the text of the anchorblock to @p text. This text can include markup
+ * format tags, including <c>\<a href=anchorname\></a></c> to begin a segment
+ * of text that will be specially styled and react to click events, ended
+ * with either of \</a\> or \</\>. When clicked, the anchor will emit an
+ * "anchor,clicked" signal that you can attach a callback to with
+ * evas_object_smart_callback_add(). The name of the anchor given in the
+ * event info struct will be the one set in the href attribute, in this
+ * case, anchorname.
+ *
+ * Other markup can be used to style the text in different ways, but it's
+ * up to the style defined in the theme which tags do what.
+ */
EAPI void elm_anchorblock_text_set(Evas_Object *obj, const char *text) EINA_ARG_NONNULL(1);
+ /**
+ * Get the markup text set for the anchorblock
+ *
+ * Retrieves the text set on the anchorblock, with markup tags included.
+ *
+ * @param obj The anchorblock object
+ * @return The markup text set or @c NULL if nothing was set or an error
+ * occurred
+ */
EAPI const char *elm_anchorblock_text_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Set the parent of the hover popup
+ *
+ * Sets the parent object to use by the hover created by the anchorblock
+ * when an anchor is clicked. See @ref Hover for more details on this.
+ *
+ * @param obj The anchorblock object
+ * @param parent The object to use as parent for the hover
+ */
EAPI void elm_anchorblock_hover_parent_set(Evas_Object *obj, Evas_Object *parent) EINA_ARG_NONNULL(1);
+ /**
+ * Get the parent of the hover popup
+ *
+ * Get the object used as parent for the hover created by the anchorblock
+ * widget. See @ref Hover for more details on this.
+ * If no parent is set, the same anchorblock object will be used.
+ *
+ * @param obj The anchorblock object
+ * @return The object used as parent for the hover, NULL if none is set.
+ */
EAPI Evas_Object *elm_anchorblock_hover_parent_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Set the style that the hover should use
+ *
+ * When creating the popup hover, anchorblock will request that it's
+ * themed according to @p style.
+ *
+ * @param obj The anchorblock object
+ * @param style The style to use for the underlying hover
+ *
+ * @see elm_object_style_set()
+ */
EAPI void elm_anchorblock_hover_style_set(Evas_Object *obj, const char *style) EINA_ARG_NONNULL(1);
+ /**
+ * Get the style that the hover should use
+ *
+ * Get the style the hover created by anchorblock will use.
+ *
+ * @param obj The anchorblock object
+ * @return The style to use by the hover. NULL means the default is used.
+ *
+ * @see elm_object_style_set()
+ */
EAPI const char *elm_anchorblock_hover_style_get(const Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Ends the hover popup in the anchorblock
+ *
+ * When an anchor is clicked, the anchorblock widget will create a hover
+ * object to use as a popup with user provided content. This function
+ * terminates this popup, returning the anchorblock to its normal state.
+ *
+ * @param obj The anchorblock object
+ */
EAPI void elm_anchorblock_hover_end(Evas_Object *obj) EINA_ARG_NONNULL(1);
+ /**
+ * Appends a custom item provider to the given anchorblock
+ *
+ * Appends the given function to the list of items providers. This list is
+ * called, one function at a time, with the given @p data pointer, the
+ * anchorblock object and, in the @p item parameter, the item name as
+ * referenced in its href string. Following functions in the list will be
+ * called in order until one of them returns something different to NULL,
+ * which should be an Evas_Object which will be used in place of the item
+ * element.
+ *
+ * Items in the markup text take the form \<item relsize=16x16 vsize=full
+ * href=item/name\>\</item\>
+ *
+ * @param obj The anchorblock object
+ * @param func The function to add to the list of providers
+ * @param data User data that will be passed to the callback function
+ *
+ * @see elm_entry_item_provider_append()
+ */
EAPI void elm_anchorblock_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data) EINA_ARG_NONNULL(1, 2);
+ /**
+ * Prepend a custom item provider to the given anchorblock
+ *
+ * Like elm_anchorblock_item_provider_append(), but it adds the function
+ * @p func to the beginning of the list, instead of the end.
+ *
+ * @param obj The anchorblock object
+ * @param func The function to add to the list of providers
+ * @param data User data that will be passed to the callback function
+ */
EAPI void elm_anchorblock_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data) EINA_ARG_NONNULL(1, 2);
+ /**
+ * Remove a custom item provider from the list of the given anchorblock
+ *
+ * Removes the function and data pairing that matches @p func and @p data.
+ * That is, unless the same function and same user data are given, the
+ * function will not be removed from the list. This allows us to add the
+ * same callback several times, with different @p data pointers and be
+ * able to remove them later without conflicts.
+ *
+ * @param obj The anchorblock object
+ * @param func The function to remove from the list
+ * @param data The data matching the function to remove from the list
+ */
EAPI void elm_anchorblock_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data) EINA_ARG_NONNULL(1, 2);
- /* smart callbacks called:
- * "anchor,clicked" - achor called was clicked | event_info = Elm_Entry_Anchorblock_Info
+ /**
+ * @}
*/
/* bubble */
#include <Elementary.h>
#include "elm_priv.h"
-/**
- * @defgroup Anchorblock Anchorblock
- *
- * Anchorblock is for displaying text that contains markup with anchors like:
- * \<a href=1234\>something\</\> in it. These will be drawn differently and will
- * be able to be clicked on by the user to display a popup. This popup then
- * is intended to contain extra options such as "call", "add to contacts",
- * "open web page" etc.
- *
- * Signals that you can add callbacks for are:
- *
- * "anchor,clicked" - anchor called was clicked. event_info is anchor info -
- * Elm_Entry_Anchorview_Info
- */
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Anchorblock_Item_Provider Elm_Anchorblock_Item_Provider;
return NULL;
}
-/**
- * Add a new Anchorblock object
- *
- * @param parent The parent object
- * @return The new object or NULL if it cannot be created
- *
- * @ingroup Anchorblock
- */
EAPI Evas_Object *
elm_anchorblock_add(Evas_Object *parent)
{
return obj;
}
-/**
- * Set the text markup of the anchorblock
- *
- * This sets the text of the anchorblock to be the text given as @p text. This
- * text is in markup format with \<a href=XXX\> beginning an achor with the
- * string link of 'XXX', and \</\> or \</a\> ending the link. Other markup can
- * be used dependign on the style support.
- *
- * @param obj The anchorblock object
- * @param text The text to set, or NULL to clear
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_text_set(Evas_Object *obj, const char *text)
{
_sizing_eval(obj);
}
-/**
- * Get the markup text set for the anchorblock
- *
- * This retrieves back the string set by @c elm_anchorblock_text_set().
- *
- * @param obj The anchorblock object
- * @return text The markup text set or @c NULL, either if it was not set
- * or an error occurred
- *
- * @ingroup Anchorblock
- */
EAPI const char*
elm_anchorblock_text_get(const Evas_Object *obj)
{
return elm_entry_entry_get(wd->entry);
}
-/**
- * Set the parent of the hover popup
- *
- * This sets the parent of the hover that anchorblock will create. See hover
- * objects for more information on this.
- *
- * @param obj The anchorblock object
- * @param parent The parent the hover should use
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
{
evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
}
-/**
- * Get the parent of the hover popup
- *
- * This sgets the parent of the hover that anchorblock will create. See hover
- * objects for more information on this.
- *
- * @param obj The anchorblock object
- * @return The parent used by the hover
- *
- * @ingroup Anchorblock
- */
EAPI Evas_Object *
elm_anchorblock_hover_parent_get(const Evas_Object *obj)
{
return wd->hover_parent;
}
-/**
- * Set the style that the hover should use
- *
- * This sets the style for the hover that anchorblock will create. See hover
- * objects for more information
- *
- * @param obj The anchorblock object
- * @param style The style to use
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_hover_style_set(Evas_Object *obj, const char *style)
{
eina_stringshare_replace(&wd->hover_style, style);
}
-/**
- * Get the style that the hover should use
- *
- * This gets the style for the hover that anchorblock will create. See hover
- * objects for more information
- *
- * @param obj The anchorblock object
- * @return The style defined
- *
- * @ingroup Anchorblock
- */
EAPI const char *
elm_anchorblock_hover_style_get(const Evas_Object *obj)
{
return wd->hover_style;
}
-/**
- * Stop the hover popup in the anchorblock
- *
- * This will stop the hover popup in the anchorblock if it is currently active.
- *
- * @param obj The anchorblock object
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_hover_end(Evas_Object *obj)
{
wd->pop = NULL;
}
-/**
- * This appends a custom item provider to the list for that anchorblock
- *
- * This appends the given callback. The list is walked from beginning to end
- * with each function called given the item href string in the text. If the
- * function returns an object handle other than NULL (it should create an
- * and object to do this), then this object is used to replace that item. If
- * not the next provider is called until one provides an item object, or the
- * default provider in anchorblock does.
- *
- * @param obj The anchorblock object
- * @param func The function called to provide the item object
- * @param data The data passed to @p func
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data)
{
wd->item_providers = eina_list_append(wd->item_providers, ip);
}
-/**
- * This prepends a custom item provider to the list for that anchorblock
- *
- * This prepends the given callback. See elm_anchorblock_item_provider_append() for
- * more information
- *
- * @param obj The anchorblock object
- * @param func The function called to provide the item object
- * @param data The data passed to @p func
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data)
{
wd->item_providers = eina_list_prepend(wd->item_providers, ip);
}
-/**
- * This removes a custom item provider to the list for that anchorblock
- *
- * This removes the given callback. See elm_anchorblock_item_provider_append() for
- * more information
- *
- * @param obj The anchorblock object
- * @param func The function called to provide the item object
- * @param data The data passed to @p func
- *
- * @ingroup Anchorblock
- */
EAPI void
elm_anchorblock_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorblock, const char *item), void *data)
{
#include <Elementary.h>
#include "elm_priv.h"
-/**
- * @defgroup Anchorview Anchorview
- *
- * This is just like the Anchorblock object, but provides a scroller to hold
- * the text automatically.
- *
- * Signals that you can add callbacks for are:
- *
- * "anchor,clicked" - achor called was clicked. event_info is anchor info -
- * Elm_Entry_Anchorview_Info
- */
typedef struct _Widget_Data Widget_Data;
typedef struct _Elm_Anchorview_Item_Provider Elm_Anchorview_Item_Provider;
return NULL;
}
-/**
- * Add a new Anchorview object
- *
- * @param parent The parent object
- * @return The new object or NULL if it cannot be created
- *
- * @ingroup Anchorview
- */
EAPI Evas_Object *
elm_anchorview_add(Evas_Object *parent)
{
return obj;
}
-/**
- * Set the text markup of the anchorview
- *
- * This sets the text of the anchorview to be the text given as @p text. This
- * text is in markup format with \<a href=XXX\> beginning an achor with the
- * string link of 'XXX', and \</\> or \</a\> ending the link. Other markup can
- * be used dependign on the style support.
- *
- * @param obj The anchorview object
- * @param text The text to set, or NULL to clear
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_text_set(Evas_Object *obj, const char *text)
{
_sizing_eval(obj);
}
-/**
- * Get the markup text set for the anchorview
- *
- * This retrieves back the string set by @c elm_anchorview_text_set().
- *
- * @param obj The anchorview object
- * @return text The markup text set or @c NULL, either if it was not set
- * or an error occurred
- *
- * @ingroup Anchorview
- */
EAPI const char*
elm_anchorview_text_get(const Evas_Object *obj)
{
return elm_entry_entry_get(wd->entry);
}
-/**
- * Set the parent of the hover popup
- *
- * This sets the parent of the hover that anchorview will create. See hover
- * objects for more information on this.
- *
- * @param obj The anchorview object
- * @param parent The parent the hover should use
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_hover_parent_set(Evas_Object *obj, Evas_Object *parent)
{
evas_object_event_callback_add(wd->hover_parent, EVAS_CALLBACK_DEL, _parent_del, obj);
}
-/**
- * Get the parent of the hover popup
- *
- * This gets the parent of the hover that anchorview will created. See hover
- * objects for more information on this.
- *
- * @param obj The anchorview object
- * @return The parent used by hover
- *
- * @ingroup Anchorview
- */
EAPI Evas_Object *
elm_anchorview_hover_parent_get(const Evas_Object *obj)
{
return wd->hover_parent;
}
-/**
- * Set the style that the hover should use
- *
- * This sets the style for the hover that anchorview will create. See hover
- * objects for more information
- *
- * @param obj The anchorview object
- * @param style The style to use
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_hover_style_set(Evas_Object *obj, const char *style)
{
eina_stringshare_replace(&wd->hover_style, style);
}
-/**
- * Get the style that the hover should use
- *
- * This gets the style for the hover that anchorview will create. See hover
- * objects for more information
- *
- * @param obj The anchorview object
- * @return The style defined
- *
- * @ingroup Anchorview
- */
EAPI const char *
elm_anchorview_hover_style_get(const Evas_Object *obj)
{
return wd->hover_style;
}
-/**
- * Stop the hover popup in the anchorview
- *
- * This will stop the hover popup in the anchorview if it is currently active.
- *
- * @param obj The anchorview object
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_hover_end(Evas_Object *obj)
{
wd->pop = NULL;
}
-/**
- * Set bounce mode
- *
- * This will enable or disable the scroller bounce mode for the anchorview. See
- * elm_scroller_bounce_set() for details
- *
- * @param obj The anchorview anchorview
- * @param h_bounce Allow bounce horizontally
- * @param v_bounce Allow bounce vertically
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_bounce_set(Evas_Object *obj, Eina_Bool h_bounce, Eina_Bool v_bounce)
{
elm_scroller_bounce_set(wd->scroller, h_bounce, v_bounce);
}
-/**
- * Get the bounce mode
- *
- * @param obj The Anchorview object
- * @param h_bounce Allow bounce horizontally
- * @param v_bounce Allow bounce vertically
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_bounce_get(const Evas_Object *obj, Eina_Bool *h_bounce, Eina_Bool *v_bounce)
{
elm_scroller_bounce_get(wd->scroller, h_bounce, v_bounce);
}
-/**
- * This appends a custom item provider to the list for that anchorview
- *
- * This appends the given callback. The list is walked from beginning to end
- * with each function called given the item href string in the text. If the
- * function returns an object handle other than NULL (it should create an
- * and object to do this), then this object is used to replace that item. If
- * not the next provider is called until one provides an item object, or the
- * default provider in anchorview does.
- *
- * @param obj The anchorview object
- * @param func The function called to provide the item object
- * @param data The data passed to @p func
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_item_provider_append(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data)
{
wd->item_providers = eina_list_append(wd->item_providers, ip);
}
-/**
- * This prepends a custom item provider to the list for that anchorview
- *
- * This prepends the given callback. See elm_anchorview_item_provider_append() for
- * more information
- *
- * @param obj The anchorview object
- * @param func The function called to provide the item object
- * @param data The data passed to @p func
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_item_provider_prepend(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data)
{
wd->item_providers = eina_list_prepend(wd->item_providers, ip);
}
-/**
- * This removes a custom item provider to the list for that anchorview
- *
- * This removes the given callback. See elm_anchorview_item_provider_append() for
- * more information
- *
- * @param obj The anchorview object
- * @param func The function called to provide the item object
- * @param data The data passed to @p func
- *
- * @ingroup Anchorview
- */
EAPI void
elm_anchorview_item_provider_remove(Evas_Object *obj, Evas_Object *(*func) (void *data, Evas_Object *anchorview, const char *item), void *data)
{