Web - Simple example

WebKit-EFL is independent of any particular toolkit, such as Elementary, so using it on applications requires that the programmer writes a lot of boiler plate code to manage to manage the web object.

For a full featured browser this may make sense, as the programmer will want to have full control of every aspect of the web object, since it's the main component of the application. But other programs with simpler requirements, having to write so much code is undesired.

This is where elm_web comes in. Its purpose is to provide a simple way for developers to embed a simple web object in their programs, simplifying the common use cases.

This is not to say that a browser can't be made out of it, as this example shows.

We'll be making a simple browser, consisting of one window with an URL bar, a toolbar to be used for the tabs and a pager to show one page at a time.

When all tabs are closed, we'll be showing a default view with some custom content, for which we need to get the internal `ewk_view` object and use some WebKit functions on it, thus we need to include the necessary headers first.

#include <Elementary.h>
#ifdef HAVE_ELEMENTARY_WEB
#include <EWebKit.h>

A struct to keep track of the different widgets in use and the currently shown tab. There's also an `exiting` flag, used to work around the overly simplistic way in which this example is written, just to avoid some warnings when closing the program.

typedef struct _Tab_Data Tab_Data;
typedef struct
{
Evas_Object *win;
Evas_Object *main_box;
Evas_Object *naviframe;
Evas_Object *url_entry;
Evas_Object *default_web;
Evas_Object *tabs;
Evas_Object *close_tab;
Evas_Object *search_box;
Evas_Object *search_entry;
struct {
Evas_Object *back;
Evas_Object *fwd;
Evas_Object *refresh;
} nav;
Tab_Data *current_tab;
Eina_Bool exiting : 1;
} App_Data;
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition eina_types.h:527
Evas_Object
Efl_Canvas_Object Evas_Object
An Evas Object handle.
Definition Evas_Common.h:185

Each tab has its own struct too, but there's not much to it.

struct _Tab_Data
{
Evas_Object *web;
App_Data *app;
Elm_Object_Item *tab;
};
Elm_Object_Item
Eo Elm_Object_Item
An Elementary Object item handle.
Definition elm_object_item.h:6

Whenever the currently selected tab changes, we need to update some state on the application. The back and forward buttons need to be disabled accordingly and the URL bar needs to show the right address.

static void
nav_button_update(App_Data *ad)
{
Eina_Bool back, fwd;
back = !elm_web_back_possible_get(ad->current_tab->web);
fwd = !elm_web_forward_possible_get(ad->current_tab->web);
elm_object_disabled_set(ad->nav.back, back);
elm_object_disabled_set(ad->nav.fwd, fwd);
}
static void
tab_current_set(Tab_Data *td)
{
const char *url;
if (td == td->app->current_tab)
return;
td->app->current_tab = td;
url = elm_web_url_get(td->web);
elm_object_text_set(td->app->url_entry, url);
nav_button_update(td->app);
elm_entry_icon_visible_set(td->app->url_entry, EINA_TRUE);
elm_naviframe_item_simple_promote(td->app->naviframe, td->web);
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
elm_entry_icon_visible_set
void elm_entry_icon_visible_set(Elm_Entry *obj, Eina_Bool setting)
Sets the visibility of the left-side widget of the entry, set by elm_object_part_content_set.
Definition elm_entry_eo.legacy.c:267
elm_object_disabled_set
void elm_object_disabled_set(Evas_Object *obj, Eina_Bool disabled)
Set the disabled state of an Elementary object.
Definition elm_main.c:1613
elm_naviframe_item_simple_promote
void elm_naviframe_item_simple_promote(Elm_Naviframe *obj, Efl_Canvas_Object *content)
Simple version of item_promote.
Definition elm_naviframe_eo.legacy.c:75
}

Other updates happen based on events from the web object, like title change to update the name shown in the tab, and URL change which will update the URL bar if the event came from the currently selected tab.

static void
_title_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Tab_Data *td = data;
const char *title = event_info;
char buf[20] = "";
if (title)
strncpy(buf, title, sizeof(buf) - 1);
elm_object_item_text_set(td->tab, buf);
}
EINA_UNUSED
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339
elm_object_item_text_set
#define elm_object_item_text_set(it, label)
Macro to set a label of an object item.
Definition elm_object_item.h:44
static void
_url_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Tab_Data *td = data;
const char *url = event_info;
if (td != td->app->current_tab)
return;
nav_button_update(td->app);
elm_object_text_set(td->app->url_entry, url);
}

