From 43d1e777df24d2a843a88c021acfeb82f9d31a40 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 27 Aug 2013 20:56:20 +0100 Subject: Function to get releations for node entry. --- desktop/treeview.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'desktop/treeview.c') diff --git a/desktop/treeview.c b/desktop/treeview.c index bf2d0ef37..a0fbe9203 100644 --- a/desktop/treeview.c +++ b/desktop/treeview.c @@ -685,6 +685,37 @@ static inline treeview_node * treeview_node_next(treeview_node *node, bool full) } +/* Find node at given y-position + * + * \param tree Treeview object to delete node from + * \param target_y Target y-position + * \return node at y_target + */ +static treeview_node * treeview_y_node(treeview *tree, int target_y) +{ + treeview_node *n; + int y = 0; + int h; + + assert(tree != NULL); + assert(tree->root != NULL); + + n = treeview_node_next(tree->root, false); + + while (n != NULL) { + h = (n->type == TREE_NODE_ENTRY) ? + n->height : tree_g.line_height; + if (target_y >= y && target_y < y + h) + return n; + y += h; + + n = treeview_node_next(n, false); + } + + return NULL; +} + + /* Find y position of the top of a node * * \param tree Treeview object to delete node from @@ -1596,6 +1627,7 @@ void treeview_redraw(treeview *tree, int x, int y, struct rect *clip, struct treeview_selection_walk_data { enum { TREEVIEW_WALK_HAS_SELECTION, + TREEVIEW_WALK_GET_FIRST_SELECTED, TREEVIEW_WALK_CLEAR_SELECTION, TREEVIEW_WALK_SELECT_ALL, TREEVIEW_WALK_COMMIT_SELECT_DRAG, @@ -1616,6 +1648,9 @@ struct treeview_selection_walk_data { struct { treeview_node *prev; } yank; + struct { + treeview_node *n; + } first; } data; int current_y; treeview *tree; @@ -1641,6 +1676,14 @@ static nserror treeview_node_selection_walk_cb(treeview_node *n, } break; + case TREEVIEW_WALK_GET_FIRST_SELECTED: + if (n->flags & TREE_NODE_SELECTED) { + sw->data.first.n = n; + *end = true; /* Can abort tree walk */ + return NSERROR_OK; + } + break; + case TREEVIEW_WALK_DELETE_SELECTION: if (n->flags & TREE_NODE_SELECTED) { err = treeview_delete_node_internal(sw->tree, n, true); @@ -1744,6 +1787,26 @@ bool treeview_has_selection(treeview *tree) } +/** + * Get first selected node (in any) + * + * \param tree Treeview object in which to create folder + * \return the first selected treeview node, or NULL + */ +static treeview_node * treeview_get_first_selected(treeview *tree) +{ + struct treeview_selection_walk_data sw; + + sw.purpose = TREEVIEW_WALK_GET_FIRST_SELECTED; + sw.data.first.n = NULL; + + treeview_walk_internal(tree->root, false, NULL, + treeview_node_selection_walk_cb, &sw); + + return sw.data.first.n; +} + + /* Exported interface, documented in treeview.h */ bool treeview_clear_selection(treeview *tree, struct rect *rect) { @@ -2060,6 +2123,50 @@ static nserror treeview_launch_selection(treeview *tree) } +/* Exported interface, documented in treeview.h */ +nserror treeview_get_relation(treeview *tree, treeview_node **relation, + enum treeview_relationship *rel, bool at_y, int y) +{ + treeview_node *n; + + assert(tree != NULL); + + if (at_y) { + n = treeview_y_node(tree, y); + + } else { + n = treeview_get_first_selected(tree); + } + + if (n != NULL && n->parent != NULL) { + if (n == n->parent->children) { + /* First child */ + *relation = n->parent; + *rel = TREE_REL_FIRST_CHILD; + } else { + /* Not first child */ + *relation = n->prev_sib; + *rel = TREE_REL_NEXT_SIBLING; + } + } else { + if (tree->root->children == NULL) { + /* First child of root */ + *relation = tree->root; + *rel = TREE_REL_FIRST_CHILD; + } else { + /* Last child of root */ + n = tree->root->children; + while (n->next_sib != NULL) + n = n->next_sib; + *relation = n; + *rel = TREE_REL_NEXT_SIBLING; + } + } + + return NSERROR_OK; +} + + struct treeview_nav_state { treeview *tree; treeview_node *prev; -- cgit v1.2.3