From 6b997431d34d3711c62cf4bfe7f3456f45072273 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 28 May 2017 22:07:33 +0100 Subject: update RISC OS frontend to use core window for local history --- frontends/riscos/local_history.c | 438 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 438 insertions(+) create mode 100644 frontends/riscos/local_history.c (limited to 'frontends/riscos/local_history.c') diff --git a/frontends/riscos/local_history.c b/frontends/riscos/local_history.c new file mode 100644 index 000000000..fae78e6ff --- /dev/null +++ b/frontends/riscos/local_history.c @@ -0,0 +1,438 @@ +/* + * Copyright 2017 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file + * Implementation of RISC OS local history. + */ + +#include +#include +#include + +#include "utils/nsoption.h" +#include "utils/messages.h" +#include "utils/log.h" +#include "netsurf/window.h" +#include "netsurf/plotters.h" +#include "netsurf/keypress.h" +#include "desktop/local_history.h" + +#include "riscos/dialog.h" +#include "riscos/gui.h" +#include "riscos/menus.h" +#include "riscos/save.h" +#include "riscos/toolbar.h" +#include "riscos/wimp.h" +#include "riscos/wimp_event.h" +#include "riscos/wimputils.h" +#include "riscos/corewindow.h" +#include "riscos/local_history.h" + +struct ro_local_history_window { + struct ro_corewindow core; + + /** local history window context */ + struct local_history_session *session; + + /** tooltip previous x */ + int x; + /** tooltip previous y */ + int y; +}; + +/** local_history window is a singleton */ +static struct ro_local_history_window *local_history_window = NULL; + +/** riscos template for local_history window */ +static wimp_window *dialog_local_history_template; + + +/** + * callback to draw on drawable area of ro local history window + * + * \param ro_cw The riscos core window structure. + * \param r The rectangle of the window that needs updating. + * \param originx The risc os plotter x origin. + * \param originy The risc os plotter y origin. + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +ro_local_history_draw(struct ro_corewindow *ro_cw, + int originx, + int originy, + struct rect *r) +{ + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters + }; + struct ro_local_history_window *lhw; + + lhw = (struct ro_local_history_window *)ro_cw; + + ro_plot_origin_x = originx; + ro_plot_origin_y = originy; + no_font_blending = true; + local_history_redraw(lhw->session, r->x0, r->y0, r, &ctx); + no_font_blending = false; + + return NSERROR_OK; +} + + +/** + * callback for keypress on ro coookie window + * + * \param ro_cw The ro core window structure. + * \param nskey The netsurf key code. + * \return NSERROR_OK if key processed, + * NSERROR_NOT_IMPLEMENTED if key not processed + * otherwise apropriate error code + */ +static nserror +ro_local_history_key(struct ro_corewindow *ro_cw, uint32_t nskey) +{ + struct ro_local_history_window *lhw; + + lhw = (struct ro_local_history_window *)ro_cw; + + if (local_history_keypress(lhw->session, nskey)) { + return NSERROR_OK; + } + return NSERROR_NOT_IMPLEMENTED; +} + + +/** + * handle hover mouse movement for tooltips + */ +static nserror +ro_local_history_tooltip(struct ro_local_history_window *lhw, int x, int y) +{ + int width; + const char *url; + wimp_window_state state; + wimp_icon_state ic; + os_box box = {0, 0, 0, 0}; + os_error *error; + wimp_pointer pointer; + nserror res; + + /* check if tooltip are required */ + if (!nsoption_bool(history_tooltip)) { + return NSERROR_OK; + } + + /* ensure pointer has moved */ + if ((lhw->x == x) && (lhw->y == y)) { + return NSERROR_OK; + } + + lhw->x = x; + lhw->y = y; + + res = local_history_get_url(lhw->session, x, y, &url); + if (res != NSERROR_OK) { + /* 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); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + return NSERROR_OK; + } + + /* get width of string */ + error = xwimptextop_string_width(url, + strlen(url) > 256 ? 256 : strlen(url), + &width); + if (error) { + LOG("xwimptextop_string_width: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + ro_gui_set_icon_string(dialog_tooltip, 0, url, true); + + /* 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); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + 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); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + state.w = dialog_tooltip; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + /* 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); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + error = xwimp_get_pointer_info(&pointer); + if (error) { + LOG("xwimp_get_pointer_info: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + /* 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(PTR_WIMP_OPEN(&state)); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + return NSERROR_OK; +} + + +/** + * callback for mouse event on ro local_history window + * + * \param ro_cw The ro core window structure. + * \param mouse_state mouse state + * \param x location of event + * \param y location of event + * \return NSERROR_OK on sucess otherwise apropriate error code. + */ +static nserror +ro_local_history_mouse(struct ro_corewindow *ro_cw, + browser_mouse_state mouse_state, + int x, int y) +{ + struct ro_local_history_window *lhw; + + lhw = (struct ro_local_history_window *)ro_cw; + + switch (mouse_state) { + + case BROWSER_MOUSE_HOVER: + ro_local_history_tooltip(lhw, x, y); + break; + + case BROWSER_MOUSE_LEAVE: + ro_gui_dialog_close(dialog_tooltip); + break; + + default: + local_history_mouse_action(lhw->session, mouse_state, x, y); + break; + } + + return NSERROR_OK; +} + + +/** + * Creates the window for the local_history tree. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +static nserror +ro_local_history_init(struct browser_window *bw, + struct ro_local_history_window **win_out) +{ + struct ro_local_history_window *ncwin; + nserror res; + + /* memoise window so it can be represented when necessary + * instead of recreating every time. + */ + if ((*win_out) != NULL) { + res = local_history_set((*win_out)->session, bw); + return res; + } + + ncwin = malloc(sizeof(struct ro_local_history_window)); + if (ncwin == NULL) { + return NSERROR_NOMEM; + } + + /* create window from template */ + ncwin->core.wh = wimp_create_window(dialog_local_history_template); + + /* initialise callbacks */ + ncwin->core.draw = ro_local_history_draw; + ncwin->core.key = ro_local_history_key; + ncwin->core.mouse = ro_local_history_mouse; + + /* initialise core window */ + res = ro_corewindow_init(&ncwin->core, + NULL, + NULL, + 0, + NULL); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + res = local_history_init(ncwin->core.cb_table, + (struct core_window *)ncwin, + bw, + &ncwin->session); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + *win_out = ncwin; + + return NSERROR_OK; +} + + +/** + * open RISC OS local history window at the correct size + */ +static nserror +ro_local_history_open(struct ro_local_history_window *lhw, wimp_w parent) +{ + nserror res; + int width, height; + os_box box = {0, 0, 0, 0}; + wimp_window_state state; + os_error *error; + + res = local_history_get_size(lhw->session, &width, &height); + if (res != NSERROR_OK) { + return res; + } + + width *= 2; + height *= 2; + + /* set extent */ + box.x1 = width; + box.y0 = -height; + error = xwimp_set_extent(lhw->core.wh, &box); + if (error) { + LOG("xwimp_set_extent: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + /* open full size */ + state.w = lhw->core.wh; + error = xwimp_get_window_state(&state); + if (error) { + LOG("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + state.visible.x0 = 0; + state.visible.y0 = 0; + state.visible.x1 = width; + state.visible.y1 = height; + state.next = wimp_HIDDEN; + error = xwimp_open_window(PTR_WIMP_OPEN(&state)); + if (error) { + LOG("xwimp_open_window: 0x%x: %s", + error->errnum, error->errmess); + ro_warn_user("WimpError", error->errmess); + return NSERROR_NOMEM; + } + + ro_gui_dialog_open_persistent(parent, lhw->core.wh, true); + + return NSERROR_OK; +} + +/* exported interface documented in riscos/local_history.h */ +nserror ro_gui_local_history_present(wimp_w parent, struct browser_window *bw) +{ + nserror res; + + res = ro_local_history_init(bw, &local_history_window); + if (res == NSERROR_OK) { + LOG("Presenting"); + res = ro_local_history_open(local_history_window, parent); + } else { + LOG("Failed presenting error code %d", res); + } + + return res; +} + + +/* exported interface documented in riscos/local_history.h */ +void ro_gui_local_history_initialise(void) +{ + dialog_local_history_template = ro_gui_dialog_load_template("history"); +} + + +/* exported interface documented in riscos/local_history.h */ +nserror ro_gui_local_history_finalise(void) +{ + nserror res; + + if (local_history_window == NULL) { + return NSERROR_OK; + } + + res = local_history_fini(local_history_window->session); + if (res == NSERROR_OK) { + res = ro_corewindow_fini(&local_history_window->core); + + free(local_history_window); + local_history_window = NULL; + } + + return res; +} -- cgit v1.2.3