efl
620 строк · 16.7 Кб
1/*
2* gcc -o web_example_02 web_example_02.c `pkg-config --cflags --libs elementary ewebkit` -D_GNU_SOURCE
3*/
4#ifndef _GNU_SOURCE5# define _GNU_SOURCE6#endif7
8#include <Elementary.h>9#ifdef HAVE_ELEMENTARY_WEB10#include <EWebKit.h>11#endif12
13typedef struct _Tab_Data Tab_Data;14
15typedef struct16{
17Evas_Object *win;18Evas_Object *main_box;19Evas_Object *naviframe;20Evas_Object *url_entry;21Evas_Object *default_web;22Evas_Object *tabs;23Evas_Object *close_tab;24Evas_Object *search_box;25Evas_Object *search_entry;26
27struct {28Evas_Object *back;29Evas_Object *fwd;30Evas_Object *refresh;31} nav;32
33Tab_Data *current_tab;34
35Eina_Bool exiting : 1;36} App_Data;37
38struct _Tab_Data39{
40Evas_Object *web;41App_Data *app;42Elm_Object_Item *tab;43};44
45static Evas_Object * _web_create_window_cb(void *data, Evas_Object *obj, Eina_Bool js, const Elm_Web_Window_Features *wf);46
47static void48nav_button_update(App_Data *ad)49{
50Eina_Bool back, fwd;51
52back = !elm_web_back_possible_get(ad->current_tab->web);53fwd = !elm_web_forward_possible_get(ad->current_tab->web);54
55elm_object_disabled_set(ad->nav.back, back);56elm_object_disabled_set(ad->nav.fwd, fwd);57}
58
59static void60tab_current_set(Tab_Data *td)61{
62const char *url;63
64if (td == td->app->current_tab)65return;66
67td->app->current_tab = td;68
69url = elm_web_url_get(td->web);70elm_object_text_set(td->app->url_entry, url);71
72nav_button_update(td->app);73elm_entry_icon_visible_set(td->app->url_entry, EINA_TRUE);74
75elm_naviframe_item_simple_promote(td->app->naviframe, td->web);76}
77
78static void79_tab_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)80{
81Tab_Data *td = data;82/* the first toolbar_item_append() calls the select callback before the item83* is assigned, so we need a workaround for that. */
84if (!td->tab)85td->tab = event_info;86tab_current_set(td);87}
88
89static void90_title_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)91{
92Tab_Data *td = data;93const char *title = event_info;94char buf[20] = "";95
96if (title)97strncpy(buf, title, sizeof(buf) - 1);98elm_object_item_text_set(td->tab, buf);99}
100
101static void102_url_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)103{
104Tab_Data *td = data;105const char *url = event_info;106
107if (td != td->app->current_tab)108return;109
110nav_button_update(td->app);111elm_object_text_set(td->app->url_entry, url);112}
113
114static void115_web_free_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)116{
117Tab_Data *td = data;118
119if (td->tab)120elm_object_item_del(td->tab);121
122free(td);123}
124
125static void126_tb_item_del_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)127{
128Tab_Data *td = data;129if (!td->app->exiting && !elm_toolbar_selected_item_get(obj))130{131td->app->current_tab = NULL;132elm_entry_icon_visible_set(td->app->url_entry, EINA_FALSE);133if (td->app->search_box)134evas_object_del(td->app->search_box);135}136td->tab = NULL;137}
138
139Tab_Data *140tab_add(App_Data *ad)141{
142Tab_Data *td;143
144td = calloc(1, sizeof(Tab_Data));145if (!td) return NULL;146
147td->web = elm_web_add(ad->win);148elm_web_window_create_hook_set(td->web, _web_create_window_cb, ad);149elm_web_inwin_mode_set(td->web, EINA_TRUE);150evas_object_size_hint_weight_set(td->web, EVAS_HINT_EXPAND,151EVAS_HINT_EXPAND);152evas_object_size_hint_align_set(td->web, EVAS_HINT_FILL, EVAS_HINT_FILL);153elm_naviframe_item_simple_push(ad->naviframe, td->web);154
155td->app = ad;156td->tab = elm_toolbar_item_append(td->app->tabs, NULL, "New tab",157_tab_clicked_cb, td);158elm_object_item_del_cb_set(td->tab, _tb_item_del_cb);159
160evas_object_data_set(td->web, "tab_data", td);161
162evas_object_smart_callback_add(td->web, "title,changed", _title_changed_cb,163td);164evas_object_smart_callback_add(td->web, "url,changed", _url_changed_cb, td);165evas_object_event_callback_add(td->web, EVAS_CALLBACK_FREE, _web_free_cb,166td);167
168elm_toolbar_item_selected_set(td->tab, EINA_TRUE);169return td;170}
171
172static char *173url_sanitize(const char *url)174{
175char *fixed_url;176char *schema;177char *tmp;178
179if (!url || !*url) return NULL;180
181tmp = strstr(url, "://");182if (!tmp || (tmp == url) || (tmp > (url + 15)))183{184char *new_url = NULL;185if (ecore_file_exists(url))186{187schema = "file";188new_url = ecore_file_realpath(url);189}190else191schema = "http";192
193if (asprintf(&fixed_url, "%s://%s", schema, new_url ? new_url : url) >1940)195{196free(new_url);197return fixed_url;198}199free(new_url);200}201else202return strdup(url);203
204return NULL;205}
206
207static void208tab_url_set(Tab_Data *td, const char *url)209{
210char *sane_url = url_sanitize(url);211elm_web_url_set(td->web, sane_url);212free(sane_url);213}
214
215static void216_url_entry_activated_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)217{
218App_Data *ad = data;219Tab_Data *td;220const char *url = eina_stringshare_ref(elm_object_text_get(obj));221
222if (!ad->current_tab)223td = tab_add(ad);224else225td = ad->current_tab;226tab_url_set(td, url);227eina_stringshare_del(url);228}
229
230static void231_nav_back_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)232{
233App_Data *ad = data;234
235elm_web_back(ad->current_tab->web);236}
237
238static void239_nav_refresh_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)240{
241App_Data *ad = data;242const Evas_Modifier *mods = evas_key_modifier_get(evas_object_evas_get(obj));243
244if (evas_key_modifier_is_set(mods, "Shift"))245elm_web_reload_full(ad->current_tab->web);246else247elm_web_reload(ad->current_tab->web);248}
249
250static void251_nav_fwd_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)252{
253App_Data *ad = data;254
255elm_web_forward(ad->current_tab->web);256}
257
258static void259_close_tab_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)260{
261App_Data *ad = data;262
263if (!ad->current_tab)264return;265evas_object_del(ad->current_tab->web);266}
267
268static void269_add_tab_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)270{
271App_Data *ad = data;272tab_add(ad);273elm_object_focus_set(ad->url_entry, EINA_TRUE);274}
275
276static Evas_Object *277_web_create_window_cb(void *data, Evas_Object *obj EINA_UNUSED,278Eina_Bool js EINA_UNUSED, const Elm_Web_Window_Features *wf EINA_UNUSED)279{
280App_Data *ad = data;281Tab_Data *td;282
283td = tab_add(ad);284return td->web;285}
286
287static void288_win_del_request_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)289{
290App_Data *ad = data;291ad->exiting = EINA_TRUE;292}
293
294static void295_win_free_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)296{
297free(data);298}
299
300static void301_search_entry_changed_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)302{
303App_Data *ad = data;304const char *text;305
306text = elm_object_text_get(obj);307elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,308EINA_TRUE);309elm_web_text_matches_unmark_all(ad->current_tab->web);310elm_web_text_matches_mark(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,3110);312}
313
314static void315_search_entry_activate_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)316{
317App_Data *ad = data;318const char *text;319
320text = elm_object_text_get(obj);321elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,322EINA_TRUE);323}
324
325static void326_search_next_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)327{
328App_Data *ad = data;329const char *text;330
331text = elm_object_text_get(ad->search_entry);332elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_TRUE,333EINA_TRUE);334}
335
336static void337_search_prev_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)338{
339App_Data *ad = data;340const char *text;341
342text = elm_object_text_get(ad->search_entry);343elm_web_text_search(ad->current_tab->web, text, EINA_FALSE, EINA_FALSE,344EINA_TRUE);345}
346
347static void348_search_close_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)349{
350App_Data *ad = data;351evas_object_del(ad->search_box);352}
353
354static void355_search_box_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)356{
357App_Data *ad = data;358ad->search_box = NULL;359ad->search_entry = NULL;360}
361
362static void363_win_search_trigger_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)364{
365Evas_Event_Key_Down *ev = event_info;366App_Data *ad = data;367Evas_Object *box, *box2, *entry, *btn, *ic;368
369if (strcmp(ev->keyname, "f") ||370!evas_key_modifier_is_set(ev->modifiers, "Control"))371return;372if (ad->search_box || !ad->current_tab)373return;374
375box = elm_box_add(ad->win);376elm_box_horizontal_set(box, EINA_TRUE);377evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0.0);378evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);379elm_box_pack_after(ad->main_box, box, ad->url_entry);380evas_object_show(box);381
382evas_object_event_callback_add(box, EVAS_CALLBACK_DEL, _search_box_del_cb,383ad);384
385entry = elm_entry_add(ad->win);386elm_entry_single_line_set(entry, EINA_TRUE);387elm_entry_scrollable_set(entry, EINA_TRUE);388evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);389evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);390elm_box_pack_end(box, entry);391evas_object_show(entry);392
393evas_object_smart_callback_add(entry, "changed", _search_entry_changed_cb,394ad);395evas_object_smart_callback_add(entry, "activated", _search_entry_activate_cb,396ad);397
398box2 = elm_box_add(ad->win);399elm_box_horizontal_set(box2, EINA_TRUE);400elm_object_part_content_set(entry, "end", box2);401
402btn = elm_button_add(ad->win);403elm_box_pack_end(box2, btn);404evas_object_show(btn);405
406ic = elm_icon_add(ad->win);407elm_icon_standard_set(ic, "arrow_up");408elm_object_part_content_set(btn, "icon", ic);409
410evas_object_smart_callback_add(btn, "clicked", _search_prev_cb, ad);411
412btn = elm_button_add(ad->win);413elm_box_pack_end(box2, btn);414evas_object_show(btn);415
416ic = elm_icon_add(ad->win);417elm_icon_standard_set(ic, "arrow_down");418elm_object_part_content_set(btn, "icon", ic);419
420evas_object_smart_callback_add(btn, "clicked", _search_next_cb, ad);421
422btn = elm_button_add(ad->win);423elm_box_pack_end(box, btn);424evas_object_show(btn);425
426ic = elm_icon_add(ad->win);427elm_icon_standard_set(ic, "close");428elm_object_part_content_set(btn, "icon", ic);429
430evas_object_smart_callback_add(btn, "clicked", _search_close_cb, ad);431
432ad->search_box = box;433ad->search_entry = entry;434
435elm_object_focus_set(entry, EINA_TRUE);436}
437
438static void439default_content_set(Evas_Object *web)440{
441#ifdef HAVE_ELEMENTARY_WEB442Evas_Object *view, *frame;443const char contents[] = ""444"<html>\n"445" <head>\n"446" <title>Nothing to see here, move along</title>\n"447" </head>\n"448" <body>\n"449" <a href=\"http://www.enlightenment.org\" target=\"_blank\">E</a>\n"450" <br />\n"451" <a href=\"http://www.google.com\" target=\"_blank\">Google</a>\n"452" <br />\n"453" </body>\n"454"</html>\n";455
456view = elm_web_webkit_view_get(web);457frame = ewk_view_frame_main_get(view);458ewk_frame_contents_set(frame, contents, sizeof(contents) - 1, "text/html",459"UTF-8", NULL);460#else461(void) web;462#endif463}
464
465EAPI_MAIN int466elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)467{
468Evas_Object *win, *box, *box2, *btn, *ic, *url_bar, *naviframe, *tabs, *web;469Evas *e;470Evas_Modifier_Mask ctrl_mask;471App_Data *ad;472
473if (!elm_need_web())474return -1;475
476ad = calloc(1, sizeof(App_Data));477if (!ad) return -1;478
479elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);480
481win = elm_win_util_standard_add("example-web", "Web Example");482elm_win_autodel_set(win, EINA_TRUE);483
484e = evas_object_evas_get(win);485ctrl_mask = evas_key_modifier_mask_get(e, "Control");486if (!evas_object_key_grab(win, "f", ctrl_mask, 0, EINA_TRUE))487fprintf(stderr, "Could not grab trigger for search dialog\n");488
489evas_object_smart_callback_add(win, "delete,request", _win_del_request_cb,490ad);491evas_object_event_callback_add(win, EVAS_CALLBACK_KEY_DOWN,492_win_search_trigger_cb, ad);493evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _win_free_cb, ad);494
495box = elm_box_add(win);496evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);497elm_win_resize_object_add(win, box);498evas_object_show(box);499
500url_bar = elm_entry_add(win);501elm_entry_single_line_set(url_bar, EINA_TRUE);502elm_entry_scrollable_set(url_bar, EINA_TRUE);503evas_object_size_hint_weight_set(url_bar, EVAS_HINT_EXPAND, 0.0);504evas_object_size_hint_align_set(url_bar, EVAS_HINT_FILL, EVAS_HINT_FILL);505elm_box_pack_end(box, url_bar);506evas_object_show(url_bar);507
508evas_object_smart_callback_add(url_bar, "activated", _url_entry_activated_cb, ad);509
510box2 = elm_box_add(win);511elm_box_horizontal_set(box2, EINA_TRUE);512elm_object_part_content_set(url_bar, "icon", box2);513elm_entry_icon_visible_set(url_bar, EINA_FALSE);514
515btn = elm_button_add(win);516elm_box_pack_end(box2, btn);517evas_object_show(btn);518
519ad->nav.back = btn;520
521ic = elm_icon_add(win);522elm_icon_standard_set(ic, "arrow_left");523elm_object_part_content_set(btn, "icon", ic);524
525evas_object_smart_callback_add(btn, "clicked", _nav_back_cb, ad);526
527btn = elm_button_add(win);528elm_box_pack_end(box2, btn);529evas_object_show(btn);530
531ad->nav.refresh = btn;532
533ic = elm_icon_add(win);534elm_icon_standard_set(ic, "refresh");535elm_object_part_content_set(btn, "icon", ic);536
537evas_object_smart_callback_add(btn, "clicked", _nav_refresh_cb, ad);538
539btn = elm_button_add(win);540elm_box_pack_end(box2, btn);541evas_object_show(btn);542
543ad->nav.fwd = btn;544
545ic = elm_icon_add(win);546elm_icon_standard_set(ic, "arrow_right");547elm_object_part_content_set(btn, "icon", ic);548
549evas_object_smart_callback_add(btn, "clicked", _nav_fwd_cb, ad);550
551box2 = elm_box_add(win);552elm_box_horizontal_set(box2, EINA_TRUE);553evas_object_size_hint_weight_set(box2, EVAS_HINT_EXPAND, 0.0);554evas_object_size_hint_align_set(box2, EVAS_HINT_FILL, EVAS_HINT_FILL);555elm_box_pack_end(box, box2);556evas_object_show(box2);557
558btn = elm_button_add(win);559elm_box_pack_end(box2, btn);560evas_object_show(btn);561
562ic = elm_icon_add(win);563elm_icon_standard_set(ic, "file");564elm_object_part_content_set(btn, "icon", ic);565
566evas_object_smart_callback_add(btn, "clicked", _add_tab_cb, ad);567
568tabs = elm_toolbar_add(win);569elm_toolbar_align_set(tabs, 0.0);570elm_toolbar_select_mode_set(tabs, ELM_OBJECT_SELECT_MODE_ALWAYS);571elm_toolbar_homogeneous_set(tabs, EINA_FALSE);572elm_toolbar_shrink_mode_set(tabs, ELM_TOOLBAR_SHRINK_MENU);573evas_object_size_hint_weight_set(tabs, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);574evas_object_size_hint_align_set(tabs, EVAS_HINT_FILL, EVAS_HINT_FILL);575elm_box_pack_end(box2, tabs);576evas_object_show(tabs);577
578btn = elm_button_add(win);579elm_box_pack_end(box2, btn);580evas_object_show(btn);581
582evas_object_smart_callback_add(btn, "clicked", _close_tab_cb, ad);583
584ic = elm_icon_add(win);585elm_icon_standard_set(ic, "close");586elm_object_part_content_set(btn, "icon", ic);587
588naviframe = elm_naviframe_add(win);589evas_object_size_hint_weight_set(naviframe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);590evas_object_size_hint_align_set(naviframe, EVAS_HINT_FILL, EVAS_HINT_FILL);591elm_box_pack_end(box, naviframe);592evas_object_show(naviframe);593
594elm_toolbar_menu_parent_set(tabs, naviframe);595
596web = elm_web_add(win);597elm_web_window_create_hook_set(web, _web_create_window_cb, ad);598elm_web_history_enabled_set(web, EINA_FALSE);599evas_object_size_hint_weight_set(web, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);600evas_object_size_hint_align_set(web, EVAS_HINT_FILL, EVAS_HINT_FILL);601elm_naviframe_item_simple_push(naviframe, web);602
603default_content_set(web);604
605ad->win = win;606ad->main_box = box;607ad->naviframe = naviframe;608ad->url_entry = url_bar;609ad->default_web = web;610ad->tabs = tabs;611ad->close_tab = btn;612
613evas_object_resize(win, 480, 640);614evas_object_show(win);615
616elm_run();617
618return 0;619}
620ELM_MAIN()621