Adding a new tab is just a matter of creating a new web widget, its data and pushing it into the pager. A lot of the things that we should handle here, such as how to react to popups and JavaScript dialogs, are done already in the `elm_web` widget, so we can rely on their default implementations. For the JavaScript dialogs we are going to avoid having them open in a new window by setting the `Inwin` mode.

There is no default implementation, however, for the requests to create a new window, so we have to handle them by setting a callback function that will ultimately call this very same function to add a new tab.

Tab_Data *
tab_add(App_Data *ad)
{
Tab_Data *td;
td = calloc(1, sizeof(Tab_Data));
if (!td) return NULL;
td->web = elm_web_add(ad->win);
elm_web_window_create_hook_set(td->web, _web_create_window_cb, ad);
elm_web_inwin_mode_set(td->web, EINA_TRUE);
evas_object_size_hint_weight_set(td->web, EVAS_HINT_EXPAND,
EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(td->web, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_naviframe_item_simple_push(ad->naviframe, td->web);
td->app = ad;
td->tab = elm_toolbar_item_append(td->app->tabs, NULL, "New tab",
_tab_clicked_cb, td);
elm_object_item_del_cb_set(td->tab, _tb_item_del_cb);
evas_object_data_set(td->web, "tab_data", td);
evas_object_smart_callback_add(td->web, "title,changed", _title_changed_cb,
td);
evas_object_smart_callback_add(td->web, "url,changed", _url_changed_cb, td);
evas_object_event_callback_add(td->web, EVAS_CALLBACK_FREE, _web_free_cb,
td);
elm_toolbar_item_selected_set(td->tab, EINA_TRUE);
return td;
}
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_FREE
@ EVAS_CALLBACK_FREE
Object Being Freed (Called after Del).
Definition Evas_Common.h:429
EVAS_HINT_FILL
#define EVAS_HINT_FILL
Use with evas_object_size_hint_align_set(), evas_object_size_hint_align_get(), evas_object_size_hint_...
Definition Evas_Common.h:298
elm_object_item_del_cb_set
void elm_object_item_del_cb_set(Elm_Widget_Item *obj, Evas_Smart_Cb del_cb)
Set the function to be called when an item from the widget is freed.
Definition elm_widget_item_eo.legacy.c:231
elm_toolbar_item_append
Elm_Widget_Item * elm_toolbar_item_append(Elm_Toolbar *obj, const char *icon, const char *label, Evas_Smart_Cb func, const void *data)
Append item to the toolbar.
Definition elm_toolbar_eo.legacy.c:129
elm_web_add
Evas_Object * elm_web_add(Evas_Object *parent)
Add a new web object to the parent.
Definition elm_web2.c:80
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_data_set
EVAS_API void evas_object_data_set(Evas_Object *eo_obj, const char *key, const void *data)
Set an attached data pointer to an object with a given string key.
Definition evas_data.c:5
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_size_hint_align_set
EVAS_API void evas_object_size_hint_align_set(Evas_Object *obj, double x, double y)
Sets the hints for an object's alignment.
Definition evas_object_main.c:2650
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

Entering an address in the URL bar will check if a tab exists, and if not, create one and set the URL for it. The address needs to conform to the URI format, so we check that it does and add the protocol if it's missing.

static char *
url_sanitize(const char *url)
{
char *fixed_url;
char *schema;
char *tmp;
if (!url || !*url) return NULL;
tmp = strstr(url, "://");
if (!tmp || (tmp == url) || (tmp > (url + 15)))
{
char *new_url = NULL;
if (ecore_file_exists(url))
{
schema = "file";
new_url = ecore_file_realpath(url);
}
else
schema = "http";
if (asprintf(&fixed_url, "%s://%s", schema, new_url ? new_url : url) >
0)
{
free(new_url);
return fixed_url;
}
free(new_url);
}
else
return strdup(url);
return NULL;
}
static void
tab_url_set(Tab_Data *td, const char *url)
{
char *sane_url = url_sanitize(url);
elm_web_url_set(td->web, sane_url);
free(sane_url);
}
static void
_url_entry_activated_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
Tab_Data *td;
const char *url = eina_stringshare_ref(elm_object_text_get(obj));
if (!ad->current_tab)
td = tab_add(ad);
else
td = ad->current_tab;
tab_url_set(td, url);
eina_stringshare_del(url);
ecore_file_realpath
char * ecore_file_realpath(const char *file)
Gets the canonicalized absolute path name.
Definition ecore_file.c:554
ecore_file_exists
Eina_Bool ecore_file_exists(const char *file)
Checks if the given file exists.
Definition ecore_file.c:165
eina_stringshare_del
EINA_API void eina_stringshare_del(Eina_Stringshare *str)
Notes that the given string has lost an instance.
Definition eina_stringshare.c:533
eina_stringshare_ref
EINA_API Eina_Stringshare * eina_stringshare_ref(Eina_Stringshare *str)
Increment references of the given shared string.
Definition eina_stringshare.c:685
}

The navigation buttons are simple enough. As for the refresh, it normally reloads the page using anything that may exist in the caches if applicable, but we can press it while holding the `Shift` key to avoid the cache.

static void
_nav_back_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
elm_web_back(ad->current_tab->web);
}
static void
_nav_refresh_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
const Evas_Modifier *mods = evas_key_modifier_get(evas_object_evas_get(obj));
if (evas_key_modifier_is_set(mods, "Shift"))
elm_web_reload_full(ad->current_tab->web);
else
elm_web_reload(ad->current_tab->web);
}
static void
_nav_fwd_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
elm_web_forward(ad->current_tab->web);
evas_key_modifier_get
EVAS_API const Evas_Modifier * evas_key_modifier_get(const Evas *eo_e)
Returns a handle to the list of modifier keys registered in the canvas e.
Definition evas_key.c:35
Evas_Modifier
struct _Evas_Modifier Evas_Modifier
An opaque type containing information on which modifier keys are registered in an Evas canvas.
Definition Evas_Internal.h:36
evas_key_modifier_is_set
EVAS_API Eina_Bool evas_key_modifier_is_set(const Evas_Modifier *m, const char *keyname)
Checks the state of a given modifier of the default seat, at the time of the call.
Definition evas_key.c:76
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
}

