Mobile native Wearable native

Web: Managing Web Pages and Web Content

This tutorial demonstrates how you can create a simple Web browser.

Warm-up

Become familiar with the Web API basics by learning about:

Initializing the EWK WebKit

To initialize the EWK WebKit:

  1. To use the functions and data types of the WebView API (in mobile and wearable applications), include the <Ecore.h>, <Ecore_Evas.h>, <Ecore_Getopt.h>, <Eet.h>, <Eina.h>, <Elementary.h>, <Evas.h>, <EWebKit.h>, and <app.h> header files in your application:
    #include <Ecore.h>
    #include <Ecore_Evas.h>
    #include <Ecore_Getopt.h>
    #include <Eet.h>
    #include <Eina.h>
    #include <Elementary.h>
    #include <Evas.h>
    #include <EWebKit.h>
    #include <app.h>
    
  2. To use the EWK API, an application needs the following privileges:
    Table: Required privileges for an EWK application
    Privilege Description
    http://tizen.org/privilege/appmanager.launch Allows the application to open another application conditionally.
    http://tizen.org/privilege/content.write Allows the application to create, update and delete content.
    http://tizen.org/privilege/internet Allows the application to use the Internet connection.
    http://tizen.org/privilege/notification Allows the application to provide user notifications, such as messages and badges
    http://tizen.org/privilege/location Allows the application to use the user location data.
    http://tizen.org/privilege/camera Allows the application to manage the device cameras to preview and capture pictures.
    http://tizen.org/privilege/externalstorage Allows the application to access, read and write to the external storage.
    http://tizen.org/privilege/display Allows the application to access the display.
    http://tizen.org/privilege/network.get Allows the application to create a network connection.
  3. The sample browser uses several Evas objects to build the browser UI. To easily manage the UI elements, use the Browser_window data structure. The browser window data is stored in a Browser_window structure that contains 2 Evas_Object instances.
    typedef struct _Browser_Window
    { 
       Evas_Object *elm_window; 
       Evas_Object *ewk_view; 
       Evas_Object *back_button;
       Evas_Object *forward_button;
    } Browser_Window;
     
    EXPORT_API int 
    main(int argc, char *argv[]) 
    { 
       int args = 1; 
       Browser_Window window; 
       memset(&window, 0x00, sizeof(Browser_Window));
    
       ui_app_lifecycle_callback_s ops;
       memset(&ops, 0x00, sizeof(ui_app_lifecycle_callback_s));
    
       ops.create = br_app_create;
    
       return ui_app_main(argc, argv, &ops, &window); 
    }
    
  4. To create a window, call the window_create() function in the br_app_create(void *browser) function.
    window = window_create(NULL, 0, 0, EINA_FALSE);
    

Creating and Deleting a Window Object

To create and delete a window object:

  1. To create a window object, use the elm_win_add(Evas_Object* parent, const char* name, Elm_Win_Type type) function.
  2. You can add a Smart Callback to your window using the evas_object_smart_callback_add (Evas_Object * obj, const char * event, Evas_Smart_Cb func, const void * data) function.
  3. The function adds a callback to the event specified by the event on the smart object (smart event).
    static Browser_Window *window_create(Evas_Object *opener, int width, int height, Eina_Bool view_mode)
    {
       // Allocate memory
       Browser_Window *window = calloc(1, sizeof(Browser_Window));
       if (!window) 
       {
          // "ERROR: could not create browser window."
          return NULL;
       }
    
       // If you want to use gpu acceleration, use the following function
       // elm_config_accel_preference_set("opengl:depth24:stencil8");
    
       // Create window
       window->elm_window = elm_win_add(NULL, "minibrowser-window", ELM_WIN_BASIC);
       evas_object_smart_callback_add(window->elm_window, "delete,request", on_window_deletion, &window);
    }
    
  4. An application also needs a callback fired for the Deletion Window Event. In the callback's body of implementation, call the window_close() function for a returned object of the window_find_with_elm_window() function.
    static void on_window_deletion(void *user_data, Evas_Object *elm_window, void *event_info)
    {
       window_close(window_find_with_elm_window(elm_window));
    }
    

Setting the Window Layout

Create the window layout.

Figure: Window layout

Window layout

For this purpose, create new boxes (vertical_layout and horizontal_layout) using the elm_box_add() function:

// Create vertical layout
Evas_Object *vertical_layout = elm_box_add(window->elm_window);
elm_box_padding_set(vertical_layout, 0, 2);
evas_object_size_hint_weight_set(vertical_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(window->elm_window, vertical_layout);
evas_object_show(vertical_layout);

// Create horizontal layout for top bar
Evas_Object *horizontal_layout = elm_box_add(window->elm_window);
elm_box_horizontal_set(horizontal_layout, EINA_TRUE);
evas_object_size_hint_weight_set(horizontal_layout, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(horizontal_layout, EVAS_HINT_FILL, 0.0);
elm_box_pack_end(vertical_layout, horizontal_layout);
evas_object_show(horizontal_layout);

The evas_object_size_hint_weight_set() function sets the hints for an object's weight. EVAS_HINT_EXPAND is a macro definition for a value 1.0 (EVAS_HINT_FILL for -1.0). The elm_win_resize_object_add(Evas_Object* obj, Evas_Object* subobj) function adds a subobj as the resize object of obj. The evas_object_show(Evas_Object* obj) function makes an obj visible. The elm_box_pack_end(Evas_Object* obj, Evas_Object* subobj) function adds a subobject at the end of the pack list.

Setting the Window View

Create a window view and set the user agent. To create the view, use the ewk_view_add() function. The view is an object that displays pages in the browser. To set the user agent, use the ewk_view_user_agent_set() function.

static Browser_Window *window_create(Evas_Object *opener, int width, int height, Eina_Bool view_mode) 
{ 
   Evas *evas = evas_object_evas_get(window->elm_window);
   window->ewk_view = ewk_view_add(evas);

   ewk_view_user_agent_set(window->ewk_view, user_agent_string);
}

Handling Key and Mouse Events

To handle mouse or key events, corresponding callbacks need to be set by calling the evas_object_event_callback_add() function.

static Browser_Window *window_create(Evas_Object *opener, int width, int height, Eina_Bool view_mode) 
{ 
   evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_KEY_DOWN, on_key_down, window); 
   evas_object_event_callback_add(window->ewk_view, EVAS_CALLBACK_MOUSE_DOWN, on_mouse_down, window); 
}
Table: Key and mouse callbacks
Event Callback Callback type
Key down EVAS_CALLBACK_KEY_DOWN static void on_key_down(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info);
Mouse down EVAS_CALLBACK_MOUSE_DOWN static void on_mouse_down(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info);

To handle pressed key modifiers, such as Control or Alt, the evas_key_modifier_is_set() function must be called. To get the Evas_Modifier object that contains information about which key modifiers are registered, call the evas_key_modifier_get() function, passing the Evas canvas object as an argument. Example code:

static void on_key_down(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info) 
{ 
   Browser_Window *window = (Browser_Window *)user_data; 
   Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info; 

   const Evas_Modifier *mod = evas_key_modifier_get(e); 
   Eina_Bool ctrlPressed = evas_key_modifier_is_set(mod, "Control"); 
   Eina_Bool altPressed = evas_key_modifier_is_set(mod, "Alt");
}

Now ev->key contains the name of the key that caused the event trigger. For example, to check whether the combination Alt + Left Arrow was pressed, (!strcmp(ev->key, "Left") && altPressed) must evaluate to TRUE.

Table: Key behavior
Key Behavior API
Alt+Left Back view ewk_view_back
Alt+Right Forward view ewk_view_forward
F5 Reload view ewk_view_reload
Alt+F5 Reload view bypassing cache ewk_view_bypass_cache
F6 Stop ewk_view_stop

The mouse down event information is stored in Evas_Event_Mouse_Down. Similarly as in key events, ev->button contains information on which button was pressed. In this example, pressing the first button calls the view_focus_set() function to update the focus. Example code:

static void on_mouse_down(void *user_data, Evas *e, Evas_Object *ewk_view, void *event_info) 
{ 
   Browser_Window *window = (Browser_Window *)user_data; 
   Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down *)event_info; 

   if (ev->button == 1) 
      view_focus_set(window, EINA_TRUE); 
}

Showing a Window and Setting the Focus

In EFL, the UI focus control is implemented in an Elementary object, not an Evas_object. Therefore, the application using EWK derived from an Evas_object must control the focus itself. For example, steal focus away from the elm_window object and give it to the ewk_view.

To set the focus to a ewk_view, use the void elm_object_focus_set (Evas_Object *obj, Eina_Bool focus) and void evas_object_focus_set (Evas_Object *obj, Eina_Bool focus) functions. Example code:

static void view_focus_set(Browser_Window *window, Eina_Bool focus) 
{ 
   // We steal focus away from elm focus model and start to do things 
   // manually here, so elm now has no clue what is up. Tell elm that its 
   // top level UI component is to be unfocused so elm gives up the focus 
   elm_object_focus_set(elm_object_top_widget_get(window->elm_window), EINA_FALSE); 
   evas_object_focus_set(window->ewk_view, focus); 
};

Call this function in the window_create() function.

window_create()
{
   elm_win_resize_object_add(window->elm_window, window->ewk_view);
   evas_object_show(window->ewk_view);

   evas_object_show(window->elm_window);

   view_focus_set(window, EINA_TRUE);

   return window;
}

The void evas_object_show (Evas_Object *obj) function makes the given Evas object visible.

Finding a Window

This example uses 2 helper functions for finding window structures. The first one, the window_find_with_elm_window() function, takes elm_window as an argument and returns a pointer to the Browser_Window object that the window is part of. The second one, the window_find_with_ewk_view() function, does the same for ewk_view. Both of them use the EINA_LIST_FOREACH macro to iterate over the windows list.

static Browser_Window *window_find_with_elm_window(Evas_Object *elm_window) 
{ 
   Eina_List *l; 
   void *data; 

   if (!elm_window) 
      return NULL; 

   EINA_LIST_FOREACH(windows, l, data)
   { 
      Browser_Window *window = (Browser_Window *)data; 
      if (window->elm_window == elm_window) 
         return window; 
   } 

   return NULL; 
}

static Browser_Window *window_find_with_ewk_view(Evas_Object *ewk_view) 
{ 
   Eina_List *l; 
   void *data; 

   if (!ewk_view) 
      return NULL; 

   EINA_LIST_FOREACH(windows, l, data)
   { 
      Browser_Window *window = (Browser_Window *)data; 
      if (window->ewk_view == ewk_view) 
         return window; 
   } 

   return NULL; 
}

Finalizing the Application

To close the application correctly, use the ewk_shutdown() function. This function cleans up any resources your application has allocated.

static void br_app_terminate(void *app_data)
{
   ewk_shutdown();
}

In the main function, register the termination callback:

main()
{
   ops.create = br_app_create;
   ops.terminate = br_app_terminate;

   return ui_app_main(argc, argv, &ops, &window);
}
Go to top