Mercurial > pidgin.yaz
comparison pidgin/gtkwebview.c @ 32581:24c8a98a6acc
webkit: Scroll to end when appending html.
Most of the code was taken from imhtml.
author | masca@cpw.pidgin.im |
---|---|
date | Sat, 06 Feb 2010 22:18:05 +0000 |
parents | 1cebf9aa291a |
children | 1795afae76f2 |
comparison
equal
deleted
inserted
replaced
32580:23b16f51e15a | 32581:24c8a98a6acc |
---|---|
46 gboolean empty; /**< whether anything has been appended **/ | 46 gboolean empty; /**< whether anything has been appended **/ |
47 | 47 |
48 /* JS execute queue */ | 48 /* JS execute queue */ |
49 GQueue *js_queue; | 49 GQueue *js_queue; |
50 gboolean is_loading; | 50 gboolean is_loading; |
51 GtkAdjustment *vadj; | |
52 guint scroll_src; | |
53 GTimer *scroll_time; | |
51 }; | 54 }; |
52 | 55 |
53 GtkWidget* gtk_webview_new (void) | 56 GtkWidget* gtk_webview_new (void) |
54 { | 57 { |
55 GtkWebView* ret = GTK_WEBVIEW (g_object_new(gtk_webview_get_type(), NULL)); | 58 GtkWebView* ret = GTK_WEBVIEW (g_object_new(gtk_webview_get_type(), NULL)); |
288 } | 291 } |
289 g_string_append_c (str, '"'); | 292 g_string_append_c (str, '"'); |
290 return g_string_free (str, FALSE); | 293 return g_string_free (str, FALSE); |
291 } | 294 } |
292 | 295 |
296 void gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj) | |
297 { | |
298 webview->priv->vadj = vadj; | |
299 } | |
293 | 300 |
294 /* this is a "hack", my plan is to eventually handle this | 301 /* this is a "hack", my plan is to eventually handle this |
295 * correctly using a signals and a plugin: the plugin will have | 302 * correctly using a signals and a plugin: the plugin will have |
296 * the information as to what javascript function to call. It seems | 303 * the information as to what javascript function to call. It seems |
297 * wrong to hardcode that here. | 304 * wrong to hardcode that here. |
302 char* escaped = gtk_webview_quote_js_string (html); | 309 char* escaped = gtk_webview_quote_js_string (html); |
303 char* script = g_strdup_printf ("document.write(%s)", escaped); | 310 char* script = g_strdup_printf ("document.write(%s)", escaped); |
304 printf ("script: %s\n", script); | 311 printf ("script: %s\n", script); |
305 webkit_web_view_execute_script (WEBKIT_WEB_VIEW (view), script); | 312 webkit_web_view_execute_script (WEBKIT_WEB_VIEW (view), script); |
306 view->priv->empty = FALSE; | 313 view->priv->empty = FALSE; |
314 gtk_webview_scroll_to_end(view, TRUE); | |
307 g_free (script); | 315 g_free (script); |
308 g_free (escaped); | 316 g_free (escaped); |
309 } | 317 } |
310 | 318 |
311 gboolean gtk_webview_is_empty (GtkWebView *view) | 319 gboolean gtk_webview_is_empty (GtkWebView *view) |
312 { | 320 { |
313 return view->priv->empty; | 321 return view->priv->empty; |
322 } | |
323 | |
324 #define MAX_SCROLL_TIME 0.4 /* seconds */ | |
325 #define SCROLL_DELAY 33 /* milliseconds */ | |
326 | |
327 /* | |
328 * Smoothly scroll a WebView. | |
329 * | |
330 * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom. | |
331 */ | |
332 static gboolean smooth_scroll_cb(gpointer data) | |
333 { | |
334 struct GtkWebViewPriv *priv = data; | |
335 GtkAdjustment *adj = priv->vadj; | |
336 gdouble max_val = adj->upper - adj->page_size; | |
337 gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3); | |
338 | |
339 g_return_val_if_fail(priv->scroll_time != NULL, FALSE); | |
340 | |
341 if (g_timer_elapsed(priv->scroll_time, NULL) > MAX_SCROLL_TIME || scroll_val >= max_val) { | |
342 /* time's up. jump to the end and kill the timer */ | |
343 gtk_adjustment_set_value(adj, max_val); | |
344 g_timer_destroy(priv->scroll_time); | |
345 priv->scroll_time = NULL; | |
346 g_source_remove(priv->scroll_src); | |
347 priv->scroll_src = 0; | |
348 return FALSE; | |
349 } | |
350 | |
351 /* scroll by 1/3rd the remaining distance */ | |
352 gtk_adjustment_set_value(adj, scroll_val); | |
353 return TRUE; | |
354 } | |
355 | |
356 static gboolean scroll_idle_cb(gpointer data) | |
357 { | |
358 struct GtkWebViewPriv *priv = data; | |
359 GtkAdjustment *adj = priv->vadj; | |
360 if(adj) { | |
361 gtk_adjustment_set_value(adj, adj->upper - adj->page_size); | |
362 } | |
363 priv->scroll_src = 0; | |
364 return FALSE; | |
365 } | |
366 | |
367 void gtk_webview_scroll_to_end(GtkWebView *webview, gboolean smooth) | |
368 { | |
369 struct GtkWebViewPriv *priv = webview->priv; | |
370 if (priv->scroll_time) | |
371 g_timer_destroy(priv->scroll_time); | |
372 if (priv->scroll_src) | |
373 g_source_remove(priv->scroll_src); | |
374 if(smooth) { | |
375 priv->scroll_time = g_timer_new(); | |
376 priv->scroll_src = g_timeout_add_full(G_PRIORITY_LOW, SCROLL_DELAY, smooth_scroll_cb, priv, NULL); | |
377 } else { | |
378 priv->scroll_time = NULL; | |
379 priv->scroll_src = g_idle_add_full(G_PRIORITY_LOW, scroll_idle_cb, priv, NULL); | |
380 } | |
314 } | 381 } |
315 | 382 |
316 GType gtk_webview_get_type (void) | 383 GType gtk_webview_get_type (void) |
317 { | 384 { |
318 static GType mview_type = 0; | 385 static GType mview_type = 0; |