The callback set for the new window request creates a new tab and returns the web widget associated with it. This is important, this function must return a valid web widget returned by elm_web_add().

static Evas_Object *
_web_create_window_cb(void *data, Evas_Object *obj EINA_UNUSED,
Eina_Bool js EINA_UNUSED, const Elm_Web_Window_Features *wf EINA_UNUSED)
{
App_Data *ad = data;
Tab_Data *td;
td = tab_add(ad);
return td->web;
}
Elm_Web_Window_Features
struct _Elm_Web_Window_Features Elm_Web_Window_Features
Opaque handler containing the features (such as statusbar, menubar, etc) that are to be set on a newl...
Definition elm_web_common.h:121

Pressing `Ctrl-F` will bring up the search box. Nothing about the box itself is worth mentioning here, but it works as you would expect from any other browser. While typing on it, it will highlight all occurrences of the searched word. Pressing `Enter` will go to the next instance and the two buttons next to the entry will move forward and backwards through the found keywords.

static void
_win_free_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
free(data);
}
static void
_search_entry_changed_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
const char *text;
text = elm_object_text_get(obj);
elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,
EINA_TRUE);
elm_web_text_matches_unmark_all(ad->current_tab->web);
elm_web_text_matches_mark(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,
0);
}
static void
_search_entry_activate_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
const char *text;
text = elm_object_text_get(obj);
elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,
EINA_TRUE);
}
static void
_search_next_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
const char *text;
text = elm_object_text_get(ad->search_entry);
elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,
EINA_TRUE);
}
static void
_search_prev_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
const char *text;
text = elm_object_text_get(ad->search_entry);
elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_FALSE,
EINA_TRUE);
}
static void
_search_close_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
evas_object_del(ad->search_box);
}
static void
_search_box_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
App_Data *ad = data;
ad->search_box = NULL;
ad->search_entry = NULL;
}
static void
_win_search_trigger_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition eina_types.h:533
Evas
Eo Evas
An opaque handle to an Evas canvas.
Definition Evas_Common.h:163
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_Event_Key_Down *ev = event_info;
App_Data *ad = data;
Evas_Object *box, *box2, *entry, *btn, *ic;
if (strcmp(ev->keyname, "f") ||
!evas_key_modifier_is_set(ev->modifiers, "Control"))
return;
if (ad->search_box || !ad->current_tab)
return;
box = elm_box_add(ad->win);
elm_box_horizontal_set(box, EINA_TRUE);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_after(ad->main_box, box, ad->url_entry);
evas_object_show(box);
evas_object_event_callback_add(box, EVAS_CALLBACK_DEL, _search_box_del_cb,
ad);
entry = elm_entry_add(ad->win);
elm_entry_single_line_set(entry, EINA_TRUE);
elm_entry_scrollable_set(entry, EINA_TRUE);
evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, entry);
evas_object_show(entry);
evas_object_smart_callback_add(entry, "changed", _search_entry_changed_cb,
ad);
evas_object_smart_callback_add(entry, "activated", _search_entry_activate_cb,
ad);
box2 = elm_box_add(ad->win);
elm_box_horizontal_set(box2, EINA_TRUE);
elm_object_part_content_set(entry, "end", box2);
btn = elm_button_add(ad->win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
ic = elm_icon_add(ad->win);
elm_icon_standard_set(ic, "arrow_up");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _search_prev_cb, ad);
btn = elm_button_add(ad->win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
ic = elm_icon_add(ad->win);
elm_icon_standard_set(ic, "arrow_down");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _search_next_cb, ad);
btn = elm_button_add(ad->win);
elm_box_pack_end(box, btn);
evas_object_show(btn);
ic = elm_icon_add(ad->win);
elm_icon_standard_set(ic, "close");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _search_close_cb, ad);
ad->search_box = box;
ad->search_entry = entry;
elm_object_focus_set(entry, EINA_TRUE);
}
EVAS_CALLBACK_DEL
@ EVAS_CALLBACK_DEL
Object Being Deleted (called before Free).
Definition Evas_Common.h:439
elm_box_horizontal_set
void elm_box_horizontal_set(Elm_Box *obj, Eina_Bool horizontal)
Set the horizontal orientation.
Definition elm_box_eo.legacy.c:27
elm_box_pack_after
void elm_box_pack_after(Elm_Box *obj, Efl_Canvas_Object *subobj, Efl_Canvas_Object *after)
Adds an object to the box after the indicated object.
Definition elm_box_eo.legacy.c:75
elm_box_add
Evas_Object * elm_box_add(Evas_Object *parent)
Add a new box to the parent.
Definition elm_box.c:363
elm_box_pack_end
void elm_box_pack_end(Elm_Box *obj, Efl_Canvas_Object *subobj)
Add an object at the end of the pack list.
Definition elm_box_eo.legacy.c:57
elm_button_add
Evas_Object * elm_button_add(Evas_Object *parent)
Add a new button to the parent's canvas.
Definition efl_ui_button.c:459
elm_entry_scrollable_set
void elm_entry_scrollable_set(Elm_Entry *obj, Eina_Bool scroll)
Enable or disable scrolling in entry.
Definition elm_entry_eo.legacy.c:3
elm_entry_single_line_set
void elm_entry_single_line_set(Elm_Entry *obj, Eina_Bool single_line)
Sets the entry to single line mode.
Definition elm_entry_eo.legacy.c:123
elm_entry_add
Evas_Object * elm_entry_add(Evas_Object *parent)
This adds an entry to parent object.
Definition elm_entry.c:4183
elm_object_focus_set
void elm_object_focus_set(Evas_Object *obj, Eina_Bool focus)
Set/unset focus to a given Elementary object.
Definition elm_focus_legacy.c:374
elm_object_part_content_set
void elm_object_part_content_set(Evas_Object *obj, const char *part, Evas_Object *content)
Set the content on part of a given container widget.
Definition elm_main.c:1562
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:876
elm_icon_add
Evas_Object * elm_icon_add(Evas_Object *parent)
Add a new icon object to the parent.
Definition elm_icon.c:604
Evas_Event_Key_Down
struct _Evas_Event_Key_Down Evas_Event_Key_Down
Event structure for EVAS_CALLBACK_KEY_DOWN event callbacks.
Definition Evas_Legacy.h:154
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_Event_Key_Down::keyname
char * keyname
the name string of the key pressed
Definition Evas_Legacy.h:315
_Evas_Event_Key_Down::modifiers
Evas_Modifier * modifiers
modifier keys pressed during the event
Definition Evas_Legacy.h:317

