summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2013-09-02 16:19:16 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2013-09-02 16:19:16 +0100
commit49c7994d0580a655ddcc78e07205eea45d74132c (patch)
tree7047078437c94d519654fd2ad86f5a8e5be43af3 /desktop
parent46e569c481f1c5196fd90b05bd801809355f2d84 (diff)
downloadnetsurf-49c7994d0580a655ddcc78e07205eea45d74132c.tar.gz
netsurf-49c7994d0580a655ddcc78e07205eea45d74132c.tar.bz2
Remove bulk of old treeview implementation.
Diffstat (limited to 'desktop')
-rw-r--r--desktop/tree.c3002
-rw-r--r--desktop/tree.h176
2 files changed, 33 insertions, 3145 deletions
diff --git a/desktop/tree.c b/desktop/tree.c
index 607d12ba0..9e86668ce 100644
--- a/desktop/tree.c
+++ b/desktop/tree.c
@@ -30,152 +30,21 @@
#include "content/hlcache.h"
#include "css/utils.h"
#include "desktop/browser.h"
-#include "desktop/knockout.h"
-#include "desktop/textarea.h"
-#include "desktop/textinput.h"
#include "desktop/tree.h"
#include "utils/nsoption.h"
-#include "desktop/plotters.h"
#include "render/font.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/url.h"
-#undef TREE_NOISY_DEBUG
-
-#define MAXIMUM_URL_LENGTH 1024
-
-#define TREE_TEXT_SIZE_PT 11
-#define TREE_ICON_SIZE 17
-#define NODE_INSTEP 20
-
-static int tree_text_size_px;
-static int TREE_LINE_HEIGHT;
-
-static char *tree_icons_dir = NULL;
-
-static plot_font_style_t plot_fstyle = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = TREE_TEXT_SIZE_PT * FONT_SIZE_SCALE,
- .weight = 400,
- .flags = FONTF_NONE
-};
-
-static plot_font_style_t plot_fstyle_def_folder = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = TREE_TEXT_SIZE_PT * FONT_SIZE_SCALE,
- .weight = 700,
- .flags = FONTF_NONE
-};
-
-static plot_font_style_t plot_fstyle_selected = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = TREE_TEXT_SIZE_PT * FONT_SIZE_SCALE,
- .weight = 400,
- .flags = FONTF_NONE
-};
-
-static plot_font_style_t plot_fstyle_selected_def_folder = {
- .family = PLOT_FONT_FAMILY_SANS_SERIF,
- .size = TREE_TEXT_SIZE_PT * FONT_SIZE_SCALE,
- .weight = 700,
- .flags = FONTF_NONE
-};
-
-/** plot style for treeview backgrounds. */
-static plot_style_t plot_style_fill_tree_background = {
- .fill_type = PLOT_OP_TYPE_SOLID
-};
-
-/** plot style for treeview backgrounds. */
-static plot_style_t plot_style_fill_tree_selected = {
- .fill_type = PLOT_OP_TYPE_SOLID
-};
-
-/** plot style for treeview furniture lines. */
-static plot_style_t plot_style_stroke_tree_furniture = {
- .stroke_type = PLOT_OP_TYPE_SOLID
-};
-
-/** plot style for treeview furniture fills. */
-static plot_style_t plot_style_fill_tree_furniture = {
- .fill_type = PLOT_OP_TYPE_SOLID
-};
-
-struct node;
-struct tree;
-
-struct node_element_box {
- int x; /**< X offset from origin */
- int y; /**< Y offset from origin */
- int width; /**< Element width */
- int height; /**< Element height */
-};
-
-struct node_element {
- struct node *parent; /**< Parent node */
- node_element_type type; /**< Element type */
- struct node_element_box box; /**< Element bounding box */
- char *text; /**< Text for the element */
- void *bitmap; /**< Bitmap for the element */
- struct node_element *next; /**< Next node element */
- unsigned int flag; /**< Client specified flag for data
- being represented */
- bool editable; /**< Whether the node text can be
- * modified, editable text is deleted
- * without noticing the tree user
- */
-};
-
-struct node {
- bool selected; /**< Whether the node is selected */
- bool expanded; /**< Whether the node is expanded */
- bool folder; /**< Whether the node is a folder */
- bool def_folder; /**< Whether the node is the default folder */
- bool retain_in_memory; /**< Whether the node remains
- in memory after deletion */
- bool deleted; /**< Whether the node is currently
- deleted */
- bool processing; /**< Internal flag used when moving */
- struct node_element_box box; /**< Bounding box of all elements */
- struct node_element data; /**< Data to display */
- struct node *parent; /**< Parent entry (NULL for root) */
- struct node *child; /**< First child */
- struct node *last_child; /**< Last child */
- struct node *previous; /**< Previous child of the parent */
- struct node *next; /**< Next child of the parent */
-
- /** Sorting function for the node (for folder nodes only) */
- int (*sort) (struct node *, struct node *);
- /** Gets called for each deleted node_element and on node launch */
- tree_node_user_callback user_callback;
- /** User data to be passed to delete_callback */
- void *callback_data;
-};
-
struct tree {
- struct node *root; /* Tree root element */
- int width; /* Tree width */
- int height; /* Tree height */
- unsigned int flags; /* Tree flags */
- struct textarea *textarea; /* Handle for UTF-8 textarea */
- int ta_height; /* Textarea height */
- struct node_element *editing; /* Node element being edited */
-
- bool redraw; /* Flag indicating whether the tree
- should be redrawn on layout
- changes */
+ unsigned int flags; /* Tree flags */
tree_drag_type drag;
const struct treeview_table *callbacks;
- void *client_data; /* User assigned data for the
- callbacks */
- struct node *def_folder; /* Node to be used for additions by default */
+ void *client_data; /* User assigned data for the callbacks */
};
-
-
-
#include "desktop/treeview.h"
#include "desktop/hotlist.h"
#include "desktop/cookie_manager.h"
@@ -184,7 +53,6 @@ struct tree {
struct sslcert_session_data *ssl_current_session = NULL;
const char *tree_hotlist_path = NULL;
-
int treeview_inits;
static void treeview_test_redraw_request(struct core_window *cw,
@@ -257,7 +125,7 @@ static bool treeview_test_init(struct tree *tree)
{
nserror err;
- if (tree->flags & TREE_SSLCERT) {
+ if (tree->flags == TREE_SSLCERT) {
treeview_inits++;
@@ -277,19 +145,19 @@ static bool treeview_test_init(struct tree *tree)
if (treeview_inits == 1)
treeview_init();
- if (tree->flags & TREE_COOKIES) {
+ if (tree->flags == TREE_COOKIES) {
err = cookie_manager_init(&cw_t, (struct core_window *)tree);
if (err != NSERROR_OK) {
warn_user("Couldn't init new cookie manager.", 0);
}
}
- if (tree->flags & TREE_HISTORY) {
+ if (tree->flags == TREE_HISTORY) {
err = global_history_init(&cw_t, (struct core_window *)tree);
if (err != NSERROR_OK) {
warn_user("Couldn't init new global history.", 0);
}
}
- if (tree->flags & TREE_HOTLIST) {
+ if (tree->flags == TREE_HOTLIST) {
err = hotlist_init(&cw_t, (struct core_window *)tree,
tree_hotlist_path);
if (err != NSERROR_OK) {
@@ -304,7 +172,7 @@ static bool treeview_test_fini(struct tree *tree)
{
nserror err;
- if (tree->flags & TREE_SSLCERT) {
+ if (tree->flags == TREE_SSLCERT) {
err = sslcert_viewer_fini(ssl_current_session);
if (err != NSERROR_OK) {
warn_user("Couldn't finalise sslcert viewer.", 0);
@@ -317,19 +185,19 @@ static bool treeview_test_fini(struct tree *tree)
return true;
}
- if (tree->flags & TREE_COOKIES) {
+ if (tree->flags == TREE_COOKIES) {
err = cookie_manager_fini();
if (err != NSERROR_OK) {
warn_user("Couldn't finalise cookie manager.", 0);
}
}
- if (tree->flags & TREE_HISTORY) {
+ if (tree->flags == TREE_HISTORY) {
err = global_history_fini();
if (err != NSERROR_OK) {
warn_user("Couldn't finalise cookie manager.", 0);
}
}
- if (tree->flags & TREE_HOTLIST) {
+ if (tree->flags == TREE_HOTLIST) {
err = hotlist_fini(tree_hotlist_path);
if (err != NSERROR_OK) {
warn_user("Couldn't finalise hotlist.", 0);
@@ -354,20 +222,20 @@ static bool treeview_test_redraw(struct tree *tree, int x, int y,
clip.x1 = clip_x + clip_width;
clip.y1 = clip_y + clip_height;
- if (tree->flags & TREE_SSLCERT) {
+ if (tree->flags == TREE_SSLCERT) {
sslcert_viewer_redraw(ssl_current_session, x, y, &clip, ctx);
return true;
}
- if (tree->flags & TREE_COOKIES) {
+ if (tree->flags == TREE_COOKIES) {
cookie_manager_redraw(x, y, &clip, ctx);
return true;
}
- if (tree->flags & TREE_HISTORY) {
+ if (tree->flags == TREE_HISTORY) {
global_history_redraw(x, y, &clip, ctx);
return true;
}
- if (tree->flags & TREE_HOTLIST) {
+ if (tree->flags == TREE_HOTLIST) {
hotlist_redraw(x, y, &clip, ctx);
return true;
}
@@ -378,20 +246,20 @@ static bool treeview_test_redraw(struct tree *tree, int x, int y,
static bool treeview_test_mouse_action(struct tree *tree,
browser_mouse_state mouse, int x, int y)
{
- if (tree->flags & TREE_SSLCERT) {
+ if (tree->flags == TREE_SSLCERT) {
sslcert_viewer_mouse_action(ssl_current_session, mouse, x, y);
return true;
}
- if (tree->flags & TREE_COOKIES) {
+ if (tree->flags == TREE_COOKIES) {
cookie_manager_mouse_action(mouse, x, y);
return true;
}
- if (tree->flags & TREE_HISTORY) {
+ if (tree->flags == TREE_HISTORY) {
global_history_mouse_action(mouse, x, y);
return true;
}
- if (tree->flags & TREE_HOTLIST) {
+ if (tree->flags == TREE_HOTLIST) {
hotlist_mouse_action(mouse, x, y);
return true;
}
@@ -401,20 +269,20 @@ static bool treeview_test_mouse_action(struct tree *tree,
static bool treeview_test_keypress(struct tree *tree, uint32_t key)
{
- if (tree->flags & TREE_SSLCERT) {
+ if (tree->flags == TREE_SSLCERT) {
sslcert_viewer_keypress(ssl_current_session, key);
return true;
}
- if (tree->flags & TREE_COOKIES) {
+ if (tree->flags == TREE_COOKIES) {
cookie_manager_keypress(key);
return true;
}
- if (tree->flags & TREE_HISTORY) {
+ if (tree->flags == TREE_HISTORY) {
global_history_keypress(key);
return true;
}
- if (tree->flags & TREE_HOTLIST) {
+ if (tree->flags == TREE_HOTLIST) {
hotlist_keypress(key);
return true;
}
@@ -422,68 +290,10 @@ static bool treeview_test_keypress(struct tree *tree, uint32_t key)
return false;
}
+/* -------------------------------------------------------------------------- */
-
-
-
-
-
-
-
-
-
-
-
-void tree_set_icon_dir(char *icon_dir)
-{
- LOG(("Tree icon directory set to %s", icon_dir));
- tree_icons_dir = icon_dir;
-}
-
-/**
- * Set up colours for plot styles used in tree redraw.
- */
-void tree_setup_colours(void)
-{
- /* Background colour */
- plot_style_fill_tree_background.fill_colour =
- gui_system_colour_char("Window");
-
- /* Selection background colour */
- plot_style_fill_tree_selected.fill_colour =
- gui_system_colour_char("Highlight");
-
- /* Furniture line colour */
- plot_style_stroke_tree_furniture.stroke_colour = blend_colour(
- gui_system_colour_char("Window"),
- gui_system_colour_char("WindowText"));
-
- /* Furniture fill colour */
- plot_style_fill_tree_furniture.fill_colour =
- gui_system_colour_char("Window");
-
- /* Text colour */
- plot_fstyle.foreground = gui_system_colour_char("WindowText");
- plot_fstyle.background = gui_system_colour_char("Window");
- plot_fstyle_def_folder.foreground =
- gui_system_colour_char("InfoText");
- plot_fstyle_def_folder.background =
- gui_system_colour_char("Window");
-
- /* Selected text colour */
- plot_fstyle_selected.foreground =
- gui_system_colour_char("HighlightText");
- plot_fstyle_selected.background =
- gui_system_colour_char("Highlight");
- plot_fstyle_selected_def_folder.foreground =
- gui_system_colour_char("HighlightText");
- plot_fstyle_selected_def_folder.background =
- gui_system_colour_char("Highlight");
-}
-
-
/**
* Creates and initialises a new tree.
*
@@ -504,41 +314,11 @@ struct tree *tree_create(unsigned int flags,
return NULL;
}
- tree->root = tree_create_folder_node(NULL,
- NULL,
- messages_get("Root"),
- false, false, false);
- if (tree->root == NULL) {
- free(tree);
- return NULL;
- }
- tree->root->expanded = true;
-
- tree->width = 0;
- tree->height = 0;
tree->flags = flags;
- tree->textarea = NULL;
- tree->editing = NULL;
- tree->redraw = false;
tree->drag = TREE_NO_DRAG;
tree->callbacks = callbacks;
tree->client_data = client_data;
- /* Set text height in pixels */
- tree_text_size_px =
- (TREE_TEXT_SIZE_PT * FIXTOINT(nscss_screen_dpi) + 36) /
- 72;
- /* Set line height appropriate for this text height in pixels
- * Using 4/3 text height */
- TREE_LINE_HEIGHT = (tree_text_size_px * 8 + 3) / 6;
-
- /* But if that's too small for the icons, base the line height on
- * the icon height. */
- if (TREE_LINE_HEIGHT < TREE_ICON_SIZE + 2)
- TREE_LINE_HEIGHT = TREE_ICON_SIZE + 2;
-
- tree_setup_colours();
-
treeview_test_init(tree);
return tree;
@@ -546,1750 +326,18 @@ struct tree *tree_create(unsigned int flags,
/**
- * Recalculates the dimensions of a node element.
- *
- * \param tree the tree to which the element belongs, may be NULL
- * \param element the element to recalculate
- */
-static void tree_recalculate_node_element(struct tree *tree,
- struct node_element *element)
-{
- struct bitmap *bitmap = NULL;
- int width, height;
- static char *cache_text = NULL;
- static int cache_size = 0;
- plot_font_style_t *fstyle;
- static plot_font_style_t *cache_fstyle = NULL;
-
- assert(element != NULL);
-
- if (element->parent->def_folder)
- fstyle = &plot_fstyle_def_folder;
- else
- fstyle = &plot_fstyle;
-
- switch (element->type) {
- case NODE_ELEMENT_TEXT_PLUS_ICON:
- case NODE_ELEMENT_TEXT:
- if(element->text == NULL)
- break;
-
- if (tree != NULL && element == tree->editing) {
- textarea_get_dimensions(tree->textarea,
- &element->box.width, NULL);
- } else {
- if ((cache_text != NULL) &&
- (strcmp(cache_text, element->text) == 0) &&
- (cache_fstyle == fstyle)) {
- element->box.width = cache_size;
- #ifdef TREE_NOISY_DEBUG
- LOG(("Tree font width cache hit"));
- #endif
- } else {
- if(cache_text != NULL) free(cache_text);
- nsfont.font_width(fstyle,
- element->text,
- strlen(element->text),
- &cache_size);
- element->box.width = cache_size;
- cache_text = strdup(element->text);
- cache_fstyle = fstyle;
- }
- }
-
- element->box.width += 8;
- element->box.height = TREE_LINE_HEIGHT;
-
- if (element->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- element->box.width += NODE_INSTEP;
-
- break;
-
- case NODE_ELEMENT_BITMAP:
- bitmap = element->bitmap;
- if (bitmap != NULL) {
- width = bitmap_get_width(bitmap);
- height = bitmap_get_height(bitmap);
- element->box.width = width + 1;
- element->box.height = height + 2;
- } else {
- element->box.width = 0;
- element->box.height = 0;
- }
- break;
- }
-}
-
-
-/**
- * Calculates the height of a node including any children
- *
- * \param node the node to calculate the height of
- * \return the total height of the node and children
- */
-static int tree_get_node_height(struct node *node)
-{
- int y1;
-
- assert(node != NULL);
-
- if ((node->child == NULL) || (node->expanded == false)) {
- return node->box.height;
- }
-
- y1 = node->box.y;
- if (y1 < 0) {
- y1 = 0;
- }
- node = node->child;
-
- while ((node->next != NULL) ||
- ((node->child != NULL) && (node->expanded))) {
- for (; node->next != NULL; node = node->next);
-
- if ((node->child != NULL) && (node->expanded)) {
- node = node->child;
- }
- }
- return node->box.y + node->box.height - y1;
-}
-
-
-/**
- * Calculates the width of a node including any children
- *
- * \param node the node to calculate the height of
- * \return the total width of the node and children
- */
-static int tree_get_node_width(struct node *node)
-{
- int width = 0;
- int child_width;
-
- assert(node != NULL);
-
- for (; node != NULL; node = node->next) {
- if (width < (node->box.x + node->box.width)) {
- width = node->box.x + node->box.width;
- }
-
- if ((node->child != NULL) && (node->expanded)) {
- child_width = tree_get_node_width(node->child);
- if (width < child_width) {
- width = child_width;
- }
- }
- }
- return width;
-}
-
-
-/**
- * Recalculates the position of a node, its siblings and children.
- *
- * \param tree the tree to which 'root' belongs
- * \param root the root node to update from
- */
-static void tree_recalculate_node_positions(struct tree *tree,
- struct node *root)
-{
- struct node *parent;
- struct node *node;
- struct node *child;
- struct node_element *element;
- int y;
- bool has_icon;
-
- for (node = root; node != NULL; node = node->next) {
-
- parent = node->parent;
-
- if (node->previous != NULL) {
- node->box.x = node->previous->box.x;
- node->box.y = node->previous->box.y +
- tree_get_node_height(node->previous);
- } else if (parent != NULL) {
- node->box.x = parent->box.x + NODE_INSTEP;
- node->box.y = parent->box.y +
- parent->box.height;
- for (child = parent->child; child != node;
- child = child->next)
- node->box.y += child->box.height;
- } else {
- node->box.x = tree->flags & TREE_NO_FURNITURE
- ? -NODE_INSTEP + 4 : 0;
- node->box.y = -TREE_LINE_HEIGHT;
- }
-
- if (!node->expanded) {
- node->data.box.x = node->box.x;
- node->data.box.y = node->box.y;
- continue;
- }
-
- if (node->folder) {
- node->data.box.x = node->box.x;
- node->data.box.y = node->box.y;
- tree_recalculate_node_positions(tree, node->child);
- } else {
- y = node->box.y;
- has_icon = false;
- for (element = &node->data; element != NULL;
- element = element->next)
- if (element->type ==
- NODE_ELEMENT_TEXT_PLUS_ICON) {
- has_icon = true;
- break;
- }
-
- for (element = &node->data; element != NULL;
- element = element->next) {
- element->box.x = node->box.x;
- if (element->type !=
- NODE_ELEMENT_TEXT_PLUS_ICON &&
- has_icon)
- element->box.x += NODE_INSTEP;
- element->box.y = y;
- y += element->box.height;
- }
- }
-
- }
-}
-
-
-/**
- * Recalculates the size of a node.
- *
- * \param tree the tree to which node belongs, may be NULL
- * \param node the node to update
- * \param recalculate_sizes whether the node elements have changed
- */
-static void tree_recalculate_node_sizes(struct tree *tree, struct node *node,
- bool recalculate_sizes)
-{
- struct node_element *element;
- int height;
-
- assert(node != NULL);
-
- height = node->box.height;
- node->box.width = 0;
- node->box.height = 0;
- if (node->expanded) {
- for (element = &node->data; element != NULL;
- element = element->next) {
- if (recalculate_sizes) {
- #ifdef TREE_NOISY_DEBUG
- if(element->text) LOG(("%s", element->text));
- #endif
- tree_recalculate_node_element(tree, element);
- }
- node->box.width = (node->box.width > element->box.x +
- element->box.width - node->box.x) ?
- node->box.width :
- element->box.width + element->box.x -
- node->box.x;
- node->box.height += element->box.height;
- }
- } else {
- if (recalculate_sizes)
- for (element = &node->data; element != NULL;
- element = element->next) {
- #ifdef TREE_NOISY_DEBUG
- if(element->text) LOG(("%s", element->text));
- #endif
- tree_recalculate_node_element(tree, element);
- }
-
- node->box.width = node->data.box.width;
- node->box.height = node->data.box.height;
- }
-
- if (tree != NULL && height != node->box.height)
- tree_recalculate_node_positions(tree, tree->root);
-}
-
-
-/* exported interface documented in desktop/tree.h */
-struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
- const char *title, bool editable, bool retain_in_memory,
- bool deleted)
-{
- struct node *node;
-
- assert(title != NULL);
-
- node = calloc(sizeof(struct node), 1);
- if (node == NULL) {
- return NULL;
- }
-
- node->data.text = strdup(title);
- if (node->data.text == NULL) {
- free(node);
- return NULL;
- }
-
- node->folder = true;
- node->retain_in_memory = retain_in_memory;
- node->deleted = deleted;
- node->data.parent = node;
- node->data.type = NODE_ELEMENT_TEXT;
- node->data.flag = TREE_ELEMENT_TITLE;
- node->data.editable = editable;
- node->sort = NULL;
- node->user_callback = NULL;
- node->previous = NULL;
-
- tree_recalculate_node_sizes(tree, node, true);
- if (parent != NULL) {
- tree_link_node(tree, parent, node, false);
- }
-
- return node;
-}
-
-/* exported interface documented in desktop/tree.h */
-struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
- const char *title, bool editable, bool retain_in_memory,
- bool deleted)
-{
- struct node *node;
-
- assert(title != NULL);
-
- node = calloc(sizeof(struct node), 1);
- if (node == NULL) {
- return NULL;
- }
-
- node->data.text = strdup(title);
- if (node->data.text == NULL) {
- free(node);
- return NULL;
- }
-
- node->folder = false;
- node->retain_in_memory = retain_in_memory;
- node->deleted = deleted;
- node->data.parent = node;
- node->data.type = NODE_ELEMENT_TEXT;
- node->data.flag = TREE_ELEMENT_TITLE;
- node->data.editable = editable;
- node->sort = NULL;
- node->user_callback = NULL;
- node->previous = NULL;
-
- tree_recalculate_node_sizes(tree, node, true);
- if (parent != NULL) {
- tree_link_node(tree, parent, node, false);
- }
-
- return node;
-}
-
-
-/**
- * Creates an empty text node element and links it to a node.
- *
- * \param parent the parent node
- * \param type the required element type
- * \param flag user assigned flag used for searches
- * \return the newly created element.
- */
-struct node_element *tree_create_node_element(struct node *parent,
- node_element_type type, unsigned int flag, bool editable)
-{
- struct node_element *element;
-
- element = calloc(sizeof(struct node_element), 1);
- if (element == NULL)
- return NULL;
-
- element->parent = parent;
- element->flag = flag;
- element->type = type;
- element->editable = editable;
- element->next = parent->data.next;
- parent->data.next = element;
-
- return element;
-}
-
-
-/**
- * Inserts a node into the correct place according to the parent's sort function
- *
- * \param parent the node whose child node 'node' becomes
- * \param node the node to be inserted
- */
-static void tree_sort_insert(struct node *parent, struct node *node)
-{
- struct node *after;
-
- assert(node != NULL);
- assert(parent != NULL);
- assert(parent->sort != NULL);
-
- after = parent->last_child;
- while ((after != NULL) &&
- (parent->sort(node, after) == -1))
- after = after->previous;
-
- if (after != NULL) {
- if (after->next != NULL)
- after->next->previous = node;
- node->next = after->next;
- node->previous = after;
- after->next = node;
- } else {
- node->previous = NULL;
- node->next = parent->child;
- if (parent->child != NULL) {
- parent->child->previous = node;
- }
- parent->child = node;
- }
-
- if (node->next == NULL)
- parent->last_child = node;
-
- node->parent = parent;
-}
-
-
-/**
- * Recalculates the size of a tree.
- *
- * \param tree the tree to recalculate
- */
-static void tree_recalculate_size(struct tree *tree)
-{
- int width, height;
-
- assert(tree != NULL);
-
- width = tree->width;
- height = tree->height;
-
- tree->width = tree_get_node_width(tree->root);
- tree->height = tree_get_node_height(tree->root);
-
- if ((width != tree->width) || (height != tree->height))
- tree->callbacks->resized(tree, tree->width, tree->height,
- tree->client_data);
-}
-
-/**
- * Recalculate the node data and redraw the relevant section of the tree.
- *
- * \param tree the tree to redraw, may be NULL
- * \param node the node to update
- * \param recalculate_sizes whether the elements have changed
- * \param expansion the request is the result of a node expansion
- */
-static void tree_handle_node_changed(struct tree *tree, struct node *node,
- bool recalculate_sizes, bool expansion)
-{
- int node_width, node_height, tree_width, tree_height;
-
- assert(node != NULL);
- assert(tree != NULL);
-
- node_width = node->box.width;
- node_height = node->box.height;
- tree_width = tree->width;
- tree_height = tree->height;
-
- if ((recalculate_sizes) || (expansion)) {
- tree_recalculate_node_sizes(tree, node, true);
- }
-
- if (tree != NULL) {
- if ((node->box.height != node_height) || (expansion)) {
- tree_recalculate_node_positions(tree, tree->root);
- tree_recalculate_size(tree);
- if (tree->width > tree_width)
- tree_width = tree->width;
- if (tree->height > tree_height)
- tree_height = tree->height;
- if (tree->redraw) {
- tree->callbacks->redraw_request(0, node->box.y,
- tree_width,
- tree_height - node->box.y,
- tree->client_data);
- }
- } else {
- if (node->box.width > node_width)
- node_width = node->box.width;
- if (tree->redraw)
- tree->callbacks->redraw_request(node->box.x,
- node->box.y,
- node_width, node->box.height,
- tree->client_data);
- if (recalculate_sizes) {
- tree_recalculate_size(tree);
- }
- }
- }
-}
-
-
-/**
- * Links a node to another node.
- *
- * \param tree the tree in which the link takes place, may be NULL
- * \param link the node to link before/as a child (folders)
- * or before/after (link)
- * \param node the node to link
- * \param before whether to link siblings before or after the supplied node
- */
-void tree_link_node(struct tree *tree, struct node *link, struct node *node,
- bool before)
-{
-
- struct node *parent;
- bool sort = false;
-
- assert(link != NULL);
- assert(node != NULL);
-
- if ((link->folder == 0) || (before)) {
- parent = node->parent = link->parent;
- if (parent->sort) {
- sort = true;
- } else {
- if (before) {
- node->next = link;
- node->previous = link->previous;
- if (link->previous != NULL)
- link->previous->next = node;
- link->previous = node;
- if ((parent != NULL) && (parent->child == link))
- parent->child = node;
- } else {
- node->previous = link;
- node->next = link->next;
- if (link->next != NULL)
- link->next->previous = node;
- link->next = node;
- if ((parent != NULL) &&
- (parent->last_child == link))
- parent->last_child = node;
- }
- }
- } else {
- parent = node->parent = link;
- if (parent->sort != NULL) {
- sort = true;
- } else {
- node->next = NULL;
- if (link->child == NULL) {
- link->child = link->last_child = node;
- node->previous = NULL;
- } else {
- link->last_child->next = node;
- node->previous = link->last_child;
- link->last_child = node;
- }
- }
-
- }
-
- if (sort) {
- tree_sort_insert(parent, node);
- }
-
- tree_handle_node_changed(tree, link, false, true);
-
- node->deleted = false;
-}
-
-
-/**
- * Recalculate the node element and redraw the relevant section of the tree.
- * The tree size is not updated.
- *
- * \param tree the tree to redraw, may be NULL
- * \param element the node element to update
- */
-static void tree_handle_node_element_changed(struct tree *tree,
- struct node_element *element, bool text_changed)
-{
- int width, height;
-
- assert(element != NULL);
-
- width = element->box.width;
- height = element->box.height;
-
- if(text_changed == true) {
- #ifdef TREE_NOISY_DEBUG
- if(element->text) LOG(("%s", element->text));
- #endif
- tree_recalculate_node_element(tree, element);
- }
-
- if (element->box.height != height) {
- tree_recalculate_node_sizes(tree, element->parent, false);
- if ((tree != NULL) && (tree->redraw)) {
- tree->callbacks->redraw_request(0, element->box.y,
- tree->width + element->box.width -
- width,
- tree->height - element->box.y +
- element->box.height - height,
- tree->client_data);
- }
- } else {
- if (element->box.width != width) {
- tree_recalculate_node_sizes(tree, element->parent,
- false);
- }
-
- if (tree != NULL) {
- width = (width > element->box.width) ? width :
- element->box.width;
- if (tree->redraw) {
- tree->callbacks->redraw_request(element->box.x,
- element->box.y,
- width,
- element->box.height,
- tree->client_data);
- }
- }
- }
-}
-
-
-/**
- * Stops editing a node_element
- *
- * \param tree The tree to stop editing for
- * \param keep_changes If true the changes made to the text will be kept,
- * if false they will be dropped
- */
-static void tree_stop_edit(struct tree *tree, bool keep_changes)
-{
- int text_len;
- char *text = NULL;
- struct node_element *element;
- struct node_msg_data msg_data;
- node_callback_resp response;
-
- assert(tree != NULL);
-
- if (tree->editing == NULL || tree->textarea == NULL)
- return;
-
- element = tree->editing;
-
- if (keep_changes) {
- text_len = textarea_get_text(tree->textarea, NULL, 0);
- text = malloc(text_len * sizeof(char));
- if (text == NULL) {
- LOG(("malloc failed"));
- warn_user("NoMemory", 0);
- textarea_destroy(tree->textarea);
- tree->textarea = NULL;
- return;
- }
- textarea_get_text(tree->textarea, text, text_len);
- }
-
-
- if (keep_changes && element->parent->user_callback != NULL) {
- msg_data.msg = NODE_ELEMENT_EDIT_FINISHING;
- msg_data.flag = element->flag;
- msg_data.node = element->parent;
- msg_data.data.text = text;
- response = element->parent->user_callback(
- element->parent->callback_data,
- &msg_data);
-
- switch (response) {
- case NODE_CALLBACK_REJECT:
- free(text);
- text = NULL;
- break;
- case NODE_CALLBACK_CONTINUE:
- free(text);
- text = NULL;
- return;
- case NODE_CALLBACK_HANDLED:
- case NODE_CALLBACK_NOT_HANDLED:
- text = msg_data.data.text;
- break;
- }
- }
-
- textarea_destroy(tree->textarea);
- tree->textarea = NULL;
- tree->editing = NULL;
-
- if (text != NULL)
- tree_update_node_element(tree, element, text, NULL);
- else
- tree_handle_node_element_changed(tree, element, true);
-
-
- tree_recalculate_size(tree);
- if (element->parent->user_callback != NULL) {
- msg_data.msg = keep_changes ? NODE_ELEMENT_EDIT_FINISHED :
- NODE_ELEMENT_EDIT_CANCELLED;
- msg_data.flag = element->flag;
- msg_data.node = element->parent;
- element->parent->user_callback(element->parent->callback_data,
- &msg_data);
- }
-}
-
-
-/**
- * Delinks a node from the tree structures.
- *
- * \param tree the tree in which the delink takes place, may be NULL
- * \param node the node to delink
- */
-void tree_delink_node(struct tree *tree, struct node *node)
-{
- struct node *parent;
-
- assert(node != NULL);
-
- /* do not remove the root */
- if (tree != NULL && node == tree->root)
- return;
- if ((tree != NULL) && (tree->editing != NULL)) {
- parent = tree->editing->parent;
- while (parent != NULL) {
- if (node == parent) {
- tree_stop_edit(tree, false);
- break;
- }
- parent = parent->parent;
- }
- }
-
- if (node->parent->child == node)
- node->parent->child = node->next;
- if (node->parent->last_child == node)
- node->parent->last_child = node->previous;
- parent = node->parent;
- node->parent = NULL;
-
- if (node->previous != NULL)
- node->previous->next = node->next;
- if (node->next != NULL)
- node->next->previous = node->previous;
- node->previous = NULL;
- node->next = NULL;
-
- tree_handle_node_changed(tree, parent, false, true);
-}
-
-
-/**
- * Deletes a node from the tree.
- *
- * \param tree the tree to delete from, may be NULL
- * \param node the node to delete
- * \param siblings whether to delete all siblings
- */
-static void tree_delete_node_internal(struct tree *tree, struct node *node,
- bool siblings)
-{
- struct node *next, *child, *parent;
- struct node_element *e, *f;
- node_callback_resp response;
- struct node_msg_data msg_data;
-
- assert(node != NULL);
-
- if (tree != NULL && tree->root == node)
- return;
-
- next = node->next;
- parent = node->parent;
- if (tree != NULL && parent == tree->root)
- parent = NULL;
- if ((tree != NULL) && (tree->def_folder == node))
- tree->def_folder = NULL;
- tree_delink_node(tree, node);
- child = node->child;
- node->child = NULL;
-
- node->deleted = true;
- if (child != NULL)
- tree_delete_node_internal(tree, child, true);
-
- if (!node->retain_in_memory) {
- node->retain_in_memory = true;
- for (e = &node->data; e != NULL; e = f) {
- if (e->text != NULL) {
- response = NODE_CALLBACK_NOT_HANDLED;
- if (!e->editable &&
- node->user_callback != NULL) {
- msg_data.msg = NODE_DELETE_ELEMENT_TXT;
- msg_data.flag = e->flag;
- msg_data.node = node;
- msg_data.data.text = (void *)e->text;
- response = node->user_callback(
- node->callback_data,
- &msg_data);
- }
- if (response != NODE_CALLBACK_HANDLED)
- free((void *)e->text);
- e->text = NULL;
- }
- if (e->bitmap != NULL) {
- response = NODE_CALLBACK_NOT_HANDLED;
- if (node->user_callback != NULL) {
- msg_data.msg = NODE_DELETE_ELEMENT_IMG;
- msg_data.flag = e->flag;
- msg_data.node = node;
- msg_data.data.bitmap =
- (void *)e->bitmap;
- response = node->user_callback(
- node->callback_data,
- &msg_data);
- }
- /* TODO the type of this field is platform
- dependent */
- if (response != NODE_CALLBACK_HANDLED)
- free(e->bitmap);
- e->bitmap = NULL;
- }
- f = e->next;
- if (e != &node->data)
- free(e);
- }
- free(node);
- }
-
- if (siblings && next)
- tree_delete_node_internal(tree, next, true);
- if ((tree->flags & TREE_DELETE_EMPTY_DIRS) && parent != NULL &&
- parent->child == NULL && !parent->deleted)
- tree_delete_node_internal(tree, parent, false);
-}
-
-
-/**
* Deletes all nodes of a tree and the tree itself.
*
* \param tree the tree to be deleted
*/
void tree_delete(struct tree *tree)
{
- tree->redraw = false;
-
treeview_test_fini(tree);
-
- if (tree->root->child != NULL)
- tree_delete_node_internal(tree, tree->root->child, true);
-
- free((void *)tree->root->data.text);
- free(tree->root);
free(tree);
}
/**
- * Gets the redraw property of the given tree.
- *
- * \param tree the tree for which to retrieve the property
- * \return the redraw property of the tree
- */
-bool tree_get_redraw(struct tree *tree)
-{
- return tree->redraw;
-}
-
-
-/**
- * Deletes a node from the tree.
- *
- * \param tree the tree to delete from, may be NULL
- * \param node the node to delete
- * \param siblings whether to delete all siblings
- */
-void tree_delete_node(struct tree *tree, struct node *node, bool siblings)
-{
- int y = node->box.y;
- int height = tree->height;
- int width = tree->width;
- bool redraw_setting = tree->redraw;
-
- tree->redraw = false;
-
- tree_delete_node_internal(tree, node, siblings);
- tree_recalculate_node_positions(tree, tree->root);
-
- tree->redraw = redraw_setting;
-
- if (tree->redraw)
- tree->callbacks->redraw_request(0, y,
- width, height, tree->client_data);
- tree_recalculate_size(tree);
-}
-
-
-/**
- * Sets an icon for a node
- *
- * \param tree The tree to which node belongs, may be NULL
- * \param node The node for which the icon is set
- * \param icon the image to use
- */
-void tree_set_node_icon(struct tree *tree, struct node *node,
- hlcache_handle *icon)
-{
- node->data.type = NODE_ELEMENT_TEXT_PLUS_ICON;
- tree_update_node_element(tree, &(node->data), NULL, icon);
-}
-
-
-/**
- * Updates all siblings and descendants of a node to an expansion state.
- * No update is performed for the tree changes.
- *
- * \param tree the tree to which 'node' belongs
- * \param node the node to set all siblings and descendants of
- * \param expanded the expansion state to set
- */
-static void tree_set_node_expanded_all(struct tree *tree, struct node *node,
- bool expanded)
-{
- for (; node != NULL; node = node->next) {
- if (node->expanded != expanded) {
- node->expanded = expanded;
- tree_recalculate_node_sizes(tree, node, false);
- }
- if ((node->child != NULL) && (node->expanded))
- tree_set_node_expanded_all(tree, node->child, expanded);
- }
-}
-
-
-/**
- * Updates [all siblings and descendants of] a node to an expansion state.
- *
- * \param tree the tree to update
- * \param node the node to set [all siblings and descendants of]
- * \param expanded the expansion state to set
- * \param folder whether to update folders, if this together with leaf
- * will be false only 'node' will be updated
- * \param leaf whether to update leaves (check also description for folder)
- * \return whether any changes were made
- */
-static bool tree_set_node_expanded_internal(struct tree *tree,
- struct node *node, bool expanded, bool folder, bool leaf)
-{
- bool redraw = false;
- struct node *end = (folder == false && leaf == false) ?
- node->next : NULL;
-
- if (tree->editing != NULL && node == tree->editing->parent)
- tree_stop_edit(tree, false);
-
- for (; node != end; node = node->next) {
- if ((node->expanded != expanded) && (node != tree->root) &&
- ((folder && (node->folder)) ||
- (leaf && (!node->folder)) ||
- (!folder && !leaf))) {
- node->expanded = expanded;
- if (node->child != NULL)
- tree_set_node_expanded_all(tree,
- node->child, false);
- if ((node->data.next != NULL) &&
- (node->data.next->box.height == 0))
- tree_recalculate_node_sizes(tree, node, true);
- else
- tree_recalculate_node_sizes(tree, node, false);
- redraw = true;
- }
- if ((folder || leaf) && (node->child != NULL) &&
- (node->expanded))
- redraw |= tree_set_node_expanded_internal(tree,
- node->child, expanded, folder, leaf);
- }
- return redraw;
-}
-
-
-/**
- * Updates [all siblings and descendants of] a node to an expansion state.
- *
- * \param tree the tree to update
- * \param node the node to set [all siblings and descendants of]
- * \param expanded the expansion state to set
- * \param folder whether to update folders, if this together with leaf
- * will be false only 'node' will be updated
- * \param leaf whether to update leaves (check also description for folder)
- */
-void tree_set_node_expanded(struct tree *tree, struct node *node, bool expanded,
- bool folder, bool leaf)
-{
- if (tree_set_node_expanded_internal(tree, node, expanded, folder, leaf))
- tree_handle_node_changed(tree, node, false, true);
-}
-
-
-/**
- * Updates a node to an selected state. The required areas of the tree are
- * redrawn.
- *
- * \param tree the tree to update nodes for, may be NULL
- * \param node the node to set all siblings and descendants of
- * \param all if true update node together with its siblings and
- * descendants
- * \param selected the selection state to set
- */
-void tree_set_node_selected(struct tree *tree, struct node *node, bool all,
- bool selected)
-{
- struct node *end;
-
- if (tree != NULL && node == tree->root)
- node = tree->root->child;
- if (node == NULL)
- return;
-
- end = all ? NULL : node->next;
-
- for (; node != end; node = node->next) {
- if (node->selected != selected) {
- node->selected = selected;
- if (tree != NULL && tree->redraw)
- tree->callbacks->redraw_request(
- node->data.box.x,
- node->data.box.y,
- node->data.box.width,
- node->data.box.height,
- tree->client_data);
- }
- if (all && (node->child != NULL) && (node->expanded))
- tree_set_node_selected(tree, node->child, all,
- selected);
- }
-}
-
-
-/**
- * Sets the sort function for a node
- *
- * \param tree the tree to which 'node' belongs, may be NULL
- * \param node the node to be inserted
- * \param sort pointer to the sorting function
- */
-void tree_set_node_sort_function(struct tree *tree, struct node *node,
- int (*sort) (struct node *, struct node *))
-{
- struct node *child;
-
- node->sort = sort;
-
- if (tree != NULL && tree->editing != NULL)
- tree_stop_edit(tree, false);
-
- /* the node had already some children so they must get sorted */
- if (node->child != NULL) {
-
- child = node->child;
- node->child = NULL;
-
- while (child != NULL) {
- tree_sort_insert(node, child);
- child = child->next;
- }
-
- }
-
- if (tree != NULL)
- tree_recalculate_node_positions(tree, node->child);
-}
-
-
-/**
- * Sets the delete callback for a node.
- *
- * \param node the node for which the callback is set
- * \param callback the callback functions to be set
- * \param data user data to be passed to callback
- */
-void tree_set_node_user_callback(struct node *node,
- tree_node_user_callback callback, void *data)
-{
- node->user_callback = callback;
- node->callback_data = data;
-}
-
-
-/**
- * Sets the redraw property to the given value. If redraw is true, the tree will
- * be redrawn on layout/appearance changes.
- *
- * \param tree the tree for which the property is set
- * \param redraw the value to set
- */
-void tree_set_redraw(struct tree *tree, bool redraw)
-{
- /* the tree might have no graphical representation, do not set the
- redraw flag in such case */
- if (tree->callbacks == NULL)
- return;
- tree->redraw = redraw;
-}
-
-
-/**
- * Checks whether a node, its siblings or any children are selected.
- *
- * \param node the root node to check from
- * \return whether 'node', its siblings or any children are selected.
- */
-bool tree_node_has_selection(struct node *node)
-{
- for (; node != NULL; node = node->next) {
- if (node->selected)
- return true;
- if ((node->child != NULL) && (node->expanded) &&
- (tree_node_has_selection(node->child)))
- return true;
- }
- return false;
-}
-
-
-/**
- * Returns the current value of the nodes deleted property.
- *
- * \param node the node to be checked
- * \return the current value of the nodes deleted property
- */
-bool tree_node_is_deleted(struct node *node)
-{
- return node->deleted;
-}
-
-
-/**
- * Returns true if the node is a folder
- *
- * \param node the node to be checked
- * \return true if the node is a folder, false otherwise
- */
-bool tree_node_is_folder(struct node *node)
-{
- return node->folder;
-}
-
-
-/**
- * Returns true if the node is the default folder for a tree
- *
- * \param node the node to be checked
- * \return true if the node is a default folder, false otherwise
- */
-bool tree_node_is_default(struct node *node)
-{
- return node->def_folder;
-}
-
-
-/**
- * Update the text of a node element if it has changed.
- *
- * \param element The node element to update.
- * \param text The text to update the element with. The ownership of
- * this string is taken by this function and must not be
- * referred to after the function exits.
- */
-bool tree_update_element_text(struct tree *tree,
- struct node_element *element, char *text)
-{
- const char *node_text; /* existing node text */
-
- if (text == NULL)
- return false;
-
- if (element == NULL) {
- free(text);
- return false;
- }
-
- node_text = tree_node_element_get_text(element);
-
- if ((node_text == NULL) || (strcmp(node_text, text) != 0)) {
- tree_update_node_element(tree, element, text, NULL);
- } else {
- /* text does not need changing, free it */
- free(text);
- }
- return true;
-}
-
-
-/**
- * Updates the content of a node_element.
- *
- * \param tree the tree owning element, may be NULL
- * \param element the element to be updated
- * \param text new text to be set, may be NULL
- * \param bitmap new bitmap to be set, may be NULL
- */
-void tree_update_node_element(struct tree *tree, struct node_element *element,
- const char *text, void *bitmap)
-{
- node_callback_resp response;
- struct node_msg_data msg_data;
- bool text_changed = false;
-
- assert(element != NULL);
-
- if ((tree != NULL) && (element == tree->editing)) {
- tree_stop_edit(tree, false);
- }
-
- if ((text != NULL) &&
- (element->type == NODE_ELEMENT_TEXT ||
- element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) {
- if (element->text != NULL) {
- if (strcmp(element->text, text) == 0) {
- text_changed = true;
- }
- response = NODE_CALLBACK_NOT_HANDLED;
- if ((!element->editable) &&
- (element->parent->user_callback != NULL)) {
- msg_data.msg = NODE_DELETE_ELEMENT_TXT;
- msg_data.flag = element->flag;
- msg_data.node = element->parent;
- msg_data.data.text = (void *)element->text;
- response = element->parent->user_callback(
- element->parent->callback_data,
- &msg_data);
- }
- if (response != NODE_CALLBACK_HANDLED) {
- free(element->text);
- }
- }
- element->text = (char *)text;
- }
-
- if ((bitmap != NULL) &&
- ((element->type == NODE_ELEMENT_BITMAP) ||
- (element->type == NODE_ELEMENT_TEXT_PLUS_ICON))) {
- if (element->bitmap != NULL) {
- response = NODE_CALLBACK_NOT_HANDLED;
- if (element->parent->user_callback != NULL) {
- msg_data.msg = NODE_DELETE_ELEMENT_IMG;
- msg_data.flag = element->flag;
- msg_data.node = element->parent;
- msg_data.data.bitmap = (void *)element->bitmap;
- response = element->parent->user_callback(
- element->parent->callback_data,
- &msg_data);
- }
-
- if (response != NODE_CALLBACK_HANDLED) {
- free(element->bitmap);
- }
- } else {
- /* Increase the box width to accomodate the new icon */
- element->box.width += NODE_INSTEP;
- }
-
- element->bitmap = bitmap;
- }
-
- tree_handle_node_element_changed(tree, element, text_changed);
-}
-
-
-/**
- * Returns the node element's text
- *
- * \return the node element's text
- */
-const char *tree_node_element_get_text(struct node_element *element)
-{
- return element->text;
-}
-
-
-/**
- * Returns the node element's icon
- *
- * \return the node element's icon
- */
-struct bitmap *tree_node_element_get_icon(struct node_element *element)
-{
- return element->bitmap;
-}
-
-
-/**
- * Get the root node of a tree
- *
- * \param tree the tree to get the root of
- * \return the root of the tree
- */
-struct node *tree_get_root(struct tree *tree)
-{
- return tree->root;
-}
-
-
-/**
- * Returns whether the current tree is being edited at this time
- *
- * \param tree the tree to be checked
- * \return true if the tree is currently being edited
- */
-bool tree_is_edited(struct tree *tree)
-{
- return tree->editing == NULL ? false : true;
-}
-
-
-/**
- * Get the drag state of a tree
- *
- * \param tree the tree to get the state of
- * \return drag type (defined in desktop/tree.h)
- */
-tree_drag_type tree_drag_status(struct tree *tree)
-{
- return tree->drag;
-}
-
-
-/**
- * Get the default node of a tree for additions
- *
- * \param tree the tree to get the default node of
- * \return the default node
- */
-struct node *tree_get_default_folder_node(struct tree *tree)
-{
- if (tree->def_folder != NULL) {
- return tree->def_folder;
- } else {
- return tree_get_root(tree);
- }
-}
-
-
-/**
- * Set the default node of a tree to the selected node
- *
- * \param tree the tree to set the default node of
- * \param node the node to set as default (NULL for selected node)
- * \return success
- */
-bool tree_set_default_folder_node(struct tree *tree, struct node *node)
-{
- struct node *sel_node;
-
- if (node == NULL) {
- sel_node = tree_get_selected_node(tree->root);
- } else {
- sel_node = node;
- }
-
- if((sel_node == NULL) ||
- (tree_node_is_folder(sel_node) == false)) {
- return false;
- }
-
- tree_clear_default_folder_node(tree);
-
- tree->def_folder = sel_node;
- sel_node->def_folder = true;
- tree_handle_node_changed(tree, sel_node, true, false);
-
- return true;
-}
-
-
-/**
- * Clear the default node of a tree
- *
- * \param tree the tree to clear the default node of
- */
-void tree_clear_default_folder_node(struct tree *tree)
-{
- struct node *def_node = NULL;
- def_node = tree_get_default_folder_node(tree);
-
- if (def_node != NULL) {
- tree->def_folder = NULL;
- def_node->def_folder = false;
- tree_handle_node_changed(tree, def_node, true, false);
- }
-}
-
-
-/**
- * Returns the parent of a node
- *
- * \param node the node to get the parent of
- * \return the node's parent
- */
-struct node *tree_node_get_parent(struct node *node)
-{
- return node->parent;
-}
-
-
-/**
- * Returns the first child of a node
- *
- * \param node the node to get the child of
- * \return the nodes first child
- */
-struct node *tree_node_get_child(struct node *node)
-{
- return node->child;
-}
-
-
-/**
- * Returns the closest sibling a node
- *
- * \param node the node to get the sibling of
- * \return the nodes sibling
- */
-struct node *tree_node_get_next(struct node *node)
-{
- return node->next;
-}
-
-
-/**
- * Draws an element's expansion icon
- *
- * \param tree the tree to draw the expansion for
- * \param element the element to draw the expansion for
- * \param tree_x X coordinate of the tree
- * \param tree_y Y coordinate of the tree
- * \param ctx current redraw context
- */
-static void tree_draw_node_expansion_toggle(struct tree *tree,
- struct node *node, int tree_x, int tree_y,
- const struct redraw_context *ctx)
-{
- const struct plotter_table *plot = ctx->plot;
- int x, y;
-
- assert(tree != NULL);
- assert(node != NULL);
-
- if ((node->child != NULL) || (node->data.next != NULL)) {
- x = tree_x + node->box.x - (NODE_INSTEP / 2) - 4;
- y = tree_y + node->box.y + (TREE_LINE_HEIGHT - 9) / 2;
- plot->rectangle(x, y, x + 9, y + 9,
- &plot_style_fill_tree_furniture);
- plot->rectangle(x , y, x + 8, y + 8,
- &plot_style_stroke_tree_furniture);
- plot->line(x + 2, y + 4, x + 7, y + 4,
- &plot_style_stroke_tree_furniture);
- if (!node->expanded)
- plot->line(x + 4, y + 2, x + 4, y + 7,
- &plot_style_stroke_tree_furniture);
-
- }
-
-}
-
-
-/**
- * Draws an element, including any expansion icons
- *
- * \param tree the tree to draw an element for
- * \param element the element to draw
- * \param tree_x X coordinate to draw the tree at (wrt plot origin)
- * \param tree_y Y coordinate to draw the tree at (wrt plot origin)
- * \param clip clipping rectangle (wrt plot origin)
- * \param ctx current redraw context
- */
-static void tree_draw_node_element(struct tree *tree,
- struct node_element *element, int tree_x, int tree_y,
- const struct rect *clip, const struct redraw_context *ctx)
-{
- const struct plotter_table *plot = ctx->plot;
- struct bitmap *bitmap = NULL;
- int x, y, width;
- bool selected = false;
- bool def_folder = false;
- hlcache_handle *icon;
- plot_font_style_t *fstyle;
- const int icon_inset = (TREE_LINE_HEIGHT - TREE_ICON_SIZE) / 2;
-
- assert(tree != NULL);
- assert(element != NULL);
- assert(element->parent != NULL);
-
- x = tree_x + element->box.x;
- y = tree_y + element->box.y;
- width = element->box.width;
- if (&element->parent->data == element) {
- if (element->parent->selected)
- selected = true;
- if (element->parent->def_folder)
- def_folder = true;
- }
-
- switch (element->type) {
- case NODE_ELEMENT_TEXT_PLUS_ICON:
- icon = element->bitmap;
- if (icon != NULL && (content_get_status(icon) ==
- CONTENT_STATUS_READY ||
- content_get_status(icon) ==
- CONTENT_STATUS_DONE) &&
- x + TREE_ICON_SIZE > clip->x0 &&
- x < clip->x1) {
- struct rect c;
- /* Clip to image area */
- c.x0 = x;
- c.y0 = y + icon_inset;
- c.x1 = x + TREE_ICON_SIZE;
- c.y1 = y + icon_inset + TREE_ICON_SIZE;
- if (c.x0 < clip->x0) c.x0 = clip->x0;
- if (c.y0 < clip->y0) c.y0 = clip->y0;
- if (c.x1 > clip->x1) c.x1 = clip->x1;
- if (c.y1 > clip->y1) c.y1 = clip->y1;
-
- if (c.x1 > c.x0 && c.y1 > c.y0) {
- /* Valid clip rectangles only */
- struct content_redraw_data data;
-
- plot->clip(&c);
-
- data.x = x;
- data.y = y + icon_inset;
- data.width = TREE_ICON_SIZE;
- data.height = TREE_ICON_SIZE;
-
- data.background_colour = 0xFFFFFF;
- data.scale = 1;
- data.repeat_x = false;
- data.repeat_y = false;
-
- content_redraw(icon, &data, &c, ctx);
-
- /* Restore previous clipping area */
- plot->clip(clip);
- }
- }
-
- x += NODE_INSTEP;
- width -= NODE_INSTEP;
-
- /* fall through */
- case NODE_ELEMENT_TEXT:
- if (element->text == NULL || clip->x1 < x)
- break;
-
- if (element == tree->editing)
- return;
-
- if (selected) {
- if (def_folder == true)
- fstyle = &plot_fstyle_selected_def_folder;
- else
- fstyle = &plot_fstyle_selected;
-
- plot->rectangle(x, y, x + width,
- y + element->box.height,
- &plot_style_fill_tree_selected);
- } else {
- if (def_folder == true)
- fstyle = &plot_fstyle_def_folder;
- else
- fstyle = &plot_fstyle;
- }
-
- plot->text(x + 4, y + (TREE_LINE_HEIGHT * 3 + 2) / 4,
- element->text, strlen(element->text),
- fstyle);
- break;
- case NODE_ELEMENT_BITMAP:
- bitmap = element->bitmap;
- if (bitmap == NULL)
- break;
- plot->bitmap(x, y, element->box.width - 1,
- element->box.height - 2,
- bitmap, 0xFFFFFF, BITMAPF_NONE);
- if (!(tree->flags & TREE_NO_FURNITURE))
- plot->rectangle(x, y, x + element->box.width - 1,
- y + element->box.height - 3,
- &plot_style_stroke_tree_furniture);
-
- break;
- }
-
-}
-
-
-/**
- * Redraws a node.
- *
- * \param tree the tree to draw
- * \param node the node to draw children and siblings of
- * \param tree_x X coordinate to draw the tree at (wrt plot origin)
- * \param tree_y Y coordinate to draw the tree at (wrt plot origin)
- * \param clip clipping rectangle (wrt plot origin)
- * \param ctx current redraw context
- */
-static void tree_draw_node(struct tree *tree, struct node *node,
- int tree_x, int tree_y, struct rect clip,
- const struct redraw_context *ctx)
-{
- const struct plotter_table *plot = ctx->plot;
- struct node_element *element;
- struct node *parent;
- int x0, y0, x1, y1;
- struct rect node_extents;
-
- assert(tree != NULL);
- assert(node != NULL);
-
- /* Find node's extents, including children's area */
- node_extents.x0 = tree_x + node->box.x - NODE_INSTEP;
- node_extents.y0 = tree_y + node->box.y;
- node_extents.x1 = tree_x + node->box.x + node->box.width + NODE_INSTEP;
- if (node->next != NULL)
- node_extents.y1 = tree_y + node->next->box.y;
- else
- node_extents.y1 = tree_y + node->box.y + node->box.height;
-
- /* Nothing to draw, if node is outside clip region */
- if ((node_extents.x1 < clip.x0) && (node_extents.y1 < clip.y0) &&
- (node_extents.x0 > clip.x1) &&
- (node_extents.y0 > clip.y1)) {
- return;
- }
-
- /* Intersect clip region with node's extents */
- if (clip.x0 < node_extents.x0) clip.x0 = node_extents.x0;
- if (clip.y0 < node_extents.y0) clip.y0 = node_extents.y0;
- if (clip.x1 > node_extents.x1) clip.x1 = node_extents.x1;
- if (clip.y1 > node_extents.y1) clip.y1 = node_extents.y1;
-
- if (clip.x0 >= clip.x1 || clip.y0 >= clip.y1) {
- /* Invalid clip rectangle */
- return;
- }
-
- /* Set up the clipping area */
- plot->clip(&clip);
-
- /* Draw node's furniture */
- if (!(tree->flags & TREE_NO_FURNITURE)) {
- /* Display furniture */
- if (node->previous != NULL) {
- /* There is a node above this
- * Display furniture; line connecting up to previous */
- x0 = x1 = tree_x + node->box.x - (NODE_INSTEP / 2);
- y0 = tree_y + node->previous->box.y;
- y1 = tree_y + node->box.y + (TREE_LINE_HEIGHT / 2);
- plot->line(x0, y0, x1, y1,
- &plot_style_stroke_tree_furniture);
- }
- if (node->next != NULL) {
- /* There is a node below this
- * Display furniture; line connecting down to next */
- x0 = x1 = tree_x + node->box.x - (NODE_INSTEP / 2);
- y0 = tree_y + node->box.y + (TREE_LINE_HEIGHT / 2);
- y1 = tree_y + node->next->box.y;
- plot->line(x0, y0, x1, y1,
- &plot_style_stroke_tree_furniture);
- }
-
- parent = node->parent;
- if ((parent != NULL) && (parent != tree->root) &&
- (parent->child == node)) {
- /* Node is first child */
- x0 = x1 = tree_x + parent->box.x + (NODE_INSTEP / 2);
- y0 = tree_y + parent->data.box.y +
- parent->data.box.height;
- y1 = y0 + (TREE_LINE_HEIGHT / 2);
- plot->line(x0, y0, x1, y1,
- &plot_style_stroke_tree_furniture);
- }
- /* Line from expansion toggle to icon */
- x0 = tree_x + node->box.x - (NODE_INSTEP / 2);
- x1 = x0 + (NODE_INSTEP / 2) - 2;
- y0 = y1 = tree_y + node->data.box.y + node->data.box.height -
- (TREE_LINE_HEIGHT / 2);
- plot->line(x0, y0, x1, y1, &plot_style_stroke_tree_furniture);
-
- tree_draw_node_expansion_toggle(tree, node,
- tree_x, tree_y, ctx);
- }
-
- /* Draw node's element(s)
- * NOTE: node's children are handled later in tree_draw_tree() */
- if (node->expanded) {
- for (element = &node->data; element != NULL;
- element = element->next) {
- /* Draw each element of expanded node */
- tree_draw_node_element(tree, element, tree_x, tree_y,
- &clip, ctx);
- }
- } else {
- /* Draw main title element of node */
- tree_draw_node_element(tree, &node->data, tree_x, tree_y,
- &clip, ctx);
- }
-}
-
-
-/**
- * Redraws a node's descendants.
- *
- * \param tree the tree to draw
- * \param node the node to draw children and siblings of
- * \param tree_x X coordinate to draw the tree at (wrt plot origin)
- * \param tree_y Y coordinate to draw the tree at (wrt plot origin)
- * \param clip clipping rectangle (wrt plot origin)
- * \param ctx current redraw context
- */
-static void tree_draw_tree(struct tree *tree, struct node *node,
- int tree_x, int tree_y, struct rect clip,
- const struct redraw_context *ctx)
-{
- struct node *child;
-
- assert(tree != NULL);
- assert(node != NULL);
-
- for (child = node->child; child != NULL; child = child->next) {
- /* Draw children that are inside the clip region */
-
- if (child->next != NULL &&
- (child->next->box.y + tree_y < clip.y0))
- /* Child is above clip region */
- continue;
- if (child->box.y + tree_y > clip.y1)
- /* Child is below clip region
- * further siblings will be too */
- return;
-
- /* Draw current child */
- tree_draw_node(tree, child, tree_x, tree_y, clip, ctx);
- /* And its children */
- if ((child->child != NULL) && (child->expanded)) {
- /* Child has children and they are visible */
- tree_draw_tree(tree, child, tree_x, tree_y, clip, ctx);
- }
- }
-}
-
-
-/**
* Redraws a tree.
*
* \param tree the tree to draw
@@ -2305,352 +353,10 @@ void tree_draw(struct tree *tree, int x, int y,
int clip_x, int clip_y, int clip_width, int clip_height,
const struct redraw_context *ctx)
{
- struct redraw_context new_ctx = *ctx;
- struct rect clip;
-
assert(tree != NULL);
- assert(tree->root != NULL);
-
- if (treeview_test_redraw(tree, x, y, clip_x, clip_y,
- clip_width, clip_height, ctx)) {
- return;
- }
-
- /* Start knockout rendering if it's available for this plotter */
- if (ctx->plot->option_knockout)
- knockout_plot_start(ctx, &new_ctx);
-
- /* Set up clip rectangle */
- clip.x0 = x + clip_x;
- clip.y0 = y + clip_y;
- clip.x1 = clip.x0 + clip_width;
- clip.y1 = clip.y0 + clip_height;
- new_ctx.plot->clip(&clip);
-
- /* Flat fill extents of clipping area */
- new_ctx.plot->rectangle(clip.x0, clip.y0, clip.x1, clip.y1,
- &plot_style_fill_tree_background);
-
- /* don't draw empty trees or trees with redraw flag set to false */
- if (tree->root->child != NULL && tree->redraw) {
-
- /* Draw the tree */
- tree_draw_tree(tree, tree->root, x, y, clip, &new_ctx);
-
- /* Draw textarea, if present */
- if (tree->editing != NULL) {
- x = x + tree->editing->box.x;
- y = y + tree->editing->box.y;
- if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- x += NODE_INSTEP;
- textarea_redraw(tree->textarea, x, y,
- plot_style_fill_tree_background.
- fill_colour,
- 1.0, &clip, &new_ctx);
- }
- }
-
- /* Rendering complete */
- if (ctx->plot->option_knockout)
- knockout_plot_end();
-}
-
-
-/**
- * Finds a node element from a node with a specific user_type
- *
- * \param node the node to examine
- * \param flag user assinged flag used is searches
- * \param after if this is not NULL the search will start after the given
- * node_element
- * \return the corresponding element
- */
-struct node_element *tree_node_find_element(struct node *node,
- unsigned int flag, struct node_element *after)
-{
- struct node_element *element;
-
- if (after == NULL)
- element = &node->data;
- else {
- assert(after->parent == node);
- element = after->next;
- }
-
- for (; element != NULL; element = element->next)
- if (element->flag == flag) return element;
-
- return NULL;
-}
-
-
-/**
- * Deletes all selected nodes from the tree.
- *
- * \param tree the tree to delete from
- * \param node the node to delete
- */
-void tree_delete_selected_nodes(struct tree *tree, struct node *node)
-{
- struct node *next;
- int y = node->box.y;
- int height = tree->height;
- int width = tree->width;
- bool redraw_setting = tree->redraw;
-
- tree->redraw = false;
-
- if (node == tree->root) {
- if (node->child != NULL)
- tree_delete_selected_nodes(tree, node->child);
-
- tree->redraw = redraw_setting;
-
- if (tree->redraw)
- tree->callbacks->redraw_request(0, y,
- width, height,
- tree->client_data);
- return;
- }
-
- while (node != NULL) {
- next = node->next;
- if (node->selected)
- tree_delete_node(tree, node, false);
- else if (node->child != NULL)
- tree_delete_selected_nodes(tree, node->child);
- node = next;
- }
-
- tree->redraw = redraw_setting;
- if (tree->redraw)
- tree->callbacks->redraw_request(0, y,
- width, height,
- tree->client_data);
-}
-
-
-/**
- * Returns the selected node, or NULL if multiple nodes are selected.
- *
- * \param node the node to search sibling and children
- * \return the selected node, or NULL if multiple nodes are selected
- */
-struct node *tree_get_selected_node(struct node *node)
-{
- struct node *result = NULL;
- struct node *temp;
-
- for (; node != NULL; node = node->next) {
- if (node->selected) {
- if (result != NULL)
- return NULL;
- result = node;
- }
- if ((node->child != NULL) && (node->expanded)) {
- temp = tree_get_selected_node(node->child);
- if (temp != NULL) {
- if (result != NULL)
- return NULL;
- else
- result = temp;
- }
- }
- }
- return result;
-}
-
-
-/**
- * Finds a node element at a specific location.
- *
- * \param node the root node to check from
- * \param x the x co-ordinate
- * \param y the y co-ordinate
- * \param expansion_toggle whether the coordinate was in an expansion toggle
- * \return the node at the specified position, or NULL for none
- */
-static struct node_element *tree_get_node_element_at(struct node *node,
- int x, int y, bool *expansion_toggle)
-{
- struct node_element *element;
- int x0, x1, y0, y1;
-
- *expansion_toggle = false;
- for (; node != NULL; node = node->next) {
- if (node->box.y > y) return NULL;
- if ((node->box.x - NODE_INSTEP < x) && (node->box.y < y) &&
- (node->box.x + node->box.width >= x) &&
- (node->box.y + node->box.height >= y)) {
- if (node->expanded) {
- for (element = &node->data; element != NULL;
- element = element->next) {
- x0 = element->box.x;
- y0 = element->box.y;
- x1 = element->box.x +
- element->box.width;
- y1 = element->box.y +
- element->box.height;
- if ((x0 < x) && (y0 < y) && (x1 >= x)
- && (y1 >= y))
- return element;
- }
- } else {
- x0 = node->data.box.x;
- y0 = node->data.box.y;
- x1 = node->data.box.x + node->data.box.width;
- y1 = node->data.box.y + node->data.box.height;
- if ((x0 < x) && (y0 < y) && (x1 >= x) &&
- (y1>= y))
- return &node->data;
- }
- if (((node->child != NULL) ||
- (node->data.next != NULL)) &&
- (node->data.box.x - NODE_INSTEP + 4 < x)
- && (node->data.box.y + 4 < y) &&
- (node->data.box.x > x) &&
- (node->data.box.y + TREE_LINE_HEIGHT > y)) {
- /* Node either has node children, or node
- * has more than one element.
- * Coordinate is over node expansion toggle area
- */
- *expansion_toggle = true;
- return &node->data;
- }
- }
-
- element = tree_get_node_element_at(node->child, x, y,
- expansion_toggle);
- if ((node->child != NULL) && (node->expanded) &&
- (element != NULL))
- return element;
- }
- return NULL;
-}
-
-
-/**
- * Finds a node at a specific location.
- *
- * \param root the root node to check from
- * \param x the x co-ordinate
- * \param y the y co-ordinate
- * \param expansion_toggle whether the coordinate was in an expansion toggle
- * \return the node at the specified position, or NULL for none
- */
-static struct node *tree_get_node_at(struct node *root, int x, int y,
- bool *expansion_toggle)
-{
- struct node_element *result;
-
- if ((result = tree_get_node_element_at(root, x, y, expansion_toggle)))
- return result->parent;
- return NULL;
-}
-
-
-/**
- * Gets link characteristics to insert a node at a specified position.
- *
- * \param tree the tree to find link information for
- * \param x the x co-ordinate
- * \param y the y co-ordinate
- * \param before set to whether the node should be linked before on exit
- * \return the node to link with
- */
-struct node *tree_get_link_details(struct tree *tree, int x, int y,
- bool *before)
-{
- struct node *node = NULL;
- bool expansion_toggle;
-
- assert(tree != NULL);
- assert(tree->root != NULL);
-
- *before = false;
- if (tree->root->child != NULL)
- node = tree_get_node_at(tree->root->child, x, y,
- &expansion_toggle);
- if ((node == NULL) || (expansion_toggle))
- return tree->root;
-
- if (y < (node->box.y + (node->box.height / 2))) {
- *before = true;
- } else if ((node->folder) && (node->expanded) &&
- (node->child != NULL)) {
- node = node->child;
- *before = true;
- }
- return node;
-}
-
-
-/**
- * Launches all the selected nodes of the tree
- *
- * \param tree the tree for which all nodes will be launched
- * \param node the node which will be checked together with its children
- * \param tabs launch node in a new tab instead of a new window
- */
-static void tree_launch_selected_internal(struct tree *tree, struct node *node,
- bool tabs)
-{
- struct node_msg_data msg_data;
-
- msg_data.data.bw = NULL;
-
- for (; node != NULL; node = node->next) {
- if (node->selected && node->user_callback != NULL) {
- msg_data.msg = NODE_LAUNCH;
- if (tabs == true) {
- msg_data.flag = TREE_ELEMENT_LAUNCH_IN_TABS;
- } else {
- msg_data.flag = TREE_ELEMENT_TITLE;
- }
-
- msg_data.node = node;
- node->user_callback(node->callback_data, &msg_data);
- }
- if (node->child != NULL)
- tree_launch_selected_internal(tree, node->child, tabs);
- }
-}
-
-
-/**
- * Launches all the selected nodes of the tree
- *
- * \param tree the tree for which all nodes will be launched
- * \param tabs launch nodes in new tabs instead of new windows
- */
-void tree_launch_selected(struct tree *tree, bool tabs)
-{
- if (tree->root->child != NULL)
- tree_launch_selected_internal(tree, tree->root->child, tabs);
-}
-
-
-/**
- * Updates the node at position x,y to a selected state.
- * The required areas of the tree are redrawn.
- *
- * \param tree the tree to update nodes for, may be NULL
- * \param x x position in tree
- * \param y y position in tree
- * \param selected the selection state to set
- */
-void tree_set_node_selected_at(struct tree *tree, int x, int y, bool selected)
-{
- bool expansion_toggle;
- struct node *node;
-
- node = tree_get_node_at(tree->root, x, y, &expansion_toggle);
-
- if ((node == NULL) || (expansion_toggle == true))
- return;
-
- tree_set_node_selected(tree, node, false, selected);
+ treeview_test_redraw(tree, x, y, clip_x, clip_y,
+ clip_width, clip_height, ctx);
}
@@ -2666,413 +372,17 @@ void tree_set_node_selected_at(struct tree *tree, int x, int y, bool selected)
bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse, int x,
int y)
{
- bool expansion_toggle;
- struct node *node;
- struct node *last;
- struct node_element *element;
- struct node_msg_data msg_data;
-
- bool double_click_1 = mouse & BROWSER_MOUSE_DOUBLE_CLICK &&
- mouse & BROWSER_MOUSE_CLICK_1;
- bool double_click_2 = mouse & BROWSER_MOUSE_DOUBLE_CLICK &&
- mouse & BROWSER_MOUSE_CLICK_2;
-
assert(tree != NULL);
- assert(tree->root != NULL);
if (treeview_test_mouse_action(tree, mouse, x, y)) {
return true;
}
- if (tree->root->child == NULL)
- return true;
-
- element = tree_get_node_element_at(tree->root->child, x, y,
- &expansion_toggle);
-
- /* pass in-textarea mouse action and drags which started in it
- to the textarea */
- if (tree->editing != NULL) {
- int x0, x1, y0, y1;
- x0 = tree->editing->box.x;
- if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- x0 += NODE_INSTEP;
- x1 = tree->editing->box.x + tree->editing->box.width;
- y0 = tree->editing->box.y;
- y1 = tree->editing->box.y + tree->ta_height;
-
- if (tree->drag == TREE_TEXTAREA_DRAG &&
- (mouse & (BROWSER_MOUSE_HOLDING_1 |
- BROWSER_MOUSE_HOLDING_2))) {
- /* Track the drag path */
- textarea_mouse_action(tree->textarea, mouse,
- x - x0, y - y0);
- return true;
- }
-
- if ((x >= x0) && (x < x1) && (y >= y0) && (y < y1)) {
- textarea_mouse_action(tree->textarea, mouse,
- x - x0, y - y0);
- return true;
-
- }
- }
-
- /* we are not interested in the drag path, return */
- if (mouse & (BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_HOLDING_2))
- return true;
-
- /* cancel edit */
- if (tree->editing != NULL)
- tree_stop_edit(tree, false);
-
- /* no item either means cancel selection on (select) click or a drag */
- if (element == NULL) {
- if (tree->flags & TREE_SINGLE_SELECT) {
- tree_set_node_selected(tree, tree->root->child, true,
- false);
- return true;
- }
- if (mouse & (BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_DRAG_1))
- tree_set_node_selected(tree, tree->root->child, true,
- false);
- if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2)) {
-
- /** @todo the tree window has to scroll the tree when
- * mouse reaches border while dragging this isn't
- * solved for the browser window too.
- */
- tree->drag = TREE_SELECT_DRAG;
- }
- return true;
- }
-
- node = element->parent;
-
- /* A click on expansion toggle or double click on folder toggles node
- * expansion */
- if (((expansion_toggle) && (mouse & (BROWSER_MOUSE_CLICK_1 |
- BROWSER_MOUSE_CLICK_2))) ||
- (((!expansion_toggle) && (node->child != NULL)) &&
- (double_click_1 || double_click_2))) {
-
- /* clear any selection */
- tree_set_node_selected(tree, tree->root->child, true, false);
-
- /* expand / contract node and redraw */
- tree_set_node_expanded(tree, node, !node->expanded,
- false, false);
-
- /* find the last child node if expanded */
- last = node;
- if ((last->child != NULL) && (last->expanded)) {
- last = last->child;
- while ((last->next != NULL) ||
- ((last->child != NULL) &&
- (last->expanded))) {
- if (last->next != NULL)
- 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 != NULL; element = element->next);
- tree->callbacks->scroll_visible(element->box.y,
- element->box.height,
- tree->client_data);
- tree->callbacks->scroll_visible(node->data.box.y,
- node->data.box.height,
- tree->client_data);
- return true;
- }
-
- /* no use for any other expansion toggle click */
- if (expansion_toggle)
- return true;
-
- /* single/double ctrl+click or alt+click starts editing */
- if ((element->editable) && (!tree->editing) &&
- ((element->type == NODE_ELEMENT_TEXT) ||
- (element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) &&
- (mouse & BROWSER_MOUSE_CLICK_1 || double_click_1) &&
- (mouse & BROWSER_MOUSE_MOD_2 ||
- mouse & BROWSER_MOUSE_MOD_3)) {
- tree_set_node_selected(tree, tree->root->child, true, false);
- tree_start_edit(tree, element);
- return true;
- }
-
- /* double click launches the leaf */
- if (double_click_1 || double_click_2) {
- if (node->user_callback == NULL)
- return false;
- msg_data.msg = NODE_LAUNCH;
- msg_data.flag = TREE_ELEMENT_TITLE;
- msg_data.node = node;
- if (node->user_callback(node->callback_data, &msg_data) !=
- NODE_CALLBACK_HANDLED)
- return false;
-
- return true;
- }
-
- /* single click (select) cancels current selection and selects item */
- if (mouse & BROWSER_MOUSE_CLICK_1 || (mouse & BROWSER_MOUSE_CLICK_2 &&
- tree->flags & TREE_SINGLE_SELECT)) {
- if (tree->flags & TREE_NO_SELECT)
- return true;
- if (!node->selected) {
- tree_set_node_selected(tree, tree->root->child, true,
- false);
- node->selected = true;
- tree_handle_node_element_changed(tree, &node->data, false);
- }
- return true;
- }
-
- /* single click (adjust) toggles item selection */
- if (mouse & BROWSER_MOUSE_CLICK_2) {
- if (tree->flags & TREE_NO_SELECT)
- return true;
- node->selected = !node->selected;
- tree_handle_node_element_changed(tree, &node->data, false);
- return true;
- }
-
- /* drag starts a drag operation */
- if ((!tree->editing) && (mouse & (BROWSER_MOUSE_DRAG_1 |
- BROWSER_MOUSE_DRAG_2))) {
- if (tree->flags & TREE_NO_DRAGS)
- return true;
-
- if (!node->selected) {
- tree_set_node_selected(tree, tree->root->child, true,
- false);
- node->selected = true;
- tree_handle_node_element_changed(tree, &node->data, false);
- }
-
- if (tree->flags & TREE_MOVABLE)
- tree->drag = TREE_MOVE_DRAG;
- else tree->drag = TREE_UNKNOWN_DRAG;
-
- return true;
- }
-
-
return false;
}
/**
- * Updates the selected state for a region of nodes.
- *
- * \param tree the tree to update
- * \param node the node to update children and siblings of
- * \param y the minimum y of the selection rectangle
- * \param height the height of the selection rectangle
- * \param invert whether to invert the selected state
- */
-static void tree_handle_selection_area_node(struct tree *tree,
- struct node *node, int y, int height, bool invert)
-{
- struct node_element *element;
- struct node *update;
- int y_max;
- int y0, y1;
-
- assert(tree != NULL);
- assert(node != NULL);
-
- y_max = y + height;
-
- for (; node != NULL; node = node->next) {
- if (node->box.y > y_max) return;
- y0 = node->box.y;
- y1 = node->box.y + node->box.height;
- if ((y0 < y_max) && (y1 >= y)) {
- update = NULL;
- if (node->expanded) {
- for (element = &node->data; element != NULL;
- element = element->next) {
- y0 = element->box.y;
- y1 = element->box.y +
- element->box.height;
- if ((y0 < y_max) && (y1 >= y)) {
- update = element->parent;
- break;
- }
- }
- } else {
- y0 = node->data.box.y;
- y1 = node->data.box.y + node->data.box.height;
- if ((y0 < y_max) && (y1 >= y))
- update = node->data.parent;
- }
- if ((update) && (node != tree->root)) {
- if (invert) {
- node->selected = !node->selected;
- tree_handle_node_element_changed(tree,
- &node->data, false);
- } else if (!node->selected) {
- node->selected = true;
- tree_handle_node_element_changed(tree,
- &node->data, false);
- }
- }
- }
- if ((node->child != NULL) && (node->expanded))
- tree_handle_selection_area_node(tree, node->child, y,
- height, invert);
- }
-}
-
-
-/**
- * Updates the selected state for a region of nodes.
- *
- * \param tree the tree to update
- * \param y the minimum y of the selection rectangle
- * \param height the height of the selection rectangle
- * \param invert whether to invert the selected state
- */
-static void tree_handle_selection_area(struct tree *tree, int y, int height,
- bool invert)
-{
- assert(tree != NULL);
- assert(tree->root != NULL);
-
- if (tree->root->child == NULL)
- return;
-
- if (height < 0) {
- y += height;
- height = -height;
- }
- tree_handle_selection_area_node(tree, tree->root->child, y, height,
- invert);
-}
-
-
-/**
- * Clears the processing flag.
- *
- * \param node the node to process siblings and children of
- */
-static void tree_clear_processing(struct node *node)
-{
- for (; node != NULL; node = node->next) {
- node->processing = false;
- if (node->child != NULL)
- tree_clear_processing(node->child);
- }
-}
-
-
-/**
- * Sets the processing flag to the selection state.
- *
- * \param node the node to process siblings and children of
- */
-static void tree_selected_to_processing(struct node *node)
-{
- for (; node != NULL; node = node->next) {
- node->processing = node->selected;
- if ((node->child != NULL) && (node->expanded))
- tree_selected_to_processing(node->child);
- }
-}
-
-
-/**
- * Moves the first node in a tree with the processing flag set.
- *
- * \param tree the tree in which the move takes place
- * \param node the node to move siblings/children of
- * \param link the node to link before/as a child (folders) or before/after
- * (link)
- * \param before whether to link siblings before or after the supplied node
- * \param first whether to always link after the supplied node (ie not
- * inside of folders)
- * \return the node moved
- */
-static struct node *tree_move_processing_node(struct tree *tree,
- struct node *node, struct node *link, bool before, bool first)
-{
- struct node *result;
-
- bool folder = link->folder;
- for (; node != NULL; node = node->next) {
- if (node->processing) {
- node->processing = false;
- tree_delink_node(tree, node);
- if (!first)
- link->folder = false;
- tree_link_node(tree, link, node, before);
- if (!first)
- link->folder = folder;
- return node;
- }
- if (node->child != NULL) {
- result = tree_move_processing_node(tree, node->child,
- link, before, first);
- if (result != NULL)
- return result;
- }
- }
- return NULL;
-}
-
-
-/**
- * Moves nodes within a tree.
- *
- * \param tree the tree to process
- * \param destination the node to link before/as a child (folders)
- * or before/after (link)
- * \param before whether to link siblings before or after the supplied
- * node
- */
-static void tree_move_selected_nodes(struct tree *tree,
- struct node *destination, bool before)
-{
- struct node *link;
- struct node *test;
- bool error;
-
- tree_clear_processing(tree->root);
- tree_selected_to_processing(tree->root);
-
- /* the destination node cannot be a child of any node with
- the processing flag set */
- error = destination->processing;
- for (test = destination; test != NULL; test = test->parent)
- error |= test->processing;
- if (error) {
- tree_clear_processing(tree->root);
- return;
- }
- if ((destination->folder) && (!destination->expanded) && (!before)) {
- tree_set_node_expanded(tree, destination, true, false, false);
- }
- link = tree_move_processing_node(tree, tree->root, destination, before,
- true);
- while (link != NULL)
- link = tree_move_processing_node(tree, tree->root, link, false,
- false);
-
- tree_clear_processing(tree->root);
- tree_recalculate_node_positions(tree, tree->root);
- if (tree->redraw)
- tree->callbacks->redraw_request(0, 0, tree->width, tree->height,
- tree->client_data);
-}
-
-
-/**
* Handle the end of a drag operation
*
* \param tree the tree on which the drag was performed
@@ -3085,43 +395,9 @@ static void tree_move_selected_nodes(struct tree *tree,
void tree_drag_end(struct tree *tree, browser_mouse_state mouse, int x0, int y0,
int x1, int y1)
{
+ assert(tree != NULL);
- bool before;
- struct node *node;
- int x, y;
-
- if (treeview_test_mouse_action(tree, BROWSER_MOUSE_HOVER, x1, y1)) {
- return;
- }
-
- switch (tree->drag) {
- case TREE_NO_DRAG:
- case TREE_UNKNOWN_DRAG:
- break;
-
- case TREE_TEXTAREA_DRAG:
- x = tree->editing->box.x;
- y = tree->editing->box.y;
- if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- x += NODE_INSTEP;
- textarea_mouse_action(tree->textarea, BROWSER_MOUSE_HOVER,
- x1 - x, y1 - y);
- break;
-
- case TREE_SELECT_DRAG:
- tree_handle_selection_area(tree, y0, y1 - y0,
- (mouse | BROWSER_MOUSE_HOLDING_2));
- break;
-
- case TREE_MOVE_DRAG:
- if (!(tree->flags & TREE_MOVABLE))
- return;
- node = tree_get_link_details(tree, x1, y1, &before);
- tree_move_selected_nodes(tree, node, before);
- break;
- }
-
- tree->drag = TREE_NO_DRAG;
+ treeview_test_mouse_action(tree, BROWSER_MOUSE_HOVER, x1, y1);
}
@@ -3138,231 +414,11 @@ bool tree_keypress(struct tree *tree, uint32_t key)
return true;
}
- if (tree->editing != NULL)
- switch (key) {
- case KEY_ESCAPE:
- tree_stop_edit(tree, false);
- return true;
- case KEY_NL:
- case KEY_CR:
- tree_stop_edit(tree, true);
- return true;
- default:
- return textarea_keypress(tree->textarea, key);
- }
-
return false;
}
-
-/**
- * Alphabetical comparison function for nodes
- *
- * \param n1 first node to compare
- * \param n2 first node to compare
- * \return 0 if equal, greater then zero if n1 > n2,
- * less then zero if n2 < n1
- */
-int tree_alphabetical_sort(struct node *n1, struct node *n2)
-{
- return strcmp(n1->data.text, n2->data.text);
-}
-
-
-/**
- * Redraw requests from the textarea are piped through this because we have to
- * check the redraw flag of the tree before requesting a redraw and change the
- * position to tree origin relative.
- */
-
-static void tree_textarea_callback(void *data, struct textarea_msg *msg)
-{
- struct tree *tree = data;
- int x, y;
-
- switch (msg->type) {
- case TEXTAREA_MSG_DRAG_REPORT:
- if (msg->data.drag == TEXTAREA_DRAG_NONE) {
- /* Textarea drag finished */
- tree->drag = TREE_NO_DRAG;
- } else {
- /* Textarea drag started */
- tree->drag = TREE_TEXTAREA_DRAG;
- }
- break;
-
- case TEXTAREA_MSG_REDRAW_REQUEST:
- x = msg->data.redraw.x0 + tree->editing->box.x;
- y = msg->data.redraw.y0 + tree->editing->box.y;
-
- if (tree->editing->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- x += NODE_INSTEP;
-
- /* Redraw the textarea */
- if (tree->redraw)
- tree->callbacks->redraw_request(x, y,
- msg->data.redraw.x1 -
- msg->data.redraw.x0,
- msg->data.redraw.y1 -
- msg->data.redraw.y0,
- tree->client_data);
- break;
-
- default:
- break;
- }
-}
-
-
-/**
- * Starts editing a node_element
- *
- * \param tree The tree to which element belongs
- * \param element The element to start being edited
- */
-void tree_start_edit(struct tree *tree, struct node_element *element)
+tree_drag_type tree_drag_status(struct tree *tree)
{
- struct node *parent;
- int width, height;
- textarea_setup ta_setup;
- textarea_flags ta_flags;
-
assert(tree != NULL);
- assert(element != NULL);
-
- if (tree->editing != NULL)
- tree_stop_edit(tree, true);
-
- parent = element->parent;
- if (&parent->data == element)
- parent = parent->parent;
- for (; parent != NULL; parent = parent->parent) {
- if (!parent->expanded) {
- tree_set_node_expanded(tree, parent, true,
- false, false);
- }
- }
-
- tree->editing = element;
- tree->callbacks->get_window_dimensions(&width, NULL, tree->client_data);
- width -= element->box.x;
- height = element->box.height;
- if (element->type == NODE_ELEMENT_TEXT_PLUS_ICON)
- width -= NODE_INSTEP;
-
- tree->ta_height = height;
-
- ta_flags = TEXTAREA_INTERNAL_CARET;
-
- ta_setup.width = width;
- ta_setup.height = tree->ta_height;
- ta_setup.pad_top = 0;
- ta_setup.pad_right = 4;
- ta_setup.pad_bottom = 0;
- ta_setup.pad_left = 4;
- ta_setup.border_width = 1;
- ta_setup.border_col = 0x000000;
- ta_setup.selected_text = 0xffffff;
- ta_setup.selected_bg = 0x000000;
- ta_setup.text = plot_fstyle;
- ta_setup.text.foreground = 0x000000;
- ta_setup.text.background = 0xffffff;
-
- tree->textarea = textarea_create(ta_flags, &ta_setup,
- tree_textarea_callback, tree);
- if (tree->textarea == NULL) {
- tree_stop_edit(tree, false);
- return;
- }
- textarea_set_text(tree->textarea, element->text);
-
- tree_handle_node_element_changed(tree, element, true);
- tree_recalculate_size(tree);
- tree->callbacks->scroll_visible(element->box.y, element->box.height,
- tree->client_data);
-}
-
-
-/**
- * Callback for fetchcache(). Should be removed once bitmaps get loaded directly
- * from disc
- */
-static nserror tree_icon_callback(hlcache_handle *handle,
- const hlcache_event *event, void *pw)
-{
- return NSERROR_OK;
-}
-
-
-/**
- * Tree utility function. Placed here so that this code doesn't have to be
- * copied by each user.
- *
- * \param name the name of the loaded icon, if it's not a full path the icon is
- * looked for in the directory specified by tree_icons_dir
- * \return the icon in form of a content or NULL on failure
- */
-hlcache_handle *tree_load_icon(const char *name)
-{
- char *url = NULL;
- const char *icon_url = NULL;
- int len;
- hlcache_handle *c;
- nserror err;
- nsurl *icon_nsurl;
-
- /** @todo something like bitmap_from_disc is needed here */
-
- if (!strncmp(name, "file://", 7)) {
- icon_url = name;
- } else {
- char *native_path;
-
- if (tree_icons_dir == NULL)
- return NULL;
-
- /* path + separator + leafname + '\0' */
- len = strlen(tree_icons_dir) + 1 + strlen(name) + 1;
- native_path = malloc(len);
- if (native_path == NULL) {
- LOG(("malloc failed"));
- warn_user("NoMemory", 0);
- return NULL;
- }
-
- /* Build native path */
- memcpy(native_path, tree_icons_dir,
- strlen(tree_icons_dir) + 1);
- path_add_part(native_path, len, name);
-
- /* Convert native path to URL */
- url = path_to_url(native_path);
-
- free(native_path);
- icon_url = url;
- }
-
- err = nsurl_create(icon_url, &icon_nsurl);
- if (err != NSERROR_OK) {
- if (url != NULL)
- free(url);
- return NULL;
- }
-
- /* Fetch the icon */
- err = hlcache_handle_retrieve(icon_nsurl, 0, 0, 0,
- tree_icon_callback, 0, 0,
- CONTENT_IMAGE, &c);
-
- nsurl_unref(icon_nsurl);
-
- /* If we built the URL here, free it */
- if (url != NULL)
- free(url);
-
- if (err != NSERROR_OK) {
- return NULL;
- }
-
- return c;
+ return tree->drag;
}
diff --git a/desktop/tree.h b/desktop/tree.h
index 84d90f316..52bea7d13 100644
--- a/desktop/tree.h
+++ b/desktop/tree.h
@@ -28,48 +28,22 @@
#include <stdint.h>
#include "desktop/browser.h"
-#include "image/bitmap.h"
struct sslcert_session_data;
extern struct sslcert_session_data *ssl_current_session;
extern const char *tree_hotlist_path;
-
-struct hlcache_handle;
-
/* Tree flags */
enum tree_flags {
- TREE_NO_FLAGS = 0,
- TREE_NO_DRAGS = 1,
- TREE_NO_FURNITURE = 2,
- TREE_SINGLE_SELECT = 4,
- TREE_NO_SELECT = 8,
- TREE_MOVABLE = 16,
- TREE_DELETE_EMPTY_DIRS = 32, /**< if the last child of a
- * directory is deleted the
- * directory will be deleted
- * too.
- */
- /* The following are to aid transition to new treeviews */
- TREE_HISTORY = 64,
- TREE_COOKIES = 128,
- TREE_SSLCERT = 256,
- TREE_HOTLIST = 512
+ TREE_HISTORY,
+ TREE_COOKIES,
+ TREE_SSLCERT,
+ TREE_HOTLIST
};
-/** A "flag" value to indicate the element data contains title
- * text. This value should be the first node_element in every
- * node. All other values should be different than this one. The term
- * flag is misused as it is actually a value used by the API consumer
- * to indicate teh type of data a node element contains.
- */
-#define TREE_ELEMENT_TITLE 0x00
-#define TREE_ELEMENT_LAUNCH_IN_TABS 0x05 /* Launch in tabs instead of windows */
struct tree;
-struct node;
-struct node_element;
typedef enum {
TREE_NO_DRAG = 0,
@@ -79,45 +53,6 @@ typedef enum {
TREE_UNKNOWN_DRAG /** < A drag the tree itself won't handle */
} tree_drag_type;
-typedef enum {
- NODE_ELEMENT_TEXT, /**< Text only */
- NODE_ELEMENT_TEXT_PLUS_ICON, /**< Text and icon */
- NODE_ELEMENT_BITMAP /**< Bitmap only */
-} node_element_type;
-
-typedef enum {
- NODE_DELETE_ELEMENT_TXT, /**< The text of an element of the
- * node is being deleted */
- NODE_DELETE_ELEMENT_IMG, /**< The bitmap or icon of a node is
- * being deleted */
- NODE_LAUNCH, /**< The node has been launched */
- NODE_ELEMENT_EDIT_CANCELLED, /**< Editing opperation cancelled. */
- NODE_ELEMENT_EDIT_FINISHING, /**< New text has to be accepted
- * or rejected. */
- NODE_ELEMENT_EDIT_FINISHED /**< Editing of a node_element has
- * been finished. */
-} node_msg;
-
-typedef enum {
- NODE_CALLBACK_HANDLED,
- NODE_CALLBACK_NOT_HANDLED,
- NODE_CALLBACK_REJECT, /**< reject new text for node element
- * and leave editing mode. */
- NODE_CALLBACK_CONTINUE /**< don't leave editig mode. */
-} node_callback_resp;
-
-/** Internal node message. */
-struct node_msg_data {
- node_msg msg; /**< The type of message. */
- unsigned int flag; /**< message flags. */
- struct node *node; /**< tree node messsage concerns. */
- union {
- char *text; /**< textural data. */
- void *bitmap; /**< bitmap data. */
- struct browser_window *bw; /**< clone browser_window. */
- } data; /**< The message data. */
-};
-
/** callbacks to perform necessary operations on treeview. */
struct treeview_table {
void (*redraw_request)(int x, int y, int width, int height,
@@ -128,123 +63,20 @@ struct treeview_table {
void (*get_window_dimensions)(int *width, int *height, void *data); /**< get dimensions of window */
};
-/**
- * Informs the client about any events requiring his action
- *
- * \param user_data the user data which was passed at tree creation
- * \param msg_data structure containing all the message information
- * \return the appropriate node_callback_resp response
- */
-typedef node_callback_resp (*tree_node_user_callback)(void *user_data,
- struct node_msg_data *msg_data);
-
-/* Non-platform specific code */
-
-void tree_set_icon_dir(char *icon_dir);
-void tree_setup_colours(void);
-
-/* Functions for creating/deleting tree primitives and for tree structure
- manipulation */
struct tree *tree_create(unsigned int flags,
const struct treeview_table *callbacks,
void *client_data);
-/**
- * Creates a folder node with the specified title, and optionally links it into
- * the tree.
- *
- * \param tree the owner tree of 'parent', may be NULL
- * \param parent the parent node, or NULL not to link
- * \param title the node title
- * \param editable if true, the node title will be editable
- * \param retain_in_memory if true, the node will stay in memory after deletion
- * \param deleted if true, the node is created with the deleted flag
- * \return the newly created node or NULL on error.
- */
-struct node *tree_create_folder_node(struct tree *tree, struct node *parent,
- const char *title, bool editable, bool retain_in_memory,
- bool deleted);
-
-/**
- * Creates a leaf node with the specified title, and optionally links it into
- * the tree.
- *
- * \param tree the owner tree of 'parent', may be NULL
- * \param parent the parent node, or NULL not to link
- * \param title the node title.
- * \param editable if true, the node title will be editable
- * \param retain_in_memory if true, the node will stay in memory after deletion
- * \param deleted if true, the node is created with the deleted flag
- * \return the newly created node or NULL on error.
- */
-struct node *tree_create_leaf_node(struct tree *tree, struct node *parent,
- const char *title, bool editable, bool retain_in_memory,
- bool deleted);
-
-struct node_element *tree_create_node_element(struct node *parent,
- node_element_type type, unsigned int flag, bool editable);
-void tree_link_node(struct tree *tree, struct node *link, struct node *node,
- bool before);
-void tree_delink_node(struct tree *tree, struct node *node);
void tree_delete(struct tree *tree);
-void tree_delete_node(struct tree *tree, struct node *node, bool siblings);
-
-/* setters and getters for properties and data */
-void tree_set_node_icon(struct tree *tree, struct node *node,
- struct hlcache_handle *icon);
-void tree_set_node_expanded(struct tree *tree, struct node *node, bool expanded,
- bool folder, bool leaf);
-void tree_set_node_selected(struct tree *tree, struct node *node, bool all,
- bool selected);
-void tree_set_node_selected_at(struct tree *tree, int x, int y, bool selected);
-void tree_set_node_sort_function(struct tree *tree, struct node *node,
- int (*sort) (struct node *, struct node *));
-void tree_set_node_user_callback(struct node *node,
- tree_node_user_callback callback, void *data);
-void tree_set_redraw(struct tree *tree, bool redraw);
-bool tree_get_redraw(struct tree *tree);
-bool tree_node_has_selection(struct node *node);
-bool tree_node_is_deleted(struct node *node);
-bool tree_node_is_folder(struct node *node);
-bool tree_node_is_default(struct node *node);
-void tree_update_node_element(struct tree *tree, struct node_element *element,
- const char *text, void *bitmap);
-bool tree_update_element_text(struct tree *tree, struct node_element *element, char *text);
-const char *tree_node_element_get_text(struct node_element *element);
-struct bitmap *tree_node_element_get_icon(struct node_element *element);
-struct node *tree_get_root(struct tree *tree);
-bool tree_is_edited(struct tree *tree);
tree_drag_type tree_drag_status(struct tree *tree);
-
-struct node *tree_get_default_folder_node(struct tree *tree);
-bool tree_set_default_folder_node(struct tree *tree, struct node *node);
-void tree_clear_default_folder_node(struct tree *tree);
-
-/* functions for traversing the tree */
-struct node *tree_node_get_parent(struct node *node);
-struct node *tree_node_get_child(struct node *node);
-struct node *tree_node_get_next(struct node *node);
-
void tree_draw(struct tree *tree, int x, int y,
int clip_x, int clip_y, int clip_width, int clip_height,
const struct redraw_context *ctx);
-
-struct node_element *tree_node_find_element(struct node *node,
- unsigned int flag, struct node_element *after);
-void tree_delete_selected_nodes(struct tree *tree, struct node *node);
-struct node *tree_get_selected_node(struct node *node);
-struct node *tree_get_link_details(struct tree *tree, int x, int y,
- bool *before);
-void tree_launch_selected(struct tree *tree, bool tabs);
-
bool tree_mouse_action(struct tree *tree, browser_mouse_state mouse,
int x, int y);
void tree_drag_end(struct tree *tree, browser_mouse_state mouse, int x0, int y0,
int x1, int y1);
bool tree_keypress(struct tree *tree, uint32_t key);
-int tree_alphabetical_sort(struct node *, struct node *);
-void tree_start_edit(struct tree *tree, struct node_element *element);
-struct hlcache_handle *tree_load_icon(const char *name);
#endif