Gitweb links:
...log
http://git.netsurf-browser.org/netsurf.git/shortlog/de1f0afde282acbf46c03...
...commit
http://git.netsurf-browser.org/netsurf.git/commit/de1f0afde282acbf46c03cc...
...tree
http://git.netsurf-browser.org/netsurf.git/tree/de1f0afde282acbf46c03ccba...
The branch, master has been updated
via de1f0afde282acbf46c03ccba4148974ebf8b210 (commit)
via ec50fdaefa90f55e664a2e4d83c44ad37d51ca14 (commit)
via 3e33721ab6498deecd611fde8595d690a505e55e (commit)
via 5616221064b7cf503373a00faed854fc83c09a02 (commit)
from c256320b082fe7fb7ef0f0e4360fd3965170f7d4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=de1f0afde282acbf46c...
commit de1f0afde282acbf46c03ccba4148974ebf8b210
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Change how nodes are deleted.
diff --git a/desktop/treeview.c b/desktop/treeview.c
index 9a9aa41..5b2d327 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -469,34 +469,123 @@ nserror treeview_create_node_entry(treeview *tree,
}
-/**
- * Delete a treeview node
+/* Walk a treeview subtree, calling a callback at each node (depth first)
*
- * \param tree Treeview object to delete node from
- * \param n Node to delete
- * \param interaction Delete is result of user interaction with treeview
- * \return NSERROR_OK on success, appropriate error otherwise
+ * \param root Root to walk tree from (doesn't get a callback call)
+ * \param full Iff true, visit children of collapsed nodes
+ * \param callback_bwd Function to call on each node in backwards order
+ * \param callback_fwd Function to call on each node in forwards order
+ * \param ctx Context to pass to callback
+ * \return NSERROR_OK on success, or appropriate error otherwise
*
- * Will emit folder or entry deletion msg callback.
+ * Note: Any node deletion must happen in callback_bwd.
*/
-static nserror treeview_delete_node_internal(treeview *tree,
- treeview_node *n, bool interaction)
+static nserror treeview_walk_internal(treeview_node *root, bool full,
+ nserror (*callback_bwd)(treeview_node *n, void *ctx, bool *end),
+ nserror (*callback_fwd)(treeview_node *n, void *ctx,
+ bool *skip_children, bool *end),
+ void *ctx)
{
- struct treeview_node_msg msg;
- msg.msg = TREE_MSG_NODE_DELETE;
- treeview_node *p;
- static int nest_depth = 0;
+ treeview_node *node, *child, *parent, *next_sibling;
+ bool abort = false;
+ bool skip_children = false;
+ nserror err;
- if (interaction && (tree->flags & TREEVIEW_NO_DELETES)) {
- return NSERROR_OK;
- }
+ node = root;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (!skip_children &&
+ (full || (node->flags & TREE_NODE_EXPANDED))) ?
+ node->children : NULL;
+
+ while (node != NULL) {
- /* Destroy children first */
- nest_depth++;
- while (n->children != NULL) {
- treeview_delete_node_internal(tree, n->children, interaction);
+ if (child != NULL) {
+ /* Down to children */
+ node = child;
+ } else {
+ /* No children. As long as we're not at the root,
+ * go to next sibling if present, or nearest ancestor
+ * with a next sibling. */
+
+ while (node != root &&
+ next_sibling == NULL) {
+ if (callback_bwd != NULL) {
+ /* Backwards callback */
+ err = callback_bwd(node, ctx, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early
+ * termination */
+ return NSERROR_OK;
+ }
+ }
+ node = parent;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ }
+
+ if (node == root)
+ break;
+
+ if (callback_bwd != NULL) {
+ /* Backwards callback */
+ err = callback_bwd(node, ctx, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early
+ * termination */
+ return NSERROR_OK;
+ }
+ }
+ node = next_sibling;
+ }
+
+ assert(node != NULL);
+ assert(node != root);
+
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (full || (node->flags & TREE_NODE_EXPANDED)) ?
+ node->children : NULL;
+
+ if (callback_fwd != NULL) {
+ /* Forwards callback */
+ err = callback_fwd(node, ctx, &skip_children, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early termination */
+ return NSERROR_OK;
+ }
+ }
+ child = skip_children ? NULL : child;
}
- nest_depth--;
+ return NSERROR_OK;
+}
+
+
+struct treeview_node_delete {
+ treeview *tree;
+ int height_reduction;
+};
+/** Treewalk node callback deleting nodes. */
+static nserror treeview_delete_node_walk_cb(treeview_node *n,
+ void *ctx, bool *end)
+{
+ struct treeview_node_delete *nd = (struct treeview_node_delete *)ctx;
+ struct treeview_node_msg msg;
+ msg.msg = TREE_MSG_NODE_DELETE;
+
+ assert(n->children == NULL);
/* Unlink node from tree */
if (n->parent != NULL && n->parent->children == n) {
@@ -514,19 +603,19 @@ static nserror treeview_delete_node_internal(treeview *tree,
}
/* Reduce ancestor heights */
- p = n->parent;
- while (p != NULL && p->flags & TREE_NODE_EXPANDED) {
- p->height -= n->height;
- p = p->parent;
+ if (n->parent != NULL && n->parent->flags & TREE_NODE_EXPANDED) {
+ int height = (n->type == TREE_NODE_ENTRY) ? n->height :
+ tree_g.line_height;
+ nd->height_reduction += height;
}
/* Handle any special treatment */
switch (n->type) {
case TREE_NODE_ENTRY:
- tree->callbacks->entry(msg, n->client_data);
+ nd->tree->callbacks->entry(msg, n->client_data);
break;
case TREE_NODE_FOLDER:
- tree->callbacks->folder(msg, n->client_data);
+ nd->tree->callbacks->folder(msg, n->client_data);
break;
case TREE_NODE_ROOT:
break;
@@ -534,26 +623,145 @@ static nserror treeview_delete_node_internal(treeview *tree,
return NSERROR_BAD_PARAMETER;
}
- if (nest_depth == 0) {
- /* This is the node we were originally asked to delete */
-
- if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS &&
- n->parent != NULL &&
- n->parent->type != TREE_NODE_ROOT &&
- n->parent->children == NULL) {
- /* Delete empty parent */
- nest_depth++;
- treeview_delete_node_internal(tree, n->parent,
- interaction);
- nest_depth--;
- }
+ /* Free the node */
+ free(n);
- /* Inform front end of change in dimensions */
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ return NSERROR_OK;
+}
+/**
+ * Delete a treeview node
+ *
+ * \param tree Treeview object to delete node from
+ * \param n Node to delete
+ * \param interaction Delete is result of user interaction with treeview
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * Will emit folder or entry deletion msg callback.
+ *
+ * Note this can be called from inside a treeview_walk fwd callback.
+ * For example walking the tree and calling this for any node that's selected.
+ *
+ * This function does not delete empty nodes, so if TREEVIEW_DEL_EMPTY_DIRS is
+ * set, caller must also call treeview_delete_empty.
+ */
+static nserror treeview_delete_node_internal(treeview *tree, treeview_node *n,
+ bool interaction)
+{
+ nserror err;
+ treeview_node *p = n->parent;
+ struct treeview_node_delete nd = {
+ .tree = tree,
+ .height_reduction = 0
+ };
+
+ if (interaction && (tree->flags & TREEVIEW_NO_DELETES)) {
+ return NSERROR_OK;
}
- /* Free the node */
- free(n);
+ /* Delete any children first */
+ err = treeview_walk_internal(n, true, treeview_delete_node_walk_cb,
+ NULL, &nd);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ /* Now delete node */
+ if (n == tree->root)
+ tree->root = NULL;
+ err = treeview_delete_node_walk_cb(n, &nd, false);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ /* Reduce ancestor heights */
+ while (p != NULL && p->flags & TREE_NODE_EXPANDED) {
+ p->height -= nd.height_reduction;
+ p = p->parent;
+ }
+
+ /* Inform front end of change in dimensions */
+ if (tree->root != NULL)
+ tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Delete a treeview node
+ *
+ * \param tree Treeview object to delete empty nodes from
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * Note this must not be called within a treeview_walk. It may delete the
+ * walker's 'current' node, making it impossible to move on without invalid
+ * reads.
+ */
+static nserror treeview_delete_empty_nodes(treeview *tree)
+{
+ treeview_node *node, *child, *parent, *next_sibling;
+ treeview_node *root = tree->root;
+ bool abort = false;
+ nserror err;
+ struct treeview_node_delete nd = {
+ .tree = tree,
+ .height_reduction = 0
+ };
+
+ node = root;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (node->flags & TREE_NODE_EXPANDED) ? node->children : NULL;
+
+ while (node != NULL) {
+
+ if (child != NULL) {
+ /* Down to children */
+ node = child;
+ } else {
+ /* No children. As long as we're not at the root,
+ * go to next sibling if present, or nearest ancestor
+ * with a next sibling. */
+
+ while (node != root &&
+ next_sibling == NULL) {
+ if (node->type == TREE_NODE_FOLDER &&
+ node->children == NULL) {
+ /* Delete node */
+ err = treeview_delete_node_walk_cb(
+ node, &nd, &abort);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+ }
+ node = parent;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ }
+
+ if (node == root)
+ break;
+
+ if (node->type == TREE_NODE_FOLDER &&
+ node->children == NULL) {
+ /* Delete node */
+ err = treeview_delete_node_walk_cb(
+ node, &nd, &abort);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+ }
+ node = next_sibling;
+ }
+
+ assert(node != NULL);
+ assert(node != root);
+
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (node->flags & TREE_NODE_EXPANDED) ?
+ node->children : NULL;
+ }
return NSERROR_OK;
}
@@ -562,7 +770,20 @@ static nserror treeview_delete_node_internal(treeview *tree,
/* Exported interface, documented in treeview.h */
nserror treeview_delete_node(treeview *tree, treeview_node *n)
{
- return treeview_delete_node_internal(tree, n, false);
+ nserror err;
+
+ err = treeview_delete_node_internal(tree, n, false);
+ if (err != NSERROR_OK)
+ return err;
+
+ if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS) {
+ /* Delete any empty nodes */
+ err = treeview_delete_empty_nodes(tree);
+ if (err != NSERROR_OK)
+ return err;
+ }
+
+ return NSERROR_OK;
}
@@ -668,95 +889,6 @@ nserror treeview_destroy(treeview *tree)
}
-/* Walk a treeview subtree, calling a callback at each node (depth first)
- *
- * \param root Root to walk tree from (doesn't get a callback call)
- * \param full Iff true, visit children of collapsed nodes
- * \param callback_bwd Function to call on each node in backwards order
- * \param callback_fwd Function to call on each node in forwards order
- * \param ctx Context to pass to callback
- * \return NSERROR_OK on success, or appropriate error otherwise
- */
-static nserror treeview_walk_internal(treeview_node *root, bool full,
- nserror (*callback_bwd)(treeview_node *n, void *ctx, bool *end),
- nserror (*callback_fwd)(treeview_node *n, void *ctx, bool *end),
- void *ctx)
-{
- treeview_node *node, *next;
- bool abort = false;
- nserror err;
-
- node = root;
-
- while (node != NULL) {
- next = (full || (node->flags & TREE_NODE_EXPANDED)) ?
- node->children : NULL;
-
- if (next != NULL) {
- /* Down to children */
- node = next;
- } else {
- /* No children. As long as we're not at the root,
- * go to next sibling if present, or nearest ancestor
- * with a next sibling. */
-
- while (node != root &&
- node->sibling_next == NULL) {
- if (callback_bwd != NULL) {
- /* Backwards callback */
- err = callback_bwd(node, ctx, &abort);
-
- if (err != NSERROR_OK) {
- return err;
-
- } else if (abort) {
- /* callback requested early
- * termination */
- return NSERROR_OK;
- }
- }
- node = node->parent;
- }
-
- if (node == root)
- break;
-
- if (callback_bwd != NULL) {
- /* Backwards callback */
- err = callback_bwd(node, ctx, &abort);
-
- if (err != NSERROR_OK) {
- return err;
-
- } else if (abort) {
- /* callback requested early
- * termination */
- return NSERROR_OK;
- }
- }
- node = node->sibling_next;
- }
-
- assert(node != NULL);
- assert(node != root);
-
- if (callback_fwd != NULL) {
- /* Forwards callback */
- err = callback_fwd(node, ctx, &abort);
-
- if (err != NSERROR_OK) {
- return err;
-
- } else if (abort) {
- /* callback requested early termination */
- return NSERROR_OK;
- }
- }
- }
- return NSERROR_OK;
-}
-
-
/* Exported interface, documented in treeview.h */
nserror treeview_node_expand(treeview *tree,
treeview_node *node)
@@ -844,34 +976,33 @@ nserror treeview_node_expand(treeview *tree,
/** Treewalk node callback for handling node contraction. */
-static nserror treeview_node_contract_cb(treeview_node *node, void *ctx,
- bool *end)
+static nserror treeview_node_contract_cb(treeview_node *n, void *ctx,
+ bool *skip_children, bool *end)
{
int height_reduction;
- assert(node != NULL);
- assert(node->type != TREE_NODE_ROOT);
+ assert(n != NULL);
+ assert(n->type != TREE_NODE_ROOT);
- if ((node->flags & TREE_NODE_EXPANDED) == false) {
+ if ((n->flags & TREE_NODE_EXPANDED) == false) {
/* Nothing to do. */
return NSERROR_OK;
}
- node->flags ^= TREE_NODE_EXPANDED;
- height_reduction = node->height - tree_g.line_height;
+ n->flags ^= TREE_NODE_EXPANDED;
+ height_reduction = n->height - tree_g.line_height;
assert(height_reduction >= 0);
do {
- node->height -= height_reduction;
- node = node->parent;
- } while (node != NULL);
+ n->height -= height_reduction;
+ n = n->parent;
+ } while (n != NULL);
return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
-nserror treeview_node_contract(treeview *tree,
- treeview_node *node)
+nserror treeview_node_contract(treeview *tree, treeview_node *node)
{
assert(node != NULL);
@@ -886,7 +1017,7 @@ nserror treeview_node_contract(treeview *tree,
treeview_node_contract_cb, NULL);
/* Contract node */
- treeview_node_contract_cb(node, NULL, false);
+ treeview_node_contract_cb(node, NULL, false, false);
/* Inform front end of change in dimensions */
tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
@@ -1144,21 +1275,20 @@ struct treeview_selection_walk_data {
treeview *tree;
};
/** Treewalk node callback for handling selection related actions. */
-static nserror treeview_node_selection_walk_cb(treeview_node *node,
- void *ctx, bool *end)
+static nserror treeview_node_selection_walk_cb(treeview_node *n,
+ void *ctx, bool *skip_children, bool *end)
{
struct treeview_selection_walk_data *sw = ctx;
int height;
bool changed = false;
nserror err;
- height = (node->type == TREE_NODE_ENTRY) ? node->height :
- tree_g.line_height;
+ height = (n->type == TREE_NODE_ENTRY) ? n->height : tree_g.line_height;
sw->current_y += height;
switch (sw->purpose) {
case TREEVIEW_WALK_HAS_SELECTION:
- if (node->flags & TREE_NODE_SELECTED) {
+ if (n->flags & TREE_NODE_SELECTED) {
sw->data.has_selection = true;
*end = true; /* Can abort tree walk */
return NSERROR_OK;
@@ -1166,26 +1296,26 @@ static nserror treeview_node_selection_walk_cb(treeview_node
*node,
break;
case TREEVIEW_WALK_DELETE_SELECTION:
- if (node->flags & TREE_NODE_SELECTED) {
- err = treeview_delete_node_internal(sw->tree, node,
- true);
+ if (n->flags & TREE_NODE_SELECTED) {
+ err = treeview_delete_node_internal(sw->tree, n, true);
if (err != NSERROR_OK) {
return err;
}
+ *skip_children = true;
changed = true;
}
break;
case TREEVIEW_WALK_CLEAR_SELECTION:
- if (node->flags & TREE_NODE_SELECTED) {
- node->flags ^= TREE_NODE_SELECTED;
+ if (n->flags & TREE_NODE_SELECTED) {
+ n->flags ^= TREE_NODE_SELECTED;
changed = true;
}
break;
case TREEVIEW_WALK_SELECT_ALL:
- if (!(node->flags & TREE_NODE_SELECTED)) {
- node->flags ^= TREE_NODE_SELECTED;
+ if (!(n->flags & TREE_NODE_SELECTED)) {
+ n->flags ^= TREE_NODE_SELECTED;
changed = true;
}
break;
@@ -1194,7 +1324,7 @@ static nserror treeview_node_selection_walk_cb(treeview_node *node,
if (sw->current_y > sw->data.drag.sel_min &&
sw->current_y - height <
sw->data.drag.sel_max) {
- node->flags ^= TREE_NODE_SELECTED;
+ n->flags ^= TREE_NODE_SELECTED;
}
return NSERROR_OK;
}
@@ -1329,6 +1459,7 @@ bool treeview_keypress(treeview *tree, uint32_t key)
{
struct rect r; /**< Redraw rectangle */
bool redraw = false;
+ nserror err;
assert(tree != NULL);
@@ -1342,6 +1473,12 @@ bool treeview_keypress(treeview *tree, uint32_t key)
case KEY_DELETE_LEFT:
case KEY_DELETE_RIGHT:
redraw = treeview_delete_selection(tree, &r);
+
+ if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS) {
+ /* Delete any empty nodes */
+ err = treeview_delete_empty_nodes(tree);
+ r.y0 = 0;
+ }
break;
case KEY_CR:
case KEY_NL:
@@ -1380,7 +1517,7 @@ struct treeview_mouse_action {
};
/** Treewalk node callback for handling mouse action. */
static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
- bool *end)
+ bool *skip_children, bool *end)
{
struct treeview_mouse_action *ma = ctx;
struct rect r;
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=ec50fdaefa90f55e664...
commit ec50fdaefa90f55e664a2e4d83c44ad37d51ca14
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Fix rendering of animated background images. Give them sensible redraw area.
diff --git a/render/html_object.c b/render/html_object.c
index aad0dac..0868ce3 100644
--- a/render/html_object.c
+++ b/render/html_object.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include "content/hlcache.h"
+#include "css/utils.h"
#include "utils/nsoption.h"
#include "desktop/scrollbar.h"
#include "render/box.h"
@@ -215,26 +216,109 @@ html_object_callback(hlcache_handle *object,
box_coords(box, &x, &y);
- if (hlcache_handle_get_content(object) ==
- event->data.redraw.object) {
- data.redraw.x = data.redraw.x *
- box->width / content_get_width(object);
- data.redraw.y = data.redraw.y *
- box->height /
- content_get_height(object);
- data.redraw.width = data.redraw.width *
- box->width / content_get_width(object);
- data.redraw.height = data.redraw.height *
- box->height /
- content_get_height(object);
+ if (object == box->background) {
+ /* Redraw request is for background */
+ css_fixed hpos = 0, vpos = 0;
+ css_unit hunit = CSS_UNIT_PX;
+ css_unit vunit = CSS_UNIT_PX;
+ int width = box->padding[LEFT] + box->width +
+ box->padding[RIGHT];
+ int height = box->padding[TOP] + box->height +
+ box->padding[BOTTOM];
+ int t, h, l, w;
+
+ /* Need to know background-position */
+ css_computed_background_position(box->style,
+ &hpos, &hunit, &vpos, &vunit);
+
+ w = content_get_width(box->background);
+ if (hunit == CSS_UNIT_PCT) {
+ l = (width - w) * hpos / INTTOFIX(100);
+ } else {
+ l = FIXTOINT(nscss_len2px(hpos, hunit,
+ box->style));
+ }
+
+ h = content_get_height(box->background);
+ if (vunit == CSS_UNIT_PCT) {
+ t = (height - h) * vpos / INTTOFIX(100);
+ } else {
+ t = FIXTOINT(nscss_len2px(vpos, vunit,
+ box->style));
+ }
+
+ /* Redraw area depends on background-repeat */
+ switch (css_computed_background_repeat(
+ box->style)) {
+ case CSS_BACKGROUND_REPEAT_REPEAT:
+ data.redraw.x = 0;
+ data.redraw.y = 0;
+ data.redraw.width = box->width;
+ data.redraw.height = box->height;
+ break;
+
+ case CSS_BACKGROUND_REPEAT_REPEAT_X:
+ data.redraw.x = 0;
+ data.redraw.y = t;
+ data.redraw.width = box->width;
+ data.redraw.height = h;
+ break;
+
+ case CSS_BACKGROUND_REPEAT_REPEAT_Y:
+ data.redraw.x = l;
+ data.redraw.y = 0;
+ data.redraw.width = w;
+ data.redraw.height = box->height;
+ break;
+
+ case CSS_BACKGROUND_REPEAT_NO_REPEAT:
+ data.redraw.x = l;
+ data.redraw.y = t;
+ data.redraw.width = w;
+ data.redraw.height = h;
+ break;
+
+ default:
+ break;
+ }
+
data.redraw.object_width = box->width;
data.redraw.object_height = box->height;
- }
- data.redraw.x += x + box->padding[LEFT];
- data.redraw.y += y + box->padding[TOP];
- data.redraw.object_x += x + box->padding[LEFT];
- data.redraw.object_y += y + box->padding[TOP];
+ /* Add offset to box */
+ data.redraw.x += x;
+ data.redraw.y += y;
+ data.redraw.object_x += x;
+ data.redraw.object_y += y;
+
+ content_broadcast(&c->base,
+ CONTENT_MSG_REDRAW, data);
+ break;
+
+ } else {
+ /* Non-background case */
+ int w = content_get_width(object);
+ int h = content_get_height(object);
+ if (hlcache_handle_get_content(object) ==
+ event->data.redraw.object) {
+ data.redraw.x = data.redraw.x *
+ box->width / w;
+ data.redraw.y = data.redraw.y *
+ box->height / h;
+ data.redraw.width = data.redraw.width *
+ box->width / w;
+ data.redraw.height =
+ data.redraw.height *
+ box->height / h;
+ data.redraw.object_width = box->width;
+ data.redraw.object_height = box->height;
+ }
+
+ data.redraw.x += x + box->padding[LEFT];
+ data.redraw.y += y + box->padding[TOP];
+ data.redraw.object_x += x + box->padding[LEFT];
+ data.redraw.object_y += y + box->padding[TOP];
+ }
content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
}
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=3e33721ab6498deecd6...
commit 3e33721ab6498deecd611fde8595d690a505e55e
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Make tree walker use nserror.
diff --git a/desktop/treeview.c b/desktop/treeview.c
index a31e7b9..9a9aa41 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -675,14 +675,16 @@ nserror treeview_destroy(treeview *tree)
* \param callback_bwd Function to call on each node in backwards order
* \param callback_fwd Function to call on each node in forwards order
* \param ctx Context to pass to callback
- * \return true iff callback caused premature abort
+ * \return NSERROR_OK on success, or appropriate error otherwise
*/
-static bool treeview_walk_internal(treeview_node *root, bool full,
- bool (*callback_bwd)(treeview_node *n, void *ctx),
- bool (*callback_fwd)(treeview_node *n, void *ctx),
+static nserror treeview_walk_internal(treeview_node *root, bool full,
+ nserror (*callback_bwd)(treeview_node *n, void *ctx, bool *end),
+ nserror (*callback_fwd)(treeview_node *n, void *ctx, bool *end),
void *ctx)
{
treeview_node *node, *next;
+ bool abort = false;
+ nserror err;
node = root;
@@ -700,10 +702,18 @@ static bool treeview_walk_internal(treeview_node *root, bool full,
while (node != root &&
node->sibling_next == NULL) {
- if (callback_bwd != NULL &&
- callback_bwd(node, ctx)) {
- /* callback caused early termination */
- return true;
+ if (callback_bwd != NULL) {
+ /* Backwards callback */
+ err = callback_bwd(node, ctx, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early
+ * termination */
+ return NSERROR_OK;
+ }
}
node = node->parent;
}
@@ -711,9 +721,18 @@ static bool treeview_walk_internal(treeview_node *root, bool full,
if (node == root)
break;
- if (callback_bwd != NULL && callback_bwd(node, ctx)) {
- /* callback caused early termination */
- return true;
+ if (callback_bwd != NULL) {
+ /* Backwards callback */
+ err = callback_bwd(node, ctx, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early
+ * termination */
+ return NSERROR_OK;
+ }
}
node = node->sibling_next;
}
@@ -721,13 +740,20 @@ static bool treeview_walk_internal(treeview_node *root, bool full,
assert(node != NULL);
assert(node != root);
- if (callback_fwd != NULL && callback_fwd(node, ctx)) {
- /* callback caused early termination */
- return true;
- }
+ if (callback_fwd != NULL) {
+ /* Forwards callback */
+ err = callback_fwd(node, ctx, &abort);
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early termination */
+ return NSERROR_OK;
+ }
+ }
}
- return false;
+ return NSERROR_OK;
}
@@ -818,7 +844,8 @@ nserror treeview_node_expand(treeview *tree,
/** Treewalk node callback for handling node contraction. */
-static bool treeview_node_contract_cb(treeview_node *node, void *ctx)
+static nserror treeview_node_contract_cb(treeview_node *node, void *ctx,
+ bool *end)
{
int height_reduction;
@@ -827,7 +854,7 @@ static bool treeview_node_contract_cb(treeview_node *node, void *ctx)
if ((node->flags & TREE_NODE_EXPANDED) == false) {
/* Nothing to do. */
- return false;
+ return NSERROR_OK;
}
node->flags ^= TREE_NODE_EXPANDED;
@@ -840,7 +867,7 @@ static bool treeview_node_contract_cb(treeview_node *node, void *ctx)
node = node->parent;
} while (node != NULL);
- return false; /* Don't want to abort tree walk */
+ return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
nserror treeview_node_contract(treeview *tree,
@@ -859,7 +886,7 @@ nserror treeview_node_contract(treeview *tree,
treeview_node_contract_cb, NULL);
/* Contract node */
- treeview_node_contract_cb(node, NULL);
+ treeview_node_contract_cb(node, NULL, false);
/* Inform front end of change in dimensions */
tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
@@ -1117,12 +1144,13 @@ struct treeview_selection_walk_data {
treeview *tree;
};
/** Treewalk node callback for handling selection related actions. */
-static bool treeview_node_selection_walk_cb(treeview_node *node,
- void *ctx)
+static nserror treeview_node_selection_walk_cb(treeview_node *node,
+ void *ctx, bool *end)
{
struct treeview_selection_walk_data *sw = ctx;
int height;
bool changed = false;
+ nserror err;
height = (node->type == TREE_NODE_ENTRY) ? node->height :
tree_g.line_height;
@@ -1132,13 +1160,18 @@ static bool treeview_node_selection_walk_cb(treeview_node *node,
case TREEVIEW_WALK_HAS_SELECTION:
if (node->flags & TREE_NODE_SELECTED) {
sw->data.has_selection = true;
- return true; /* Can abort tree walk */
+ *end = true; /* Can abort tree walk */
+ return NSERROR_OK;
}
break;
case TREEVIEW_WALK_DELETE_SELECTION:
if (node->flags & TREE_NODE_SELECTED) {
- treeview_delete_node_internal(sw->tree, node, true);
+ err = treeview_delete_node_internal(sw->tree, node,
+ true);
+ if (err != NSERROR_OK) {
+ return err;
+ }
changed = true;
}
break;
@@ -1163,7 +1196,7 @@ static bool treeview_node_selection_walk_cb(treeview_node *node,
sw->data.drag.sel_max) {
node->flags ^= TREE_NODE_SELECTED;
}
- return false; /* Don't stop walk */
+ return NSERROR_OK;
}
if (changed) {
@@ -1177,7 +1210,7 @@ static bool treeview_node_selection_walk_cb(treeview_node *node,
}
}
- return false; /* Don't stop walk */
+ return NSERROR_OK;
}
@@ -1264,7 +1297,7 @@ static void treeview_commit_selection_drag(treeview *tree)
/**
- * Commit a current selection drag, modifying the node's selection state.
+ * Delete a selection.
*/
static bool treeview_delete_selection(treeview *tree, struct rect *rect)
{
@@ -1346,7 +1379,8 @@ struct treeview_mouse_action {
int current_y; /* Y coordinate value of top of current node */
};
/** Treewalk node callback for handling mouse action. */
-static bool treeview_node_mouse_action_cb(treeview_node *node, void *ctx)
+static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
+ bool *end)
{
struct treeview_mouse_action *ma = ctx;
struct rect r;
@@ -1369,7 +1403,7 @@ static bool treeview_node_mouse_action_cb(treeview_node *node, void
*ctx)
/* Skip line if we've not reached mouse y */
if (ma->y > ma->current_y + height) {
ma->current_y += height;
- return false; /* Don't want to abort tree walk */
+ return NSERROR_OK; /* Don't want to abort tree walk */
}
/* Find where the mouse is */
@@ -1500,6 +1534,9 @@ static bool treeview_node_mouse_action_cb(treeview_node *node, void
*ctx)
} else {
err = treeview_node_expand(ma->tree, node);
}
+ if (err != NSERROR_OK) {
+ return err;
+ }
/* Set up redraw */
if (!redraw || r.y0 > ma->current_y)
@@ -1556,7 +1593,8 @@ static bool treeview_node_mouse_action_cb(treeview_node *node, void
*ctx)
ma->tree->cw_t->redraw_request(ma->tree->cw_h, r);
}
- return true; /* Reached line with click; stop walking tree */
+ *end = true; /* Reached line with click; stop walking tree */
+ return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
void treeview_mouse_action(treeview *tree,
commitdiff
http://git.netsurf-browser.org/netsurf.git/commit/?id=5616221064b7cf50337...
commit 5616221064b7cf503373a00faed854fc83c09a02
Author: Michael Drake <tlsa(a)netsurf-browser.org>
Commit: Michael Drake <tlsa(a)netsurf-browser.org>
Typedefs for internal treeview and treeview_node structs.
diff --git a/desktop/global_history.c b/desktop/global_history.c
index d3d3391..a60cccd 100644
--- a/desktop/global_history.c
+++ b/desktop/global_history.c
@@ -46,12 +46,12 @@ enum global_history_folders {
};
struct global_history_folder {
- struct treeview_node *folder;
+ treeview_node *folder;
struct treeview_field_data data;
};
struct global_history_ctx {
- struct treeview *tree;
+ treeview *tree;
struct treeview_field_desc fields[N_FIELDS];
struct global_history_folder folders[GH_N_FOLDERS];
time_t today;
@@ -64,7 +64,7 @@ struct global_history_entry {
int slot;
nsurl *url;
time_t t;
- struct treeview_node *entry;
+ treeview_node *entry;
struct global_history_entry *next;
struct global_history_entry *prev;
@@ -113,7 +113,7 @@ static nserror global_history_create_dir(enum global_history_folders
f)
{
nserror err;
time_t t = gh_ctx.today;
- struct treeview_node *relation = NULL;
+ treeview_node *relation = NULL;
enum treeview_relationship rel = TREE_REL_FIRST_CHILD;
const char *label;
int age;
@@ -200,7 +200,7 @@ static nserror global_history_create_dir(enum global_history_folders
f)
* \return NSERROR_OK on success, appropriate error otherwise
*/
static inline nserror global_history_get_parent_treeview_node(
- struct treeview_node **parent, int slot)
+ treeview_node **parent, int slot)
{
int folder_index;
struct global_history_folder *f;
@@ -304,7 +304,7 @@ static nserror global_history_entry_insert(struct global_history_entry
*e,
{
nserror err;
- struct treeview_node *parent;
+ treeview_node *parent;
err = global_history_get_parent_treeview_node(&parent, slot);
if (err != NSERROR_OK) {
return err;
diff --git a/desktop/treeview.c b/desktop/treeview.c
index f123c4e..a31e7b9 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -78,10 +78,10 @@ struct treeview_node {
int height; /**< Includes height of any descendants (pixels) */
int inset; /**< Node's inset depending on tree depth (pixels) */
- struct treeview_node *parent;
- struct treeview_node *sibling_prev;
- struct treeview_node *sibling_next;
- struct treeview_node *children;
+ treeview_node *parent;
+ treeview_node *sibling_prev;
+ treeview_node *sibling_next;
+ treeview_node *children;
void *client_data; /**< Passed to client on node event msg callback */
@@ -89,7 +89,7 @@ struct treeview_node {
}; /**< Treeview node */
struct treeview_node_entry {
- struct treeview_node base;
+ treeview_node base;
struct treeview_field fields[];
}; /**< Entry class inherits node base class */
@@ -107,7 +107,7 @@ struct treeview_drag {
TV_DRAG_MOVE,
TV_DRAG_TEXTAREA
} type; /**< Drag type */
- struct treeview_node *start_node; /**< Start node */
+ treeview_node *start_node; /**< Start node */
bool selected; /**< Start node is selected */
enum treeview_node_section section; /**< Node section at start */
struct treeview_pos start; /**< Start pos */
@@ -119,7 +119,7 @@ struct treeview {
treeview_flags flags; /** Treeview behaviour settings */
- struct treeview_node *root; /**< Root node */
+ treeview_node *root; /**< Root node */
struct treeview_field *fields; /**< Array of fields */
int n_fields; /**< fields[n_fields] is folder, lower are entry fields */
@@ -184,9 +184,9 @@ static struct treeview_text treeview_furn[TREE_FURN_LAST] = {
* \param root Returns root node
* \return NSERROR_OK on success, appropriate error otherwise
*/
-static nserror treeview_create_node_root(struct treeview_node **root)
+static nserror treeview_create_node_root(treeview_node **root)
{
- struct treeview_node *n;
+ treeview_node *n;
n = malloc(sizeof(struct treeview_node));
if (n == NULL) {
@@ -225,8 +225,8 @@ static nserror treeview_create_node_root(struct treeview_node **root)
* \param b tree node to insert a as a relation of
* \param rel a's relationship to b
*/
-static inline void treeview_insert_node(struct treeview_node *a,
- struct treeview_node *b,
+static inline void treeview_insert_node(treeview_node *a,
+ treeview_node *b,
enum treeview_relationship rel)
{
assert(a != NULL);
@@ -282,14 +282,14 @@ static inline void treeview_insert_node(struct treeview_node *a,
/* Exported interface, documented in treeview.h */
-nserror treeview_create_node_folder(struct treeview *tree,
- struct treeview_node **folder,
- struct treeview_node *relation,
+nserror treeview_create_node_folder(treeview *tree,
+ treeview_node **folder,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data *field,
void *data, treeview_node_create_flags flags)
{
- struct treeview_node *n;
+ treeview_node *n;
assert(data != NULL);
assert(tree != NULL);
@@ -334,8 +334,8 @@ nserror treeview_create_node_folder(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_update_node_entry(struct treeview *tree,
- struct treeview_node *entry,
+nserror treeview_update_node_entry(treeview *tree,
+ treeview_node *entry,
const struct treeview_field_data fields[],
void *data)
{
@@ -395,16 +395,16 @@ nserror treeview_update_node_entry(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_create_node_entry(struct treeview *tree,
- struct treeview_node **entry,
- struct treeview_node *relation,
+nserror treeview_create_node_entry(treeview *tree,
+ treeview_node **entry,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data fields[],
void *data, treeview_node_create_flags flags)
{
bool match;
struct treeview_node_entry *e;
- struct treeview_node *n;
+ treeview_node *n;
int i;
assert(data != NULL);
@@ -423,7 +423,7 @@ nserror treeview_create_node_entry(struct treeview *tree,
}
- n = (struct treeview_node *) e;
+ n = (treeview_node *) e;
n->flags = TREE_NODE_NONE;
n->type = TREE_NODE_ENTRY;
@@ -479,12 +479,12 @@ nserror treeview_create_node_entry(struct treeview *tree,
*
* Will emit folder or entry deletion msg callback.
*/
-static nserror treeview_delete_node_internal(struct treeview *tree,
- struct treeview_node *n, bool interaction)
+static nserror treeview_delete_node_internal(treeview *tree,
+ treeview_node *n, bool interaction)
{
struct treeview_node_msg msg;
msg.msg = TREE_MSG_NODE_DELETE;
- struct treeview_node *p;
+ treeview_node *p;
static int nest_depth = 0;
if (interaction && (tree->flags & TREEVIEW_NO_DELETES)) {
@@ -560,14 +560,14 @@ static nserror treeview_delete_node_internal(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_delete_node(struct treeview *tree, struct treeview_node *n)
+nserror treeview_delete_node(treeview *tree, treeview_node *n)
{
return treeview_delete_node_internal(tree, n, false);
}
/* Exported interface, documented in treeview.h */
-nserror treeview_create(struct treeview **tree,
+nserror treeview_create(treeview **tree,
const struct treeview_callback_table *callbacks,
int n_fields, struct treeview_field_desc fields[],
const struct core_window_callback_table *cw_t,
@@ -646,7 +646,7 @@ nserror treeview_create(struct treeview **tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_destroy(struct treeview *tree)
+nserror treeview_destroy(treeview *tree)
{
int f;
@@ -677,12 +677,12 @@ nserror treeview_destroy(struct treeview *tree)
* \param ctx Context to pass to callback
* \return true iff callback caused premature abort
*/
-static bool treeview_walk_internal(struct treeview_node *root, bool full,
- bool (*callback_bwd)(struct treeview_node *node, void *ctx),
- bool (*callback_fwd)(struct treeview_node *node, void *ctx),
+static bool treeview_walk_internal(treeview_node *root, bool full,
+ bool (*callback_bwd)(treeview_node *n, void *ctx),
+ bool (*callback_fwd)(treeview_node *n, void *ctx),
void *ctx)
{
- struct treeview_node *node, *next;
+ treeview_node *node, *next;
node = root;
@@ -732,10 +732,10 @@ static bool treeview_walk_internal(struct treeview_node *root, bool
full,
/* Exported interface, documented in treeview.h */
-nserror treeview_node_expand(struct treeview *tree,
- struct treeview_node *node)
+nserror treeview_node_expand(treeview *tree,
+ treeview_node *node)
{
- struct treeview_node *child;
+ treeview_node *child;
struct treeview_node_entry *e;
int additional_height = 0;
int i;
@@ -818,7 +818,7 @@ nserror treeview_node_expand(struct treeview *tree,
/** Treewalk node callback for handling node contraction. */
-static bool treeview_node_contract_cb(struct treeview_node *node, void *ctx)
+static bool treeview_node_contract_cb(treeview_node *node, void *ctx)
{
int height_reduction;
@@ -843,8 +843,8 @@ static bool treeview_node_contract_cb(struct treeview_node *node, void
*ctx)
return false; /* Don't want to abort tree walk */
}
/* Exported interface, documented in treeview.h */
-nserror treeview_node_contract(struct treeview *tree,
- struct treeview_node *node)
+nserror treeview_node_contract(treeview *tree,
+ treeview_node *node)
{
assert(node != NULL);
@@ -869,11 +869,11 @@ nserror treeview_node_contract(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-void treeview_redraw(struct treeview *tree, int x, int y, struct rect *clip,
+void treeview_redraw(treeview *tree, int x, int y, struct rect *clip,
const struct redraw_context *ctx)
{
struct redraw_context new_ctx = *ctx;
- struct treeview_node *node, *root, *next;
+ treeview_node *node, *root, *next;
struct treeview_node_entry *entry;
struct treeview_node_style *style = &plot_style_odd;
struct content_redraw_data data;
@@ -1114,10 +1114,10 @@ struct treeview_selection_walk_data {
} drag;
} data;
int current_y;
- struct treeview *tree;
+ treeview *tree;
};
/** Treewalk node callback for handling selection related actions. */
-static bool treeview_node_selection_walk_cb(struct treeview_node *node,
+static bool treeview_node_selection_walk_cb(treeview_node *node,
void *ctx)
{
struct treeview_selection_walk_data *sw = ctx;
@@ -1182,7 +1182,7 @@ static bool treeview_node_selection_walk_cb(struct treeview_node
*node,
/* Exported interface, documented in treeview.h */
-bool treeview_has_selection(struct treeview *tree)
+bool treeview_has_selection(treeview *tree)
{
struct treeview_selection_walk_data sw;
@@ -1197,7 +1197,7 @@ bool treeview_has_selection(struct treeview *tree)
/* Exported interface, documented in treeview.h */
-bool treeview_clear_selection(struct treeview *tree, struct rect *rect)
+bool treeview_clear_selection(treeview *tree, struct rect *rect)
{
struct treeview_selection_walk_data sw;
@@ -1219,7 +1219,7 @@ bool treeview_clear_selection(struct treeview *tree, struct rect
*rect)
/* Exported interface, documented in treeview.h */
-bool treeview_select_all(struct treeview *tree, struct rect *rect)
+bool treeview_select_all(treeview *tree, struct rect *rect)
{
struct treeview_selection_walk_data sw;
@@ -1243,7 +1243,7 @@ bool treeview_select_all(struct treeview *tree, struct rect *rect)
/**
* Commit a current selection drag, modifying the node's selection state.
*/
-static void treeview_commit_selection_drag(struct treeview *tree)
+static void treeview_commit_selection_drag(treeview *tree)
{
struct treeview_selection_walk_data sw;
@@ -1266,7 +1266,7 @@ static void treeview_commit_selection_drag(struct treeview *tree)
/**
* Commit a current selection drag, modifying the node's selection state.
*/
-static bool treeview_delete_selection(struct treeview *tree, struct rect *rect)
+static bool treeview_delete_selection(treeview *tree, struct rect *rect)
{
struct treeview_selection_walk_data sw;
@@ -1292,7 +1292,7 @@ static bool treeview_delete_selection(struct treeview *tree, struct
rect *rect)
/* Exported interface, documented in treeview.h */
-bool treeview_keypress(struct treeview *tree, uint32_t key)
+bool treeview_keypress(treeview *tree, uint32_t key)
{
struct rect r; /**< Redraw rectangle */
bool redraw = false;
@@ -1339,14 +1339,14 @@ bool treeview_keypress(struct treeview *tree, uint32_t key)
}
struct treeview_mouse_action {
- struct treeview *tree;
+ treeview *tree;
browser_mouse_state mouse;
int x;
int y;
int current_y; /* Y coordinate value of top of current node */
};
/** Treewalk node callback for handling mouse action. */
-static bool treeview_node_mouse_action_cb(struct treeview_node *node, void *ctx)
+static bool treeview_node_mouse_action_cb(treeview_node *node, void *ctx)
{
struct treeview_mouse_action *ma = ctx;
struct rect r;
@@ -1559,7 +1559,7 @@ static bool treeview_node_mouse_action_cb(struct treeview_node
*node, void *ctx)
return true; /* Reached line with click; stop walking tree */
}
/* Exported interface, documented in treeview.h */
-void treeview_mouse_action(struct treeview *tree,
+void treeview_mouse_action(treeview *tree,
browser_mouse_state mouse, int x, int y)
{
bool redraw = false;
diff --git a/desktop/treeview.h b/desktop/treeview.h
index 475b90e..5662dfa 100644
--- a/desktop/treeview.h
+++ b/desktop/treeview.h
@@ -30,8 +30,8 @@
#include "desktop/textinput.h"
#include "utils/types.h"
-struct treeview;
-struct treeview_node;
+typedef struct treeview treeview;
+typedef struct treeview_node treeview_node;
enum treeview_relationship {
TREE_REL_FIRST_CHILD,
@@ -127,7 +127,7 @@ nserror treeview_fini(void);
*
* So fields[0] and fields[N-1] have TREE_FLAG_DEFAULT set.
*/
-nserror treeview_create(struct treeview **tree,
+nserror treeview_create(treeview **tree,
const struct treeview_callback_table *callbacks,
int n_fields, struct treeview_field_desc fields[],
const struct core_window_callback_table *cw_t,
@@ -141,7 +141,7 @@ nserror treeview_create(struct treeview **tree,
*
* Will emit folder and entry deletion msg callbacks for all nodes in treeview.
*/
-nserror treeview_destroy(struct treeview *tree);
+nserror treeview_destroy(treeview *tree);
/**
* Create a folder node in given treeview
@@ -159,9 +159,9 @@ nserror treeview_destroy(struct treeview *tree);
*
* If relation is NULL, will insert as child of root node.
*/
-nserror treeview_create_node_folder(struct treeview *tree,
- struct treeview_node **folder,
- struct treeview_node *relation,
+nserror treeview_create_node_folder(treeview *tree,
+ treeview_node **folder,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data *field,
void *data, treeview_node_create_flags flags);
@@ -182,9 +182,9 @@ nserror treeview_create_node_folder(struct treeview *tree,
*
* If relation is NULL, will insert as child of root node.
*/
-nserror treeview_create_node_entry(struct treeview *tree,
- struct treeview_node **entry,
- struct treeview_node *relation,
+nserror treeview_create_node_entry(treeview *tree,
+ treeview_node **entry,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data fields[],
void *data, treeview_node_create_flags flags);
@@ -200,8 +200,8 @@ nserror treeview_create_node_entry(struct treeview *tree,
*
* Fields array names must match names past in treeview_create fields[0...N-2].
*/
-nserror treeview_update_node_entry(struct treeview *tree,
- struct treeview_node *entry,
+nserror treeview_update_node_entry(treeview *tree,
+ treeview_node *entry,
const struct treeview_field_data fields[],
void *data);
@@ -214,7 +214,7 @@ nserror treeview_update_node_entry(struct treeview *tree,
*
* Will emit folder or entry deletion msg callback.
*/
-nserror treeview_delete_node(struct treeview *tree, struct treeview_node *n);
+nserror treeview_delete_node(treeview *tree, treeview_node *n);
/**
* Expand a treeview node
@@ -223,8 +223,7 @@ nserror treeview_delete_node(struct treeview *tree, struct
treeview_node *n);
* \param node Node to expand
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror treeview_node_expand(struct treeview *tree,
- struct treeview_node *node);
+nserror treeview_node_expand(treeview *tree, treeview_node *node);
/**
* Contract a treeview node
@@ -233,8 +232,7 @@ nserror treeview_node_expand(struct treeview *tree,
* \param node Node to contract
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror treeview_node_contract(struct treeview *tree,
- struct treeview_node *node);
+nserror treeview_node_contract(treeview *tree, treeview_node *node);
/**
* Redraw a treeview object
@@ -245,7 +243,7 @@ nserror treeview_node_contract(struct treeview *tree,
* \param clip Current clip rectangle (wrt tree origin)
* \param ctx Current redraw context
*/
-void treeview_redraw(struct treeview *tree, int x, int y, struct rect *clip,
+void treeview_redraw(treeview *tree, int x, int y, struct rect *clip,
const struct redraw_context *ctx);
/**
@@ -255,7 +253,7 @@ void treeview_redraw(struct treeview *tree, int x, int y, struct rect
*clip,
* \param key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
-bool treeview_keypress(struct treeview *tree, uint32_t key);
+bool treeview_keypress(treeview *tree, uint32_t key);
/**
* Handles all kinds of mouse action
@@ -265,7 +263,7 @@ bool treeview_keypress(struct treeview *tree, uint32_t key);
* \param x X coordinate
* \param y Y coordinate
*/
-void treeview_mouse_action(struct treeview *tree,
+void treeview_mouse_action(treeview *tree,
browser_mouse_state mouse, int x, int y);
/**
@@ -274,7 +272,7 @@ void treeview_mouse_action(struct treeview *tree,
* \param tree Treeview object to delete node from
* \return true iff treeview has a selection
*/
-bool treeview_has_selection(struct treeview *tree);
+bool treeview_has_selection(treeview *tree);
/**
* Clear any selection in a treeview
@@ -283,7 +281,7 @@ bool treeview_has_selection(struct treeview *tree);
* \param rect Redraw rectangle (if redraw required)
* \return true iff redraw required
*/
-bool treeview_clear_selection(struct treeview *tree, struct rect *rect);
+bool treeview_clear_selection(treeview *tree, struct rect *rect);
/**
* Select all in a treeview
@@ -292,7 +290,7 @@ bool treeview_clear_selection(struct treeview *tree, struct rect
*rect);
* \param rect Redraw rectangle (if redraw required)
* \return true iff redraw required
*/
-bool treeview_select_all(struct treeview *tree, struct rect *rect);
+bool treeview_select_all(treeview *tree, struct rect *rect);
/**
* Find current height of a treeview
@@ -300,6 +298,6 @@ bool treeview_select_all(struct treeview *tree, struct rect *rect);
* \param tree Treeview object to find height of
* \return height of treeview in px
*/
-int treeview_get_height(struct treeview *tree);
+int treeview_get_height(treeview *tree);
#endif
-----------------------------------------------------------------------
Summary of changes:
desktop/global_history.c | 12 +-
desktop/treeview.c | 535 ++++++++++++++++++++++++++++++----------------
desktop/treeview.h | 46 ++--
render/html_object.c | 118 +++++++++--
4 files changed, 484 insertions(+), 227 deletions(-)
diff --git a/desktop/global_history.c b/desktop/global_history.c
index d3d3391..a60cccd 100644
--- a/desktop/global_history.c
+++ b/desktop/global_history.c
@@ -46,12 +46,12 @@ enum global_history_folders {
};
struct global_history_folder {
- struct treeview_node *folder;
+ treeview_node *folder;
struct treeview_field_data data;
};
struct global_history_ctx {
- struct treeview *tree;
+ treeview *tree;
struct treeview_field_desc fields[N_FIELDS];
struct global_history_folder folders[GH_N_FOLDERS];
time_t today;
@@ -64,7 +64,7 @@ struct global_history_entry {
int slot;
nsurl *url;
time_t t;
- struct treeview_node *entry;
+ treeview_node *entry;
struct global_history_entry *next;
struct global_history_entry *prev;
@@ -113,7 +113,7 @@ static nserror global_history_create_dir(enum global_history_folders
f)
{
nserror err;
time_t t = gh_ctx.today;
- struct treeview_node *relation = NULL;
+ treeview_node *relation = NULL;
enum treeview_relationship rel = TREE_REL_FIRST_CHILD;
const char *label;
int age;
@@ -200,7 +200,7 @@ static nserror global_history_create_dir(enum global_history_folders
f)
* \return NSERROR_OK on success, appropriate error otherwise
*/
static inline nserror global_history_get_parent_treeview_node(
- struct treeview_node **parent, int slot)
+ treeview_node **parent, int slot)
{
int folder_index;
struct global_history_folder *f;
@@ -304,7 +304,7 @@ static nserror global_history_entry_insert(struct global_history_entry
*e,
{
nserror err;
- struct treeview_node *parent;
+ treeview_node *parent;
err = global_history_get_parent_treeview_node(&parent, slot);
if (err != NSERROR_OK) {
return err;
diff --git a/desktop/treeview.c b/desktop/treeview.c
index f123c4e..5b2d327 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -78,10 +78,10 @@ struct treeview_node {
int height; /**< Includes height of any descendants (pixels) */
int inset; /**< Node's inset depending on tree depth (pixels) */
- struct treeview_node *parent;
- struct treeview_node *sibling_prev;
- struct treeview_node *sibling_next;
- struct treeview_node *children;
+ treeview_node *parent;
+ treeview_node *sibling_prev;
+ treeview_node *sibling_next;
+ treeview_node *children;
void *client_data; /**< Passed to client on node event msg callback */
@@ -89,7 +89,7 @@ struct treeview_node {
}; /**< Treeview node */
struct treeview_node_entry {
- struct treeview_node base;
+ treeview_node base;
struct treeview_field fields[];
}; /**< Entry class inherits node base class */
@@ -107,7 +107,7 @@ struct treeview_drag {
TV_DRAG_MOVE,
TV_DRAG_TEXTAREA
} type; /**< Drag type */
- struct treeview_node *start_node; /**< Start node */
+ treeview_node *start_node; /**< Start node */
bool selected; /**< Start node is selected */
enum treeview_node_section section; /**< Node section at start */
struct treeview_pos start; /**< Start pos */
@@ -119,7 +119,7 @@ struct treeview {
treeview_flags flags; /** Treeview behaviour settings */
- struct treeview_node *root; /**< Root node */
+ treeview_node *root; /**< Root node */
struct treeview_field *fields; /**< Array of fields */
int n_fields; /**< fields[n_fields] is folder, lower are entry fields */
@@ -184,9 +184,9 @@ static struct treeview_text treeview_furn[TREE_FURN_LAST] = {
* \param root Returns root node
* \return NSERROR_OK on success, appropriate error otherwise
*/
-static nserror treeview_create_node_root(struct treeview_node **root)
+static nserror treeview_create_node_root(treeview_node **root)
{
- struct treeview_node *n;
+ treeview_node *n;
n = malloc(sizeof(struct treeview_node));
if (n == NULL) {
@@ -225,8 +225,8 @@ static nserror treeview_create_node_root(struct treeview_node **root)
* \param b tree node to insert a as a relation of
* \param rel a's relationship to b
*/
-static inline void treeview_insert_node(struct treeview_node *a,
- struct treeview_node *b,
+static inline void treeview_insert_node(treeview_node *a,
+ treeview_node *b,
enum treeview_relationship rel)
{
assert(a != NULL);
@@ -282,14 +282,14 @@ static inline void treeview_insert_node(struct treeview_node *a,
/* Exported interface, documented in treeview.h */
-nserror treeview_create_node_folder(struct treeview *tree,
- struct treeview_node **folder,
- struct treeview_node *relation,
+nserror treeview_create_node_folder(treeview *tree,
+ treeview_node **folder,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data *field,
void *data, treeview_node_create_flags flags)
{
- struct treeview_node *n;
+ treeview_node *n;
assert(data != NULL);
assert(tree != NULL);
@@ -334,8 +334,8 @@ nserror treeview_create_node_folder(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_update_node_entry(struct treeview *tree,
- struct treeview_node *entry,
+nserror treeview_update_node_entry(treeview *tree,
+ treeview_node *entry,
const struct treeview_field_data fields[],
void *data)
{
@@ -395,16 +395,16 @@ nserror treeview_update_node_entry(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_create_node_entry(struct treeview *tree,
- struct treeview_node **entry,
- struct treeview_node *relation,
+nserror treeview_create_node_entry(treeview *tree,
+ treeview_node **entry,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data fields[],
void *data, treeview_node_create_flags flags)
{
bool match;
struct treeview_node_entry *e;
- struct treeview_node *n;
+ treeview_node *n;
int i;
assert(data != NULL);
@@ -423,7 +423,7 @@ nserror treeview_create_node_entry(struct treeview *tree,
}
- n = (struct treeview_node *) e;
+ n = (treeview_node *) e;
n->flags = TREE_NODE_NONE;
n->type = TREE_NODE_ENTRY;
@@ -469,34 +469,123 @@ nserror treeview_create_node_entry(struct treeview *tree,
}
-/**
- * Delete a treeview node
+/* Walk a treeview subtree, calling a callback at each node (depth first)
*
- * \param tree Treeview object to delete node from
- * \param n Node to delete
- * \param interaction Delete is result of user interaction with treeview
- * \return NSERROR_OK on success, appropriate error otherwise
+ * \param root Root to walk tree from (doesn't get a callback call)
+ * \param full Iff true, visit children of collapsed nodes
+ * \param callback_bwd Function to call on each node in backwards order
+ * \param callback_fwd Function to call on each node in forwards order
+ * \param ctx Context to pass to callback
+ * \return NSERROR_OK on success, or appropriate error otherwise
*
- * Will emit folder or entry deletion msg callback.
+ * Note: Any node deletion must happen in callback_bwd.
*/
-static nserror treeview_delete_node_internal(struct treeview *tree,
- struct treeview_node *n, bool interaction)
+static nserror treeview_walk_internal(treeview_node *root, bool full,
+ nserror (*callback_bwd)(treeview_node *n, void *ctx, bool *end),
+ nserror (*callback_fwd)(treeview_node *n, void *ctx,
+ bool *skip_children, bool *end),
+ void *ctx)
{
- struct treeview_node_msg msg;
- msg.msg = TREE_MSG_NODE_DELETE;
- struct treeview_node *p;
- static int nest_depth = 0;
+ treeview_node *node, *child, *parent, *next_sibling;
+ bool abort = false;
+ bool skip_children = false;
+ nserror err;
- if (interaction && (tree->flags & TREEVIEW_NO_DELETES)) {
- return NSERROR_OK;
- }
+ node = root;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (!skip_children &&
+ (full || (node->flags & TREE_NODE_EXPANDED))) ?
+ node->children : NULL;
- /* Destroy children first */
- nest_depth++;
- while (n->children != NULL) {
- treeview_delete_node_internal(tree, n->children, interaction);
+ while (node != NULL) {
+
+ if (child != NULL) {
+ /* Down to children */
+ node = child;
+ } else {
+ /* No children. As long as we're not at the root,
+ * go to next sibling if present, or nearest ancestor
+ * with a next sibling. */
+
+ while (node != root &&
+ next_sibling == NULL) {
+ if (callback_bwd != NULL) {
+ /* Backwards callback */
+ err = callback_bwd(node, ctx, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early
+ * termination */
+ return NSERROR_OK;
+ }
+ }
+ node = parent;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ }
+
+ if (node == root)
+ break;
+
+ if (callback_bwd != NULL) {
+ /* Backwards callback */
+ err = callback_bwd(node, ctx, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early
+ * termination */
+ return NSERROR_OK;
+ }
+ }
+ node = next_sibling;
+ }
+
+ assert(node != NULL);
+ assert(node != root);
+
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (full || (node->flags & TREE_NODE_EXPANDED)) ?
+ node->children : NULL;
+
+ if (callback_fwd != NULL) {
+ /* Forwards callback */
+ err = callback_fwd(node, ctx, &skip_children, &abort);
+
+ if (err != NSERROR_OK) {
+ return err;
+
+ } else if (abort) {
+ /* callback requested early termination */
+ return NSERROR_OK;
+ }
+ }
+ child = skip_children ? NULL : child;
}
- nest_depth--;
+ return NSERROR_OK;
+}
+
+
+struct treeview_node_delete {
+ treeview *tree;
+ int height_reduction;
+};
+/** Treewalk node callback deleting nodes. */
+static nserror treeview_delete_node_walk_cb(treeview_node *n,
+ void *ctx, bool *end)
+{
+ struct treeview_node_delete *nd = (struct treeview_node_delete *)ctx;
+ struct treeview_node_msg msg;
+ msg.msg = TREE_MSG_NODE_DELETE;
+
+ assert(n->children == NULL);
/* Unlink node from tree */
if (n->parent != NULL && n->parent->children == n) {
@@ -514,19 +603,19 @@ static nserror treeview_delete_node_internal(struct treeview *tree,
}
/* Reduce ancestor heights */
- p = n->parent;
- while (p != NULL && p->flags & TREE_NODE_EXPANDED) {
- p->height -= n->height;
- p = p->parent;
+ if (n->parent != NULL && n->parent->flags & TREE_NODE_EXPANDED) {
+ int height = (n->type == TREE_NODE_ENTRY) ? n->height :
+ tree_g.line_height;
+ nd->height_reduction += height;
}
/* Handle any special treatment */
switch (n->type) {
case TREE_NODE_ENTRY:
- tree->callbacks->entry(msg, n->client_data);
+ nd->tree->callbacks->entry(msg, n->client_data);
break;
case TREE_NODE_FOLDER:
- tree->callbacks->folder(msg, n->client_data);
+ nd->tree->callbacks->folder(msg, n->client_data);
break;
case TREE_NODE_ROOT:
break;
@@ -534,40 +623,172 @@ static nserror treeview_delete_node_internal(struct treeview
*tree,
return NSERROR_BAD_PARAMETER;
}
- if (nest_depth == 0) {
- /* This is the node we were originally asked to delete */
-
- if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS &&
- n->parent != NULL &&
- n->parent->type != TREE_NODE_ROOT &&
- n->parent->children == NULL) {
- /* Delete empty parent */
- nest_depth++;
- treeview_delete_node_internal(tree, n->parent,
- interaction);
- nest_depth--;
- }
+ /* Free the node */
+ free(n);
- /* Inform front end of change in dimensions */
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ return NSERROR_OK;
+}
+/**
+ * Delete a treeview node
+ *
+ * \param tree Treeview object to delete node from
+ * \param n Node to delete
+ * \param interaction Delete is result of user interaction with treeview
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * Will emit folder or entry deletion msg callback.
+ *
+ * Note this can be called from inside a treeview_walk fwd callback.
+ * For example walking the tree and calling this for any node that's selected.
+ *
+ * This function does not delete empty nodes, so if TREEVIEW_DEL_EMPTY_DIRS is
+ * set, caller must also call treeview_delete_empty.
+ */
+static nserror treeview_delete_node_internal(treeview *tree, treeview_node *n,
+ bool interaction)
+{
+ nserror err;
+ treeview_node *p = n->parent;
+ struct treeview_node_delete nd = {
+ .tree = tree,
+ .height_reduction = 0
+ };
+
+ if (interaction && (tree->flags & TREEVIEW_NO_DELETES)) {
+ return NSERROR_OK;
}
- /* Free the node */
- free(n);
+ /* Delete any children first */
+ err = treeview_walk_internal(n, true, treeview_delete_node_walk_cb,
+ NULL, &nd);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ /* Now delete node */
+ if (n == tree->root)
+ tree->root = NULL;
+ err = treeview_delete_node_walk_cb(n, &nd, false);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ /* Reduce ancestor heights */
+ while (p != NULL && p->flags & TREE_NODE_EXPANDED) {
+ p->height -= nd.height_reduction;
+ p = p->parent;
+ }
+
+ /* Inform front end of change in dimensions */
+ if (tree->root != NULL)
+ tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Delete a treeview node
+ *
+ * \param tree Treeview object to delete empty nodes from
+ * \return NSERROR_OK on success, appropriate error otherwise
+ *
+ * Note this must not be called within a treeview_walk. It may delete the
+ * walker's 'current' node, making it impossible to move on without invalid
+ * reads.
+ */
+static nserror treeview_delete_empty_nodes(treeview *tree)
+{
+ treeview_node *node, *child, *parent, *next_sibling;
+ treeview_node *root = tree->root;
+ bool abort = false;
+ nserror err;
+ struct treeview_node_delete nd = {
+ .tree = tree,
+ .height_reduction = 0
+ };
+
+ node = root;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (node->flags & TREE_NODE_EXPANDED) ? node->children : NULL;
+
+ while (node != NULL) {
+
+ if (child != NULL) {
+ /* Down to children */
+ node = child;
+ } else {
+ /* No children. As long as we're not at the root,
+ * go to next sibling if present, or nearest ancestor
+ * with a next sibling. */
+
+ while (node != root &&
+ next_sibling == NULL) {
+ if (node->type == TREE_NODE_FOLDER &&
+ node->children == NULL) {
+ /* Delete node */
+ err = treeview_delete_node_walk_cb(
+ node, &nd, &abort);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+ }
+ node = parent;
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ }
+
+ if (node == root)
+ break;
+
+ if (node->type == TREE_NODE_FOLDER &&
+ node->children == NULL) {
+ /* Delete node */
+ err = treeview_delete_node_walk_cb(
+ node, &nd, &abort);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+ }
+ node = next_sibling;
+ }
+
+ assert(node != NULL);
+ assert(node != root);
+
+ parent = node->parent;
+ next_sibling = node->sibling_next;
+ child = (node->flags & TREE_NODE_EXPANDED) ?
+ node->children : NULL;
+ }
return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
-nserror treeview_delete_node(struct treeview *tree, struct treeview_node *n)
+nserror treeview_delete_node(treeview *tree, treeview_node *n)
{
- return treeview_delete_node_internal(tree, n, false);
+ nserror err;
+
+ err = treeview_delete_node_internal(tree, n, false);
+ if (err != NSERROR_OK)
+ return err;
+
+ if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS) {
+ /* Delete any empty nodes */
+ err = treeview_delete_empty_nodes(tree);
+ if (err != NSERROR_OK)
+ return err;
+ }
+
+ return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
-nserror treeview_create(struct treeview **tree,
+nserror treeview_create(treeview **tree,
const struct treeview_callback_table *callbacks,
int n_fields, struct treeview_field_desc fields[],
const struct core_window_callback_table *cw_t,
@@ -646,7 +867,7 @@ nserror treeview_create(struct treeview **tree,
/* Exported interface, documented in treeview.h */
-nserror treeview_destroy(struct treeview *tree)
+nserror treeview_destroy(treeview *tree)
{
int f;
@@ -668,74 +889,11 @@ nserror treeview_destroy(struct treeview *tree)
}
-/* Walk a treeview subtree, calling a callback at each node (depth first)
- *
- * \param root Root to walk tree from (doesn't get a callback call)
- * \param full Iff true, visit children of collapsed nodes
- * \param callback_bwd Function to call on each node in backwards order
- * \param callback_fwd Function to call on each node in forwards order
- * \param ctx Context to pass to callback
- * \return true iff callback caused premature abort
- */
-static bool treeview_walk_internal(struct treeview_node *root, bool full,
- bool (*callback_bwd)(struct treeview_node *node, void *ctx),
- bool (*callback_fwd)(struct treeview_node *node, void *ctx),
- void *ctx)
-{
- struct treeview_node *node, *next;
-
- node = root;
-
- while (node != NULL) {
- next = (full || (node->flags & TREE_NODE_EXPANDED)) ?
- node->children : NULL;
-
- if (next != NULL) {
- /* Down to children */
- node = next;
- } else {
- /* No children. As long as we're not at the root,
- * go to next sibling if present, or nearest ancestor
- * with a next sibling. */
-
- while (node != root &&
- node->sibling_next == NULL) {
- if (callback_bwd != NULL &&
- callback_bwd(node, ctx)) {
- /* callback caused early termination */
- return true;
- }
- node = node->parent;
- }
-
- if (node == root)
- break;
-
- if (callback_bwd != NULL && callback_bwd(node, ctx)) {
- /* callback caused early termination */
- return true;
- }
- node = node->sibling_next;
- }
-
- assert(node != NULL);
- assert(node != root);
-
- if (callback_fwd != NULL && callback_fwd(node, ctx)) {
- /* callback caused early termination */
- return true;
- }
-
- }
- return false;
-}
-
-
/* Exported interface, documented in treeview.h */
-nserror treeview_node_expand(struct treeview *tree,
- struct treeview_node *node)
+nserror treeview_node_expand(treeview *tree,
+ treeview_node *node)
{
- struct treeview_node *child;
+ treeview_node *child;
struct treeview_node_entry *e;
int additional_height = 0;
int i;
@@ -818,33 +976,33 @@ nserror treeview_node_expand(struct treeview *tree,
/** Treewalk node callback for handling node contraction. */
-static bool treeview_node_contract_cb(struct treeview_node *node, void *ctx)
+static nserror treeview_node_contract_cb(treeview_node *n, void *ctx,
+ bool *skip_children, bool *end)
{
int height_reduction;
- assert(node != NULL);
- assert(node->type != TREE_NODE_ROOT);
+ assert(n != NULL);
+ assert(n->type != TREE_NODE_ROOT);
- if ((node->flags & TREE_NODE_EXPANDED) == false) {
+ if ((n->flags & TREE_NODE_EXPANDED) == false) {
/* Nothing to do. */
- return false;
+ return NSERROR_OK;
}
- node->flags ^= TREE_NODE_EXPANDED;
- height_reduction = node->height - tree_g.line_height;
+ n->flags ^= TREE_NODE_EXPANDED;
+ height_reduction = n->height - tree_g.line_height;
assert(height_reduction >= 0);
do {
- node->height -= height_reduction;
- node = node->parent;
- } while (node != NULL);
+ n->height -= height_reduction;
+ n = n->parent;
+ } while (n != NULL);
- return false; /* Don't want to abort tree walk */
+ return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
-nserror treeview_node_contract(struct treeview *tree,
- struct treeview_node *node)
+nserror treeview_node_contract(treeview *tree, treeview_node *node)
{
assert(node != NULL);
@@ -859,7 +1017,7 @@ nserror treeview_node_contract(struct treeview *tree,
treeview_node_contract_cb, NULL);
/* Contract node */
- treeview_node_contract_cb(node, NULL);
+ treeview_node_contract_cb(node, NULL, false, false);
/* Inform front end of change in dimensions */
tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
@@ -869,11 +1027,11 @@ nserror treeview_node_contract(struct treeview *tree,
/* Exported interface, documented in treeview.h */
-void treeview_redraw(struct treeview *tree, int x, int y, struct rect *clip,
+void treeview_redraw(treeview *tree, int x, int y, struct rect *clip,
const struct redraw_context *ctx)
{
struct redraw_context new_ctx = *ctx;
- struct treeview_node *node, *root, *next;
+ treeview_node *node, *root, *next;
struct treeview_node_entry *entry;
struct treeview_node_style *style = &plot_style_odd;
struct content_redraw_data data;
@@ -1114,45 +1272,50 @@ struct treeview_selection_walk_data {
} drag;
} data;
int current_y;
- struct treeview *tree;
+ treeview *tree;
};
/** Treewalk node callback for handling selection related actions. */
-static bool treeview_node_selection_walk_cb(struct treeview_node *node,
- void *ctx)
+static nserror treeview_node_selection_walk_cb(treeview_node *n,
+ void *ctx, bool *skip_children, bool *end)
{
struct treeview_selection_walk_data *sw = ctx;
int height;
bool changed = false;
+ nserror err;
- height = (node->type == TREE_NODE_ENTRY) ? node->height :
- tree_g.line_height;
+ height = (n->type == TREE_NODE_ENTRY) ? n->height : tree_g.line_height;
sw->current_y += height;
switch (sw->purpose) {
case TREEVIEW_WALK_HAS_SELECTION:
- if (node->flags & TREE_NODE_SELECTED) {
+ if (n->flags & TREE_NODE_SELECTED) {
sw->data.has_selection = true;
- return true; /* Can abort tree walk */
+ *end = true; /* Can abort tree walk */
+ return NSERROR_OK;
}
break;
case TREEVIEW_WALK_DELETE_SELECTION:
- if (node->flags & TREE_NODE_SELECTED) {
- treeview_delete_node_internal(sw->tree, node, true);
+ if (n->flags & TREE_NODE_SELECTED) {
+ err = treeview_delete_node_internal(sw->tree, n, true);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+ *skip_children = true;
changed = true;
}
break;
case TREEVIEW_WALK_CLEAR_SELECTION:
- if (node->flags & TREE_NODE_SELECTED) {
- node->flags ^= TREE_NODE_SELECTED;
+ if (n->flags & TREE_NODE_SELECTED) {
+ n->flags ^= TREE_NODE_SELECTED;
changed = true;
}
break;
case TREEVIEW_WALK_SELECT_ALL:
- if (!(node->flags & TREE_NODE_SELECTED)) {
- node->flags ^= TREE_NODE_SELECTED;
+ if (!(n->flags & TREE_NODE_SELECTED)) {
+ n->flags ^= TREE_NODE_SELECTED;
changed = true;
}
break;
@@ -1161,9 +1324,9 @@ static bool treeview_node_selection_walk_cb(struct treeview_node
*node,
if (sw->current_y > sw->data.drag.sel_min &&
sw->current_y - height <
sw->data.drag.sel_max) {
- node->flags ^= TREE_NODE_SELECTED;
+ n->flags ^= TREE_NODE_SELECTED;
}
- return false; /* Don't stop walk */
+ return NSERROR_OK;
}
if (changed) {
@@ -1177,12 +1340,12 @@ static bool treeview_node_selection_walk_cb(struct treeview_node
*node,
}
}
- return false; /* Don't stop walk */
+ return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
-bool treeview_has_selection(struct treeview *tree)
+bool treeview_has_selection(treeview *tree)
{
struct treeview_selection_walk_data sw;
@@ -1197,7 +1360,7 @@ bool treeview_has_selection(struct treeview *tree)
/* Exported interface, documented in treeview.h */
-bool treeview_clear_selection(struct treeview *tree, struct rect *rect)
+bool treeview_clear_selection(treeview *tree, struct rect *rect)
{
struct treeview_selection_walk_data sw;
@@ -1219,7 +1382,7 @@ bool treeview_clear_selection(struct treeview *tree, struct rect
*rect)
/* Exported interface, documented in treeview.h */
-bool treeview_select_all(struct treeview *tree, struct rect *rect)
+bool treeview_select_all(treeview *tree, struct rect *rect)
{
struct treeview_selection_walk_data sw;
@@ -1243,7 +1406,7 @@ bool treeview_select_all(struct treeview *tree, struct rect *rect)
/**
* Commit a current selection drag, modifying the node's selection state.
*/
-static void treeview_commit_selection_drag(struct treeview *tree)
+static void treeview_commit_selection_drag(treeview *tree)
{
struct treeview_selection_walk_data sw;
@@ -1264,9 +1427,9 @@ static void treeview_commit_selection_drag(struct treeview *tree)
/**
- * Commit a current selection drag, modifying the node's selection state.
+ * Delete a selection.
*/
-static bool treeview_delete_selection(struct treeview *tree, struct rect *rect)
+static bool treeview_delete_selection(treeview *tree, struct rect *rect)
{
struct treeview_selection_walk_data sw;
@@ -1292,10 +1455,11 @@ static bool treeview_delete_selection(struct treeview *tree,
struct rect *rect)
/* Exported interface, documented in treeview.h */
-bool treeview_keypress(struct treeview *tree, uint32_t key)
+bool treeview_keypress(treeview *tree, uint32_t key)
{
struct rect r; /**< Redraw rectangle */
bool redraw = false;
+ nserror err;
assert(tree != NULL);
@@ -1309,6 +1473,12 @@ bool treeview_keypress(struct treeview *tree, uint32_t key)
case KEY_DELETE_LEFT:
case KEY_DELETE_RIGHT:
redraw = treeview_delete_selection(tree, &r);
+
+ if (tree->flags & TREEVIEW_DEL_EMPTY_DIRS) {
+ /* Delete any empty nodes */
+ err = treeview_delete_empty_nodes(tree);
+ r.y0 = 0;
+ }
break;
case KEY_CR:
case KEY_NL:
@@ -1339,14 +1509,15 @@ bool treeview_keypress(struct treeview *tree, uint32_t key)
}
struct treeview_mouse_action {
- struct treeview *tree;
+ treeview *tree;
browser_mouse_state mouse;
int x;
int y;
int current_y; /* Y coordinate value of top of current node */
};
/** Treewalk node callback for handling mouse action. */
-static bool treeview_node_mouse_action_cb(struct treeview_node *node, void *ctx)
+static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
+ bool *skip_children, bool *end)
{
struct treeview_mouse_action *ma = ctx;
struct rect r;
@@ -1369,7 +1540,7 @@ static bool treeview_node_mouse_action_cb(struct treeview_node
*node, void *ctx)
/* Skip line if we've not reached mouse y */
if (ma->y > ma->current_y + height) {
ma->current_y += height;
- return false; /* Don't want to abort tree walk */
+ return NSERROR_OK; /* Don't want to abort tree walk */
}
/* Find where the mouse is */
@@ -1500,6 +1671,9 @@ static bool treeview_node_mouse_action_cb(struct treeview_node
*node, void *ctx)
} else {
err = treeview_node_expand(ma->tree, node);
}
+ if (err != NSERROR_OK) {
+ return err;
+ }
/* Set up redraw */
if (!redraw || r.y0 > ma->current_y)
@@ -1556,10 +1730,11 @@ static bool treeview_node_mouse_action_cb(struct treeview_node
*node, void *ctx)
ma->tree->cw_t->redraw_request(ma->tree->cw_h, r);
}
- return true; /* Reached line with click; stop walking tree */
+ *end = true; /* Reached line with click; stop walking tree */
+ return NSERROR_OK;
}
/* Exported interface, documented in treeview.h */
-void treeview_mouse_action(struct treeview *tree,
+void treeview_mouse_action(treeview *tree,
browser_mouse_state mouse, int x, int y)
{
bool redraw = false;
diff --git a/desktop/treeview.h b/desktop/treeview.h
index 475b90e..5662dfa 100644
--- a/desktop/treeview.h
+++ b/desktop/treeview.h
@@ -30,8 +30,8 @@
#include "desktop/textinput.h"
#include "utils/types.h"
-struct treeview;
-struct treeview_node;
+typedef struct treeview treeview;
+typedef struct treeview_node treeview_node;
enum treeview_relationship {
TREE_REL_FIRST_CHILD,
@@ -127,7 +127,7 @@ nserror treeview_fini(void);
*
* So fields[0] and fields[N-1] have TREE_FLAG_DEFAULT set.
*/
-nserror treeview_create(struct treeview **tree,
+nserror treeview_create(treeview **tree,
const struct treeview_callback_table *callbacks,
int n_fields, struct treeview_field_desc fields[],
const struct core_window_callback_table *cw_t,
@@ -141,7 +141,7 @@ nserror treeview_create(struct treeview **tree,
*
* Will emit folder and entry deletion msg callbacks for all nodes in treeview.
*/
-nserror treeview_destroy(struct treeview *tree);
+nserror treeview_destroy(treeview *tree);
/**
* Create a folder node in given treeview
@@ -159,9 +159,9 @@ nserror treeview_destroy(struct treeview *tree);
*
* If relation is NULL, will insert as child of root node.
*/
-nserror treeview_create_node_folder(struct treeview *tree,
- struct treeview_node **folder,
- struct treeview_node *relation,
+nserror treeview_create_node_folder(treeview *tree,
+ treeview_node **folder,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data *field,
void *data, treeview_node_create_flags flags);
@@ -182,9 +182,9 @@ nserror treeview_create_node_folder(struct treeview *tree,
*
* If relation is NULL, will insert as child of root node.
*/
-nserror treeview_create_node_entry(struct treeview *tree,
- struct treeview_node **entry,
- struct treeview_node *relation,
+nserror treeview_create_node_entry(treeview *tree,
+ treeview_node **entry,
+ treeview_node *relation,
enum treeview_relationship rel,
const struct treeview_field_data fields[],
void *data, treeview_node_create_flags flags);
@@ -200,8 +200,8 @@ nserror treeview_create_node_entry(struct treeview *tree,
*
* Fields array names must match names past in treeview_create fields[0...N-2].
*/
-nserror treeview_update_node_entry(struct treeview *tree,
- struct treeview_node *entry,
+nserror treeview_update_node_entry(treeview *tree,
+ treeview_node *entry,
const struct treeview_field_data fields[],
void *data);
@@ -214,7 +214,7 @@ nserror treeview_update_node_entry(struct treeview *tree,
*
* Will emit folder or entry deletion msg callback.
*/
-nserror treeview_delete_node(struct treeview *tree, struct treeview_node *n);
+nserror treeview_delete_node(treeview *tree, treeview_node *n);
/**
* Expand a treeview node
@@ -223,8 +223,7 @@ nserror treeview_delete_node(struct treeview *tree, struct
treeview_node *n);
* \param node Node to expand
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror treeview_node_expand(struct treeview *tree,
- struct treeview_node *node);
+nserror treeview_node_expand(treeview *tree, treeview_node *node);
/**
* Contract a treeview node
@@ -233,8 +232,7 @@ nserror treeview_node_expand(struct treeview *tree,
* \param node Node to contract
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror treeview_node_contract(struct treeview *tree,
- struct treeview_node *node);
+nserror treeview_node_contract(treeview *tree, treeview_node *node);
/**
* Redraw a treeview object
@@ -245,7 +243,7 @@ nserror treeview_node_contract(struct treeview *tree,
* \param clip Current clip rectangle (wrt tree origin)
* \param ctx Current redraw context
*/
-void treeview_redraw(struct treeview *tree, int x, int y, struct rect *clip,
+void treeview_redraw(treeview *tree, int x, int y, struct rect *clip,
const struct redraw_context *ctx);
/**
@@ -255,7 +253,7 @@ void treeview_redraw(struct treeview *tree, int x, int y, struct rect
*clip,
* \param key The ucs4 character codepoint
* \return true if the keypress is dealt with, false otherwise.
*/
-bool treeview_keypress(struct treeview *tree, uint32_t key);
+bool treeview_keypress(treeview *tree, uint32_t key);
/**
* Handles all kinds of mouse action
@@ -265,7 +263,7 @@ bool treeview_keypress(struct treeview *tree, uint32_t key);
* \param x X coordinate
* \param y Y coordinate
*/
-void treeview_mouse_action(struct treeview *tree,
+void treeview_mouse_action(treeview *tree,
browser_mouse_state mouse, int x, int y);
/**
@@ -274,7 +272,7 @@ void treeview_mouse_action(struct treeview *tree,
* \param tree Treeview object to delete node from
* \return true iff treeview has a selection
*/
-bool treeview_has_selection(struct treeview *tree);
+bool treeview_has_selection(treeview *tree);
/**
* Clear any selection in a treeview
@@ -283,7 +281,7 @@ bool treeview_has_selection(struct treeview *tree);
* \param rect Redraw rectangle (if redraw required)
* \return true iff redraw required
*/
-bool treeview_clear_selection(struct treeview *tree, struct rect *rect);
+bool treeview_clear_selection(treeview *tree, struct rect *rect);
/**
* Select all in a treeview
@@ -292,7 +290,7 @@ bool treeview_clear_selection(struct treeview *tree, struct rect
*rect);
* \param rect Redraw rectangle (if redraw required)
* \return true iff redraw required
*/
-bool treeview_select_all(struct treeview *tree, struct rect *rect);
+bool treeview_select_all(treeview *tree, struct rect *rect);
/**
* Find current height of a treeview
@@ -300,6 +298,6 @@ bool treeview_select_all(struct treeview *tree, struct rect *rect);
* \param tree Treeview object to find height of
* \return height of treeview in px
*/
-int treeview_get_height(struct treeview *tree);
+int treeview_get_height(treeview *tree);
#endif
diff --git a/render/html_object.c b/render/html_object.c
index aad0dac..0868ce3 100644
--- a/render/html_object.c
+++ b/render/html_object.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include "content/hlcache.h"
+#include "css/utils.h"
#include "utils/nsoption.h"
#include "desktop/scrollbar.h"
#include "render/box.h"
@@ -215,26 +216,109 @@ html_object_callback(hlcache_handle *object,
box_coords(box, &x, &y);
- if (hlcache_handle_get_content(object) ==
- event->data.redraw.object) {
- data.redraw.x = data.redraw.x *
- box->width / content_get_width(object);
- data.redraw.y = data.redraw.y *
- box->height /
- content_get_height(object);
- data.redraw.width = data.redraw.width *
- box->width / content_get_width(object);
- data.redraw.height = data.redraw.height *
- box->height /
- content_get_height(object);
+ if (object == box->background) {
+ /* Redraw request is for background */
+ css_fixed hpos = 0, vpos = 0;
+ css_unit hunit = CSS_UNIT_PX;
+ css_unit vunit = CSS_UNIT_PX;
+ int width = box->padding[LEFT] + box->width +
+ box->padding[RIGHT];
+ int height = box->padding[TOP] + box->height +
+ box->padding[BOTTOM];
+ int t, h, l, w;
+
+ /* Need to know background-position */
+ css_computed_background_position(box->style,
+ &hpos, &hunit, &vpos, &vunit);
+
+ w = content_get_width(box->background);
+ if (hunit == CSS_UNIT_PCT) {
+ l = (width - w) * hpos / INTTOFIX(100);
+ } else {
+ l = FIXTOINT(nscss_len2px(hpos, hunit,
+ box->style));
+ }
+
+ h = content_get_height(box->background);
+ if (vunit == CSS_UNIT_PCT) {
+ t = (height - h) * vpos / INTTOFIX(100);
+ } else {
+ t = FIXTOINT(nscss_len2px(vpos, vunit,
+ box->style));
+ }
+
+ /* Redraw area depends on background-repeat */
+ switch (css_computed_background_repeat(
+ box->style)) {
+ case CSS_BACKGROUND_REPEAT_REPEAT:
+ data.redraw.x = 0;
+ data.redraw.y = 0;
+ data.redraw.width = box->width;
+ data.redraw.height = box->height;
+ break;
+
+ case CSS_BACKGROUND_REPEAT_REPEAT_X:
+ data.redraw.x = 0;
+ data.redraw.y = t;
+ data.redraw.width = box->width;
+ data.redraw.height = h;
+ break;
+
+ case CSS_BACKGROUND_REPEAT_REPEAT_Y:
+ data.redraw.x = l;
+ data.redraw.y = 0;
+ data.redraw.width = w;
+ data.redraw.height = box->height;
+ break;
+
+ case CSS_BACKGROUND_REPEAT_NO_REPEAT:
+ data.redraw.x = l;
+ data.redraw.y = t;
+ data.redraw.width = w;
+ data.redraw.height = h;
+ break;
+
+ default:
+ break;
+ }
+
data.redraw.object_width = box->width;
data.redraw.object_height = box->height;
- }
- data.redraw.x += x + box->padding[LEFT];
- data.redraw.y += y + box->padding[TOP];
- data.redraw.object_x += x + box->padding[LEFT];
- data.redraw.object_y += y + box->padding[TOP];
+ /* Add offset to box */
+ data.redraw.x += x;
+ data.redraw.y += y;
+ data.redraw.object_x += x;
+ data.redraw.object_y += y;
+
+ content_broadcast(&c->base,
+ CONTENT_MSG_REDRAW, data);
+ break;
+
+ } else {
+ /* Non-background case */
+ int w = content_get_width(object);
+ int h = content_get_height(object);
+ if (hlcache_handle_get_content(object) ==
+ event->data.redraw.object) {
+ data.redraw.x = data.redraw.x *
+ box->width / w;
+ data.redraw.y = data.redraw.y *
+ box->height / h;
+ data.redraw.width = data.redraw.width *
+ box->width / w;
+ data.redraw.height =
+ data.redraw.height *
+ box->height / h;
+ data.redraw.object_width = box->width;
+ data.redraw.object_height = box->height;
+ }
+
+ data.redraw.x += x + box->padding[LEFT];
+ data.redraw.y += y + box->padding[TOP];
+ data.redraw.object_x += x + box->padding[LEFT];
+ data.redraw.object_y += y + box->padding[TOP];
+ }
content_broadcast(&c->base, CONTENT_MSG_REDRAW, data);
}
--
NetSurf Browser