From 5a72700817565b139e9576738d5b1ec23e23e69e Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sat, 25 Mar 2006 20:30:35 +0000 Subject: [project @ 2006-03-25 20:30:35 by bursa] Split local history into portable and RISC OS specific code. Improve layout of history tree. svn path=/import/netsurf/; revision=2164 --- riscos/history.c | 699 ++++++++++++++----------------------------------------- 1 file changed, 171 insertions(+), 528 deletions(-) (limited to 'riscos/history.c') diff --git a/riscos/history.c b/riscos/history.c index 8b9beaa12..ce8d5a75d 100644 --- a/riscos/history.c +++ b/riscos/history.c @@ -2,246 +2,43 @@ * 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 2004 James Bursa + * Copyright 2006 James Bursa * Copyright 2005 Richard Wilson */ /** \file - * Browser history tree and window (implementation). + * Browser history window (RISC OS implementation). + * + * There is only one history window, not one per browser window. */ #include #include #include -#include -#include "oslib/colourtrans.h" -#include "oslib/font.h" #include "oslib/wimp.h" -#include "netsurf/content/url_store.h" -#include "netsurf/image/bitmap.h" -#include "netsurf/riscos/bitmap.h" +#include "netsurf/desktop/history_core.h" +#include "netsurf/desktop/plotters.h" #include "netsurf/riscos/dialog.h" -#include "netsurf/riscos/image.h" #include "netsurf/riscos/options.h" #include "netsurf/riscos/gui.h" -#include "netsurf/riscos/thumbnail.h" -#include "netsurf/riscos/tinct.h" #include "netsurf/riscos/wimp.h" #include "netsurf/riscos/wimp_event.h" #include "netsurf/utils/log.h" #include "netsurf/utils/url.h" #include "netsurf/utils/utils.h" -#define SIZE 10 -#define WIDTH (THUMBNAIL_WIDTH << 1) -#define HEIGHT (THUMBNAIL_HEIGHT << 1) -#define MARGIN 32 -#define FULL_WIDTH (WIDTH + MARGIN + MARGIN) -#define FULL_HEIGHT (HEIGHT + MARGIN + MARGIN) - -/** A node in the history tree. */ -struct history_entry { - char *url; /**< Page URL. */ - char *frag_id; /** Fragment identifier */ - char *title; /**< Page title. */ - struct history_entry *back; /**< Parent. */ - struct history_entry *next; /**< Next sibling. */ - struct history_entry *forward; /**< First child. */ - struct history_entry *forward_pref; /**< Child in direction of - current entry. */ - struct history_entry *forward_last; /**< Last child. */ - unsigned int children; /**< Number of children. */ - int x, y, width; - struct bitmap *bitmap; /**< Thumbnail bitmap, or 0. */ -}; - -/** History tree for a window. */ -struct history { - /** First page in tree (page that window opened with). */ - struct history_entry *start; - /** Current position in tree. */ - struct history_entry *current; -}; static struct browser_window *history_bw; static struct history *history_current = 0; -/* Position of mouse in window */ -static int mouse_x = 0, mouse_y = 0; +/* Last position of mouse in window. */ +static int mouse_x = 0; +/* Last position of mouse in window. */ +static int mouse_y = 0; wimp_w history_window; -font_f history_font; - -static void history_free_entry(struct history_entry *entry); -static void ro_gui_history_redraw_tree(struct history_entry *he, - int x0, int y0); -static struct history_entry * ro_gui_history_click_find( - struct history_entry *he, - int x, int y); -static void history_go(struct browser_window *bw, - struct history_entry *entry, bool new_window); + static void ro_gui_history_redraw(wimp_draw *redraw); static bool ro_gui_history_click(wimp_pointer *pointer); -/** - * Create a new history tree for a window. - * - * \return pointer to an opaque history structure, 0 on failure. - */ - -struct history *history_create(void) -{ - struct history *history; - - history = malloc(sizeof *history); - if (!history) { - warn_user("NoMemory", 0); - return 0; - } - - history->start = 0; - history->current = 0; - - return history; -} - - -/** - * Insert a url into the history tree. - * - * \param history opaque history structure, as returned by history_create() - * \param content content to add to history - * \param frag_id fragment identifier - * - * The page is added after the current entry and becomes current. - */ - -void history_add(struct history *history, struct content *content, char *frag_id) -{ - url_func_result res; - struct history_entry *entry; - char *url; - char *title; - char *split; - int width; - struct bitmap *bitmap; - - if (!history) - return; - - /* allocate space */ - entry = malloc(sizeof *entry); - res = url_normalize(content->url, &url); - if (res != URL_FUNC_OK) { - warn_user("NoMemory", 0); - return; - } - title = strdup(content->title ? content->title : url); - if (!entry || !url || !title) { - warn_user("NoMemory", 0); - free(entry); - free(url); - free(title); - return; - } - - /* truncate title to available width */ - font_scan_string(history_font, title, font_GIVEN_FONT | font_KERN, - WIDTH * 400, 0x7fffffff, - 0, 0, 0, &split, &width, 0, 0); - if (title[split - title]) { - title[split - title - 2] = 0x8c; /* ellipsis */ - title[split - title - 1] = 0; - } - - entry->url = url; - entry->frag_id = frag_id ? strdup(frag_id) : 0; - entry->title = title; - entry->back = history->current; - entry->next = 0; - entry->forward = entry->forward_pref = entry->forward_last = 0; - entry->children = 0; - entry->width = width / 400; - entry->bitmap = 0; - if (history->current) { - if (history->current->forward_last) - history->current->forward_last->next = entry; - else - history->current->forward = entry; - history->current->forward_pref = entry; - history->current->forward_last = entry; - history->current->children++; - } else { - history->start = entry; - } - history->current = entry; - - /* if we have a thumbnail, don't update until the page has finished - * loading */ - bitmap = url_store_get_thumbnail(url); - if (!bitmap) { - bitmap = bitmap_create(WIDTH / 2, HEIGHT / 2, - BITMAP_NEW | BITMAP_CLEAR_MEMORY | - BITMAP_OPAQUE | BITMAP_PERSISTENT); - if (!bitmap) { - LOG(("Thumbnail initialisation failed.")); - return; - } - thumbnail_create(content, bitmap, url); - } - entry->bitmap = bitmap; -} - - -/** - * Update the thumbnail for the current entry. - * - * \param history opaque history structure, as returned by history_create() - * \param content content for current entry - */ - -void history_update(struct history *history, struct content *content) -{ - if (!history || !history->current || !history->current->bitmap) - return; - - thumbnail_create(content, history->current->bitmap, NULL); -} - - -/** - * Free a history structure. - * - * \param history opaque history structure, as returned by history_create() - */ - -void history_destroy(struct history *history) -{ - if (!history) - return; - if (history_current == history) { - wimp_close_window(history_window); - history_current = 0; - } - history_free_entry(history->start); - free(history); -} - - -/** - * Free an entry in the tree recursively. - */ - -void history_free_entry(struct history_entry *entry) -{ - if (!entry) - return; - history_free_entry(entry->forward); - history_free_entry(entry->next); - free(entry->url); - if (entry->frag_id) - free(entry->frag_id); - free(entry->title); - free(entry); -} /** @@ -251,7 +48,6 @@ void history_free_entry(struct history_entry *entry) void ro_gui_history_init(void) { history_window = ro_gui_dialog_create("history"); - history_font = font_find_font("Homerton.Medium", 112, 128, 0, 0, 0, 0); ro_gui_wimp_event_register_redraw_window(history_window, ro_gui_history_redraw); ro_gui_wimp_event_register_mouse_click(history_window, @@ -260,106 +56,64 @@ void ro_gui_history_init(void) } -/** - * Free history window resources. - */ - -void ro_gui_history_quit(void) -{ - font_lose_font(history_font); -} - - -/** - * Update resources folowing a mode change - */ -void ro_gui_history_mode_change(void) -{ - font_lose_font(history_font); - history_font = font_find_font("Homerton.Medium", 112, 128, 0, 0, 0, 0); -} - /** * Open history window. * - * \param pointer whether to open the window at the pointer + * \param bw browser window to open history for + * \param history history to open + * \param at_pointer open the window at the pointer */ void ro_gui_history_open(struct browser_window *bw, - struct history *history, bool pointer) + struct history *history, bool at_pointer) { - bool done = false; - unsigned int i, j, max_y = 0; - int x; int width, height; - struct history_entry *row[SIZE], *row2[SIZE]; - struct history_entry *he; os_box box = {0, 0, 0, 0}; wimp_window_state state; + os_error *error; - if (!history || !history->start) - return; - - history_bw = bw; history_current = history; + history_bw = bw; - /* calculate layout */ - for (i = 0; i != SIZE; i++) - row[i] = row2[i] = 0; - row[0] = history->start; - history->start->x = 0; - history->start->y = 0; - for (x = 1; !done; x++) { - for (i = 0; i != SIZE; i++) { - if (row[i]) { - for (j = i; j != SIZE && row2[j]; j++) - ; - if (j == SIZE) { - if (row[i]->forward) - row[i]->forward->x = -1; - break; - } - for (he = row[i]->forward; he; he = he->next) { - row2[j++] = he; - if (j == SIZE) { - if (he->next) - he->next->x = -1; - break; - } - } - if (j == SIZE) - break; - } - } - done = true; - for (i = 0; i != SIZE; i++) { - row[i] = row2[i]; - if (row[i]) { - row[i]->x = x; - row[i]->y = i; - if (max_y < i) - max_y = i; - done = false; - } - row2[i] = 0; - } - } - - width = FULL_WIDTH * (x - 1); - height = FULL_HEIGHT * (max_y + 1); + history_size(history, &width, &height); + width *= 2; + height *= 2; + /* set extent */ box.x1 = width; box.y0 = -height; - wimp_set_extent(history_window, &box); + error = xwimp_set_extent(history_window, &box); + if (error) { + LOG(("xwimp_set_extent: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + + /* open full size */ state.w = history_window; - wimp_get_window_state(&state); + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } state.visible.x0 = 0; state.visible.y0 = 0; state.visible.x1 = width; state.visible.y1 = height; state.next = wimp_HIDDEN; - wimp_open_window((wimp_open *) &state); - ro_gui_dialog_open_persistent(bw->window->window, history_window, pointer); + error = xwimp_open_window((wimp_open *) &state); + if (error) { + LOG(("xwimp_open_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + + ro_gui_dialog_open_persistent(bw->window->window, history_window, + at_pointer); } @@ -370,98 +124,46 @@ void ro_gui_history_open(struct browser_window *bw, void ro_gui_history_redraw(wimp_draw *redraw) { osbool more; + os_error *error; - more = wimp_redraw_window(redraw); + plot = ro_plotters; + ro_plot_set_scale(1.0); - while (more) { - ro_gui_history_redraw_tree(history_current->start, - redraw->box.x0 - redraw->xscroll, - redraw->box.y1 - redraw->yscroll); - more = wimp_get_rectangle(redraw); + error = xwimp_redraw_window(redraw, &more); + if (error) { + LOG(("xwimp_redraw_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; } -} - - -/** - * Redraw history tree recursively. - */ - -void ro_gui_history_redraw_tree(struct history_entry *he, - int x0, int y0) -{ - struct history_entry *c; - -/* os_plot(os_MOVE_TO, x0 + he->x * FULL_WIDTH + MARGIN, - y0 - he->y * FULL_HEIGHT - MARGIN); - os_plot(os_PLOT_RECTANGLE | os_PLOT_BY, WIDTH, -HEIGHT);*/ - - if (he == history_current->current) - colourtrans_set_gcol(os_COLOUR_RED, 0, os_ACTION_OVERWRITE, 0); - else - colourtrans_set_gcol(os_COLOUR_MID_DARK_GREY, 0, - os_ACTION_OVERWRITE, 0); - - os_plot(os_MOVE_TO, x0 + he->x * FULL_WIDTH + MARGIN - 1, - y0 - he->y * FULL_HEIGHT - MARGIN); - os_plot(os_PLOT_SOLID | os_PLOT_BY, WIDTH + 1, 0); - os_plot(os_PLOT_SOLID | os_PLOT_BY, 0, -HEIGHT - 1); - os_plot(os_PLOT_SOLID | os_PLOT_BY, -WIDTH - 1, 0); - os_plot(os_PLOT_SOLID | os_PLOT_BY, 0, HEIGHT + 1); - - if (he->bitmap) { - if (bitmap_get_buffer(he->bitmap)) { - image_redraw(he->bitmap->sprite_area, - x0 + he->x * FULL_WIDTH + MARGIN, - y0 - he->y * FULL_HEIGHT - MARGIN, - he->bitmap->width, he->bitmap->height, - he->bitmap->width, he->bitmap->height, - 0xffffff, - false, false, false, - IMAGE_PLOT_TINCT_OPAQUE); - } else { - url_store_add_thumbnail(he->url, NULL); - he->bitmap = NULL; - + while (more) { + ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; + history_redraw(history_current); + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG(("xwimp_get_rectangle: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; } } - - if (he == history_current->current) - wimp_set_font_colours(wimp_COLOUR_WHITE, wimp_COLOUR_RED); - else - wimp_set_font_colours(wimp_COLOUR_WHITE, wimp_COLOUR_BLACK); - - xfont_paint(history_font, he->title, - font_OS_UNITS | font_GIVEN_FONT | font_KERN, - x0 + he->x * FULL_WIDTH + (FULL_WIDTH - he->width) / 2, - y0 - he->y * FULL_HEIGHT - HEIGHT - MARGIN - 24, - NULL, NULL, 0); - - colourtrans_set_gcol(os_COLOUR_MID_DARK_GREY, 0, - os_ACTION_OVERWRITE, 0); - - for (c = he->forward; c; c = c->next) { - if (c->x == -1) - continue; - os_plot(os_MOVE_TO, x0 + c->x * FULL_WIDTH - MARGIN, - y0 - he->y * FULL_HEIGHT - FULL_HEIGHT / 2); - os_plot(os_PLOT_SOLID | os_PLOT_TO, - x0 + c->x * FULL_WIDTH + MARGIN, - y0 - c->y * FULL_HEIGHT - FULL_HEIGHT / 2); - ro_gui_history_redraw_tree(c, x0, y0); - } } + /** * Handle mouse movements over the history window. */ + void ro_gui_history_mouse_at(wimp_pointer *pointer) { int x, y; long width; - struct history_entry *he; + const char *url; wimp_window_state state; wimp_icon_state ic; os_box box = {0, 0, 0, 0}; + os_error *error; /* If the mouse hasn't moved, or if we don't want tooltips, exit */ if ((mouse_x == pointer->pos.x && mouse_y == pointer->pos.y) || @@ -474,188 +176,129 @@ void ro_gui_history_mouse_at(wimp_pointer *pointer) /* Find history tree entry under mouse */ state.w = history_window; - wimp_get_window_state(&state); - - x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / FULL_WIDTH; - y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / FULL_HEIGHT; - he = ro_gui_history_click_find(history_current->start, x, y); - if (he) { - /* get width of string */ - xwimptextop_string_width(he->url, - strlen(he->url) > 256 ? 256 : strlen(he->url), - (int*)&width); - - ro_gui_set_icon_string(dialog_tooltip, 0, he->url); - - /* resize icon appropriately */ - ic.w = dialog_tooltip; - ic.i = 0; - wimp_get_icon_state(&ic); - wimp_resize_icon(dialog_tooltip, 0, - ic.icon.extent.x0, ic.icon.extent.y0, - width + 16, ic.icon.extent.y1); - - state.w = dialog_tooltip; - wimp_get_window_state(&state); - - /* update window extent */ - box.x1 = width + 16; - box.y0 = -36; - xwimp_set_extent(dialog_tooltip, &box); - - /* set visible area */ - state.visible.x0 = pointer->pos.x + 24; - state.visible.y0 = pointer->pos.y - 22 - 36; - state.visible.x1 = pointer->pos.x + 24 + width + 16; - state.visible.y1 = pointer->pos.y - 22; - state.next = wimp_TOP; - /* open window */ - wimp_open_window((wimp_open *) &state); - } - else { - /* not over a tree entry => close tooltip window. */ - wimp_close_window(dialog_tooltip); + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; } -} - -/** - * Handle mouse clicks in the history window. - * - * \return true if the event was handled, false to pass it on - */ -bool ro_gui_history_click(wimp_pointer *pointer) -{ - int x, y; - struct history_entry *he; - wimp_window_state state; - - if (pointer->buttons != wimp_CLICK_SELECT && - pointer->buttons != wimp_CLICK_ADJUST) - /* return if not select or adjust click */ - return true; - - state.w = history_window; - wimp_get_window_state(&state); - - x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / FULL_WIDTH; - y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / FULL_HEIGHT; - he = ro_gui_history_click_find(history_current->start, x, y); - if (he) { - if (pointer->buttons == wimp_CLICK_SELECT) - history_current->current = he; - wimp_close_window(history_window); - history_current = 0; - history_go(history_bw, he, - pointer->buttons == wimp_CLICK_ADJUST); + x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; + y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; + url = history_position_url(history_current, x, y); + if (!url) { + /* not over a tree entry => close tooltip window. */ + error = xwimp_close_window(dialog_tooltip); + if (error) { + LOG(("xwimp_close_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + return; } - return true; -} - -/** - * Search for an entry with the specified coordinates. - */ - -struct history_entry * ro_gui_history_click_find(struct history_entry *he, - int x, int y) -{ - struct history_entry *c, *d; - if (he->x == x && he->y == y) - return he; - for (c = he->forward; c; c = c->next) { - d = ro_gui_history_click_find(c, x, y); - if (d) - return d; + /* get width of string */ + error = xwimptextop_string_width(url, + strlen(url) > 256 ? 256 : strlen(url), + (int *) &width); + if (error) { + LOG(("xwimptextop_string_width: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; } - return 0; -} + ro_gui_set_icon_string(dialog_tooltip, 0, url); -/** - * Go back in the history. - * - * \param bw browser window - * \param history history of the window - */ - -void history_back(struct browser_window *bw, struct history *history) -{ - if (!history || !history->current || !history->current->back) + /* resize icon appropriately */ + ic.w = dialog_tooltip; + ic.i = 0; + error = xwimp_get_icon_state(&ic); + if (error) { + LOG(("xwimp_get_icon_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); return; - history->current = history->current->back; - history_go(bw, history->current, false); -} - - -/** - * Go forward in the history. - * - * \param bw browser window - * \param history history of the window - */ - -void history_forward(struct browser_window *bw, struct history *history) -{ - if (!history || !history->current || !history->current->forward_pref) + } + error = xwimp_resize_icon(dialog_tooltip, 0, + ic.icon.extent.x0, ic.icon.extent.y0, + width + 16, ic.icon.extent.y1); + if (error) { + LOG(("xwimp_resize_icon: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); return; - history->current = history->current->forward_pref; - history_go(bw, history->current, false); -} + } + state.w = dialog_tooltip; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } -/** - * Check whether it is pssible to go back in the history. - * - * \param history history of the window - * \return true if the history can go back, false otherwise - */ + /* update window extent */ + box.x1 = width + 16; + box.y0 = -36; + error = xwimp_set_extent(dialog_tooltip, &box); + if (error) { + LOG(("xwimp_set_extent: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } -bool history_back_available(struct history *history) { - return (history && history->current && history->current->back); + /* set visible area */ + state.visible.x0 = pointer->pos.x + 24; + state.visible.y0 = pointer->pos.y - 22 - 36; + state.visible.x1 = pointer->pos.x + 24 + width + 16; + state.visible.y1 = pointer->pos.y - 22; + state.next = wimp_TOP; + /* open window */ + error = xwimp_open_window((wimp_open *) &state); + if (error) { + LOG(("xwimp_open_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } } /** - * Check whether it is pssible to go forwards in the history. + * Handle mouse clicks in the history window. * - * \param history history of the window - * \return true if the history can go forwards, false otherwise + * \return true if the event was handled, false to pass it on */ -bool history_forward_available(struct history *history) { - return (history && history->current && history->current->forward_pref); -} - -/** - * Open a history entry in the specified browser window - * - * \param bw browser window - * \param entry entry to open - * \param new_window open entry in new window - */ -void history_go(struct browser_window *bw, struct history_entry *entry, - bool new_window) +bool ro_gui_history_click(wimp_pointer *pointer) { - char *url; + int x, y; + wimp_window_state state; + os_error *error; - if (entry->frag_id) { - url = calloc(strlen(entry->url) + strlen(entry->frag_id) + 5, - sizeof(char)); - if (!url) { - warn_user("NoMemory", 0); - return; - } - sprintf(url, "%s#%s", entry->url, entry->frag_id); + if (pointer->buttons != wimp_CLICK_SELECT && + pointer->buttons != wimp_CLICK_ADJUST) + /* return if not select or adjust click */ + return true; + + state.w = history_window; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return true; } - else - url = entry->url; - if (new_window) - browser_window_create(url, bw, 0); - else - browser_window_go_post(bw, url, 0, 0, false, 0, false); + x = (pointer->pos.x - (state.visible.x0 - state.xscroll)) / 2; + y = -(pointer->pos.y - (state.visible.y1 - state.yscroll)) / 2; + history_click(history_bw, history_current, x, y, + pointer->buttons == wimp_CLICK_ADJUST); - if (entry->frag_id) - free(url); + return true; } -- cgit v1.2.3