From 5aae53ef919c695136ee52ce30435820d8dc1771 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Mon, 27 Nov 2006 17:13:24 +0000 Subject: Merge GTK frames branch to trunk. svn path=/trunk/netsurf/; revision=3075 --- gtk/font_pango.c | 2 +- gtk/gtk_bitmap.c | 2 +- gtk/gtk_options.c | 2 +- gtk/gtk_plotters.c | 27 +- gtk/gtk_plotters.h | 18 + gtk/gtk_scaffolding.c | 778 +++++++++++++++++++++++++++++++++ gtk/gtk_scaffolding.h | 25 ++ gtk/gtk_schedule.h | 13 + gtk/gtk_thumbnail.c | 2 +- gtk/gtk_window.c | 1136 +++++++++++++------------------------------------ gtk/gtk_window.h | 28 +- gtk/res/netsurf.glade | 29 +- 12 files changed, 1181 insertions(+), 881 deletions(-) create mode 100644 gtk/gtk_scaffolding.c create mode 100644 gtk/gtk_scaffolding.h create mode 100644 gtk/gtk_schedule.h (limited to 'gtk') diff --git a/gtk/font_pango.c b/gtk/font_pango.c index c0d107988..a100745d7 100644 --- a/gtk/font_pango.c +++ b/gtk/font_pango.c @@ -17,7 +17,7 @@ #include #include "netsurf/css/css.h" #include "netsurf/gtk/font_pango.h" -#include "netsurf/gtk/gtk_window.h" +#include "netsurf/gtk/gtk_plotters.h" #include "netsurf/render/font.h" #include "netsurf/utils/utils.h" #include "netsurf/utils/log.h" diff --git a/gtk/gtk_bitmap.c b/gtk/gtk_bitmap.c index a587a0768..6a4606d37 100644 --- a/gtk/gtk_bitmap.c +++ b/gtk/gtk_bitmap.c @@ -17,7 +17,7 @@ #include #include #include "netsurf/content/content.h" -#include "netsurf/gtk/gtk_window.h" +#include "netsurf/gtk/gtk_scaffolding.h" #include "netsurf/image/bitmap.h" #include "netsurf/utils/log.h" diff --git a/gtk/gtk_options.c b/gtk/gtk_options.c index 59a00927c..b5ad9f0d9 100644 --- a/gtk/gtk_options.c +++ b/gtk/gtk_options.c @@ -14,7 +14,7 @@ #include "netsurf/desktop/options.h" #include "netsurf/gtk/options.h" #include "netsurf/gtk/gtk_gui.h" -#include "netsurf/gtk/gtk_window.h" +#include "netsurf/gtk/gtk_scaffolding.h" #include "netsurf/gtk/gtk_options.h" GtkWindow *wndChoices; diff --git a/gtk/gtk_plotters.c b/gtk/gtk_plotters.c index d782d6d13..b78bcd5e6 100644 --- a/gtk/gtk_plotters.c +++ b/gtk/gtk_plotters.c @@ -21,13 +21,20 @@ #include "netsurf/desktop/plotters.h" #include "netsurf/gtk/font_pango.h" #include "netsurf/gtk/gtk_plotters.h" -#include "netsurf/gtk/gtk_window.h" +#include "netsurf/gtk/gtk_scaffolding.h" #include "netsurf/render/font.h" #include "netsurf/utils/log.h" #include "netsurf/desktop/options.h" #include "netsurf/gtk/options.h" #include "netsurf/gtk/gtk_bitmap.h" +GtkWidget *current_widget; +GdkDrawable *current_drawable; +GdkGC *current_gc; +#ifdef CAIRO_VERSION +cairo_t *current_cr; +#endif + static bool nsgtk_plot_clg(colour c); static bool nsgtk_plot_rectangle(int x0, int y0, int width, int height, int line_width, colour c, bool dotted, bool dashed); @@ -436,3 +443,21 @@ float nsgtk_plot_get_scale(void) return nsgtk_plot_scale; } +/** Plot a caret. It is assumed that the plotters have been set up. */ +void nsgtk_plot_caret(int x, int y, int h) +{ + GdkColor colour; + + colour.red = 0; + colour.green = 0; + colour.blue = 0; + colour.pixel = 0; + gdk_color_alloc(gdk_colormap_get_system(), + &colour); + gdk_gc_set_foreground(current_gc, &colour); + + gdk_draw_line(current_drawable, current_gc, + x, y, + x, y + h - 1); +} + diff --git a/gtk/gtk_plotters.h b/gtk/gtk_plotters.h index 85ab4b9b0..69a765110 100644 --- a/gtk/gtk_plotters.h +++ b/gtk/gtk_plotters.h @@ -9,7 +9,25 @@ * Target independent plotting (GDK / GTK+ interface). */ +#ifndef NETSURF_GTK_PLOTTERS_H +#define NETSURF_GTK_PLOTTERS_H 1 + +#include + struct plotter_table; extern const struct plotter_table nsgtk_plotters; +extern GtkWidget *current_widget; +extern GdkDrawable *current_drawable; +extern GdkGC *current_gc; +#ifdef CAIRO_VERSION +extern cairo_t *current_cr; +#endif + +void nsgtk_plot_set_scale(float s); +float nsgtk_plot_get_scale(void); +void nsgtk_set_colour(colour c); +void nsgtk_plot_caret(int x, int y, int h); + +#endif /* NETSURF_GTK_PLOTTERS_H */ diff --git a/gtk/gtk_scaffolding.c b/gtk/gtk_scaffolding.c new file mode 100644 index 000000000..22235e0ca --- /dev/null +++ b/gtk/gtk_scaffolding.c @@ -0,0 +1,778 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2006 Rob Kendrick + */ + +#include +#include +#include +#include +#include +#include +#include "netsurf/content/content.h" +#include "netsurf/desktop/browser.h" +#include "netsurf/desktop/history_core.h" +#include "netsurf/desktop/gui.h" +#include "netsurf/desktop/netsurf.h" +#include "netsurf/desktop/plotters.h" +#include "netsurf/desktop/options.h" +#include "netsurf/desktop/textinput.h" +#include "netsurf/desktop/gesture_core.h" +#include "netsurf/gtk/gtk_gui.h" +#include "netsurf/gtk/gtk_plotters.h" +#include "netsurf/gtk/gtk_scaffolding.h" +#include "netsurf/gtk/gtk_options.h" +#include "netsurf/gtk/gtk_completion.h" +#include "netsurf/gtk/gtk_throbber.h" +#include "netsurf/gtk/gtk_history.h" +#include "netsurf/gtk/gtk_window.h" +#include "netsurf/gtk/gtk_schedule.h" +#include "netsurf/render/box.h" +#include "netsurf/render/font.h" +#include "netsurf/render/form.h" +#include "netsurf/render/html.h" +#include "netsurf/utils/messages.h" +#include "netsurf/utils/utils.h" +#undef NDEBUG +#include "netsurf/utils/log.h" + +struct gtk_history_window; + +struct gtk_scaffolding { + GtkWindow *window; + GtkEntry *url_bar; + GtkEntryCompletion *url_bar_completion; + GtkLabel *status_bar; + GtkToolButton *back_button; + GtkToolButton *forward_button; + GtkToolButton *stop_button; + GtkToolButton *reload_button; + GtkMenuItem *back_menu; + GtkMenuItem *forward_menu; + GtkMenuItem *stop_menu; + GtkMenuItem *reload_menu; + GtkImage *throbber; + GtkPaned *status_pane; + + GladeXML *xml; + + struct gtk_history_window *history_window; + + int throb_frame; + struct gui_window *top_level; + int being_destroyed; +}; + +struct gtk_history_window { + struct gtk_scaffolding *g; + GtkWindow *window; + GtkScrolledWindow *scrolled; + GtkDrawingArea *drawing_area; +}; + +struct menu_events { + const char *widget; + GCallback handler; +}; + +static int open_windows = 0; /**< current number of open browsers */ + +static void nsgtk_window_destroy_event(GtkWidget *, gpointer); + +static void nsgtk_window_update_back_forward(struct gtk_scaffolding *); +static void nsgtk_throb(void *); +static gboolean nsgtk_window_back_button_clicked(GtkWidget *, gpointer); +static gboolean nsgtk_window_forward_button_clicked(GtkWidget *, gpointer); +static gboolean nsgtk_window_stop_button_clicked(GtkWidget *, gpointer); +static gboolean nsgtk_window_reload_button_clicked(GtkWidget *, gpointer); +static gboolean nsgtk_window_home_button_clicked(GtkWidget *, gpointer); +static gboolean nsgtk_window_url_activate_event(GtkWidget *, gpointer); +static gboolean nsgtk_window_url_changed(GtkWidget *, GdkEventKey *, gpointer); + +static gboolean nsgtk_history_expose_event(GtkWidget *, GdkEventExpose *, + gpointer); +static gboolean nsgtk_history_motion_notify_event(GtkWidget *, GdkEventMotion *, + gpointer); +static gboolean nsgtk_history_button_press_event(GtkWidget *, GdkEventButton *, + gpointer); + +static void nsgtk_attach_menu_handlers(GladeXML *, gpointer); + +#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) } +#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \ + GtkMenuItem *widget, gpointer g) +/* prototypes for menu handlers */ +/* file menu */ +MENUPROTO(new_window); +MENUPROTO(close_window); +MENUPROTO(quit); + +/* edit menu */ +MENUPROTO(choices); + +/* view menu */ +MENUPROTO(stop); +MENUPROTO(reload); +MENUPROTO(zoom_in); +MENUPROTO(normal_size); +MENUPROTO(zoom_out); +MENUPROTO(save_window_size); +MENUPROTO(toggle_debug_rendering); + +/* navigate menu */ +MENUPROTO(back); +MENUPROTO(forward); +MENUPROTO(home); +MENUPROTO(local_history); +MENUPROTO(global_history); + +/* help menu */ +MENUPROTO(about); + +/* structure used by nsgtk_attach_menu_handlers to connect menu items to + * their handling functions. + */ +static struct menu_events menu_events[] = { + /* file menu */ + MENUEVENT(new_window), + MENUEVENT(close_window), + MENUEVENT(quit), + + /* edit menu */ + MENUEVENT(choices), + + /* view menu */ + MENUEVENT(stop), + MENUEVENT(reload), + MENUEVENT(zoom_in), + MENUEVENT(normal_size), + MENUEVENT(zoom_out), + MENUEVENT(save_window_size), + MENUEVENT(toggle_debug_rendering), + + /* navigate menu */ + MENUEVENT(back), + MENUEVENT(forward), + MENUEVENT(home), + MENUEVENT(local_history), + MENUEVENT(global_history), + + /* help menu */ + MENUEVENT(about), + + /* sentinel */ + { NULL, NULL } +}; + +void nsgtk_attach_menu_handlers(GladeXML *xml, gpointer g) +{ + struct menu_events *event = menu_events; + + while (event->widget != NULL) + { + GtkWidget *w = glade_xml_get_widget(xml, event->widget); + g_signal_connect(G_OBJECT(w), "activate", event->handler, g); + event++; + } +} + +/* event handlers and support functions for them */ + +void nsgtk_window_destroy_event(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + LOG(("Being Destroyed = %d", g->being_destroyed)); + gtk_widget_destroy(GTK_WIDGET(g->history_window->window)); + gtk_widget_destroy(GTK_WIDGET(g->window)); + + if (--open_windows == 0) + netsurf_quit = true; + + if (!g->being_destroyed) { + g->being_destroyed = 1; + gui_window_destroy(g->top_level); + } +} + +void nsgtk_scaffolding_destroy(nsgtk_scaffolding *scaffold) +{ + /* Our top_level has asked us to die */ + LOG(("Being Destroyed = %d", scaffold->being_destroyed)); + if (scaffold->being_destroyed) return; + scaffold->being_destroyed = 1; + nsgtk_window_destroy_event(0, scaffold); +} + + +void nsgtk_window_update_back_forward(struct gtk_scaffolding *g) +{ + int width, height; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + gtk_widget_set_sensitive(GTK_WIDGET(g->back_button), + history_back_available(bw->history)); + gtk_widget_set_sensitive(GTK_WIDGET(g->forward_button), + history_forward_available(bw->history)); + + gtk_widget_set_sensitive(GTK_WIDGET(g->back_menu), + history_back_available(bw->history)); + gtk_widget_set_sensitive(GTK_WIDGET(g->forward_menu), + history_forward_available(bw->history)); + + /* update the local history window, as well as queuing a redraw + * for it. + */ + history_size(bw->history, &width, &height); + gtk_widget_set_size_request(GTK_WIDGET(g->history_window->drawing_area), + width, height); + gtk_widget_queue_draw(GTK_WIDGET(g->history_window->drawing_area)); +} + +void nsgtk_throb(void *p) +{ + struct gtk_scaffolding *g = p; + + if (g->throb_frame >= (nsgtk_throbber->nframes - 1)) + g->throb_frame = 1; + else + g->throb_frame++; + + gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[ + g->throb_frame]); + + schedule(10, nsgtk_throb, p); +} + +/* signal handling functions for the toolbar and URL bar */ +gboolean nsgtk_window_back_button_clicked(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + if (!history_back_available(bw->history)) + return TRUE; + + history_back(bw, bw->history); + nsgtk_window_update_back_forward(g); + + return TRUE; +} + +gboolean nsgtk_window_forward_button_clicked(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + if (!history_forward_available(bw->history)) + return TRUE; + + history_forward(bw, bw->history); + nsgtk_window_update_back_forward(g); + + return TRUE; +} + +gboolean nsgtk_window_stop_button_clicked(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + browser_window_stop(bw); + + return TRUE; +} + +gboolean nsgtk_window_reload_button_clicked(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + browser_window_reload(bw, true); + + return TRUE; +} + +gboolean nsgtk_window_home_button_clicked(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + static const char *addr = "http://netsurf.sourceforge.net/"; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + if (option_homepage_url != NULL) + addr = option_homepage_url; + + browser_window_go(bw, addr, 0, true); + + return TRUE; +} + +gboolean nsgtk_window_url_activate_event(GtkWidget *widget, gpointer data) +{ + struct gtk_scaffolding *g = data; + char *referer = 0; + struct browser_window *bw = nsgtk_get_browser_for_gui(g->top_level); + + if (bw->current_content && bw->current_content->url) + referer = bw->current_content->url; + + browser_window_go(bw, gtk_entry_get_text(GTK_ENTRY(g->url_bar)), + referer, true); + + return TRUE; +} + + +gboolean nsgtk_window_url_changed(GtkWidget *widget, GdkEventKey *event, + gpointer data) +{ + const char *prefix; + + prefix = gtk_entry_get_text(GTK_ENTRY(widget)); + nsgtk_completion_update(prefix); + + return TRUE; +} + + +/* signal handlers for menu entries */ +#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \ + gpointer g) + +MENUHANDLER(new_window) +{ + return TRUE; +} + +MENUHANDLER(close_window) +{ + struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; + + gtk_widget_destroy(GTK_WIDGET(gw->window)); + + return TRUE; +} + +MENUHANDLER(quit) +{ + netsurf_quit = true; + return TRUE; +} + +MENUHANDLER(choices) +{ + gtk_widget_show(GTK_WIDGET(wndChoices)); + + return TRUE; +} + +MENUHANDLER(zoom_in) +{ + struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; + struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level); + float old_scale = nsgtk_get_scale_for_gui(gw->top_level); + + browser_window_set_scale(bw, old_scale + 0.05, true); + + return TRUE; +} + +MENUHANDLER(normal_size) +{ + struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; + struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level); + + browser_window_set_scale(bw, 1.0, true); + + return TRUE; +} + +MENUHANDLER(zoom_out) +{ + struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; + struct browser_window *bw = nsgtk_get_browser_for_gui(gw->top_level); + float old_scale = nsgtk_get_scale_for_gui(gw->top_level); + + browser_window_set_scale(bw, old_scale - 0.05, true); + + return TRUE; +} + +MENUHANDLER(save_window_size) +{ + struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; + + option_toolbar_status_width = gtk_paned_get_position(gw->status_pane); + gtk_window_get_position(gw->window, &option_window_x, &option_window_y); + gtk_window_get_size(gw->window, &option_window_width, + &option_window_height); + + + options_write(options_file_location); + + return TRUE; +} + +MENUHANDLER(toggle_debug_rendering) +{ + html_redraw_debug = !html_redraw_debug; + gui_window_redraw_window(g); + + return TRUE; +} + +MENUHANDLER(stop) +{ + return nsgtk_window_stop_button_clicked(GTK_WIDGET(widget), g); +} + +MENUHANDLER(reload) +{ + return nsgtk_window_reload_button_clicked(GTK_WIDGET(widget), g); +} + +MENUHANDLER(back) +{ + return nsgtk_window_back_button_clicked(GTK_WIDGET(widget), g); +} + +MENUHANDLER(forward) +{ + return nsgtk_window_forward_button_clicked(GTK_WIDGET(widget), g); +} + +MENUHANDLER(home) +{ + return nsgtk_window_home_button_clicked(GTK_WIDGET(widget), g); +} + +MENUHANDLER(local_history) +{ + struct gtk_scaffolding *gw = (struct gtk_scaffolding *)g; + + gtk_widget_show(GTK_WIDGET(gw->history_window->window)); + gdk_window_raise(GDK_WINDOW(gw->history_window->window)); + + return TRUE; +} + +MENUHANDLER(global_history) +{ + gtk_widget_show(GTK_WIDGET(wndHistory)); + gdk_window_raise(GDK_WINDOW(wndHistory)); + + return TRUE; +} + +MENUHANDLER(about) +{ + gtk_widget_show(GTK_WIDGET(wndAbout)); + gdk_window_raise(GDK_WINDOW(wndAbout)); + return TRUE; +} + +/* signal handler functions for the local history window */ +gboolean nsgtk_history_expose_event(GtkWidget *widget, + GdkEventExpose *event, gpointer g) +{ + struct gtk_history_window *hw = (struct gtk_history_window *)g; + struct browser_window *bw = nsgtk_get_browser_for_gui(hw->g->top_level); + + current_widget = widget; + current_drawable = widget->window; + current_gc = gdk_gc_new(current_drawable); +#ifdef CAIRO_VERSION + current_cr = gdk_cairo_create(current_drawable); +#endif + plot = nsgtk_plotters; + nsgtk_plot_set_scale(1.0); + + history_redraw(bw->history); + + g_object_unref(current_gc); +#ifdef CAIRO_VERSION + cairo_destroy(current_cr); +#endif + return FALSE; +} + +gboolean nsgtk_history_motion_notify_event(GtkWidget *widget, + GdkEventMotion *event, gpointer g) +{ + /* if we're hovering over a history item, popup our tooltip bodge + * describing the page. + */ + struct gtk_history_window *gw = g; + struct browser_window *bw = nsgtk_get_browser_for_gui(gw->g->top_level); + const char *url; + int winx, winy; + +// if (!option_history_tooltip) +// return TRUE; + + url = history_position_url(bw->history, event->x, event->y); + if (url == NULL) { + gtk_widget_hide(GTK_WIDGET(wndTooltip)); + return TRUE; + } + + gtk_label_set_text(labelTooltip, url); + gtk_window_get_position(gw->g->window, &winx, &winy); + + LOG(("winx = %d, winy = %d, event->x = %d, event->y = %d", + winx, winy, (int)(event->x), (int)(event->y))); + + gtk_widget_show(GTK_WIDGET(wndTooltip)); + LOG(("Move")); + gtk_window_move(wndTooltip, event->x + winx, event->y + winy); + + return TRUE; +} + +gboolean nsgtk_history_button_press_event(GtkWidget *widget, + GdkEventButton *event, gpointer g) +{ + struct gtk_history_window *hw = (struct gtk_history_window *)g; + struct browser_window *bw = nsgtk_get_browser_for_gui(hw->g->top_level); + + LOG(("X=%d, Y=%d", event->x, event->y)); + + history_click(bw, bw->history, + event->x, event->y, false); + + return TRUE; +} + +#define GET_WIDGET(x) glade_xml_get_widget(g->xml, (x)) + +void nsgtk_attach_toplevel_viewport(nsgtk_scaffolding *g, + GtkViewport *vp) +{ + /* Insert the viewport into the right part of our table */ + GtkTable *table = GTK_TABLE(GET_WIDGET("centreTable")); + LOG(("Attaching viewport to scaffolding %p", g)); + gtk_table_attach_defaults(table, GTK_WIDGET(vp), 0, 1, 0, 1); + + /* connect our scrollbars to the viewport */ + gtk_viewport_set_hadjustment(vp, + gtk_range_get_adjustment(GTK_RANGE(GET_WIDGET("coreScrollHorizontal")))); + gtk_viewport_set_vadjustment(vp, + gtk_range_get_adjustment(GTK_RANGE(GET_WIDGET("coreScrollVertical")))); + + /* And set the size-request to zero to cause it to get its act together */ + gtk_widget_set_size_request(GTK_WIDGET(vp), 0, 0); + +} + +nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel) +{ + struct gtk_scaffolding *g = malloc(sizeof(*g)); + + LOG(("Constructing a scaffold of %p for gui_window %p", g, toplevel)); + + g->top_level = toplevel; + + open_windows++; + + /* load the window template from the glade xml file, and extract + * widget references from it for later use. + */ + g->xml = glade_xml_new(glade_file_location, "wndBrowser", NULL); + glade_xml_signal_autoconnect(g->xml); + g->window = GTK_WINDOW(GET_WIDGET("wndBrowser")); + g->url_bar = GTK_ENTRY(GET_WIDGET("URLBar")); + g->status_bar = GTK_LABEL(GET_WIDGET("statusBar")); + g->back_button = GTK_TOOL_BUTTON(GET_WIDGET("toolBack")); + g->forward_button = GTK_TOOL_BUTTON(GET_WIDGET("toolForward")); + g->stop_button = GTK_TOOL_BUTTON(GET_WIDGET("toolStop")); + g->reload_button = GTK_TOOL_BUTTON(GET_WIDGET("toolReload")); + g->back_menu = GTK_MENU_ITEM(GET_WIDGET("back")); + g->forward_menu = GTK_MENU_ITEM(GET_WIDGET("forward")); + g->stop_menu = GTK_MENU_ITEM(GET_WIDGET("stop")); + g->reload_menu = GTK_MENU_ITEM(GET_WIDGET("reload")); + g->throbber = GTK_IMAGE(GET_WIDGET("throbber")); + g->status_pane = GTK_PANED(GET_WIDGET("hpaned1")); + + /* set this window's size and position to what's in the options, or + * or some sensible default if they're not set yet. + */ + if (option_window_width > 0) { + gtk_window_move(g->window, option_window_x, option_window_y); + gtk_window_resize(g->window, option_window_width, + option_window_height); + } else { + gtk_window_set_default_size(g->window, 600, 600); + } + + /* set the size of the hpane with status bar and h scrollbar */ + gtk_paned_set_position(g->status_pane, option_toolbar_status_width); + + /* set the URL entry box to expand, as we can't do this from within + * glade because of the way it emulates toolbars. + */ + gtk_tool_item_set_expand(GTK_TOOL_ITEM(GET_WIDGET("toolURLBar")), TRUE); + + /* disable toolbar buttons that make no sense initially. */ + gtk_widget_set_sensitive(GTK_WIDGET(g->back_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(g->forward_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(g->stop_button), FALSE); + + /* create the local history window to be assoicated with this browser */ + g->history_window = malloc(sizeof(struct gtk_history_window)); + g->history_window->g = g; + g->history_window->window = GTK_WINDOW( + gtk_window_new(GTK_WINDOW_TOPLEVEL)); + gtk_window_set_transient_for(g->history_window->window, g->window); + gtk_window_set_default_size(g->history_window->window, 400, 400); + gtk_window_set_title(g->history_window->window, "NetSurf History"); + gtk_window_set_type_hint(g->history_window->window, + GDK_WINDOW_TYPE_HINT_UTILITY); + g->history_window->scrolled = GTK_SCROLLED_WINDOW( + gtk_scrolled_window_new(0, 0)); + gtk_container_add(GTK_CONTAINER(g->history_window->window), + GTK_WIDGET(g->history_window->scrolled)); + + gtk_widget_show(GTK_WIDGET(g->history_window->scrolled)); + g->history_window->drawing_area = GTK_DRAWING_AREA( + gtk_drawing_area_new()); + + gtk_widget_set_events(GTK_WIDGET(g->history_window->drawing_area), + GDK_EXPOSURE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK); + gtk_widget_modify_bg(GTK_WIDGET(g->history_window->drawing_area), + GTK_STATE_NORMAL, + &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); + gtk_scrolled_window_add_with_viewport(g->history_window->scrolled, + GTK_WIDGET(g->history_window->drawing_area)); + gtk_widget_show(GTK_WIDGET(g->history_window->drawing_area)); + + /* set up URL bar completion */ + g->url_bar_completion = gtk_entry_completion_new(); + gtk_entry_set_completion(g->url_bar, g->url_bar_completion); + gtk_entry_completion_set_match_func(g->url_bar_completion, + nsgtk_completion_match, NULL, NULL); + gtk_entry_completion_set_model(g->url_bar_completion, + GTK_TREE_MODEL(nsgtk_completion_list)); + gtk_entry_completion_set_text_column(g->url_bar_completion, 0); + gtk_entry_completion_set_minimum_key_length(g->url_bar_completion, 1); + gtk_entry_completion_set_popup_completion(g->url_bar_completion, TRUE); + g_object_set(G_OBJECT(g->url_bar_completion), + "popup-set-width", TRUE, + "popup-single-match", TRUE, + NULL); + + /* set up the throbber. */ + gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]); + g->throb_frame = 0; + +#define CONNECT(obj, sig, callback, ptr) \ + g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + + /* connect history window signals to their handlers */ + CONNECT(g->history_window->drawing_area, "expose_event", + nsgtk_history_expose_event, g->history_window); +// CONNECT(g->history_window->drawing_area, "motion_notify_event", +// nsgtk_history_motion_notify_event, g->history_window); + CONNECT(g->history_window->drawing_area, "button_press_event", + nsgtk_history_button_press_event, g->history_window); + CONNECT(g->history_window->window, "delete_event", + gtk_widget_hide_on_delete, NULL); + + /* connect signals to handlers. */ + CONNECT(g->window, "destroy", nsgtk_window_destroy_event, g); + + /* toolbar and URL bar signal handlers */ + CONNECT(g->back_button, "clicked", nsgtk_window_back_button_clicked, g); + CONNECT(g->forward_button, "clicked", + nsgtk_window_forward_button_clicked, g); + CONNECT(g->stop_button, "clicked", nsgtk_window_stop_button_clicked, g); + CONNECT(g->reload_button, "clicked", + nsgtk_window_reload_button_clicked, g); + CONNECT(GET_WIDGET("toolHome"), "clicked", + nsgtk_window_home_button_clicked, g); + CONNECT(g->url_bar, "activate", nsgtk_window_url_activate_event, g); + CONNECT(g->url_bar, "changed", nsgtk_window_url_changed, g); + + /* set up the menu signal handlers */ + nsgtk_attach_menu_handlers(g->xml, g); + + g->being_destroyed = 0; + + /* finally, show the window. */ + gtk_widget_show(GTK_WIDGET(g->window)); + + return g; +} + +void gui_window_set_title(struct gui_window *_g, const char *title) +{ + static char suffix[] = " - NetSurf"; + char nt[strlen(title) + strlen(suffix) + 1]; + struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + if (g->top_level != _g) return; + + if (title == NULL || title[0] == '\0') + { + gtk_window_set_title(g->window, "NetSurf"); + + } + else + { + strcpy(nt, title); + strcat(nt, suffix); + gtk_window_set_title(g->window, nt); + } +} + +void gui_window_set_status(struct gui_window *_g, const char *text) +{ + struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + gtk_label_set_text(g->status_bar, text); +} + +void gui_window_set_url(struct gui_window *_g, const char *url) +{ + struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + if (g->top_level != _g) return; + gtk_entry_set_text(g->url_bar, url); + gtk_editable_set_position(GTK_EDITABLE(g->url_bar), -1); +} + +void gui_window_start_throbber(struct gui_window* _g) +{ + struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + gtk_widget_set_sensitive(GTK_WIDGET(g->stop_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g->reload_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(g->stop_menu), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g->reload_button), FALSE); + + nsgtk_window_update_back_forward(g); + + schedule(10, nsgtk_throb, g); +} + +void gui_window_stop_throbber(struct gui_window* _g) +{ + struct gtk_scaffolding *g = nsgtk_get_scaffold(_g); + gtk_widget_set_sensitive(GTK_WIDGET(g->stop_button), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(g->reload_button), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(g->stop_menu), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(g->reload_menu), TRUE); + + nsgtk_window_update_back_forward(g); + + schedule_remove(nsgtk_throb, g); + + gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]); + // Issue a final reflow so that the content object reports its size correctly + nsgtk_gui_window_update_targets(_g); + schedule(5, (gtk_callback)(nsgtk_window_reflow_content), _g); +} + +gboolean nsgtk_scaffolding_is_busy(nsgtk_scaffolding *scaffold) +{ + /* We are considered "busy" if the stop button is sensitive */ + return GTK_WIDGET_SENSITIVE((GTK_WIDGET(scaffold->stop_button))); +} diff --git a/gtk/gtk_scaffolding.h b/gtk/gtk_scaffolding.h new file mode 100644 index 000000000..38014807b --- /dev/null +++ b/gtk/gtk_scaffolding.h @@ -0,0 +1,25 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2005 James Bursa + */ + +#ifndef NETSURF_GTK_SCAFFOLDING_H +#define NETSURF_GTK_SCAFFOLDING_H 1 + +#include +#include "netsurf/desktop/gui.h" +#include "netsurf/desktop/plotters.h" + +typedef struct gtk_scaffolding nsgtk_scaffolding; + +nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel); + +gboolean nsgtk_scaffolding_is_busy(nsgtk_scaffolding *scaffold); + +void nsgtk_attach_toplevel_viewport(nsgtk_scaffolding *g, GtkViewport *vp); + +void nsgtk_scaffolding_destroy(nsgtk_scaffolding *scaffold); + +#endif /* NETSURF_GTK_SCAFFOLDING_H */ diff --git a/gtk/gtk_schedule.h b/gtk/gtk_schedule.h new file mode 100644 index 000000000..ec675b9ac --- /dev/null +++ b/gtk/gtk_schedule.h @@ -0,0 +1,13 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2006 Daniel Silverstone + */ + +#ifndef NETSURF_GTK_CALLBACK_H +#define NETSURF_GTK_CALLBACK_H 1 + +typedef void (*gtk_callback)(void *p); + +#endif /* NETSURF_GTK_CALLBACK_H */ diff --git a/gtk/gtk_thumbnail.c b/gtk/gtk_thumbnail.c index 60c7b9752..2209fcf3f 100644 --- a/gtk/gtk_thumbnail.c +++ b/gtk/gtk_thumbnail.c @@ -22,7 +22,7 @@ #include "netsurf/image/bitmap.h" #include "netsurf/render/font.h" #include "netsurf/utils/log.h" -#include "netsurf/gtk/gtk_window.h" +#include "netsurf/gtk/gtk_scaffolding.h" #include "netsurf/gtk/gtk_plotters.h" #include "netsurf/gtk/gtk_bitmap.h" diff --git a/gtk/gtk_window.c b/gtk/gtk_window.c index 636880bd5..4a87a2776 100644 --- a/gtk/gtk_window.c +++ b/gtk/gtk_window.c @@ -1,104 +1,61 @@ /* - * This file is part of NetSurf, http://netsurf-browser.org/ + * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license + * Copyright 2006 Daniel Silverstone * Copyright 2006 Rob Kendrick */ -#include -#include -#include -#include -#include -#include -#include -#include "netsurf/content/content.h" +#include "netsurf/gtk/gtk_window.h" #include "netsurf/desktop/browser.h" -#include "netsurf/desktop/history_core.h" -#include "netsurf/desktop/gui.h" -#include "netsurf/desktop/netsurf.h" -#include "netsurf/desktop/plotters.h" -#include "netsurf/desktop/options.h" #include "netsurf/desktop/textinput.h" -#include "netsurf/desktop/gesture_core.h" #include "netsurf/gtk/gtk_gui.h" +#include "netsurf/gtk/gtk_scaffolding.h" #include "netsurf/gtk/gtk_plotters.h" -#include "netsurf/gtk/gtk_window.h" -#include "netsurf/gtk/gtk_options.h" -#include "netsurf/gtk/gtk_completion.h" -#include "netsurf/gtk/gtk_throbber.h" -#include "netsurf/gtk/gtk_history.h" -#include "netsurf/render/box.h" -#include "netsurf/render/font.h" -#include "netsurf/render/form.h" -#include "netsurf/render/html.h" -#include "netsurf/utils/messages.h" -#include "netsurf/utils/utils.h" +#include "netsurf/gtk/gtk_schedule.h" +#undef NDEBUG #include "netsurf/utils/log.h" - -struct gtk_history_window; +#include +#include struct gui_window { - GtkWindow *window; - GtkEntry *url_bar; - GtkEntryCompletion *url_bar_completion; - GtkDrawingArea *drawing_area; - GtkViewport *viewport; - GtkLabel *status_bar; - GtkToolButton *back_button; - GtkToolButton *forward_button; - GtkToolButton *stop_button; - GtkToolButton *reload_button; - GtkMenuItem *back_menu; - GtkMenuItem *forward_menu; - GtkMenuItem *stop_menu; - GtkMenuItem *reload_menu; - GtkImage *throbber; - GtkPaned *status_pane; - - GladeXML *xml; - - struct browser_window *bw; + /* All gui_window objects have an ultimate scaffold */ + nsgtk_scaffolding *scaffold; + /* A gui_window is the rendering of a browser_window */ + struct browser_window *bw; + + /* These are the storage for the rendering */ float scale; int target_width, target_height; int caretx, carety, careth; gui_pointer_shape current_pointer; - int throb_frame; - - struct gtk_history_window *history_window; - int last_x, last_y; - - struct gui_window *next, *prev; -}; - -struct gtk_history_window { - struct gui_window *g; - GtkWindow *window; - GtkScrolledWindow *scrolled; + + /* Within GTK, a gui_window is a scrolled window + * with a viewport inside + * with a gtkfixed in that + * with a drawing area in that + * The scrolled window is optional and only chosen + * for frames which need it. Otherwise we just use + * a viewport. + */ + GtkScrolledWindow *scrolledwindow; + GtkViewport *viewport; + GtkFixed *fixed; GtkDrawingArea *drawing_area; + + /* Keep gui_windows in a list for cleanup later */ + struct gui_window *next, *prev; }; -GtkWidget *current_widget; -GdkDrawable *current_drawable; -GdkGC *current_gc; -#ifdef CAIRO_VERSION -cairo_t *current_cr; -#endif - -struct menu_events { - const char *widget; - GCallback handler; -}; - -static int open_windows = 0; /**< current number of open browsers */ static struct gui_window *window_list = 0; /**< first entry in win list*/ static wchar_t gdkkey_to_nskey(GdkEventKey *); -static void nsgtk_window_destroy_event(GtkWidget *, gpointer); -static void nsgtk_plot_caret(int x, int y, int h); +static void nsgtk_gui_window_attach_child(struct gui_window *parent, + struct gui_window *child); +/* Methods which apply only to a gui_window */ static gboolean nsgtk_window_expose_event(GtkWidget *, GdkEventExpose *, - gpointer); + gpointer); static gboolean nsgtk_window_motion_notify_event(GtkWidget *, GdkEventMotion *, gpointer); static gboolean nsgtk_window_button_press_event(GtkWidget *, GdkEventButton *, @@ -107,192 +64,197 @@ static gboolean nsgtk_window_keypress_event(GtkWidget *, GdkEventKey *, gpointer); static gboolean nsgtk_window_size_allocate_event(GtkWidget *, GtkAllocation *, gpointer); +/* Other useful bits */ +static void nsgtk_redraw_caret(struct gui_window *g); -static void nsgtk_perform_deferred_resize(void *); -static void nsgtk_window_update_back_forward(struct gui_window *); -static void nsgtk_throb(void *); -static void nsgtk_redraw_caret(struct gui_window *); - -static gboolean nsgtk_window_back_button_clicked(GtkWidget *, gpointer); -static gboolean nsgtk_window_forward_button_clicked(GtkWidget *, gpointer); -static gboolean nsgtk_window_stop_button_clicked(GtkWidget *, gpointer); -static gboolean nsgtk_window_reload_button_clicked(GtkWidget *, gpointer); -static gboolean nsgtk_window_home_button_clicked(GtkWidget *, gpointer); -static gboolean nsgtk_window_url_activate_event(GtkWidget *, gpointer); -static gboolean nsgtk_window_url_changed(GtkWidget *, GdkEventKey *, gpointer); - -static gboolean nsgtk_history_expose_event(GtkWidget *, GdkEventExpose *, - gpointer); -static gboolean nsgtk_history_motion_notify_event(GtkWidget *, GdkEventMotion *, - gpointer); -static gboolean nsgtk_history_button_press_event(GtkWidget *, GdkEventButton *, - gpointer); - -static void nsgtk_attach_menu_handlers(GladeXML *, gpointer); - -#define MENUEVENT(x) { #x, G_CALLBACK(nsgtk_on_##x##_activate) } -#define MENUPROTO(x) static gboolean nsgtk_on_##x##_activate( \ - GtkMenuItem *widget, gpointer g) -/* prototypes for menu handlers */ -/* file menu */ -MENUPROTO(new_window); -MENUPROTO(close_window); -MENUPROTO(quit); - -/* edit menu */ -MENUPROTO(choices); - -/* view menu */ -MENUPROTO(stop); -MENUPROTO(reload); -MENUPROTO(zoom_in); -MENUPROTO(normal_size); -MENUPROTO(zoom_out); -MENUPROTO(save_window_size); -MENUPROTO(toggle_debug_rendering); - -/* navigate menu */ -MENUPROTO(back); -MENUPROTO(forward); -MENUPROTO(home); -MENUPROTO(local_history); -MENUPROTO(global_history); - -/* help menu */ -MENUPROTO(about); - -/* structure used by nsgtk_attach_menu_handlers to connect menu items to - * their handling functions. - */ -static struct menu_events menu_events[] = { - /* file menu */ - MENUEVENT(new_window), - MENUEVENT(close_window), - MENUEVENT(quit), - - /* edit menu */ - MENUEVENT(choices), - - /* view menu */ - MENUEVENT(stop), - MENUEVENT(reload), - MENUEVENT(zoom_in), - MENUEVENT(normal_size), - MENUEVENT(zoom_out), - MENUEVENT(save_window_size), - MENUEVENT(toggle_debug_rendering), - - /* navigate menu */ - MENUEVENT(back), - MENUEVENT(forward), - MENUEVENT(home), - MENUEVENT(local_history), - MENUEVENT(global_history), - - /* help menu */ - MENUEVENT(about), - - /* sentinel */ - { NULL, NULL } -}; -void nsgtk_reflow_all_windows(void) +nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g) { - struct gui_window *g = window_list; - - while (g != NULL) { - nsgtk_perform_deferred_resize(g); - g = g->next; - } + return g->scaffold; } -void nsgtk_attach_menu_handlers(GladeXML *xml, gpointer g) +struct browser_window *nsgtk_get_browser_for_gui(struct gui_window *g) { - struct menu_events *event = menu_events; + return g->bw; +} - while (event->widget != NULL) - { - GtkWidget *w = glade_xml_get_widget(xml, event->widget); - g_signal_connect(G_OBJECT(w), "activate", event->handler, g); - event++; - } +float nsgtk_get_scale_for_gui(struct gui_window *g) +{ + return g->scale; } -wchar_t gdkkey_to_nskey(GdkEventKey *key) +/* Create a gui_window */ +struct gui_window *gui_create_browser_window(struct browser_window *bw, + struct browser_window *clone) { - /* this function will need to become much more complex to support - * everything that the RISC OS version does. But this will do for - * now. I hope. - */ + struct gui_window *g; /**< what we're creating to return */ + GtkPolicyType scrollpolicy; + + g = malloc(sizeof(*g)); + + LOG(("Creating gui window %p for browser window %p", g, bw)); + + + g->bw = bw; + g->current_pointer = GUI_POINTER_DEFAULT; + if (clone != NULL) + g->scale = clone->window->scale; + else + g->scale = 1.0; - switch (key->keyval) - { - case GDK_BackSpace: return KEY_DELETE_LEFT; - case GDK_Delete: return KEY_DELETE_RIGHT; - case GDK_Linefeed: return 13; - case GDK_Return: return 10; - case GDK_Left: return KEY_LEFT; - case GDK_Right: return KEY_RIGHT; - case GDK_Up: return KEY_UP; - case GDK_Down: return KEY_DOWN; + g->careth = 0; + + /* Attach ourselves to the list (push_top) */ + if (window_list) + window_list->prev = g; + g->next = window_list; + g->prev = NULL; + window_list = g; + + if (bw->parent != NULL) { + /* Find our parent's scaffolding */ + g->scaffold = bw->parent->window->scaffold; + } else { + /* Now construct and attach a scaffold */ + g->scaffold = nsgtk_new_scaffolding(g); + } + + /* Construct our primary elements */ + g->fixed = GTK_FIXED(gtk_fixed_new()); + g->drawing_area = GTK_DRAWING_AREA(gtk_drawing_area_new()); + gtk_fixed_put(g->fixed, GTK_WIDGET(g->drawing_area), 0, 0); + gtk_container_set_border_width(GTK_CONTAINER(g->fixed), 0); + + if (bw->parent != NULL ) { + g->scrolledwindow = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL)); + gtk_scrolled_window_add_with_viewport(g->scrolledwindow, + GTK_WIDGET(g->fixed)); + gtk_scrolled_window_set_shadow_type(g->scrolledwindow, + GTK_SHADOW_NONE); + g->viewport = gtk_bin_get_child(GTK_BIN(g->scrolledwindow)); + /* Attach ourselves into our parent at the right point */ + nsgtk_gui_window_attach_child(bw->parent->window, g); + } else { + g->scrolledwindow = 0; + g->viewport = GTK_VIEWPORT(gtk_viewport_new(NULL, NULL)); /* Need to attach adjustments */ + gtk_container_add(GTK_CONTAINER(g->viewport), GTK_WIDGET(g->fixed)); + + /* Attach our viewport into the scaffold */ + nsgtk_attach_toplevel_viewport(g->scaffold, g->viewport); + } + + gtk_container_set_border_width(GTK_CONTAINER(g->viewport), 0); + gtk_viewport_set_shadow_type(g->viewport, GTK_SHADOW_NONE); + if (g->scrolledwindow) + gtk_widget_show(GTK_WIDGET(g->scrolledwindow)); + /* And enable visibility from our viewport down */ + gtk_widget_show(GTK_WIDGET(g->viewport)); + gtk_widget_show(GTK_WIDGET(g->fixed)); + gtk_widget_show(GTK_WIDGET(g->drawing_area)); + + switch(bw->scrolling) { + case SCROLLING_NO: + scrollpolicy = GTK_POLICY_NEVER; + break; + case SCROLLING_YES: + scrollpolicy = GTK_POLICY_ALWAYS; + break; + case SCROLLING_AUTO: + scrollpolicy = GTK_POLICY_AUTOMATIC; + break; + }; + + switch(bw->browser_window_type) { + case BROWSER_WINDOW_FRAMESET: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + GTK_POLICY_NEVER, + GTK_POLICY_NEVER); + break; + case BROWSER_WINDOW_FRAME: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + scrollpolicy, + scrollpolicy); + break; + case BROWSER_WINDOW_NORMAL: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + scrollpolicy, + scrollpolicy); + break; + case BROWSER_WINDOW_IFRAME: + if (g->scrolledwindow) + gtk_scrolled_window_set_policy(g->scrolledwindow, + scrollpolicy, + scrollpolicy); + break; + } + + /* set the events we're interested in receiving from the browser's + * drawing area. + */ + gtk_widget_set_events(GTK_WIDGET(g->drawing_area), + GDK_EXPOSURE_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_POINTER_MOTION_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK); + GTK_WIDGET_SET_FLAGS(GTK_WIDGET(g->drawing_area), GTK_CAN_FOCUS); - /* Modifiers - do nothing for now */ - case GDK_Shift_L: - case GDK_Shift_R: - case GDK_Control_L: - case GDK_Control_R: - case GDK_Caps_Lock: - case GDK_Shift_Lock: - case GDK_Meta_L: - case GDK_Meta_R: - case GDK_Alt_L: - case GDK_Alt_R: - case GDK_Super_L: - case GDK_Super_R: - case GDK_Hyper_L: - case GDK_Hyper_R: return 0; + /* set the default background colour of the drawing area to white. */ + gtk_widget_modify_bg(GTK_WIDGET(g->drawing_area), GTK_STATE_NORMAL, + &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); - default: return key->keyval; - } +#define CONNECT(obj, sig, callback, ptr) \ + g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) + CONNECT(g->drawing_area, "expose_event", nsgtk_window_expose_event, g); + CONNECT(g->drawing_area, "motion_notify_event", + nsgtk_window_motion_notify_event, g); + CONNECT(g->drawing_area, "button_press_event", + nsgtk_window_button_press_event, g); + CONNECT(g->drawing_area, "key_press_event", + nsgtk_window_keypress_event, g); + CONNECT(g->viewport, "size_allocate", + nsgtk_window_size_allocate_event, g); + + return g; } -/* event handlers and support functions for them */ - -void nsgtk_window_destroy_event(GtkWidget *widget, gpointer data) +static void nsgtk_gui_window_attach_child(struct gui_window *parent, + struct gui_window *child) { - struct gui_window *g = data; - - gui_window_destroy(g); + /* Attach the child gui_window (frame) into the parent. + * It will be resized later on. + */ + GtkFixed *parent_fixed = parent->fixed; + GtkWidget *child_widget = GTK_WIDGET(child->scrolledwindow); + gtk_fixed_put(parent_fixed, child_widget, 0, 0); } -/** Plot a caret. It is assumed that the plotters have been set up. */ -void nsgtk_plot_caret(int x, int y, int h) +void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1) { - GdkColor colour; - - colour.red = 0; - colour.green = 0; - colour.blue = 0; - colour.pixel = 0; - gdk_color_alloc(gdk_colormap_get_system(), - &colour); - gdk_gc_set_foreground(current_gc, &colour); - - gdk_draw_line(current_drawable, current_gc, - x, y, - x, y + h - 1); + /* g is a child frame, we need to place it relative to its parent */ + GtkWidget *w = GTK_WIDGET(g->scrolledwindow); + GtkFixed *f = g->bw->parent->window->fixed; + assert(w); + assert(f); + LOG(("%s: %d,%d %dx%d", g->bw->name, x0, y0, x1-x0+2, y1-y0+2)); + gtk_fixed_move(f, w, x0, y0); + gtk_widget_set_size_request(w, x1 - x0 + 2, y1 - y0 + 2); } gboolean nsgtk_window_expose_event(GtkWidget *widget, - GdkEventExpose *event, gpointer data) + GdkEventExpose *event, gpointer data) { struct gui_window *g = data; struct content *c = g->bw->current_content; - + if (c == NULL) return FALSE; - - current_widget = widget; + + current_widget = widget; current_drawable = widget->window; current_gc = gdk_gc_new(current_drawable); #ifdef CAIRO_VERSION @@ -322,12 +284,12 @@ gboolean nsgtk_window_expose_event(GtkWidget *widget, } gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, - GdkEventMotion *event, gpointer data) + GdkEventMotion *event, gpointer data) { struct gui_window *g = data; browser_window_mouse_track(g->bw, 0, event->x / g->scale, - event->y / g->scale); + event->y / g->scale); g->last_x = event->x; g->last_y = event->y; @@ -336,7 +298,7 @@ gboolean nsgtk_window_motion_notify_event(GtkWidget *widget, } gboolean nsgtk_window_button_press_event(GtkWidget *widget, - GdkEventButton *event, gpointer data) + GdkEventButton *event, gpointer data) { struct gui_window *g = data; int button = BROWSER_MOUSE_CLICK_1; @@ -348,11 +310,49 @@ gboolean nsgtk_window_button_press_event(GtkWidget *widget, return TRUE; /* Do nothing for right click for now */ browser_window_mouse_click(g->bw, button, - event->x / g->scale, event->y / g->scale); + event->x / g->scale, event->y / g->scale); return TRUE; } +wchar_t gdkkey_to_nskey(GdkEventKey *key) +{ + /* this function will need to become much more complex to support + * everything that the RISC OS version does. But this will do for + * now. I hope. + */ + + switch (key->keyval) + { + case GDK_BackSpace: return KEY_DELETE_LEFT; + case GDK_Delete: return KEY_DELETE_RIGHT; + case GDK_Linefeed: return 13; + case GDK_Return: return 10; + case GDK_Left: return KEY_LEFT; + case GDK_Right: return KEY_RIGHT; + case GDK_Up: return KEY_UP; + case GDK_Down: return KEY_DOWN; + + /* Modifiers - do nothing for now */ + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Caps_Lock: + case GDK_Shift_Lock: + case GDK_Meta_L: + case GDK_Meta_R: + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Super_L: + case GDK_Super_R: + case GDK_Hyper_L: + case GDK_Hyper_R: return 0; + + default: return key->keyval; + } +} + gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { @@ -364,23 +364,41 @@ gboolean nsgtk_window_keypress_event(GtkWidget *widget, GdkEventKey *event, return TRUE; } -gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, - GtkAllocation *allocation, gpointer data) +int nsgtk_gui_window_update_targets(struct gui_window *g) { - struct gui_window *g = data; + GtkWidget *widget = GTK_WIDGET(g->viewport); + int new_width, new_height; + int changed = 0; + new_width = widget->allocation.width - 2; + new_height = widget->allocation.height; + if( new_width != g->target_width || + new_height != g->target_height ) { + changed = 1; + g->target_width = new_width; + g->target_height = new_height; + } + return changed; +} - g->target_width = widget->allocation.width - 2; - g->target_height = widget->allocation.height; +gboolean nsgtk_window_size_allocate_event(GtkWidget *widget, + GtkAllocation *allocation, gpointer data) +{ + struct gui_window *g = data; + + nsgtk_gui_window_update_targets(g); + + LOG(("Size allocate for %s => %d x %d\n", g->bw->name, g->target_width, g->target_height)); + /* schedule a callback to perform the resize for 1/10s from now */ - schedule(5, nsgtk_perform_deferred_resize, g); + schedule(5, (gtk_callback)(nsgtk_window_reflow_content), g); return TRUE; } -void nsgtk_perform_deferred_resize(void *p) +void nsgtk_window_reflow_content(struct gui_window *g) { - struct gui_window *g = p; + int updated = nsgtk_gui_window_update_targets(g); if (gui_in_multitask) return; @@ -388,535 +406,28 @@ void nsgtk_perform_deferred_resize(void *p) if (g->bw->current_content == NULL) return; - if (g->bw->current_content->status != CONTENT_STATUS_READY && + if (g->bw->current_content->status != CONTENT_STATUS_READY && g->bw->current_content->status != CONTENT_STATUS_DONE) return; - - browser_window_reformat(g->bw, + + LOG(("Doing reformat")); + + content_reformat(g->bw->current_content, g->target_width, g->target_height); - if (GTK_WIDGET_SENSITIVE((GTK_WIDGET(g->stop_button)))) - schedule(100, nsgtk_perform_deferred_resize, g); -} - -void nsgtk_window_update_back_forward(struct gui_window *g) -{ - int width, height; - - gtk_widget_set_sensitive(GTK_WIDGET(g->back_button), - history_back_available(g->bw->history)); - gtk_widget_set_sensitive(GTK_WIDGET(g->forward_button), - history_forward_available(g->bw->history)); - - gtk_widget_set_sensitive(GTK_WIDGET(g->back_menu), - history_back_available(g->bw->history)); - gtk_widget_set_sensitive(GTK_WIDGET(g->forward_menu), - history_forward_available(g->bw->history)); - - /* update the local history window, as well as queuing a redraw - * for it. - */ - history_size(g->bw->history, &width, &height); - gtk_widget_set_size_request(GTK_WIDGET(g->history_window->drawing_area), - width, height); - gtk_widget_queue_draw(GTK_WIDGET(g->history_window->drawing_area)); -} - -void nsgtk_throb(void *p) -{ - struct gui_window *g = p; - - if (g->throb_frame >= (nsgtk_throbber->nframes - 1)) - g->throb_frame = 1; - else - g->throb_frame++; - - gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[ - g->throb_frame]); - - schedule(10, nsgtk_throb, p); -} - -void nsgtk_redraw_caret(struct gui_window *g) -{ - if (g->careth == 0) - return; - - gui_window_redraw(g, g->caretx, g->carety, - g->caretx, g->carety + g->careth); -} - -/* signal handling functions for the toolbar and URL bar */ -gboolean nsgtk_window_back_button_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_window *g = data; - - if (!history_back_available(g->bw->history)) - return TRUE; - - history_back(g->bw, g->bw->history); - nsgtk_window_update_back_forward(g); - - return TRUE; -} - -gboolean nsgtk_window_forward_button_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_window *g = data; - - if (!history_forward_available(g->bw->history)) - return TRUE; - - history_forward(g->bw, g->bw->history); - nsgtk_window_update_back_forward(g); - - return TRUE; -} - -gboolean nsgtk_window_stop_button_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_window *g = data; - - browser_window_stop(g->bw); - - return TRUE; -} - -gboolean nsgtk_window_reload_button_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_window *g = data; - - browser_window_reload(g->bw, true); - - return TRUE; -} - -gboolean nsgtk_window_home_button_clicked(GtkWidget *widget, gpointer data) -{ - struct gui_window *g = data; - static const char *addr = "http://netsurf-browser.org/"; - - if (option_homepage_url != NULL) - addr = option_homepage_url; - - browser_window_go(g->bw, addr, 0, true); - - return TRUE; -} - -gboolean nsgtk_window_url_activate_event(GtkWidget *widget, gpointer data) -{ - struct gui_window *g = data; - char *referer = 0; - - if (g->bw->current_content && g->bw->current_content->url) - referer = g->bw->current_content->url; - - browser_window_go(g->bw, gtk_entry_get_text(GTK_ENTRY(g->url_bar)), - referer, true); - - return TRUE; -} - - -gboolean nsgtk_window_url_changed(GtkWidget *widget, GdkEventKey *event, - gpointer data) -{ - const char *prefix; - - prefix = gtk_entry_get_text(GTK_ENTRY(widget)); - nsgtk_completion_update(prefix); - - return TRUE; -} - - -/* signal handlers for menu entries */ -#define MENUHANDLER(x) gboolean nsgtk_on_##x##_activate(GtkMenuItem *widget, \ - gpointer g) - -MENUHANDLER(new_window) -{ - return TRUE; -} - -MENUHANDLER(close_window) -{ - struct gui_window *gw = (struct gui_window *)g; - - gtk_widget_destroy(GTK_WIDGET(gw->window)); - - return TRUE; -} - -MENUHANDLER(quit) -{ - netsurf_quit = true; - return TRUE; -} - -MENUHANDLER(choices) -{ - gtk_widget_show(GTK_WIDGET(wndChoices)); - - return TRUE; -} - -MENUHANDLER(zoom_in) -{ - struct gui_window *gw = (struct gui_window *)g; - - browser_window_set_scale(gw->bw, gw->scale + 0.05, true); - - return TRUE; -} - -MENUHANDLER(normal_size) -{ - struct gui_window *gw = (struct gui_window *)g; - - browser_window_set_scale(gw->bw, 1.0, true); - - return TRUE; -} - -MENUHANDLER(zoom_out) -{ - struct gui_window *gw = (struct gui_window *)g; - - browser_window_set_scale(gw->bw, gw->scale - 0.05, true); - - return TRUE; -} - -MENUHANDLER(save_window_size) -{ - struct gui_window *gw = (struct gui_window *)g; - - option_toolbar_status_width = gtk_paned_get_position(gw->status_pane); - gtk_window_get_position(gw->window, &option_window_x, &option_window_y); - gtk_window_get_size(gw->window, &option_window_width, - &option_window_height); - - - options_write(options_file_location); - - return TRUE; -} - -MENUHANDLER(toggle_debug_rendering) -{ - html_redraw_debug = !html_redraw_debug; - gui_window_redraw_window(g); - - return TRUE; -} - -MENUHANDLER(stop) -{ - return nsgtk_window_stop_button_clicked(GTK_WIDGET(widget), g); -} - -MENUHANDLER(reload) -{ - return nsgtk_window_reload_button_clicked(GTK_WIDGET(widget), g); -} - -MENUHANDLER(back) -{ - return nsgtk_window_back_button_clicked(GTK_WIDGET(widget), g); -} - -MENUHANDLER(forward) -{ - return nsgtk_window_forward_button_clicked(GTK_WIDGET(widget), g); -} - -MENUHANDLER(home) -{ - return nsgtk_window_home_button_clicked(GTK_WIDGET(widget), g); -} - -MENUHANDLER(local_history) -{ - struct gui_window *gw = (struct gui_window *)g; - - gtk_widget_show(GTK_WIDGET(gw->history_window->window)); - gdk_window_raise(GDK_WINDOW(gw->history_window->window)); - - return TRUE; -} - -MENUHANDLER(global_history) -{ - gtk_widget_show(GTK_WIDGET(wndHistory)); - gdk_window_raise(GDK_WINDOW(wndHistory)); - - return TRUE; + if (nsgtk_scaffolding_is_busy(g->scaffold) || updated) + schedule((updated?1:100), + (gtk_callback)(nsgtk_window_reflow_content), g); } -MENUHANDLER(about) -{ - gtk_widget_show(GTK_WIDGET(wndAbout)); - gdk_window_raise(GDK_WINDOW(wndAbout)); - return TRUE; -} - -/* signal handler functions for the local history window */ -gboolean nsgtk_history_expose_event(GtkWidget *widget, - GdkEventExpose *event, gpointer g) -{ - struct gtk_history_window *hw = (struct gtk_history_window *)g; - - current_widget = widget; - current_drawable = widget->window; - current_gc = gdk_gc_new(current_drawable); -#ifdef CAIRO_VERSION - current_cr = gdk_cairo_create(current_drawable); -#endif - plot = nsgtk_plotters; - nsgtk_plot_set_scale(1.0); - - history_redraw(hw->g->bw->history); - - g_object_unref(current_gc); -#ifdef CAIRO_VERSION - cairo_destroy(current_cr); -#endif - return FALSE; -} - -gboolean nsgtk_history_motion_notify_event(GtkWidget *widget, - GdkEventMotion *event, gpointer g) +void nsgtk_reflow_all_windows(void) { - /* if we're hovering over a history item, popup our tooltip bodge - * describing the page. - */ - struct gtk_history_window *gw = g; - const char *url; - int winx, winy; - -// if (!option_history_tooltip) -// return TRUE; + struct gui_window *g = window_list; - url = history_position_url(gw->g->bw->history, event->x, event->y); - if (url == NULL) { - gtk_widget_hide(wndTooltip); - return TRUE; + while (g != NULL) { + nsgtk_window_reflow_content(g); + g = g->next; } - - gtk_label_set_text(labelTooltip, url); - gtk_window_get_position(gw->g->window, &winx, &winy); - - LOG(("winx = %d, winy = %d, event->x = %d, event->y = %d", - winx, winy, event->x, event->y)); - - gtk_widget_show(GTK_WIDGET(wndTooltip)); - gtk_window_move(wndTooltip, event->x + winx, event->y + winy); - - return TRUE; -} - -gboolean nsgtk_history_button_press_event(GtkWidget *widget, - GdkEventButton *event, gpointer g) -{ - struct gtk_history_window *hw = (struct gtk_history_window *)g; - - history_click(hw->g->bw, hw->g->bw->history, - event->x, event->y, false); - - return TRUE; -} - -/* functions called by the core to manipulate the GUI */ -#define GET_WIDGET(x) glade_xml_get_widget(g->xml, (x)) -struct gui_window *gui_create_browser_window(struct browser_window *bw, - struct browser_window *clone) -{ - struct gui_window *g; /**< what we're creating to return */ - - g = malloc(sizeof(*g)); - - g->bw = bw; - g->current_pointer = GUI_POINTER_DEFAULT; - if (clone != NULL) - g->scale = clone->window->scale; - else - g->scale = 1.0; - - g->careth = 0; - - /* add the window to the list of open windows. */ - g->prev = 0; - g->next = window_list; - - if (window_list) - window_list->prev = g; - window_list = g; - - open_windows++; - - /* load the window template from the glade xml file, and extract - * widget references from it for later use. - */ - g->xml = glade_xml_new(glade_file_location, "wndBrowser", NULL); - glade_xml_signal_autoconnect(g->xml); - g->window = GTK_WINDOW(GET_WIDGET("wndBrowser")); - g->url_bar = GTK_ENTRY(GET_WIDGET("URLBar")); - g->drawing_area = GTK_DRAWING_AREA(GET_WIDGET("drawingArea")); - g->status_bar = GTK_LABEL(GET_WIDGET("statusBar")); - g->back_button = GTK_TOOL_BUTTON(GET_WIDGET("toolBack")); - g->forward_button = GTK_TOOL_BUTTON(GET_WIDGET("toolForward")); - g->stop_button = GTK_TOOL_BUTTON(GET_WIDGET("toolStop")); - g->reload_button = GTK_TOOL_BUTTON(GET_WIDGET("toolReload")); - g->back_menu = GTK_MENU_ITEM(GET_WIDGET("back")); - g->forward_menu = GTK_MENU_ITEM(GET_WIDGET("forward")); - g->stop_menu = GTK_MENU_ITEM(GET_WIDGET("stop")); - g->reload_menu = GTK_MENU_ITEM(GET_WIDGET("reload")); - g->throbber = GTK_IMAGE(GET_WIDGET("throbber")); - g->viewport = GTK_VIEWPORT(GET_WIDGET("viewport1")); - g->status_pane = GTK_PANED(GET_WIDGET("hpaned1")); - - /* set this window's size and position to what's in the options, or - * or some sensible default if they're not set yet. - */ - if (option_window_width > 0) { - gtk_window_move(g->window, option_window_x, option_window_y); - gtk_window_resize(g->window, option_window_width, - option_window_height); - } else { - gtk_window_set_default_size(g->window, 600, 600); - } - - /* set the size of the hpane with status bar and h scrollbar */ - gtk_paned_set_position(g->status_pane, option_toolbar_status_width); - - /* connect our scrollbars to the viewport */ - gtk_viewport_set_hadjustment(g->viewport, - gtk_range_get_adjustment(GTK_RANGE(GET_WIDGET("hscrollbar1")))); - gtk_viewport_set_vadjustment(g->viewport, - gtk_range_get_adjustment(GTK_RANGE(GET_WIDGET("vscrollbar1")))); - gtk_widget_set_size_request(GTK_WIDGET(g->viewport), 0, 0); - - /* set the URL entry box to expand, as we can't do this from within - * glade because of the way it emulates toolbars. - */ - gtk_tool_item_set_expand(GTK_TOOL_ITEM(GET_WIDGET("toolURLBar")), TRUE); - - /* set the events we're interested in receiving from the browser's - * drawing area. - */ - gtk_widget_set_events(GTK_WIDGET(g->drawing_area), - GDK_EXPOSURE_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_POINTER_MOTION_MASK | - GDK_KEY_PRESS_MASK | - GDK_KEY_RELEASE_MASK); - GTK_WIDGET_SET_FLAGS(GTK_WIDGET(g->drawing_area), GTK_CAN_FOCUS); - - /* set the default background colour of the drawing area to white. */ - gtk_widget_modify_bg(GTK_WIDGET(g->drawing_area), GTK_STATE_NORMAL, - &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); - - /* disable toolbar buttons that make no sense initially. */ - gtk_widget_set_sensitive(GTK_WIDGET(g->back_button), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(g->forward_button), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(g->stop_button), FALSE); - - /* create the local history window to be assoicated with this browser */ - g->history_window = malloc(sizeof(struct gtk_history_window)); - g->history_window->g = g; - g->history_window->window = GTK_WINDOW( - gtk_window_new(GTK_WINDOW_TOPLEVEL)); - gtk_window_set_transient_for(g->history_window->window, g->window); - gtk_window_set_default_size(g->history_window->window, 400, 400); - gtk_window_set_title(g->history_window->window, "NetSurf History"); - gtk_window_set_type_hint(g->history_window->window, - GDK_WINDOW_TYPE_HINT_UTILITY); - g->history_window->scrolled = GTK_SCROLLED_WINDOW( - gtk_scrolled_window_new(0, 0)); - gtk_container_add(GTK_CONTAINER(g->history_window->window), - GTK_WIDGET(g->history_window->scrolled)); - - gtk_widget_show(GTK_WIDGET(g->history_window->scrolled)); - g->history_window->drawing_area = GTK_DRAWING_AREA( - gtk_drawing_area_new()); - - gtk_widget_set_events(GTK_WIDGET(g->history_window->drawing_area), - GDK_EXPOSURE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_BUTTON_PRESS_MASK); - gtk_widget_modify_bg(GTK_WIDGET(g->history_window->drawing_area), - GTK_STATE_NORMAL, - &((GdkColor) { 0, 0xffff, 0xffff, 0xffff } )); - gtk_scrolled_window_add_with_viewport(g->history_window->scrolled, - GTK_WIDGET(g->history_window->drawing_area)); - gtk_widget_show(GTK_WIDGET(g->history_window->drawing_area)); - - /* set up URL bar completion */ - g->url_bar_completion = gtk_entry_completion_new(); - gtk_entry_set_completion(g->url_bar, g->url_bar_completion); - gtk_entry_completion_set_match_func(g->url_bar_completion, - nsgtk_completion_match, NULL, NULL); - gtk_entry_completion_set_model(g->url_bar_completion, - GTK_TREE_MODEL(nsgtk_completion_list)); - gtk_entry_completion_set_text_column(g->url_bar_completion, 0); - gtk_entry_completion_set_minimum_key_length(g->url_bar_completion, 1); - gtk_entry_completion_set_popup_completion(g->url_bar_completion, TRUE); - g_object_set(G_OBJECT(g->url_bar_completion), - "popup-set-width", TRUE, - "popup-single-match", TRUE, - NULL); - - /* set up the throbber. */ - gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]); - g->throb_frame = 0; - -#define CONNECT(obj, sig, callback, ptr) \ - g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr)) - - /* connect history window signals to their handlers */ - CONNECT(g->history_window->drawing_area, "expose_event", - nsgtk_history_expose_event, g->history_window); - CONNECT(g->history_window->drawing_area, "motion_notify_event", - nsgtk_history_motion_notify_event, g->history_window); - CONNECT(g->history_window->drawing_area, "button_press_event", - nsgtk_history_button_press_event, g->history_window); - CONNECT(g->history_window->window, "delete_event", - gtk_widget_hide_on_delete, NULL); - - /* connect signals to handlers. */ - CONNECT(g->window, "destroy", nsgtk_window_destroy_event, g); - CONNECT(g->drawing_area, "expose_event", nsgtk_window_expose_event, g); - CONNECT(g->drawing_area, "motion_notify_event", - nsgtk_window_motion_notify_event, g); - CONNECT(g->drawing_area, "button_press_event", - nsgtk_window_button_press_event, g); - CONNECT(g->drawing_area, "key_press_event", - nsgtk_window_keypress_event, g); - CONNECT(GET_WIDGET("viewport1"), "size_allocate", - nsgtk_window_size_allocate_event, g); - - /* toolbar and URL bar signal handlers */ - CONNECT(g->back_button, "clicked", nsgtk_window_back_button_clicked, g); - CONNECT(g->forward_button, "clicked", - nsgtk_window_forward_button_clicked, g); - CONNECT(g->stop_button, "clicked", nsgtk_window_stop_button_clicked, g); - CONNECT(g->reload_button, "clicked", - nsgtk_window_reload_button_clicked, g); - CONNECT(GET_WIDGET("toolHome"), "clicked", - nsgtk_window_home_button_clicked, g); - CONNECT(g->url_bar, "activate", nsgtk_window_url_activate_event, g); - CONNECT(g->url_bar, "changed", nsgtk_window_url_changed, g); - - /* set up the menu signal handlers */ - nsgtk_attach_menu_handlers(g->xml, g); - - /* finally, show the window. */ - gtk_widget_show(GTK_WIDGET(g->window)); - - return g; } void gui_window_destroy(struct gui_window *g) @@ -928,32 +439,24 @@ void gui_window_destroy(struct gui_window *g) if (g->next) g->next->prev = g->prev; - - gtk_widget_destroy(GTK_WIDGET(g->history_window->window)); - gtk_widget_destroy(GTK_WIDGET(g->window)); - + + LOG(("Destroy")); + + /* If we're a top-level gui_window, destroy our scaffold */ + if (g->scrolledwindow == 0) + nsgtk_scaffolding_destroy(g->scaffold); + free(g); - if (--open_windows == 0) - netsurf_quit = true; } -void gui_window_set_title(struct gui_window *g, const char *title) +void nsgtk_redraw_caret(struct gui_window *g) { - static char suffix[] = " - NetSurf"; - char nt[strlen(title) + strlen(suffix) + 1]; - - if (title == NULL || title[0] == '\0') - { - gtk_window_set_title(g->window, "NetSurf"); + if (g->careth == 0) + return; - } - else - { - strcpy(nt, title); - strcat(nt, suffix); - gtk_window_set_title(g->window, nt); - } + gui_window_redraw(g, g->caretx, g->carety, + g->caretx, g->carety + g->careth); } void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) @@ -976,8 +479,8 @@ void gui_window_update_box(struct gui_window *g, return; gtk_widget_queue_draw_area(GTK_WIDGET(g->drawing_area), - data->redraw.x, data->redraw.y, - data->redraw.width, data->redraw.height); + data->redraw.x, data->redraw.y, + data->redraw.width, data->redraw.height); } bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) @@ -1016,14 +519,11 @@ void gui_window_update_extent(struct gui_window *g) return; gtk_widget_set_size_request(GTK_WIDGET(g->drawing_area), - g->bw->current_content->width * g->scale, - g->bw->current_content->height * g->scale); + g->bw->current_content->width * g->scale, + g->bw->current_content->height * g->scale); + gtk_widget_set_size_request(GTK_WIDGET(g->viewport), 0, 0); -} - -void gui_window_set_status(struct gui_window *g, const char *text) -{ - gtk_label_set_text(g->status_bar, text); + } void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) @@ -1113,40 +613,6 @@ void gui_window_hide_pointer(struct gui_window *g) } -void gui_window_set_url(struct gui_window *g, const char *url) -{ - gtk_entry_set_text(g->url_bar, url); - gtk_editable_set_position(GTK_EDITABLE(g->url_bar), -1); -} - -void gui_window_start_throbber(struct gui_window* g) -{ - gtk_widget_set_sensitive(GTK_WIDGET(g->stop_button), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(g->reload_button), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(g->stop_menu), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(g->reload_button), FALSE); - - nsgtk_window_update_back_forward(g); - - schedule(10, nsgtk_throb, g); -} - -void gui_window_stop_throbber(struct gui_window* g) -{ - gtk_widget_set_sensitive(GTK_WIDGET(g->stop_button), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(g->reload_button), TRUE); - gtk_widget_set_sensitive(GTK_WIDGET(g->stop_menu), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(g->reload_menu), TRUE); - - nsgtk_window_update_back_forward(g); - - schedule_remove(nsgtk_throb, g); - - gtk_image_set_from_pixbuf(g->throbber, nsgtk_throbber->framedata[0]); - // Issue a final reflow so that the content object reports its size correctly - schedule(5, nsgtk_perform_deferred_resize, g); -} - void gui_window_place_caret(struct gui_window *g, int x, int y, int height) { nsgtk_redraw_caret(g); @@ -1170,7 +636,7 @@ void gui_window_remove_caret(struct gui_window *g) g->careth = 0; gui_window_redraw(g, g->caretx, g->carety, - g->caretx, g->carety + oh); + g->caretx, g->carety + oh); } void gui_window_new_content(struct gui_window *g) @@ -1190,7 +656,7 @@ bool gui_window_box_scroll_start(struct gui_window *g, } void gui_drag_save_object(gui_save_type type, struct content *c, - struct gui_window *g) + struct gui_window *g) { } @@ -1233,7 +699,7 @@ bool gui_copy_to_clipboard(struct selection *s) void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, - bool scaled) + bool scaled) { *width = GTK_WIDGET(g->drawing_area)->allocation.width; *height = GTK_WIDGET(g->drawing_area)->allocation.height; @@ -1244,10 +710,6 @@ void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, } } -void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1) -{ -} - bool gui_window_frame_resize_start(struct gui_window *g) { return true; diff --git a/gtk/gtk_window.h b/gtk/gtk_window.h index 3da9d56f8..78cacc1d1 100644 --- a/gtk/gtk_window.h +++ b/gtk/gtk_window.h @@ -1,21 +1,23 @@ /* - * This file is part of NetSurf, http://netsurf-browser.org/ + * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2005 James Bursa + * Copyright 2006 Daniel Silverstone */ -#include -#include "netsurf/desktop/plotters.h" +#ifndef NETSURF_GTK_WINDOW_H +#define NETSURF_GTK_WINDOW_H 1 -extern GtkWidget *current_widget; -extern GdkDrawable *current_drawable; -extern GdkGC *current_gc; -#ifdef CAIRO_VERSION -extern cairo_t *current_cr; -#endif +#include "netsurf/desktop/gui.h" +#include "netsurf/gtk/gtk_scaffolding.h" -void nsgtk_plot_set_scale(float s); -float nsgtk_plot_get_scale(void); -void nsgtk_set_colour(colour c); +void nsgtk_window_reflow_content(struct gui_window *g); void nsgtk_reflow_all_windows(void); + +nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g); +struct browser_window *nsgtk_get_browser_for_gui(struct gui_window *g); + +float nsgtk_get_scale_for_gui(struct gui_window *g); +int nsgtk_gui_window_update_targets(struct gui_window *g); + +#endif /* NETSURF_GTK_WINDOW_H */ diff --git a/gtk/res/netsurf.glade b/gtk/res/netsurf.glade index 42ab4f97d..aa3bfabd8 100644 --- a/gtk/res/netsurf.glade +++ b/gtk/res/netsurf.glade @@ -984,7 +984,7 @@ - + True 2 2 @@ -993,7 +993,7 @@ 0 - + True GTK_UPDATE_CONTINUOUS False @@ -1008,29 +1008,6 @@ - - - True - GTK_SHADOW_IN - - - - True - True - True - - - - - 0 - 1 - 0 - 1 - fill - fill - - - True @@ -1062,7 +1039,7 @@ - + True GTK_UPDATE_CONTINUOUS False -- cgit v1.2.3