summaryrefslogtreecommitdiff
path: root/riscos/treeview.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/treeview.c')
-rw-r--r--riscos/treeview.c2044
1 files changed, 741 insertions, 1303 deletions
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 <info@tinct.net>
+ * Copyright 2010 Stephen Fryatt <stevef@netsurf-browser.org>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -20,6 +21,8 @@
* Generic tree handling (implementation).
*/
+#include <oslib/os.h>
+
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@@ -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+<qwerty>
+ 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;
+ }
}
+