Last, create the main window and put all of the things used above in it. It contains a default web widget that will be shown when no tabs exist. This web object is not browsable per se, so history is disabled in it, and we set the same callback to create new windows, on top of setting some custom content of our own on it, with some links that will open new tabs to start browsing quickly.

static void
default_content_set(Evas_Object *web)
{
#ifdef HAVE_ELEMENTARY_WEB
Evas_Object *view, *frame;
const char contents[] = ""
"<html>\n"
" <head>\n"
" <title>Nothing to see here, move along</title>\n"
" </head>\n"
" <body>\n"
" <a href=\"http://www.enlightenment.org\" target=\"_blank\">E</a>\n"
" <br />\n"
" <a href=\"http://www.google.com\" target=\"_blank\">Google</a>\n"
" <br />\n"
" </body>\n"
"</html>\n";
view = elm_web_webkit_view_get(web);
frame = ewk_view_frame_main_get(view);
ewk_frame_contents_set(frame, contents, sizeof(contents) - 1, "text/html",
"UTF-8", NULL);
#else
(void) web;
#endif
}
EAPI_MAIN int
elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
{
Evas_Object *win, *box, *box2, *btn, *ic, *url_bar, *naviframe, *tabs, *web;
Evas *e;
Evas_Modifier_Mask ctrl_mask;
App_Data *ad;
if (!elm_need_web())
return -1;
ad = calloc(1, sizeof(App_Data));
if (!ad) return -1;
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
win = elm_win_util_standard_add("example-web", "Web Example");
elm_win_autodel_set(win, EINA_TRUE);
e = evas_object_evas_get(win);
ctrl_mask = evas_key_modifier_mask_get(e, "Control");
if (!evas_object_key_grab(win, "f", ctrl_mask, 0, EINA_TRUE))
fprintf(stderr, "Could not grab trigger for search dialog\n");
evas_object_smart_callback_add(win, "delete,request", _win_del_request_cb,
ad);
evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN,
_win_search_trigger_cb, ad);
evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _win_free_cb, ad);
box = elm_box_add(win);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, box);
evas_object_show(box);
url_bar = elm_entry_add(win);
elm_entry_single_line_set(url_bar, EINA_TRUE);
elm_entry_scrollable_set(url_bar, EINA_TRUE);
evas_object_size_hint_weight_set(url_bar, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(url_bar, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, url_bar);
evas_object_show(url_bar);
evas_object_smart_callback_add(url_bar, "activated", _url_entry_activated_cb, ad);
box2 = elm_box_add(win);
elm_box_horizontal_set(box2, EINA_TRUE);
elm_object_part_content_set(url_bar, "icon", box2);
elm_entry_icon_visible_set(url_bar, EINA_FALSE);
btn = elm_button_add(win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
ad->nav.back = btn;
ic = elm_icon_add(win);
elm_icon_standard_set(ic, "arrow_left");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _nav_back_cb, ad);
btn = elm_button_add(win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
ad->nav.refresh = btn;
ic = elm_icon_add(win);
elm_icon_standard_set(ic, "refresh");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _nav_refresh_cb, ad);
btn = elm_button_add(win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
ad->nav.fwd = btn;
ic = elm_icon_add(win);
elm_icon_standard_set(ic, "arrow_right");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _nav_fwd_cb, ad);
box2 = elm_box_add(win);
elm_box_horizontal_set(box2, EINA_TRUE);
evas_object_size_hint_weight_set(box2, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(box2, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, box2);
evas_object_show(box2);
btn = elm_button_add(win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
ic = elm_icon_add(win);
elm_icon_standard_set(ic, "file");
elm_object_part_content_set(btn, "icon", ic);
evas_object_smart_callback_add(btn, "clicked", _add_tab_cb, ad);
tabs = elm_toolbar_add(win);
elm_toolbar_align_set(tabs, 0.0);
elm_toolbar_select_mode_set(tabs, ELM_OBJECT_SELECT_MODE_ALWAYS);
elm_toolbar_homogeneous_set(tabs, EINA_FALSE);
elm_toolbar_shrink_mode_set(tabs, ELM_TOOLBAR_SHRINK_MENU);
evas_object_size_hint_weight_set(tabs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(tabs, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box2, tabs);
evas_object_show(tabs);
btn = elm_button_add(win);
elm_box_pack_end(box2, btn);
evas_object_show(btn);
evas_object_smart_callback_add(btn, "clicked", _close_tab_cb, ad);
ic = elm_icon_add(win);
elm_icon_standard_set(ic, "close");
elm_object_part_content_set(btn, "icon", ic);
naviframe = elm_naviframe_add(win);
evas_object_size_hint_weight_set(naviframe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(naviframe, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(box, naviframe);
evas_object_show(naviframe);
elm_toolbar_menu_parent_set(tabs, naviframe);
web = elm_web_add(win);
elm_web_window_create_hook_set(web, _web_create_window_cb, ad);
elm_web_history_enabled_set(web, EINA_FALSE);
evas_object_size_hint_weight_set(web, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(web, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_naviframe_item_simple_push(naviframe, web);
default_content_set(web);
ad->win = win;
ad->main_box = box;
ad->naviframe = naviframe;
ad->url_entry = url_bar;
ad->default_web = web;
ad->tabs = tabs;
ad->close_tab = btn;
evas_object_resize(win, 480, 640);
evas_object_show(win);
elm_run();
return 0;
}
ELM_MAIN()
EVAS_CALLBACK_KEY_DOWN
@ EVAS_CALLBACK_KEY_DOWN
Key Press Event.
Definition Evas_Common.h:430
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_OBJECT_SELECT_MODE_ALWAYS
@ ELM_OBJECT_SELECT_MODE_ALWAYS
always select mode.
Definition elm_general.h:39
ELM_POLICY_QUIT
@ ELM_POLICY_QUIT
under which circumstances the application should quit automatically.
Definition elm_general.h:227
elm_naviframe_add
Evas_Object * elm_naviframe_add(Evas_Object *parent)
Add a new Naviframe object to the parent.
Definition elc_naviframe.c:1605
elm_toolbar_homogeneous_set
void elm_toolbar_homogeneous_set(Elm_Toolbar *obj, Eina_Bool homogeneous)
Control homogeneous mode.
Definition elm_toolbar_eo.legacy.c:27
elm_toolbar_shrink_mode_set
void elm_toolbar_shrink_mode_set(Elm_Toolbar *obj, Elm_Toolbar_Shrink_Mode shrink_mode)
Control the item displaying mode of a given toolbar widget obj.
Definition elm_toolbar_eo.legacy.c:75
elm_toolbar_add
Evas_Object * elm_toolbar_add(Evas_Object *parent)
Add a new toolbar widget to the given parent Elementary (container) object.
Definition elm_toolbar.c:2979
elm_toolbar_align_set
void elm_toolbar_align_set(Elm_Toolbar *obj, double align)
Control the alignment of the items.
Definition elm_toolbar_eo.legacy.c:39
elm_toolbar_menu_parent_set
void elm_toolbar_menu_parent_set(Elm_Toolbar *obj, Efl_Canvas_Object *parent)
Control the parent object of the toolbar items' menus.
Definition elm_toolbar_eo.legacy.c:87
elm_toolbar_select_mode_set
void elm_toolbar_select_mode_set(Elm_Toolbar *obj, Elm_Object_Select_Mode mode)
Control the toolbar select mode.
Definition elm_toolbar_eo.legacy.c:51
elm_need_web
Eina_Bool elm_need_web(void)
Request that your elementary application needs web support.
Definition elm_web2.c:73
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:9587
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:9002
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:6199
evas_key_modifier_mask_get
EVAS_API Evas_Modifier_Mask evas_key_modifier_mask_get(const Evas *eo_e, const char *keyname)
Creates a bit mask from the keyname modifier key.
Definition evas_key.c:271
Evas_Modifier_Mask
unsigned long long Evas_Modifier_Mask
A bitmask of modifier keys.
Definition Evas_Legacy.h:132
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

Some parts of the code were left out, as they are not relevant to the example, but the full listing can be found at web_example_02.c.