a988934cc9215e1783fdb830f6b70b766219b187
[WebKit-https.git] / Tools / MiniBrowser / gtk / BrowserWindow.c
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc.
3  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4  * Copyright (C) 2011 Igalia S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "BrowserWindow.h"
29
30 enum {
31     PROP_0,
32
33     PROP_VIEW
34 };
35
36 struct _BrowserWindow {
37     GtkWindow parent;
38
39     GtkWidget *mainBox;
40     GtkWidget *uriEntry;
41     GtkWidget *backItem;
42     GtkWidget *forwardItem;
43     WebKitWebView *webView;
44
45 };
46
47 struct _BrowserWindowClass {
48     GtkWindowClass parent;
49 };
50
51 static gint windowCount = 0;
52
53 G_DEFINE_TYPE(BrowserWindow, browser_window, GTK_TYPE_WINDOW)
54
55 static void activateUriEntryCallback(BrowserWindow *window)
56 {
57     webkit_web_view_load_uri(window->webView, gtk_entry_get_text(GTK_ENTRY(window->uriEntry)));
58 }
59
60 static void goBackCallback(BrowserWindow *window)
61 {
62     webkit_web_view_go_back(window->webView);
63 }
64
65 static void goForwardCallback(BrowserWindow *window)
66 {
67     webkit_web_view_go_forward(window->webView);
68 }
69
70 static void webViewURIChanged(WebKitWebView *webView,  GParamSpec *pspec, BrowserWindow *window)
71 {
72     gtk_entry_set_text(GTK_ENTRY(window->uriEntry), webkit_web_view_get_uri(webView));
73 }
74
75 static gboolean resetEntryProgress(GtkEntry *entry)
76 {
77     gtk_entry_set_progress_fraction(entry, 0);
78     return FALSE;
79 }
80
81 static void webViewLoadProgressChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
82 {
83     gdouble progress = webkit_web_view_get_estimated_load_progress(webView);
84     gtk_entry_set_progress_fraction(GTK_ENTRY(window->uriEntry), progress);
85     if (progress == 1.0)
86         g_timeout_add(500, (GSourceFunc)resetEntryProgress, window->uriEntry);
87 }
88
89 static void browserWindowFinalize(GObject *gObject)
90 {
91     G_OBJECT_CLASS(browser_window_parent_class)->finalize(gObject);
92
93     if (g_atomic_int_dec_and_test(&windowCount))
94         gtk_main_quit();
95 }
96
97 static void browserWindowGetProperty(GObject *object, guint propId, GValue *value, GParamSpec *pspec)
98 {
99     BrowserWindow *window = BROWSER_WINDOW(object);
100
101     switch (propId) {
102     case PROP_VIEW:
103         g_value_set_object(value, browser_window_get_view(window));
104         break;
105     default:
106         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
107     }
108 }
109
110 static void browserWindowSetProperty(GObject *object, guint propId, const GValue *value, GParamSpec *pspec)
111 {
112     BrowserWindow* window = BROWSER_WINDOW(object);
113
114     switch (propId) {
115     case PROP_VIEW:
116         window->webView = g_value_get_object(value);
117         break;
118     default:
119         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
120     }
121 }
122
123 static void browser_window_init(BrowserWindow *window)
124 {
125     g_atomic_int_inc(&windowCount);
126
127     gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
128
129     window->uriEntry = gtk_entry_new();
130     g_signal_connect_swapped(window->uriEntry, "activate", G_CALLBACK(activateUriEntryCallback), (gpointer)window);
131
132     GtkWidget *toolbar = gtk_toolbar_new();
133     gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
134     gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ);
135
136     GtkToolItem *item = gtk_menu_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
137     window->backItem = GTK_WIDGET(item);
138     gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), 0);
139     g_signal_connect_swapped(item, "clicked", G_CALLBACK(goBackCallback), (gpointer)window);
140     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
141     gtk_widget_show(GTK_WIDGET(item));
142
143     item = gtk_menu_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
144     window->forwardItem = GTK_WIDGET(item);
145     gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), 0);
146     g_signal_connect_swapped(G_OBJECT(item), "clicked", G_CALLBACK(goForwardCallback), (gpointer)window);
147     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
148     gtk_widget_show(GTK_WIDGET(item));
149
150     item = gtk_tool_item_new();
151     gtk_tool_item_set_expand(item, TRUE);
152     gtk_container_add(GTK_CONTAINER(item), window->uriEntry);
153     gtk_widget_show(window->uriEntry);
154     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
155     gtk_widget_show(GTK_WIDGET(item));
156
157     item = gtk_tool_button_new_from_stock(GTK_STOCK_OK);
158     g_signal_connect_swapped(item, "clicked", G_CALLBACK(activateUriEntryCallback), (gpointer)window);
159     gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
160     gtk_widget_show(GTK_WIDGET(item));
161
162     GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
163     window->mainBox = vbox;
164     gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
165     gtk_widget_show(toolbar);
166
167     gtk_container_add(GTK_CONTAINER(window), vbox);
168     gtk_widget_show(vbox);
169 }
170
171 static void browserWindowConstructed(GObject *gObject)
172 {
173     BrowserWindow *window = BROWSER_WINDOW(gObject);
174
175     g_signal_connect(window->webView, "notify::uri", G_CALLBACK(webViewURIChanged), window);
176     g_signal_connect(window->webView, "notify::estimated-load-progress", G_CALLBACK(webViewLoadProgressChanged), window);
177
178     gtk_box_pack_start(GTK_BOX(window->mainBox), GTK_WIDGET(window->webView), TRUE, TRUE, 0);
179     gtk_widget_show(GTK_WIDGET(window->webView));
180 }
181
182 static void browser_window_class_init(BrowserWindowClass *klass)
183 {
184     GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
185
186     gobjectClass->constructed = browserWindowConstructed;
187     gobjectClass->get_property = browserWindowGetProperty;
188     gobjectClass->set_property = browserWindowSetProperty;
189     gobjectClass->finalize = browserWindowFinalize;
190
191     g_object_class_install_property(gobjectClass,
192                                     PROP_VIEW,
193                                     g_param_spec_object("view",
194                                                         "View",
195                                                         "The web view of this window",
196                                                         WEBKIT_TYPE_WEB_VIEW,
197                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
198 }
199
200 // Public API.
201 GtkWidget *browser_window_new(WebKitWebView *view)
202 {
203     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(view), 0);
204
205     return GTK_WIDGET(g_object_new(BROWSER_TYPE_WINDOW,
206                                    "type", GTK_WINDOW_TOPLEVEL,
207                                    "view", view, NULL));
208 }
209
210 WebKitWebView *browser_window_get_view(BrowserWindow *window)
211 {
212     g_return_val_if_fail(BROWSER_IS_WINDOW(window), 0);
213
214     return window->webView;
215 }