WebView in Native Application: Browsing with Multiple Tabs

This tip document will demonstrate how to implement web browsing with multiple tabs in a Native application (which is a continuation of a previous tip document: https://developer.tizen.org/community/tip-tech/webview-native-application ).

For demonstration purpose we’ll consider 200 tabs at most.

Step-1: Creating Data Structure for Browser UI with Multiple tabs

The browser window data is stored in an appdata_s structure that contains different Evas_Object instances. To handle multiple tabs, entry, web_view, goBtn, btn and evas are taken as array data structure.

typedef struct appdata {
	Evas_Object *win;
	Evas_Object *conform;
	Evas_Object *label;

	Evas_Object *entry[200];
	Evas_Object *web_view[200];
	Evas_Object *goBtn[200];
	Evas_Object *btn[200]; // storing tab buttons

	Evas *evas[200];

} appdata_s;

Step-2: GUI Modification

In this sample application, two tables are used globally for creating suitable GUI. One is for storing tab buttons and other will contain entry, web_view and go buttons. ‘positionTab’ will keep track of total number of tabs already have been created. It will also be used in proper alignment of tab buttons along ‘table_tab’.

Evas_Object *table;
Evas_Object *table_tab;
int positionTab = 0;

A button named ‘Add Tab’ is used for creating new tab.

/* 'Add Tab' Button*/
Evas_Object *btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Add Tab");
evas_object_smart_callback_add(btn, "clicked", btn_tab1_cb, ad);
my_table_pack(table_tab, btn, 0, 9, 1, 1);

Step-3: Registering callback events

For creating new tab, btn_tab1_cb callback is called. It initially hides all previous tabs such new tab can be immediately visible.

static 
void btn_tab1_cb(void *data, Evas_Object *obj, void *event_info) {
	appdata_s *ad = data;

	for (int i = 1; i <= positionTab; i++) {

		evas_object_hide(ad->entry[i]);
		evas_object_hide(ad->web_view[i]);
		evas_object_hide(ad->goBtn[i]);
	}
. . .
}

Then for new tab ‘positionTab’ is increased by one and corresponding button is added in win. After that entry, webview and go buttons are added correspondingly in Evas_Object *entry[200], Evas_Object *web_view[200], Evas_Object *goBtn[200] arrays using ‘positionTab’ index.

positionTab++;

ad->btn[positionTab] = elm_button_add(ad->win);
elm_object_text_set(ad->btn[positionTab], "Tab");

For keeping track of every tab one integer is set to every tab button. Then ‘btn_tab2_cb’ callback is made to be associated with this newly created tab button.

int *my_data;
my_data = malloc(sizeof(int));
*my_data = positionTab;
evas_object_data_set(ad->btn[positionTab], "name_of_data", my_data);
evas_object_smart_callback_add(ad->btn[positionTab], "clicked", btn_tab2_cb,
ad);

“btn_tab2_cb” simply collects position information of corresponding tab button and hides all tabs except current tab.

static void btn_tab2_cb(void *data, Evas_Object *obj, void *event_info) {
	appdata_s *ad = (appdata_s *) data;
	int *my_data;
	my_data = evas_object_data_get(obj, "name_of_data");
	for (int i = 1; i <= positionTab; i++) {
		if (*my_data == i) {
			continue;
		}
		evas_object_hide(ad->entry[i]);
		evas_object_hide(ad->web_view[i]);
		evas_object_hide(ad->goBtn[i]);
	}
	evas_object_show(ad->entry[*my_data]);
	evas_object_show(ad->web_view[*my_data]);
	evas_object_show(ad->goBtn[*my_data]);
}

For simplicity deletion of a tab is done with another button named ‘x’ that will appear above the associated tab. This ‘x’ button is associated with “btn_cross_cb” call-back.

static void btn_cross_cb(void *data, Evas_Object *obj, void *event_info) { 
	appdata_s *ad = (appdata_s *) data;
	int *my_data = evas_object_data_get(obj, "name_of_data_cross");
	int v = *my_data;
	evas_object_hide(ad->entry[v]);
	evas_object_hide(ad->goBtn[v]);
	evas_object_hide(ad->web_view[v]);
	evas_object_hide(ad->crossBtn[v]);
	evas_object_hide(ad->btn[v]);

	evas_object_del(ad->crossBtn[v]);
	evas_object_del(ad->btn[v]);
	evas_object_del(ad->entry[v]);
	evas_object_del(ad->goBtn[v]);
	evas_object_del(ad->web_view[v]);

	tab_button_ind[v] = -1;
	. . .
}

Function evas_object_data_get(..) will fetch information about tab position. Then corresponding tab elements are made hidden and deleted.

Step-4: Running the example application

Build and run the attached example. In two different tabs we browsed with two different sites correspondingly. One with http://www.google.com and other with www.tizen.org.

Figure: example of multiple tabs

File attachments: 
List
SDK Version Since: 
2.4 mobile/2.3.1 wearable