From 6173bb0e6c3bf51cd463f7bc4f725429d9087b2b Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Tue, 5 Oct 2010 19:14:46 +0000 Subject: Merge treeview-redux to trunk svn path=/trunk/netsurf/; revision=10865 --- riscos/treeview.c | 2044 +++++++++++++++++++---------------------------------- 1 file changed, 741 insertions(+), 1303 deletions(-) (limited to 'riscos/treeview.c') diff --git a/riscos/treeview.c b/riscos/treeview.c index ef23c5e3e..c992fdda7 100644 --- a/riscos/treeview.c +++ b/riscos/treeview.c @@ -1,5 +1,6 @@ /* * Copyright 2005 Richard Wilson + * Copyright 2010 Stephen Fryatt * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -20,6 +21,8 @@ * Generic tree handling (implementation). */ +#include + #include #include #include @@ -35,7 +38,9 @@ #include "content/urldb.h" #include "desktop/browser.h" #include "desktop/plotters.h" +#include "desktop/textinput.h" #include "desktop/tree.h" +#include "desktop/tree_url_node.h" #include "riscos/bitmap.h" #include "riscos/dialog.h" #include "riscos/gui.h" @@ -56,1379 +61,746 @@ #define wimp_KEY_END wimp_KEY_COPY #endif -#define TREE_EXPAND 0 -#define TREE_COLLAPSE 1 - - -static bool ro_gui_tree_initialise_sprite(const char *name, int number); -static void ro_gui_tree_launch_selected_node(struct tree *tree, struct node *node, bool all); -static bool ro_gui_tree_launch_node(struct tree *tree, struct node *node); -static void tree_handle_node_changed_callback(void *p); - - -/* an array of sprite addresses for Tinct */ -static char *ro_gui_tree_sprites[2]; - -/* origin adjustment */ -static int ro_gui_tree_origin_x; -static int ro_gui_tree_origin_y; - -/* element drawing */ -static wimp_icon ro_gui_tree_icon; -static char ro_gui_tree_icon_validation[24]; -static char ro_gui_tree_icon_null[] = ""; +/** \todo Ugh! */ +const char tree_directory_icon_name[] = "directory.png"; +const char tree_content_icon_name[] = "content.png"; -/* dragging information */ -static struct tree *ro_gui_tree_current_drag_tree; -static wimp_mouse_state ro_gui_tree_current_drag_buttons; - -/* editing information */ -static wimp_icon_create ro_gui_tree_edit_icon; - -/* dragging information */ -static char ro_gui_tree_drag_name[12]; - -/* callback update */ -struct node_update { - struct tree *tree; - struct node *node; -}; - - -/** - * Performs any initialisation for tree rendering - */ -bool ro_gui_tree_initialise(void) +struct ro_treeview { - if (ro_gui_tree_initialise_sprite("expand", TREE_EXPAND) || - ro_gui_tree_initialise_sprite("collapse", TREE_COLLAPSE)) - return false; - - ro_gui_tree_edit_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_INDIRECTED | - wimp_ICON_VCENTRED | wimp_ICON_FILLED | wimp_ICON_BORDER | - (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT) | - (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | - (wimp_BUTTON_WRITABLE << wimp_ICON_BUTTON_TYPE_SHIFT); - ro_gui_tree_edit_icon.icon.data.indirected_text.validation = - ro_gui_tree_icon_null; - ro_gui_tree_edit_icon.icon.data.indirected_text.size = 256; - - return true; -} + struct tree *tree; /*< Pointer to treeview tree block. */ + wimp_w w; /*< RO Window Handle for tree window. */ + struct toolbar *tb; /*< Pointer to toolbar block. */ + struct { + int x; /*< X origin of tree, to RO work area. */ + int y; /*< Y origin of tree, to RO work area. */ + } origin; + struct { + int x; /*< X dimension of the tree, in RO units. */ + int y; /*< Y dimension of the tree, in RO units. */ + } size; /* (Dimensions are 0 until set correctly). */ + struct { + int x; /*< X extent of the window, in RO units. */ + int y; /*< Y extent of the window, in RO units. */ + } extent; /* (Extents are 0 until set correctly). */ + struct { + int x; /*< X coordinate of drag start */ + int y; /*< Y coordinate of drag start */ + } drag_start; + bool drag; /*< True if there's a drag going on */ +}; +static void ro_treeview_redraw_request(int x, int y, int width, int height, + void *pw); +static void ro_treeview_resized(struct tree *tree, int width, int height, + void *pw); +static void ro_treeview_scroll_visible(int y, int height, void *pw); +static void ro_treeview_get_window_dimensions(int *width, int *height, + void *pw); + +static void ro_treeview_redraw(wimp_draw *redraw); +static void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, + osbool more); +static void ro_treeview_open(wimp_open *open); +static bool ro_treeview_mouse_click(wimp_pointer *pointer); +static bool ro_treeview_keypress(wimp_key *key); + +static void ro_treeview_set_window_extent(ro_treeview *tv, + int width, int height); + +static const struct treeview_table ro_tree_callbacks = { + ro_treeview_redraw_request, + ro_treeview_resized, + ro_treeview_scroll_visible, + ro_treeview_get_window_dimensions +}; /** - * Initialise a sprite for use with Tinct + * Create a RISC OS GUI implementation of a treeview tree. + * + * \param window The window to create the tree in. + * \param *toolbar A toolbar to attach to the window. + * \param flags The treeview flags. * - * \param name the name of the sprite - * \param number the sprite cache number - * \return whether an error occurred during initialisation + * \return The RISC OS treeview pointer. */ -bool ro_gui_tree_initialise_sprite(const char *name, int number) -{ - char icon_name[12]; - const char *icon = icon_name; - os_error *error; - - snprintf(icon_name, sizeof(icon_name), "tr_%s", name); - - error = xosspriteop_select_sprite(osspriteop_USER_AREA, gui_sprites, - (osspriteop_id) icon, - (osspriteop_header **) &ro_gui_tree_sprites[number]); - if (error) { - warn_user("MiscError", error->errmess); - LOG(("Failed to find sprite 'tr_%s'", name)); - return true; - } - return false; -} +ro_treeview *ro_treeview_create(wimp_w window, struct toolbar *toolbar, + unsigned int flags) +{ + ro_treeview *tv; + /* Claim memory for the treeview block, and create a tree. */ -/** - * Informs the current window manager that an area requires updating. - * - * \param tree the tree that is requesting a redraw - * \param x the x co-ordinate of the redraw area - * \param y the y co-ordinate of the redraw area - * \param width the width of the redraw area - * \param height the height of the redraw area - */ -void tree_redraw_area(struct tree *tree, int x, int y, int width, int height) -{ - os_error *error; + tv = malloc(sizeof(ro_treeview)); + if (tv == NULL) + return NULL; - assert(tree); - assert(tree->handle); + tv->w = window; + tv->tb = toolbar; - if (tree->toolbar) - y += ro_gui_theme_toolbar_height(tree->toolbar); - error = xwimp_force_redraw((wimp_w)tree->handle, tree->offset_x + x - 2, - -tree->offset_y - y - height, tree->offset_x + x + width + 4, - -tree->offset_y - y); - if (error) { - LOG(("xwimp_force_redraw: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); + tv->tree = tree_create(flags, &ro_tree_callbacks, tv); + if (tv->tree == NULL) { + free(tv); + return NULL; } -} + /* Set the tree redraw origin at a default 0,0 RO units. */ -/** - * Draws a line. - * - * \param tree the tree to draw a line for - * \param x the x co-ordinate - * \param x the y co-ordinate - * \param x the width of the line - * \param x the height of the line - */ -void tree_draw_line(int x, int y, int width, int height) -{ - os_error *error; - int y0, y1; + tv->origin.x = 0; + tv->origin.y = 0; - /* stop the 16-bit co-ordinate system from causing redraw errors */ - y1 = ro_gui_tree_origin_y - y; - if (y1 < 0) - return; - y0 = y1 - height; - if (y0 > 16384) - return; - if (y0 < 0) - y0 = 0; - if (y1 > 16384) - y1 = 16384; + /* Set the tree size as 0,0 to indicate that we don't know. */ - error = xcolourtrans_set_gcol((os_colour)0x88888800, 0, os_ACTION_OVERWRITE, - 0, 0); - if (error) { - LOG(("xcolourtrans_set_gcol: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MiscError", error->errmess); - return; - } - error = xos_plot(os_MOVE_TO, ro_gui_tree_origin_x + x, y0); - if (!error) - xos_plot(os_PLOT_TO, ro_gui_tree_origin_x + x + width, y1); - if (error) { - LOG(("xos_plot: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MiscError", error->errmess); - return; - } -} + tv->size.x = 0; + tv->size.y = 0; + /* Set the tree window extent to 0,0, to indicate that we + * don't know. */ -/** - * Draws an element, including any expansion icons - * - * \param tree the tree to draw an element for - * \param element the element to draw - */ -void tree_draw_node_element(struct tree *tree, struct node_element *element) -{ - os_error *error; - int toolbar_height = 0; - struct node_element *url_element; - const struct bitmap *bitmap = NULL; - struct node_update *update; - const uint8_t *frame; - rufl_code code; - int x0, y0, x1, y1; - bool selected = false; - colour bg, c; - - assert(tree); - assert(element); - assert(element->parent); - - if (tree->toolbar) - toolbar_height = ro_gui_theme_toolbar_height(tree->toolbar); - - x0 = ro_gui_tree_origin_x + element->box.x; - x1 = x0 + element->box.width; - y1 = ro_gui_tree_origin_y - element->box.y; - y0 = y1 - element->box.height; - if (&element->parent->data == element) - if (element->parent->selected) - selected = true; - - - switch (element->type) { - case NODE_ELEMENT_TEXT_PLUS_SPRITE: - assert(element->sprite); - - ro_gui_tree_icon.flags = wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED; - if (selected) - ro_gui_tree_icon.flags |= wimp_ICON_SELECTED; - ro_gui_tree_icon.extent.x0 = tree->offset_x + element->box.x; - ro_gui_tree_icon.extent.y1 = -tree->offset_y - element->box.y - - toolbar_height; - ro_gui_tree_icon.extent.x1 = ro_gui_tree_icon.extent.x0 + - NODE_INSTEP; - ro_gui_tree_icon.extent.y0 = -tree->offset_y - element->box.y - - element->box.height - toolbar_height; - ro_gui_tree_icon.flags |= wimp_ICON_TEXT | wimp_ICON_SPRITE; - ro_gui_tree_icon.data.indirected_text_and_sprite.text = - ro_gui_tree_icon_null; - ro_gui_tree_icon.data.indirected_text_and_sprite.validation = - ro_gui_tree_icon_validation; - ro_gui_tree_icon.data.indirected_text_and_sprite.size = 1; - if (element->parent->expanded) { - sprintf(ro_gui_tree_icon_validation, "S%s", - element->sprite->expanded_name); - } else { - sprintf(ro_gui_tree_icon_validation, "S%s", - element->sprite->name); - } - error = xwimp_plot_icon(&ro_gui_tree_icon); - if (error) { - LOG(("xwimp_plot_icon: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - } - x0 += NODE_INSTEP; + tv->extent.x = 0; + tv->extent.y = 0; - /* fall through */ - case NODE_ELEMENT_TEXT: - assert(element->text); + /* Set that there is no drag opperation at the moment */ - if (element == tree->editing) - return; + tv->drag = false; - if (ro_gui_tree_icon.flags & wimp_ICON_SELECTED) - ro_gui_tree_icon.flags |= wimp_ICON_FILLED; - if (selected) { - error = xcolourtrans_set_gcol((os_colour)0x00000000, 0, - os_ACTION_OVERWRITE, 0, 0); - if (error) { - LOG(("xcolourtrans_set_gcol: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MiscError", error->errmess); - return; - } - error = xos_plot(os_MOVE_TO, x0, y0); - if (!error) - error = xos_plot(os_PLOT_RECTANGLE | os_PLOT_TO, x1-1, y1-1); - if (error) { - LOG(("xos_plot: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MiscError", error->errmess); - return; - } - bg = 0x0000000; - c = 0x00eeeeee; - } else { - bg = 0x00ffffff; - c = 0x00000000; - } - error = xcolourtrans_set_font_colours(font_CURRENT, - bg << 8, c << 8, 14, 0, 0, 0); - if (error) { - LOG(("xcolourtrans_set_font_colours: 0x%x: %s", - error->errnum, error->errmess)); - return; - } - code = rufl_paint(ro_gui_desktop_font_family, ro_gui_desktop_font_style, - ro_gui_desktop_font_size, - element->text, strlen(element->text), - x0 + 8, y0 + 10, - rufl_BLEND_FONT); - if (code != rufl_OK) { - if (code == rufl_FONT_MANAGER_ERROR) - LOG(("rufl_paint: rufl_FONT_MANAGER_ERROR: 0x%x: %s", - rufl_fm_error->errnum, - rufl_fm_error->errmess)); - else - LOG(("rufl_paint: 0x%x", code)); - } - break; - case NODE_ELEMENT_THUMBNAIL: - url_element = tree_find_element(element->parent, TREE_ELEMENT_URL); - if (url_element) - bitmap = urldb_get_thumbnail(url_element->text); - if (bitmap) { - frame = bitmap_get_buffer((struct bitmap *) bitmap); - if (!frame) - urldb_set_thumbnail(url_element->text, NULL); - if ((!frame) || (element->box.width == 0)) { - update = calloc(sizeof(struct node_update), 1); - if (!update) - return; - update->tree = tree; - update->node = element->parent; - schedule(0, tree_handle_node_changed_callback, - update); - return; - } - image_redraw(bitmap->sprite_area, - ro_gui_tree_origin_x + element->box.x + 2, - ro_gui_tree_origin_y - element->box.y, - bitmap->width, bitmap->height, - bitmap->width, bitmap->height, - 0xffffff, - false, false, false, - IMAGE_PLOT_TINCT_OPAQUE); - if (!tree->no_furniture) { - tree_draw_line(element->box.x, - element->box.y, - element->box.width - 1, - 0); - tree_draw_line(element->box.x, - element->box.y, - 0, - element->box.height - 3); - tree_draw_line(element->box.x, - element->box.y + element->box.height - 3, - element->box.width - 1, - 0); - tree_draw_line(element->box.x + element->box.width - 1, - element->box.y, - 0, - element->box.height - 3); - } - } - break; - } -} + /* Register wimp events to handle the supplied window. */ + ro_gui_wimp_event_register_redraw_window(tv->w, ro_treeview_redraw); + ro_gui_wimp_event_register_open_window(tv->w, ro_treeview_open); + ro_gui_wimp_event_register_mouse_click(tv->w, ro_treeview_mouse_click); + ro_gui_wimp_event_register_keypress(tv->w, ro_treeview_keypress); + ro_gui_wimp_event_set_user_data(tv->w, tv); -void tree_handle_node_changed_callback(void *p) -{ - struct node_update *update = p; + /* \todo Register wimp events to handle the supplied toolbar? */ - tree_handle_node_changed(update->tree, update->node, true, false); - free(update); + return tv; } - /** - * Draws an elements expansion icon + * Delete a RISC OS GUI implementation of a treeview tree. The window is + * *not* destroyed -- this must be done by the caller. * - * \param tree the tree to draw the expansion for - * \param element the element to draw the expansion for + * \param tv The RISC OS treeview to delete. */ -void tree_draw_node_expansion(struct tree *tree, struct node *node) -{ - unsigned int type; - assert(tree); - assert(node); +void ro_treeview_destroy(ro_treeview *tv) +{ + ro_gui_wimp_event_finalise(tv->w); - if ((node->child) || (node->data.next)) { - if (node->expanded) { - type = TREE_COLLAPSE; - } else { - type = TREE_EXPAND; - } - _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), - ro_gui_tree_sprites[type], - ro_gui_tree_origin_x + node->box.x - - (NODE_INSTEP / 2) - 8, - ro_gui_tree_origin_y - node->box.y - - (TREE_TEXT_HEIGHT / 2) - 8, - tinct_BILINEAR_FILTER); + tree_delete(tv->tree); - } + free(tv); } - /** - * Sets the origin variables to the correct values for a specified tree + * Change the redraw origin of a treeview tree in RISC OS graphics units. * - * \param tree the tree to set the origin for + * \param *tv The ro_treeview object to update. + * \param x The X position, in terms of the RO window work area. + * \param y The Y position, in terms of the RO window work area. + * + * \todo -- this probably needs a rework. */ -void tree_initialise_redraw(struct tree *tree) -{ - os_error *error; - wimp_window_state state; - assert(tree->handle); - - state.w = (wimp_w)tree->handle; - 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); +void ro_treeview_set_origin(ro_treeview *tv, int x, int y) +{ + if (tv != NULL) { + tv->origin.x = x; + tv->origin.y = y; + + /* Assuming that we know how big the tree currently is, then + * adjust the window work area extent to match. If we don't, + * then presumably the tree isn't in an open window yet and + * a subsequent Open Window Event should pick it up. + */ + + if (tv->size.x != 0 && tv->size.y != 0) + ro_treeview_set_window_extent(tv, + tv->origin.x + tv->size.x, + tv->origin.y + tv->size.y); } - - ro_gui_tree_origin_x = state.visible.x0 - state.xscroll + tree->offset_x; - ro_gui_tree_origin_y = state.visible.y1 - state.yscroll - tree->offset_y; - if (tree->toolbar) - ro_gui_tree_origin_y -= ro_gui_theme_toolbar_height(tree->toolbar); } - /** - * Recalculates the dimensions of a node element. + * Return details of the tree block associated with an ro_treeview object. * - * \param element the element to recalculate + * \param *tv The ro_treeview object of interest. + * \return A pointer to the associated tree block. */ -void tree_recalculate_node_element(struct node_element *element) + +struct tree *ro_treeview_get_tree(ro_treeview *tv) { - const struct bitmap *bitmap = NULL; - struct node_element *url_element; - rufl_code code; - - assert(element); - - switch (element->type) { - case NODE_ELEMENT_TEXT_PLUS_SPRITE: - assert(element->sprite); - case NODE_ELEMENT_TEXT: - assert(element->text); - code = rufl_width(ro_gui_desktop_font_family, ro_gui_desktop_font_style, - ro_gui_desktop_font_size, - element->text, strlen(element->text), - &element->box.width); - if (code != rufl_OK) { - if (code == rufl_FONT_MANAGER_ERROR) - LOG(("rufl_width: rufl_FONT_MANAGER_ERROR: 0x%x: %s", - rufl_fm_error->errnum, - rufl_fm_error->errmess)); - else - LOG(("rufl_width: 0x%x", code)); - } - element->box.width += 16; - element->box.height = TREE_TEXT_HEIGHT; - if (element->type == NODE_ELEMENT_TEXT_PLUS_SPRITE) - element->box.width += NODE_INSTEP; - break; - case NODE_ELEMENT_THUMBNAIL: - url_element = tree_find_element(element->parent, TREE_ELEMENT_URL); - if (url_element) - bitmap = urldb_get_thumbnail(url_element->text); - if (bitmap) { -/* if ((bitmap->width == 0) && (bitmap->height == 0)) - frame = bitmap_get_buffer(bitmap); - element->box.width = bitmap->width * 2 + 2; - element->box.height = bitmap->height * 2 + 4; -*/ element->box.width = THUMBNAIL_WIDTH * 2 + 2; - element->box.height = THUMBNAIL_HEIGHT * 2 + 4; - } else { - element->box.width = 0; - element->box.height = 0; - } - } + return (tv != NULL) ? (tv->tree) : (NULL); } - /** - * Sets a node element as having a specific sprite. + * Return details of the RISC OS window handle associated with an + * ro_treeview object. * - * \param node the node to update - * \param sprite the sprite to use - * \param selected the expanded sprite name to use + * \param *tv The ro_treeview object of interest. + * \return The associated RISC OS window handle. */ -void tree_set_node_sprite(struct node *node, const char *sprite, - const char *expanded) + +wimp_w ro_treeview_get_window(ro_treeview *tv) { - assert(node); - assert(sprite); - assert(expanded); - - node->data.sprite = calloc(sizeof(struct node_sprite), 1); - if (!node->data.sprite) return; - node->data.type = NODE_ELEMENT_TEXT_PLUS_SPRITE; - node->data.sprite->area = (osspriteop_area *)1; - sprintf(node->data.sprite->name, sprite); - sprintf(node->data.sprite->expanded_name, expanded); + return (tv != NULL) ? (tv->w) : (NULL); } - /** - * Sets a node element as having a folder sprite + * Return an indication of whether the supplied treeview object contains a + * selection. * - * \param node the node to update + * \param *tv The ro_treeview object of interest. + * \return true if there is a selection in the tree; else false. */ -void tree_set_node_sprite_folder(struct node *node) -{ - assert(node->folder); - tree_set_node_sprite(node, "small_dir", "small_diro"); +bool ro_treeview_has_selection(ro_treeview *tv) +{ + if (tv != NULL) + return tree_node_has_selection(tree_get_root(tv->tree)); + else + return false; } - /** - * Updates the node details for a URL node. - * The internal node dimensions are not updated. + * Callback to force a redraw of part of the treeview window. * - * \param node the node to update - * \param url the URL - * \param data the data the node is linked to, or NULL for unlinked data + * \param x Min X Coordinate of area to be redrawn. + * \param y Min Y Coordinate of area to be redrawn. + * \param width Width of area to be redrawn. + * \param height Height of area to be redrawn. + * \param pw The treeview object to be redrawn. */ -void tree_update_URL_node(struct node *node, - const char *url, const struct url_data *data) + +void ro_treeview_redraw_request(int x, int y, int width, int height, + void *pw) { - struct node_element *element; - char buffer[256]; + if (pw != NULL) { + ro_treeview *tv = (ro_treeview *) pw; + os_error *error; + wimp_draw update; + osbool more; - assert(node); + /* The scale can't be changed; it's always 1:1. */ - element = tree_find_element(node, TREE_ELEMENT_URL); - if (!element) - return; - if (data) { - /* node is linked, update */ - assert(!node->editable); - if (!data->title) - urldb_set_url_title(url, url); + plot = ro_plotters; + ro_plot_set_scale(1.0); - if (!data->title) - return; + update.w = tv->w; + update.box.x0 = (2 * x) + tv->origin.x; + update.box.y0 = (-2 * (y + height)) + tv->origin.y; + update.box.x1 = (2 * (x + width)) + tv->origin.x; + update.box.y1 = (-2 * y) + tv->origin.y; - node->data.text = data->title; - } else { - /* node is not linked, find data */ - assert(node->editable); - data = urldb_get_url_data(element->text); - if (!data) + error = xwimp_update_window(&update, &more); + if (error) { + LOG(("xwimp_update_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); return; - } - - if (element) { - sprintf(buffer, "small_%.3x", ro_content_filetype_from_type(data->type)); - if (ro_gui_wimp_sprite_exists(buffer)) - tree_set_node_sprite(node, buffer, buffer); - else - tree_set_node_sprite(node, "small_xxx", "small_xxx"); - } - - element = tree_find_element(node, TREE_ELEMENT_LAST_VISIT); - if (element) { - snprintf(buffer, 256, messages_get("TreeLast"), - (data->last_visit > 0) ? - ctime((time_t *)&data->last_visit) : - messages_get("TreeUnknown")); - if (data->last_visit > 0) - buffer[strlen(buffer) - 1] = '\0'; - free((void *)element->text); - element->text = strdup(buffer); - } - - element = tree_find_element(node, TREE_ELEMENT_VISITS); - if (element) { - snprintf(buffer, 256, messages_get("TreeVisits"), - data->visits); - free((void *)element->text); - element->text = strdup(buffer); + } + ro_treeview_redraw_loop(&update, tv, more); } } - - /** - * Updates the tree owner following a tree resize + * Pass RISC OS redraw events on to the treeview widget. * - * \param tree the tree to update the owner of + * \param *redraw Pointer to Redraw Event block. */ -void tree_resized(struct tree *tree) + +void ro_treeview_redraw(wimp_draw *redraw) { - os_error *error; - wimp_window_state state; + osbool more; + os_error *error; + ro_treeview *tv; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(redraw->w); + if (tv == NULL) { + LOG(("NULL treeview block for window: 0x%x", + (unsigned int) redraw->w)); + /* Don't return, as not servicing redraw events isn't a good + * idea. The following code must handle (tv == NULL) + * gracefully while clearing the redraw queue. + */ + } - assert(tree->handle); + /* The scale can't be changed; it's always 1:1. */ + plot = ro_plotters; + ro_plot_set_scale(1.0); - state.w = (wimp_w)tree->handle; - error = xwimp_get_window_state(&state); + error = xwimp_redraw_window(redraw, &more); if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", + LOG(("xwimp_redraw_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); return; } - if (state.flags & wimp_WINDOW_OPEN) - ro_gui_tree_open(PTR_WIMP_OPEN(&state)); -} + ro_treeview_redraw_loop(redraw, tv, more); +} /** - * Redraws a tree window + * Redraw a treeview window, once the initial readraw block has been collected. * - * \param redraw the area to redraw - * \param tree the tree to redraw + * /param *redraw Pointer to redraw block. + * /param *tv The treeview object being redrawn. + * /param more Flag to show if more actions are required. */ -void ro_gui_tree_redraw(wimp_draw *redraw) -{ - struct tree *tree; - osbool more; - int clip_x0, clip_x1, clip_y0, clip_y1, origin_x, origin_y; - - tree = (struct tree *)ro_gui_wimp_event_get_user_data(redraw->w); - assert(tree); +void ro_treeview_redraw_loop(wimp_draw *redraw, ro_treeview *tv, osbool more) +{ + os_error *error; - more = wimp_redraw_window(redraw); while (more) { - clip_x0 = redraw->clip.x0; - clip_y0 = redraw->clip.y0; - clip_x1 = redraw->clip.x1; - clip_y1 = redraw->clip.y1; - origin_x = redraw->box.x0 - redraw->xscroll; - origin_y = redraw->box.y1 - redraw->yscroll; - if (tree->toolbar) - origin_y -= ro_gui_theme_toolbar_height(tree->toolbar); - tree_draw(tree, clip_x0 - origin_x - tree->offset_x, - origin_y - clip_y1 - tree->offset_y, - clip_x1 - clip_x0, clip_y1 - clip_y0); - more = wimp_get_rectangle(redraw); + ro_plot_origin_x = redraw->box.x0 - redraw->xscroll; + ro_plot_origin_y = redraw->box.y1 - redraw->yscroll; + + if (tv != NULL && tv->tree != NULL) { + tree_draw(tv->tree, tv->origin.x/2, -(tv->origin.y/2), + (redraw->clip.x0 + -(ro_plot_origin_x+tv->origin.x))/2, + ((ro_plot_origin_y+tv->origin.y) + -redraw->clip.y1)/2, + (redraw->clip.x1 - redraw->clip.x0)/2, + (redraw->clip.y1 - redraw->clip.y0)/2); + } + + error = xwimp_get_rectangle(redraw, &more); + if (error) { + LOG(("xwimp_redraw_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } } } - /** - * Handles a mouse click for a tree + * Callback to notify us of a new overall tree size. * - * \param pointer the pointer state - * \param tree the tree to handle a click for - * \return whether the click was handled + * \param tree The tree being resized. + * \param width The new width of the window. + * \param height The new height of the window. + * \param *pw The treeview object to be resized. */ -bool ro_gui_tree_click(wimp_pointer *pointer, struct tree *tree) -{ - bool furniture; - struct node *node; - struct node *last; - struct node_element *element; - int x, y; - int alt_pressed = 0; - wimp_window_state state; - wimp_caret caret; - wimp_drag drag; - wimp_auto_scroll_info scroll; - os_error *error; - os_box box = { pointer->pos.x - 34, pointer->pos.y - 34, - pointer->pos.x + 34, pointer->pos.y + 34 }; - - assert(tree); - assert(tree->root); - - /* gain the input focus when required */ - state.w = (wimp_w)tree->handle; - error = xwimp_get_window_state(&state); - if (error) - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - error = xwimp_get_caret_position(&caret); - if (error) - LOG(("xwimp_get_caret_position: 0x%x: %s", - error->errnum, error->errmess)); - if (((pointer->buttons == (wimp_CLICK_SELECT << 8)) || - (pointer->buttons == (wimp_CLICK_ADJUST << 8))) && - (caret.w != state.w)) { - error = xwimp_set_caret_position((wimp_w)tree->handle, -1, -100, - -100, 32, -1); - if (error) - LOG(("xwimp_set_caret_position: 0x%x: %s", - error->errnum, error->errmess)); - } - - if (!tree->root->child) - return true; - - tree_initialise_redraw(tree); - x = pointer->pos.x - ro_gui_tree_origin_x; - y = ro_gui_tree_origin_y - pointer->pos.y; - element = tree_get_node_element_at(tree->root->child, x, y, &furniture); +void ro_treeview_resized(struct tree *tree, int width, int height, + void *pw) +{ + if (pw != NULL) { + ro_treeview *tv = (ro_treeview *) pw; - /* stop editing for anything but a drag */ - if ((tree->editing) && (pointer->i != tree->edit_handle) && - (pointer->buttons != (wimp_CLICK_SELECT << 4))) - ro_gui_tree_stop_edit(tree); + /* Store the width and height in terms of RISC OS work area. */ - /* handle a menu click */ - if (pointer->buttons == wimp_CLICK_MENU) { - if ((!element) || (!tree->root->child) || - (tree_has_selection(tree->root->child))) - return true; + tv->size.x = width * 2; + tv->size.y = -(height * 2); - node = element->parent; - tree->temp_selection = node; - node->selected = true; - tree_handle_node_element_changed(tree, &node->data); - return true; + /* Resize the window. */ + ro_treeview_set_window_extent(tv, tv->size.x, tv->size.y); } +} - /* no item either means cancel selection on (select) click or a drag */ - if (!element) { - if (tree->single_selection) { - tree_set_node_selected(tree, tree->root->child, false); - return true; - } - if ((pointer->buttons == (wimp_CLICK_SELECT << 4)) || - (pointer->buttons == (wimp_CLICK_SELECT << 8))) - tree_set_node_selected(tree, tree->root->child, false); - if ((pointer->buttons == (wimp_CLICK_SELECT << 4)) || - (pointer->buttons == (wimp_CLICK_ADJUST << 4))) { - - scroll.w = (wimp_w)tree->handle; - scroll.pause_zone_sizes.y0 = 80; - scroll.pause_zone_sizes.y1 = 80; - if (tree->toolbar) - scroll.pause_zone_sizes.y1 += - ro_gui_theme_toolbar_height(tree->toolbar); - scroll.pause_duration = 0; - scroll.state_change = (void *)0; - error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL, - &scroll, 0); - if (error) - LOG(("xwimp_auto_scroll: 0x%x: %s", - error->errnum, error->errmess)); - - gui_current_drag_type = GUI_DRAG_TREE_SELECT; - ro_gui_tree_current_drag_tree = tree; - ro_gui_tree_current_drag_buttons = pointer->buttons; - - drag.w = (wimp_w)tree->handle; - drag.type = wimp_DRAG_USER_RUBBER; - drag.initial.x0 = pointer->pos.x; - drag.initial.x1 = pointer->pos.x; - drag.initial.y0 = pointer->pos.y; - drag.initial.y1 = pointer->pos.y; - drag.bbox.x0 = state.visible.x0; - drag.bbox.x1 = state.visible.x1; - drag.bbox.y0 = -16384;//state.visible.y0; - drag.bbox.y1 = 16384;//state.visible.y1 - tree->offset_y; - error = xwimp_drag_box_with_flags(&drag, - wimp_DRAG_BOX_KEEP_IN_LINE | - wimp_DRAG_BOX_CLIP); - if (error) - LOG(("xwimp_drag_box_with_flags: 0x%x: %s", - error->errnum, error->errmess)); +/** + * Callback to request that a section of the tree is scrolled into view. + * + * \param y The Y coordinate of top of the area in NS units. + * \param height The height of the area in NS units. + * \param *pw The treeview object affected. + */ +void ro_treeview_scroll_visible(int y, int height, void *pw) +{ + if (pw != NULL) { + ro_treeview *tv = (ro_treeview *) pw; + os_error *error; + wimp_window_state state; + int visible_t, visible_b; + int request_t, request_b; + + state.w = tv->w; + 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; } - return true; - } - node = element->parent; - - /* click on furniture or double click on folder toggles node expansion */ - if (((furniture) && ((pointer->buttons == wimp_CLICK_SELECT << 8) || - (pointer->buttons == wimp_CLICK_ADJUST << 8) || - (pointer->buttons == wimp_CLICK_SELECT) || - (pointer->buttons == wimp_CLICK_ADJUST))) || - ((!furniture) && (node->child) && - ((pointer->buttons == wimp_CLICK_SELECT) || - (pointer->buttons == wimp_CLICK_ADJUST)))) { - node->expanded = !node->expanded; - if (!furniture) - node->selected = false; - tree_handle_node_changed(tree, node, false, true); - - /* find the last child node if expanded */ - last = node; - if ((last->child) && (last->expanded)) { - last = last->child; - while ((last->next) || ((last->child) && (last->expanded))) { - if (last->next) - last = last->next; - else - last = last->child; - } - } - /* scroll to the bottom element then back to the top */ - element = &last->data; - if (last->expanded) - for (; element->next; element = element->next); - ro_gui_tree_scroll_visible(tree, element); - ro_gui_tree_scroll_visible(tree, &node->data); - return true; - } + /* Work out top and bottom of both the currently visible and + * the required areas, in terms of the RO work area. + */ - /* no use for any other furniture click */ - if (furniture) - return true; - - /* single/double alt+click starts editing */ - if ((node->editable) && (!tree->editing) && - ((element->data == TREE_ELEMENT_URL) || - (element->data == TREE_ELEMENT_TITLE)) && - ((pointer->buttons == wimp_CLICK_SELECT) || - (pointer->buttons == (wimp_CLICK_SELECT << 8)))) { - xosbyte1(osbyte_SCAN_KEYBOARD, 2 ^ 0x80, 0, &alt_pressed); - if (alt_pressed == 0xff) { - ro_gui_tree_start_edit(tree, element, pointer); - return true; - } - } + visible_t = state.yscroll; + visible_b = state.yscroll + - (state.visible.y1 - state.visible.y0); - /* double click starts launches the leaf */ - if ((pointer->buttons == wimp_CLICK_SELECT) || - (pointer->buttons == wimp_CLICK_ADJUST)) { - if (!ro_gui_tree_launch_node(tree, node)) - return false; - if (pointer->buttons == wimp_CLICK_ADJUST) - ro_gui_dialog_close((wimp_w)tree->handle); - return true; - } + request_t = -(2 * y);// - tv->origin.y; + request_b = -(2 * (y + height));// - tv->origin.y; - /* single click (select) cancels current selection and selects item */ - if ((pointer->buttons == (wimp_CLICK_SELECT << 8)) || - ((pointer->buttons == (wimp_CLICK_ADJUST << 8)) && - (tree->single_selection))) { - if (!node->selected) { - tree_set_node_selected(tree, tree->root->child, false); - node->selected = true; - tree_handle_node_element_changed(tree, &node->data); - } - return true; - } + /* If the area is outside the visible window, then scroll it + * in to view. + */ - /* single click (adjust) toggles item selection */ - if (pointer->buttons == (wimp_CLICK_ADJUST << 8)) { - node->selected = !node->selected; - tree_handle_node_element_changed(tree, &node->data); - return true; - } + if (request_t > visible_t || request_b < visible_b) { + if (request_t > visible_t) { + state.yscroll = request_t; + } else if (request_b < visible_b) { + state.yscroll = request_b + tv->origin.y + + (state.visible.y1 - state.visible.y0); - /* drag starts a drag operation */ - if ((!tree->editing) && ((pointer->buttons == (wimp_CLICK_SELECT << 4)) || - (pointer->buttons == (wimp_CLICK_ADJUST << 4)))) { - if (tree->no_drag) - return true; + /* If the required area is bigger than the + * visible extent, then align to the top and + * let the bottom disappear out of view. + */ - if (!node->selected) { - node->selected = true; - tree_handle_node_element_changed(tree, &node->data); - } + if (state.yscroll < request_t) + state.yscroll = request_t; + } - scroll.w = (wimp_w)tree->handle; - scroll.pause_zone_sizes.y0 = 80; - scroll.pause_zone_sizes.y1 = 80; - if (tree->toolbar) - scroll.pause_zone_sizes.y1 += - ro_gui_theme_toolbar_height(tree->toolbar); - scroll.pause_duration = -1; - scroll.state_change = (void *)0; - error = xwimp_auto_scroll(wimp_AUTO_SCROLL_ENABLE_VERTICAL, - &scroll, 0); - if (error) - LOG(("xwimp_auto_scroll: 0x%x: %s", - error->errnum, error->errmess)); - - gui_current_drag_type = GUI_DRAG_TREE_MOVE; - ro_gui_tree_current_drag_tree = tree; - ro_gui_tree_current_drag_buttons = pointer->buttons; - - node = tree_get_selected_node(tree->root); - if (node) { - if (node->folder) { - if ((node->expanded) && - (ro_gui_wimp_sprite_exists("directoryo"))) - sprintf(ro_gui_tree_drag_name, "directoryo"); - else - sprintf(ro_gui_tree_drag_name, "directory"); - } else { - /* small_xxx -> file_xxx */ - sprintf(ro_gui_tree_drag_name, "file_%s", - node->data.sprite->name + 6); - if (!ro_gui_wimp_sprite_exists(ro_gui_tree_drag_name)) - sprintf(ro_gui_tree_drag_name, "file_xxx"); + 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; } - } else { - sprintf(ro_gui_tree_drag_name, "package"); } - - error = xdragasprite_start(dragasprite_HPOS_CENTRE | - dragasprite_VPOS_CENTRE | - dragasprite_BOUND_POINTER | - dragasprite_DROP_SHADOW, - (osspriteop_area *) 1, - ro_gui_tree_drag_name, &box, 0); - if (error) - LOG(("xdragasprite_start: 0x%x: %s", - error->errnum, error->errmess)); - return true; } - - - return false; } - /** - * Handles a menu closed event + * Callback to return the tree window dimensions to the treeview system. * - * \param tree the tree to handle the event for + * \param *width Return the window width. + * \param *height Return the window height. + * \param *pw The treeview object to use. */ -void ro_gui_tree_menu_closed(struct tree *tree) + +void ro_treeview_get_window_dimensions(int *width, int *height, + void *pw) { - assert(tree); - - if (tree->temp_selection) { - tree->temp_selection->selected = false; - tree_handle_node_element_changed(tree, &tree->temp_selection->data); - tree->temp_selection = NULL; - ro_gui_menu_prepare_action((wimp_w)tree->handle, TREE_SELECTION, false); - ro_gui_menu_prepare_action((wimp_w)tree->handle, TREE_EXPAND_ALL, false); + if (pw != NULL && (width != NULL || height != NULL)) { + ro_treeview *tv = (ro_treeview *) pw; + os_error *error; + wimp_window_state state; + + state.w = tv->w; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_info_header_only: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + + if (width != NULL) + *width = (state.visible.x1 - state.visible.x0) / 2; + + if (height != NULL) + *height = (state.visible.y1 - state.visible.y0) / 2; } } - /** - * Respond to a mouse click for a tree (hotlist or history) toolbar + * Resize the RISC OS window extent of a treeview. * - * \param pointer the pointer state + * \param *tv The RISC OS treeview object to resize. + * \param width The new width of the work area, in RO units. + * \param height The new height of the work area, in RO units. */ -bool ro_gui_tree_toolbar_click(wimp_pointer* pointer) + +void ro_treeview_set_window_extent(ro_treeview *tv, int width, int height) { - struct node *node; + if (tv != NULL) { + os_error *error; + os_box extent; + wimp_window_state state; + int new_x, new_y; + int visible_x, visible_y; + int new_x_scroll, new_y_scroll; - struct toolbar *toolbar = - (struct toolbar *)ro_gui_wimp_event_get_user_data(pointer->w); - assert(toolbar); - struct tree *tree = - (struct tree *)ro_gui_wimp_event_get_user_data(toolbar->parent_handle); - assert(tree); + /* Calculate the new window extents, in RISC OS units. */ - ro_gui_tree_stop_edit(tree); + new_x = width + tv->origin.x; + new_y = height + tv->origin.y; - if (pointer->buttons == wimp_CLICK_MENU) { - ro_gui_menu_create(tree_toolbar_menu, pointer->pos.x, - pointer->pos.y, (wimp_w)tree->handle); - return true; - } + /* Get details of the existing window, and start to sanity + * check the new extents. + */ - if (tree->toolbar->editor) { - ro_gui_theme_toolbar_editor_click(tree->toolbar, pointer); - return true; - } + state.w = tv->w; + 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; + } - switch (pointer->i) { - case ICON_TOOLBAR_CREATE: - node = tree_create_folder_node(tree->root, - messages_get("TreeNewFolder")); - tree_redraw_area(tree, node->box.x - NODE_INSTEP, - 0, NODE_INSTEP, 16384); - tree_handle_node_changed(tree, node, false, true); - ro_gui_tree_start_edit(tree, &node->data, NULL); - break; - case ICON_TOOLBAR_OPEN: - tree_handle_expansion(tree, tree->root, - (pointer->buttons == wimp_CLICK_SELECT), - true, false); - break; - case ICON_TOOLBAR_EXPAND: - tree_handle_expansion(tree, tree->root, - (pointer->buttons == wimp_CLICK_SELECT), - false, true); - break; - case ICON_TOOLBAR_DELETE: - ro_gui_menu_handle_action((wimp_w)tree->handle, - TREE_SELECTION_DELETE, false); - break; - case ICON_TOOLBAR_LAUNCH: - ro_gui_menu_handle_action((wimp_w)tree->handle, - TREE_SELECTION_LAUNCH, false); - break; - } - return true; -} + /* If the extent is smaller than the current visible area, + * then extend it so that it matches the visible area. + */ + if (new_x < (state.visible.x1 - state.visible.x0)) + new_x = state.visible.x1 - state.visible.x0; -/** - * Starts an editing session - * - * \param tree the tree to start editing for - * \param element the element to edit - * \param pointer the pointer data to use for caret positioning (or NULL) - */ -void ro_gui_tree_start_edit(struct tree *tree, struct node_element *element, - wimp_pointer *pointer) -{ - os_error *error; - struct node *parent; - int toolbar_height = 0; - - assert(tree); - assert(element); - - if (tree->editing) - ro_gui_tree_stop_edit(tree); - if (tree->toolbar) - toolbar_height = ro_gui_theme_toolbar_height(tree->toolbar); - - parent = element->parent; - if (&parent->data == element) - parent = parent->parent; - for (; parent; parent = parent->parent) { - if (!parent->expanded) { - parent->expanded = true; - tree_handle_node_changed(tree, parent, false, true); - } - } + if (new_y > (state.visible.y0 - state.visible.y1)) + new_y = state.visible.y0 - state.visible.y1; - tree->editing = element; - ro_gui_tree_edit_icon.w = (wimp_w)tree->handle; - ro_gui_tree_edit_icon.icon.extent.x0 = tree->offset_x + element->box.x - 2; - ro_gui_tree_edit_icon.icon.extent.x1 = tree->offset_x + - element->box.x + element->box.width + 2; - ro_gui_tree_edit_icon.icon.extent.y1 = -tree->offset_y - toolbar_height - - element->box.y; - ro_gui_tree_edit_icon.icon.extent.y0 = -tree->offset_y - toolbar_height - - element->box.y - element->box.height; - if (element->type == NODE_ELEMENT_TEXT_PLUS_SPRITE) - ro_gui_tree_edit_icon.icon.extent.x0 += NODE_INSTEP; - ro_gui_tree_edit_icon.icon.data.indirected_text.text = - (char *) element->text; - error = xwimp_create_icon(&ro_gui_tree_edit_icon, - (wimp_i *)&tree->edit_handle); - if (error) - LOG(("xwimp_create_icon: 0x%x: %s", - error->errnum, error->errmess)); + /* Calculate the maximum visible coordinates of the existing + * window. + */ - tree->textarea_handle = ro_textarea_create((wimp_w)tree->handle, - (wimp_i)tree->edit_handle, 0, ro_gui_desktop_font_family, - ro_gui_desktop_font_size, - ro_gui_desktop_font_style); - if (!tree->textarea_handle) { - ro_gui_tree_stop_edit(tree); - return; - } - ro_textarea_set_text(tree->textarea_handle, element->text); - if (pointer) - ro_textarea_set_caret_xy(tree->textarea_handle, - pointer->pos.x, pointer->pos.y); - else - ro_textarea_set_caret(tree->textarea_handle, - strlen(element->text)); + visible_x = state.xscroll + + (state.visible.x1 - state.visible.x0); + visible_y = state.yscroll + + (state.visible.y0 - state.visible.y1); - tree_handle_node_element_changed(tree, element); - ro_gui_tree_scroll_visible(tree, element); -} + /* If the window is currently open, and the exising visible + * area is bigger than the new extent, then we need to reopen + * the window in an appropriare position before setting the + * new extent. + */ + if ((state.flags & wimp_WINDOW_OPEN) && + (visible_x > new_x || visible_y < new_y)) { + new_x_scroll = state.xscroll; + new_y_scroll = state.yscroll; -/** - * Stops any current editing session - * - * \param tree the tree to stop editing for - */ -void ro_gui_tree_stop_edit(struct tree *tree) -{ - os_error *error; + if (visible_x > new_x) + new_x_scroll = new_x - (state.visible.x1 + - state.visible.x0); - assert(tree); + if (visible_y < new_y) + new_y_scroll = new_y - (state.visible.y0 + - state.visible.y1); - if (!tree->editing) return; + if (new_x_scroll < 0) { + state.visible.x1 -= new_x_scroll; + state.xscroll = 0; + } else { + state.xscroll = new_x_scroll; + } - if (tree->textarea_handle) { - ro_textarea_destroy(tree->textarea_handle); - tree->textarea_handle = 0; - } - error = xwimp_delete_icon((wimp_w)tree->handle, (wimp_i)tree->edit_handle); - if (error) - LOG(("xwimp_delete_icon: 0x%x: %s", - error->errnum, error->errmess)); - tree_handle_node_element_changed(tree, tree->editing); - tree->editing = NULL; - - error = xwimp_set_caret_position((wimp_w)tree->handle, -1, -100, - -100, 32, -1); - if (error) - LOG(("xwimp_set_caret_position: 0x%x: %s", - error->errnum, error->errmess)); - tree_recalculate_size(tree); -} + if (new_y_scroll > 0) { + state.visible.y0 += new_y_scroll; + state.yscroll = 0; + } else { + state.yscroll = new_y_scroll; + } + error = xwimp_open_window((wimp_open *) &state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } -/** - * Scrolls the tree to make an element visible - * - * \param tree the tree to scroll - * \param element the element to display - */ -void ro_gui_tree_scroll_visible(struct tree *tree, struct node_element *element) -{ - wimp_window_state state; - int x0, x1, y0, y1; - os_error *error; - int toolbar_height = 0; + /* \todo -- Not sure if we need to reattach the + * toolbar here: the nested wimp seems to take care + * of it for us? + */ + } - assert(element); + /* Now that the new extent fits into the visible window, we + * can resize the work area. If we succeed, the values are + * recorded to save having to ask the Wimp for them + * each time. + */ - if (tree->toolbar) - toolbar_height = ro_gui_theme_toolbar_height(tree->toolbar); + extent.x0 = 0; + extent.y0 = new_y; + extent.x1 = new_x; + extent.y1 = 0; - state.w = (wimp_w)tree->handle; - error = xwimp_get_window_state(&state); - if (error) - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - if (!(state.flags & wimp_WINDOW_OPEN)) - return; - x0 = state.xscroll; - y0 = -state.yscroll; - x1 = x0 + state.visible.x1 - state.visible.x0 - tree->offset_x; - y1 = y0 - state.visible.y0 + state.visible.y1 - tree->offset_y - toolbar_height; - - state.yscroll = state.visible.y1 - state.visible.y0 - tree->offset_y - - toolbar_height - y1; - if ((element->box.y >= y0) && (element->box.y + element->box.height <= y1)) - return; - if (element->box.y < y0) - state.yscroll = -element->box.y; - if (element->box.y + element->box.height > y1) - state.yscroll = state.visible.y1 - state.visible.y0 - - tree->offset_y - toolbar_height - - (element->box.y + element->box.height); - ro_gui_tree_open(PTR_WIMP_OPEN(&state)); -} + error = xwimp_set_extent(tv->w, &extent); + if (error) { + LOG(("xwimp_set_extent: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + tv->extent.x = new_x; + tv->extent.y = new_y; + } +} /** - * Shows the a tree window. + * Handle RISC OS Window Open events for a treeview window. + * + * \param *open Pointer to the Window Open Event block. */ -void ro_gui_tree_show(struct tree *tree) + +static void ro_treeview_open(wimp_open *open) { - struct toolbar *toolbar; - - /* we may have failed to initialise */ - if (!tree) return; - toolbar = tree->toolbar; - - /* handle first time opening */ - if (!ro_gui_dialog_open_top((wimp_w)tree->handle, toolbar, 600, 800)) { - ro_gui_tree_stop_edit(tree); - if (tree->root->child) { - tree_set_node_selected(tree, tree->root, false); - tree_handle_node_changed(tree, tree->root, - false, true); - } + ro_treeview *tv; + os_error *error; + os_box extent; + int width, height; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(open->w); + if (tv == NULL) { + LOG(("NULL treeview block for window: ox%x", + (unsigned int) open->w)); + return; } - /* set the caret position */ - xwimp_set_caret_position((wimp_w)tree->handle, -1, -100, -100, 32, -1); -} + /* Calculate the window work area. It must be at least the same as + * the current visible area of the window, and needs to contain the + * tree as defined by size.x + offset.x and size.y + offset.y (note + * that the offset.y should be set to cover any toolbar, so we can + * ignore the size of that). + */ + width = open->visible.x1 - open->visible.x0; + height = open->visible.y0 - open->visible.y1; -/** - * Handles a window open request - * - * \param open the window state - */ -void ro_gui_tree_open(wimp_open *open) -{ - struct tree *tree; - os_error *error; - int width; - int height; - int toolbar_height = 0; - bool vscroll; + if (tv->size.x != 0 && width < (tv->origin.x + tv->size.x)) + width = (tv->origin.x + tv->size.x); - tree = (struct tree *)ro_gui_wimp_event_get_user_data(open->w); + if (tv->size.y != 0 && height > (tv->size.y + tv->origin.y)) + height = (tv->size.y + tv->origin.y); - if (!tree) - return; - if (tree->toolbar) - toolbar_height = ro_gui_theme_toolbar_height(tree->toolbar); + if (width != tv->extent.x || height != tv->extent.y) { + extent.x0 = 0; + extent.y0 = height; + extent.x1 = width; + extent.y1 = 0; - width = open->visible.x1 - open->visible.x0; - if (width < (tree->offset_x + tree->width)) - width = tree->offset_x + tree->width; - height = open->visible.y1 - open->visible.y0; - if (height < (tree->offset_y + toolbar_height + tree->height)) - height = tree->offset_y + toolbar_height + tree->height; - - if ((height != tree->window_height) || (width != tree->window_width)) { - os_box extent = { 0, -height, width, 0}; - error = xwimp_set_extent((wimp_w)tree->handle, &extent); + error = xwimp_set_extent(tv->w, &extent); if (error) { LOG(("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); + return; } - /* hide the scroll bar? */ - if ((tree->no_vscroll) && (height != tree->window_height)) { - vscroll = (tree->height > height); - if (ro_gui_wimp_check_window_furniture(open->w, - wimp_WINDOW_VSCROLL) != vscroll) { - ro_gui_wimp_update_window_furniture(open->w, - 0, wimp_WINDOW_VSCROLL); - if (vscroll) - open->visible.x1 -= ro_get_vscroll_width(open->w); - else - open->visible.x1 += ro_get_vscroll_width(open->w); - } - } - - tree->window_width = width; - tree->window_height = height; + tv->extent.x = width; + tv->extent.y = height; } + /* \todo -- Might need to add vertical scrollbar hiding back in here? */ + error = xwimp_open_window(open); if (error) { LOG(("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); } - if (tree->toolbar) - ro_gui_theme_process_toolbar(tree->toolbar, -1); - ro_gui_menu_prepare_action((wimp_w)tree->handle, TREE_SELECTION, false); - ro_gui_menu_prepare_action((wimp_w)tree->handle, TREE_EXPAND_ALL, false); + + if (tv->tb) + ro_gui_theme_process_toolbar(tv->tb, -1); } /** - * Handles a keypress for a tree + * Pass RISC OS Mouse Click events on to the treeview widget. * - * \param key the key pressed - * \param tree the tree to handle a keypress for - * \return whether the key was processed + * \param *pointer Pointer to the Mouse Click Event block. + * \return Return true if click handled; else false. */ -bool ro_gui_tree_keypress(wimp_key *key) + +static bool ro_treeview_mouse_click(wimp_pointer *pointer) { - wimp_window_state state; - int y; - char *new_string; - struct tree *tree; - int strlen; - os_error *error; - - tree = (struct tree *)ro_gui_wimp_event_get_user_data(key->w); - if (!tree) + os_error *error; + ro_treeview *tv; + wimp_window_state state; + int xpos, ypos; + browser_mouse_state mouse; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); + if (tv == NULL) { + LOG(("NULL treeview block for window: 0x%x", + (unsigned int) pointer->w)); return false; - - /* Handle basic keys - */ - switch (key->c) { - case 1: /* CTRL+A */ - ro_gui_menu_handle_action((wimp_w)tree->handle, - TREE_SELECT_ALL, false); - return true; - case 24: /* CTRL+X */ - ro_gui_menu_handle_action((wimp_w)tree->handle, - TREE_SELECTION_DELETE, false); - return true; - case 26: /* CTRL+Z */ - ro_gui_menu_handle_action((wimp_w)tree->handle, - TREE_CLEAR_SELECTION, false); - return true; - case wimp_KEY_RETURN: - if ((tree->editing) && (tree->textarea_handle)) { - strlen = ro_textarea_get_text( - tree->textarea_handle, - NULL, 0); - if (strlen == -1) { - ro_gui_tree_stop_edit(tree); - return true; - } - new_string = malloc(strlen); - if (!new_string) { - ro_gui_tree_stop_edit(tree); - LOG(("No memory for malloc()")); - warn_user("NoMemory", 0); - return true; - } - ro_textarea_get_text(tree->textarea_handle, - new_string, strlen); - free((void *)tree->editing->text); - tree->editing->text = new_string; - ro_gui_tree_stop_edit(tree); - tree_recalculate_size(tree); - } else { - ro_gui_tree_launch_selected(tree); - } - return true; - case wimp_KEY_ESCAPE: - if (tree->editing) { - ro_gui_tree_stop_edit(tree); - } else { - /* \todo cancel drags etc. */ - } - return true; - - case IS_WIMP_KEY | wimp_KEY_UP: - case IS_WIMP_KEY | wimp_KEY_DOWN: - case IS_WIMP_KEY | wimp_KEY_PAGE_UP: - case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: - case IS_WIMP_KEY | wimp_KEY_HOME: - case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP: - case IS_WIMP_KEY | wimp_KEY_END: - case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: - break; - default: - return false; } - /* keyboard scrolling */ - state.w = (wimp_w)tree->handle; + state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", error->errnum, error->errmess)); - return true; + warn_user("WimpError", error->errmess); + return false; } - y = state.visible.y1 - state.visible.y0 - TREE_TEXT_HEIGHT; - if (tree->toolbar) - y -= ro_gui_theme_toolbar_full_height(tree->toolbar); + /* Convert the returned mouse coordinates into NetSurf's internal + * units. + */ - switch (key->c) { - case IS_WIMP_KEY | wimp_KEY_UP: -/* if ((state.yscroll % TREE_TEXT_HEIGHT) != 0) - state.yscroll -= (state.yscroll % TREE_TEXT_HEIGHT); - else -*/ state.yscroll += TREE_TEXT_HEIGHT; - break; - case IS_WIMP_KEY | wimp_KEY_DOWN: -/* if (((state.yscroll + y) % TREE_TEXT_HEIGHT) != 0) - state.yscroll -= ((state.yscroll + y) % TREE_TEXT_HEIGHT); - else -*/ state.yscroll -= TREE_TEXT_HEIGHT; - break; - case IS_WIMP_KEY | wimp_KEY_PAGE_UP: - state.yscroll += y; - break; - case IS_WIMP_KEY | wimp_KEY_PAGE_DOWN: - state.yscroll -= y; - break; - case IS_WIMP_KEY | wimp_KEY_HOME: - case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_UP: - state.yscroll = 0x10000000; - break; - case IS_WIMP_KEY | wimp_KEY_END: - case IS_WIMP_KEY | wimp_KEY_CONTROL | wimp_KEY_DOWN: - state.yscroll = -0x10000000; - break; - } + xpos = ((pointer->pos.x - state.visible.x0) + + state.xscroll - tv->origin.x) / 2; + ypos = ((state.visible.y1 - pointer->pos.y) - + state.yscroll + tv->origin.y) / 2; - error = xwimp_open_window(PTR_WIMP_OPEN(&state)); - if (error) { - LOG(("xwimp_open_window: 0x%x: %s", - error->errnum, error->errmess)); + /* Start to process the mouse click. + * + * Select and Adjust are processed normally. To get filer-like operation + * with selections, Menu clicks are passed to the treeview first as + * Select if there are no selected nodes in the tree. + */ + + mouse = 0; + + if (pointer->buttons == wimp_CLICK_MENU) { + if (!tree_node_has_selection(tree_get_root(tv->tree))) + mouse |= BROWSER_MOUSE_CLICK_1; + } else { + mouse = ro_gui_mouse_click_state(pointer->buttons, + wimp_BUTTON_DOUBLE_CLICK_DRAG); + + /* Record drag start */ + if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) { + tv->drag_start.x = xpos; + tv->drag_start.y = ypos; + tv->drag = true; + } + + if (mouse & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_MOD_2)) + xwimp_set_caret_position(tv->w, -1, -100, -100, 32, -1); } + if (mouse != 0) + tree_mouse_action(tv->tree, mouse, xpos, ypos); + + /* We assume that the owning module will have attached a window menu + * to our parent window. If it hasn't, this call will quietly fail. + */ + + if (pointer->buttons == wimp_CLICK_MENU) + ro_gui_wimp_event_process_window_menu_click(pointer); + return true; } - /** - * Handles the completion of a selection drag (GUI_DRAG_TREE_SELECT) + * Track the mouse under Null Polls from the wimp, to support dragging. * - * \param drag the drag box information + * \param w Window handle currently under the mouse. + * \param *pointer Pointer to a Wimp Pointer block. */ -void ro_gui_tree_selection_drag_end(wimp_dragged *drag) + +void ro_treeview_mouse_at(wimp_w w, wimp_pointer *pointer) { - wimp_window_state state; - wimp_auto_scroll_info scroll; - os_error *error; - int x0, y0, x1, y1; - int toolbar_height = 0; - - if (ro_gui_tree_current_drag_tree->toolbar) - toolbar_height = ro_gui_theme_toolbar_height( - ro_gui_tree_current_drag_tree->toolbar); - - scroll.w = (wimp_w)ro_gui_tree_current_drag_tree->handle; - error = xwimp_auto_scroll(0, &scroll, 0); - if (error) - LOG(("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess)); - - state.w = (wimp_w)ro_gui_tree_current_drag_tree->handle; + os_error *error; + ro_treeview *tv; + wimp_window_state state; + int xpos, ypos; + browser_mouse_state mouse; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(pointer->w); + if (tv == NULL) { + LOG(("NULL treeview block for window: 0x%x", + (unsigned int) pointer->w)); + return; + } + + state.w = tv->w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", @@ -1437,177 +809,177 @@ void ro_gui_tree_selection_drag_end(wimp_dragged *drag) return; } - x0 = drag->final.x0 - state.visible.x0 - state.xscroll + - ro_gui_tree_current_drag_tree->offset_x; - y0 = state.visible.y1 - state.yscroll - drag->final.y0 - - ro_gui_tree_current_drag_tree->offset_y - toolbar_height; - x1 = drag->final.x1 - state.visible.x0 - state.xscroll + - ro_gui_tree_current_drag_tree->offset_x; - y1 = state.visible.y1 - state.yscroll - drag->final.y1 - - ro_gui_tree_current_drag_tree->offset_y - toolbar_height; - tree_handle_selection_area(ro_gui_tree_current_drag_tree, x0, y0, - x1 - x0, y1 - y0, - (ro_gui_tree_current_drag_buttons == (wimp_CLICK_ADJUST << 4))); - ro_gui_menu_prepare_action((wimp_w)ro_gui_tree_current_drag_tree->handle, - TREE_SELECTION, false); - ro_gui_menu_prepare_action((wimp_w)ro_gui_tree_current_drag_tree->handle, - TREE_EXPAND_ALL, false); -} + /* Convert the returned mouse coordinates into NetSurf's internal + * units. + */ + xpos = ((pointer->pos.x - state.visible.x0) + + state.xscroll - tv->origin.x) / 2; + ypos = ((state.visible.y1 - pointer->pos.y) - + state.yscroll + tv->origin.y) / 2; -/** - * Converts screen co-ordinates to tree ones - * - * \param tree the tree to calculate for - * \param x the screen x co-ordinate - * \param x the screen y co-ordinate - * \param tree_x updated to the tree x co-ordinate - * \param tree_y updated to the tree y co-ordinate - */ -void ro_gui_tree_get_tree_coordinates(struct tree *tree, int x, int y, - int *tree_x, int *tree_y) { - wimp_window_state state; - os_error *error; + /* Start to process the mouse click. */ + + mouse = 0; + + if (!(pointer->buttons & (wimp_CLICK_MENU))) { + mouse = ro_gui_mouse_drag_state(pointer->buttons, + wimp_BUTTON_DOUBLE_CLICK_DRAG); + if (mouse != 0) + tree_mouse_action(tv->tree, mouse, xpos, ypos); + + /* Check if drag ended and tell core */ + if (tv->drag && !(mouse & BROWSER_MOUSE_DRAG_ON)) { + tree_drag_end(tv->tree, mouse, tv->drag_start.x, + tv->drag_start.y, xpos, ypos); + tv->drag = false; + } - state.w = (wimp_w)tree->handle; - 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; } - *tree_x = x - state.visible.x0 - state.xscroll + tree->offset_x; - *tree_y = state.visible.y1 - state.yscroll - y - tree->offset_y; - if (tree->toolbar) - *tree_y -= ro_gui_theme_toolbar_height(tree->toolbar); } - /** - * Handles the completion of a move drag (GUI_DRAG_TREE_MOVE) + * Pass RISC OS keypress events on to the treeview widget. * - * \param drag the drag box information + * \param *key Pointer to the Key Pressed Event block. + * \return Return true if keypress handled; else false. */ -void ro_gui_tree_move_drag_end(wimp_dragged *drag) + +static bool ro_treeview_keypress(wimp_key *key) { - struct gui_window *g; - wimp_pointer pointer; - wimp_auto_scroll_info scroll; - os_error *error; - struct node *node; - struct node *single; - struct node_element *element; - bool before; - int x, y; - - scroll.w = (wimp_w)ro_gui_tree_current_drag_tree->handle; - error = xwimp_auto_scroll(0, &scroll, 0); - if (error) - LOG(("xwimp_auto_scroll: 0x%x: %s", error->errnum, error->errmess)); - - error = xwimp_get_pointer_info(&pointer); - if (error) { - LOG(("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - return; + ro_treeview *tv; + uint32_t c; + + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(key->w); + if (tv == NULL) { + LOG(("NULL treeview block for window: 0x%x", + (unsigned int) key->w)); + return false; } - if (pointer.w != (wimp_w)ro_gui_tree_current_drag_tree->handle) { - /* try to drop into a browser window */ - single = tree_get_selected_node(ro_gui_tree_current_drag_tree->root->child); - element = tree_find_element(single, TREE_ELEMENT_URL); - if (!element) - return; - if (single) { - /* \todo:send datasave for element */ - g = ro_gui_window_lookup(pointer.w); - if (g) - browser_window_go(g->bw, element->text, 0, true); - return; - } else { - /* \todo:update save.c to handle multiple concurrent saves */ + c = (uint32_t) key->c; + + if ((unsigned)c < 0x20 || (0x7f <= c && c <= 0x9f) || + (c & IS_WIMP_KEY)) { + /* Munge control keys into unused control chars */ + /* We can't map onto 1->26 (reserved for ctrl+ + That leaves 27->31 and 128->159 */ + switch (c & ~IS_WIMP_KEY) { + case wimp_KEY_TAB: c = 9; break; + case wimp_KEY_SHIFT | wimp_KEY_TAB: c = 11; break; + + /* cursor movement keys */ + case wimp_KEY_HOME: + case wimp_KEY_CONTROL | wimp_KEY_LEFT: + c = KEY_LINE_START; + break; + case wimp_KEY_END: + if (os_version >= RISCOS5) + c = KEY_LINE_END; + else + c = KEY_DELETE_RIGHT; + break; + case wimp_KEY_CONTROL | wimp_KEY_RIGHT: c = KEY_LINE_END; break; + case wimp_KEY_CONTROL | wimp_KEY_UP: c = KEY_TEXT_START; break; + case wimp_KEY_CONTROL | wimp_KEY_DOWN: c = KEY_TEXT_END; break; + case wimp_KEY_SHIFT | wimp_KEY_LEFT: c = KEY_WORD_LEFT ; break; + case wimp_KEY_SHIFT | wimp_KEY_RIGHT: c = KEY_WORD_RIGHT; break; + case wimp_KEY_SHIFT | wimp_KEY_UP: c = KEY_PAGE_UP; break; + case wimp_KEY_SHIFT | wimp_KEY_DOWN: c = KEY_PAGE_DOWN; break; + case wimp_KEY_LEFT: c = KEY_LEFT; break; + case wimp_KEY_RIGHT: c = KEY_RIGHT; break; + case wimp_KEY_UP: c = KEY_UP; break; + case wimp_KEY_DOWN: c = KEY_DOWN; break; + + /* editing */ + case wimp_KEY_CONTROL | wimp_KEY_END: + c = KEY_DELETE_LINE_END; + break; + case wimp_KEY_DELETE: + if (ro_gui_ctrl_pressed()) + c = KEY_DELETE_LINE_START; + else if (os_version < RISCOS5) + c = KEY_DELETE_LEFT; + break; + + default: + break; } - return; } - /* internal drag */ - if (!ro_gui_tree_current_drag_tree->movable) - return; - ro_gui_tree_get_tree_coordinates(ro_gui_tree_current_drag_tree, - drag->final.x0 + 34, drag->final.y0 + 34, &x, &y); - node = tree_get_link_details(ro_gui_tree_current_drag_tree, x, y, &before); - tree_move_selected_nodes(ro_gui_tree_current_drag_tree, node, before); -} + if (!(c & IS_WIMP_KEY)) { + if (tree_keypress(tv->tree, c)) + return true; + } + return false; +} -/** - * Launches all selected nodes. +/** Respond to a mouse click on a treeview toolbar. * - * \param tree the tree to launch all selected nodes for + * \param pointer Pointer to the MouseClick Event block. + * \return true if the event was handled; else false. */ -void ro_gui_tree_launch_selected(struct tree *tree) + +bool ro_gui_treeview_toolbar_click(wimp_pointer *pointer) { - assert(tree); + struct toolbar *tb; + ro_treeview *tv; - if (tree->root->child) - ro_gui_tree_launch_selected_node(tree, tree->root->child, false); -} + tb = (struct toolbar *) ro_gui_wimp_event_get_user_data(pointer->w); + if (tb == NULL) { + LOG(("NULL toolbar block for window: 0x%x", + (unsigned int) pointer->w)); + return false; + } + tv = (ro_treeview *) ro_gui_wimp_event_get_user_data(tb->parent_handle); + if (tv == NULL) { + LOG(("NULL treeview block for parent window: 0x%x", + (unsigned int) tb->parent_handle)); + return false; + } + + /* \todo -- Handle menu clicks here... */ + + /* \todo -- Deal with the editor here... */ + + switch (pointer->i) { -/** - * Launches all selected nodes. - * - * \param node the node to launch all selected nodes for - */ -void ro_gui_tree_launch_selected_node(struct tree *tree, struct node *node, - bool all) -{ - for (; node; node = node->next) { - if (((node->selected) || (all)) && (!node->folder)) - ro_gui_tree_launch_node(tree, node); - if ((node->child) && ((node->expanded) || (node->selected) | (all))) - ro_gui_tree_launch_selected_node(tree, node->child, - (node->selected) | (all)); } -} + return true; +} /** - * Launches a node using all known methods. + * Update a treeview to use a new theme. * - * \param node the node to launch - * \return whether the node could be launched + * \param *tv Pointer to the treeview to update. */ -bool ro_gui_tree_launch_node(struct tree *tree, struct node *node) + +void ro_treeview_update_theme(ro_treeview *tv) { - struct node_element *element; + if (tv != NULL && tv->tb != NULL){ + /* \todo -- Check for toolbar editing here. */ - assert(node); + if (!ro_gui_theme_update_toolbar(NULL, tv->tb)) { + ro_gui_theme_destroy_toolbar(tv->tb); + tv->tb = NULL; + } - element = tree_find_element(node, TREE_ELEMENT_URL); - if (element) { - browser_window_create(element->text, NULL, 0, true, false); - return true; - } + /* \todo -- Check for toolbar editing here. */ - element = tree_find_element(node, TREE_ELEMENT_SSL); - if (element) { - ro_gui_cert_open(tree, node); - return true; - } + ro_gui_theme_attach_toolbar(tv->tb, tv->w); + ro_treeview_set_origin(tv, 0, + -(ro_gui_theme_toolbar_height(tv->tb))); - return false; + xwimp_force_redraw(tv->w, 0, tv->extent.y, tv->extent.x, 0); + } } -int ro_gui_tree_help(int x, int y) -{ - return -1; -} -void ro_gui_tree_update_theme(struct tree *tree) -{ +#if 0 if ((tree) && (tree->toolbar)) { if (tree->toolbar->editor) if (!ro_gui_theme_update_toolbar(NULL, tree->toolbar->editor)) @@ -1621,4 +993,70 @@ void ro_gui_tree_update_theme(struct tree *tree) tree_resized(tree); xwimp_force_redraw((wimp_w)tree->handle, 0, -16384, 16384, 16384); } +#endif + +/** + * Return a token identifying the interactive help message for a given cursor + * position. + * + * Currently this is inimplemented. + * + * \param *message_data Pointer to the Wimp's help message block. + * \return Token value (-1 indicates no help available). + */ + +int ro_treeview_get_help(help_full_message_request *message_data) +{ + return -1; +} + +/** + * Convert a content type into an icon name. + * + * \todo -- Currently we don't have any icons apart from the default. + * + * \param *buffer A buffer to return the icon name + * \param type The content type to return an icon name for. + */ + +void tree_icon_name_from_content_type(char *buffer, content_type type) +{ + switch (type) { + case CONTENT_HTML: + case CONTENT_TEXTPLAIN: + case CONTENT_CSS: +#if defined(WITH_MNG) || defined(WITH_PNG) + case CONTENT_PNG: +#endif +#ifdef WITH_MNG + case CONTENT_JNG: + case CONTENT_MNG: +#endif +#ifdef WITH_JPEG + case CONTENT_JPEG: +#endif +#ifdef WITH_GIF + case CONTENT_GIF: +#endif +#ifdef WITH_BMP + case CONTENT_BMP: + case CONTENT_ICO: +#endif +#ifdef WITH_SPRITE + case CONTENT_SPRITE: +#endif +#ifdef WITH_DRAW + case CONTENT_DRAW: +#endif +#ifdef WITH_ARTWORKS + case CONTENT_ARTWORKS: +#endif +#ifdef WITH_NS_SVG + case CONTENT_SVG: +#endif + default: + sprintf(buffer, tree_content_icon_name); + break; + } } + -- cgit v1.2.3