diff options
Diffstat (limited to 'desktop/treeview.c')
-rw-r--r-- | desktop/treeview.c | 501 |
1 files changed, 331 insertions, 170 deletions
diff --git a/desktop/treeview.c b/desktop/treeview.c index 1651ff5ef..a65a37e72 100644 --- a/desktop/treeview.c +++ b/desktop/treeview.c @@ -22,13 +22,15 @@ * Treeview handling implementation. */ +#include "utils/config.h" + #include <string.h> #include "utils/utils.h" #include "utils/log.h" #include "utils/nsurl.h" +#include "utils/nscolour.h" #include "utils/nsoption.h" -#include "utils/config.h" #include "netsurf/bitmap.h" #include "netsurf/content.h" #include "netsurf/plotters.h" @@ -39,11 +41,13 @@ #include "content/hlcache.h" #include "css/utils.h" -#include "desktop/system_colour.h" +#include "desktop/bitmap.h" #include "desktop/knockout.h" #include "desktop/textarea.h" #include "desktop/treeview.h" +#include "desktop/cw_helper.h" #include "desktop/gui_internal.h" +#include "desktop/system_colour.h" /** * The maximum horizontal size a treeview can possibly be. @@ -333,7 +337,7 @@ static struct treeview_resource treeview_res[TREE_RES_LAST] = { * \param[in] tree Treeview to get the height of. * \return the display height in pixels. */ -static inline int treeview__get_display_height(treeview *tree) +static inline int treeview__get_display_height(const treeview *tree) { return (tree->search.search == false) ? tree->root->height : @@ -358,6 +362,40 @@ static inline void treeview__cw_invalidate_area( /** + * Corewindow callback wrapper: Request a full redraw of the window + * + * \param[in] tree The treeview to request redraw on. + */ +static inline void treeview__cw_full_redraw( + const struct treeview *tree) +{ + if (tree->cw_t != NULL) { + static const struct rect r = { + .x0 = 0, + .y0 = 0, + .x1 = REDRAW_MAX, + .y1 = REDRAW_MAX, + }; + tree->cw_t->invalidate(tree->cw_h, &r); + } +} + + +/** + * Get height used by treeview's search bar (or 0 if not present). + * + * \param tree Treeview object to check. + * \return height used by search bar in pixels. + */ +static inline unsigned treeview__get_search_height( + const treeview *tree) +{ + return (tree->flags & TREEVIEW_SEARCHABLE) ? + tree_g.line_height : 0; +} + + +/** * Corewindow callback wrapper: Update the limits of the window * * \param[in] tree The treeview to update size for. @@ -368,12 +406,9 @@ static inline void treeview__cw_update_size( const struct treeview *tree, int width, int height) { - int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; - if (tree->cw_t != NULL) { tree->cw_t->update_size(tree->cw_h, width, - height + search_height); + height + treeview__get_search_height(tree)); } } @@ -393,9 +428,7 @@ static inline void treeview__cw_scroll_top( .y1 = tree_g.line_height, }; - if (tree->cw_t != NULL) { - tree->cw_t->scroll_visible(tree->cw_h, &r); - } + cw_helper_scroll_visible(tree->cw_t, tree->cw_h, &r); } @@ -501,9 +534,8 @@ static inline treeview_node * treeview_node_next(treeview_node *node, bool full) */ static treeview_node * treeview_y_node(treeview *tree, int target_y) { + int y = treeview__get_search_height(tree); treeview_node *n; - int y = 0; - int h; assert(tree != NULL); assert(tree->root != NULL); @@ -511,7 +543,7 @@ static treeview_node * treeview_y_node(treeview *tree, int target_y) n = treeview_node_next(tree->root, false); while (n != NULL) { - h = (n->type == TREE_NODE_ENTRY) ? + int h = (n->type == TREE_NODE_ENTRY) ? n->height : tree_g.line_height; if (target_y >= y && target_y < y + h) return n; @@ -531,10 +563,12 @@ static treeview_node * treeview_y_node(treeview *tree, int target_y) * \param node Node to get position of * \return node's y position */ -static int treeview_node_y(treeview *tree, treeview_node *node) +static int treeview_node_y( + const treeview *tree, + const treeview_node *node) { treeview_node *n; - int y = 0; + int y = treeview__get_search_height(tree); assert(tree != NULL); assert(tree->root != NULL); @@ -553,6 +587,54 @@ static int treeview_node_y(treeview *tree, treeview_node *node) /** + * Corewindow callback_wrapper: Scroll to make node visible + * + * \param[in] tree The treeview to scroll. + * \param[in] node The treeview node to scroll to visibility. + */ +static inline void treeview__cw_scroll_to_node( + const struct treeview *tree, + const struct treeview_node *node) +{ + struct rect r = { + .x0 = 0, + .y0 = treeview_node_y(tree, node), + .x1 = 1, + .y1 = ((node->type == TREE_NODE_ENTRY) ? + node->height : tree_g.line_height), + }; + + r.y1 += r.y0; /* Apply the Y offset to the second Y coordinate */ + + cw_helper_scroll_visible(tree->cw_t, tree->cw_h, &r); +} + + +/** + * Redraw tree from given node to the bottom. + * + * \param[in] tree Tree to redraw from node in. + * \param[in] node Node to redraw from. + */ +static void treeview__redraw_from_node( + const treeview *tree, + const treeview_node *node) +{ + struct rect r = { + .x0 = 0, + .y0 = treeview_node_y(tree, node), + .x1 = REDRAW_MAX, + .y1 = treeview__get_display_height(tree) + + treeview__get_search_height(tree), + }; + + assert(tree != NULL); + + treeview__cw_invalidate_area(tree, &r); +} + + +/** * The treeview walk mode. Controls which nodes are visited in a walk. */ enum treeview_walk_mode { @@ -790,8 +872,7 @@ static nserror treeview__search( nserror err; uint32_t height; uint32_t prev_height = treeview__get_display_height(tree); - int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; + int search_height = treeview__get_search_height(tree); struct treeview_search_walk_data sw = { .len = len, .text = text, @@ -855,6 +936,12 @@ static void treeview__search_cancel(treeview *tree, bool drop_focus) return; } + if (textarea_get_text(tree->search.textarea, NULL, 0) == 1) { + // If there's no text in the search box, we drop focus on a + // cancel. Note '1' because it includes the trailing \0 + drop_focus = true; + } + if (drop_focus) { tree->search.active = false; textarea_set_caret(tree->search.textarea, -1); @@ -866,6 +953,34 @@ static void treeview__search_cancel(treeview *tree, bool drop_focus) treeview__cw_invalidate_area(tree, &r); } +/** + * Convert from treeview drag to core window drag type. + * + * \param[in] tree A treeview. + * \return Core window drag type. + */ +static core_window_drag_status treeview__get_cw_drag_type( + const treeview *tree) +{ + assert(tree != NULL); + + switch (tree->drag.type) { + case TV_DRAG_NONE: + return CORE_WINDOW_DRAG_NONE; + + case TV_DRAG_SELECTION: + return CORE_WINDOW_DRAG_SELECTION; + + case TV_DRAG_TEXTAREA: /* Fall through.*/ + case TV_DRAG_SEARCH: + return CORE_WINDOW_DRAG_TEXT_SELECTION; + + case TV_DRAG_MOVE: + return CORE_WINDOW_DRAG_MOVE; + } + + return CORE_WINDOW_DRAG_NONE; +} /** * Callback for textarea_create, in desktop/treeview.h @@ -892,7 +1007,8 @@ static void treeview_textarea_search_callback(void *data, /* Textarea drag started */ tree->drag.type = TV_DRAG_SEARCH; } - treeview__cw_drag_status(tree, tree->drag.type); + treeview__cw_drag_status(tree, + treeview__get_cw_drag_type(tree)); break; case TEXTAREA_MSG_REDRAW_REQUEST: @@ -1930,7 +2046,7 @@ treeview_create(treeview **tree, (*tree)->fields = malloc(sizeof(struct treeview_field) * n_fields); if ((*tree)->fields == NULL) { - free(tree); + free(*tree); return NSERROR_NOMEM; } @@ -1984,9 +2100,9 @@ treeview_create(treeview **tree, if (flags & TREEVIEW_SEARCHABLE) { (*tree)->search.textarea = treeview__create_textarea( *tree, 600, tree_g.line_height, - plot_style_even.text.background, - plot_style_even.text.background, - plot_style_even.text.foreground, + nscolours[NSCOLOUR_TEXT_INPUT_BG], + nscolours[NSCOLOUR_TEXT_INPUT_BG], + nscolours[NSCOLOUR_TEXT_INPUT_FG], plot_style_odd.text, treeview_textarea_search_callback); if ((*tree)->search.textarea == NULL) { @@ -2083,7 +2199,8 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node) { treeview_node *child; struct treeview_node_entry *e; - int additional_height = 0; + int additional_height_folders = 0; + int additional_height_entries = 0; int i; assert(tree != NULL); @@ -2111,7 +2228,7 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node) &(child->text.width)); } - additional_height += child->height; + additional_height_folders += child->height; child = child->next_sib; } while (child != NULL); @@ -2133,7 +2250,7 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node) } /* Add height for field */ - additional_height += tree_g.line_height; + additional_height_entries += tree_g.line_height; } break; @@ -2152,17 +2269,18 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node) for (struct treeview_node *n = node; (n != NULL) && (n->flags & TV_NFLAGS_EXPANDED); n = n->parent) { - n->height += additional_height; + n->height += additional_height_entries + + additional_height_folders; } if (tree->search.search && node->type == TREE_NODE_ENTRY && node->flags & TV_NFLAGS_MATCHED) { - tree->search.height += additional_height; + tree->search.height += additional_height_entries; } /* Inform front end of change in dimensions */ - if (additional_height != 0) { + if (additional_height_entries + additional_height_folders != 0) { treeview__cw_update_size(tree, -1, treeview__get_display_height(tree)); } @@ -2175,17 +2293,13 @@ treeview_node_expand_internal(treeview *tree, treeview_node *node) nserror treeview_node_expand(treeview *tree, treeview_node *node) { nserror res; - struct rect r; res = treeview_node_expand_internal(tree, node); + NSLOG(netsurf, INFO, "Expanding!"); if (res == NSERROR_OK) { /* expansion was successful, attempt redraw */ - r.x0 = 0; - r.y0 = treeview_node_y(tree, node); - r.x1 = REDRAW_MAX; - r.y1 = treeview__get_display_height(tree); - - treeview__cw_invalidate_area(tree, &r); + treeview__redraw_from_node(tree, node); + NSLOG(netsurf, INFO, "Expanded!"); } return res; @@ -2212,7 +2326,8 @@ struct treeview_contract_data { static nserror treeview_node_contract_cb(treeview_node *n, void *ctx, bool *end) { struct treeview_contract_data *data = ctx; - int h_reduction; + int h_reduction_folder = 0; + int h_reduction_entry = 0; assert(n != NULL); assert(n->type != TREE_NODE_ROOT); @@ -2225,17 +2340,30 @@ static nserror treeview_node_contract_cb(treeview_node *n, void *ctx, bool *end) return NSERROR_OK; } - h_reduction = n->height - tree_g.line_height; - assert(h_reduction >= 0); + switch (n->type) { + case TREE_NODE_FOLDER: + h_reduction_folder = n->height - tree_g.line_height; + break; + + case TREE_NODE_ENTRY: + h_reduction_entry = n->height - tree_g.line_height; + break; + + default: + break; + } + + + assert(h_reduction_folder + h_reduction_entry >= 0); for (struct treeview_node *node = n; (node != NULL) && (node->flags & TV_NFLAGS_EXPANDED); node = node->parent) { - node->height -= h_reduction; + node->height -= h_reduction_folder + h_reduction_entry; } if (data->tree->search.search) { - data->tree->search.height -= h_reduction; + data->tree->search.height -= h_reduction_entry; } n->flags ^= TV_NFLAGS_EXPANDED; @@ -2289,19 +2417,15 @@ treeview_node_contract_internal(treeview *tree, treeview_node *node) nserror treeview_node_contract(treeview *tree, treeview_node *node) { nserror res; - struct rect r; assert(tree != NULL); res = treeview_node_contract_internal(tree, node); + NSLOG(netsurf, INFO, "Contracting!"); if (res == NSERROR_OK) { /* successful contraction, request redraw */ - r.x0 = 0; - r.y0 = treeview_node_y(tree, node); - r.x1 = REDRAW_MAX; - r.y1 = tree->root->height; - - treeview__cw_invalidate_area(tree, &r); + treeview__redraw_from_node(tree, node); + NSLOG(netsurf, INFO, "Contracted!"); } return res; @@ -2311,6 +2435,7 @@ nserror treeview_node_contract(treeview *tree, treeview_node *node) /* Exported interface, documented in treeview.h */ nserror treeview_contract(treeview *tree, bool all) { + int search_height = treeview__get_search_height(tree); struct treeview_contract_data data; bool selected; treeview_node *n; @@ -2322,7 +2447,7 @@ nserror treeview_contract(treeview *tree, bool all) r.x0 = 0; r.y0 = 0; r.x1 = REDRAW_MAX; - r.y1 = tree->root->height; + r.y1 = tree->root->height + search_height; data.tree = tree; data.only_entries = !all; @@ -2444,7 +2569,7 @@ static void treeview_redraw_tree( const int x, const int y, int *render_y_in_out, - struct rect *r, + const struct rect *r, struct content_redraw_data *data, const struct redraw_context *ctx) { @@ -2663,7 +2788,7 @@ static void treeview_redraw_search( const int x, const int y, int *render_y_in_out, - struct rect *r, + const struct rect *r, struct content_redraw_data *data, const struct redraw_context *ctx) { @@ -3010,6 +3135,7 @@ struct treeview_selection_walk_data { } drag; struct { treeview_node *prev; + treeview_node *fixed; } yank; struct { treeview_node *n; @@ -3112,6 +3238,10 @@ treeview_node_selection_walk_cb(treeview_node *n, treeview_node *p = n->parent; int h = 0; + if (n == sw->data.yank.fixed) { + break; + } + if (treeview_unlink_node(n)) h = n->height; @@ -3270,8 +3400,7 @@ static bool treeview_clear_selection(treeview *tree, struct rect *rect) sw.purpose = TREEVIEW_WALK_CLEAR_SELECTION; sw.data.redraw.required = false; sw.data.redraw.rect = rect; - sw.current_y = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; + sw.current_y = treeview__get_search_height(tree); treeview_walk_internal(tree, tree->root, TREEVIEW_WALK_MODE_DISPLAY, NULL, @@ -3300,8 +3429,7 @@ static bool treeview_select_all(treeview *tree, struct rect *rect) sw.purpose = TREEVIEW_WALK_SELECT_ALL; sw.data.redraw.required = false; sw.data.redraw.rect = rect; - sw.current_y = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; + sw.current_y = treeview__get_search_height(tree); treeview_walk_internal(tree, tree->root, TREEVIEW_WALK_MODE_DISPLAY, NULL, @@ -3321,8 +3449,7 @@ static void treeview_commit_selection_drag(treeview *tree) struct treeview_selection_walk_data sw; sw.purpose = TREEVIEW_WALK_COMMIT_SELECT_DRAG; - sw.current_y = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; + sw.current_y = treeview__get_search_height(tree); if (tree->drag.start.y > tree->drag.prev.y) { sw.data.drag.sel_min = tree->drag.prev.y; @@ -3341,13 +3468,15 @@ static void treeview_commit_selection_drag(treeview *tree) /** * Yank a selection to the node move list. * - * \param tree Treeview object to yank selection from + * \param tree Treeview object to yank selection from + * \param fixed Treeview node that should not be yanked */ -static void treeview_move_yank_selection(treeview *tree) +static void treeview_move_yank_selection(treeview *tree, treeview_node *fixed) { struct treeview_selection_walk_data sw; sw.purpose = TREEVIEW_WALK_YANK_SELECTION; + sw.data.yank.fixed = fixed; sw.data.yank.prev = NULL; sw.tree = tree; @@ -3404,12 +3533,12 @@ static bool treeview_delete_selection(treeview *tree, struct rect *rect) rect->x0 = 0; rect->y0 = 0; rect->x1 = REDRAW_MAX; - rect->y1 = tree->root->height; + rect->y1 = treeview__get_display_height(tree); sw.purpose = TREEVIEW_WALK_DELETE_SELECTION; sw.data.redraw.required = false; sw.data.redraw.rect = rect; - sw.current_y = 0; + sw.current_y = treeview__get_search_height(tree); sw.tree = tree; treeview_walk_internal(tree, tree->root, @@ -3442,7 +3571,7 @@ static bool treeview_propagate_selection(treeview *tree, struct rect *rect) sw.purpose = TREEVIEW_WALK_PROPAGATE_SELECTION; sw.data.redraw.required = false; sw.data.redraw.rect = rect; - sw.current_y = 0; + sw.current_y = treeview__get_search_height(tree); sw.tree = tree; treeview_walk_internal(tree, tree->root, @@ -3521,16 +3650,17 @@ static nserror treeview_move_selection(treeview *tree, struct rect *rect) parent = relation->parent; } - /* The node that we're moving selection to can't itself be selected */ - assert(!(relation->flags & TV_NFLAGS_SELECTED)); - /* Move all selected nodes from treeview to tree->move.root */ - treeview_move_yank_selection(tree); + treeview_move_yank_selection(tree, relation); /* Move all nodes on tree->move.root to target location */ for (node = tree->move.root; node != NULL; node = next) { next = node->next_sib; + if (node == relation) { + continue; + } + if (!(parent->flags & TV_NFLAGS_EXPANDED)) { if (node->flags & TV_NFLAGS_EXPANDED) treeview_node_contract_internal(tree, node); @@ -3769,8 +3899,10 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) .n_selected = 0, .prev_n_selected = 0 }; - int h = tree->root->height; + int search_height = treeview__get_search_height(tree); + int h = treeview__get_display_height(tree) + search_height; bool redraw = false; + struct treeview_node *scroll_to_node = NULL; /* Fill out the nav. state struct, by examining the current selection * state */ @@ -3778,6 +3910,8 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) TREEVIEW_WALK_MODE_DISPLAY, NULL, treeview_node_nav_cb, &ns); + scroll_to_node = ns.curr; + if (tree->search.search == false) { if (ns.next == NULL) ns.next = tree->root->children; @@ -3798,10 +3932,12 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) ns.curr->parent->type != TREE_NODE_ROOT) { /* Step to parent */ ns.curr->parent->flags |= TV_NFLAGS_SELECTED; + scroll_to_node = ns.curr->parent; } else if (ns.curr != NULL && tree->root->children != NULL) { /* Select first node in tree */ tree->root->children->flags |= TV_NFLAGS_SELECTED; + scroll_to_node = tree->root->children; } break; @@ -3814,6 +3950,7 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) /* Step to first child */ ns.curr->children->flags |= TV_NFLAGS_SELECTED; + scroll_to_node = ns.curr->children; } else { /* Retain current node selection */ ns.curr->flags |= TV_NFLAGS_SELECTED; @@ -3835,6 +3972,7 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) if (ns.prev != NULL) { /* Step to previous node */ ns.prev->flags |= TV_NFLAGS_SELECTED; + scroll_to_node = ns.prev; } break; @@ -3842,6 +3980,7 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) if (ns.next != NULL) { /* Step to next node */ ns.next->flags |= TV_NFLAGS_SELECTED; + scroll_to_node = ns.next; } break; @@ -3849,12 +3988,14 @@ treeview_keyboard_navigation(treeview *tree, uint32_t key, struct rect *rect) break; } + treeview__cw_scroll_to_node(tree, scroll_to_node); + /* TODO: Deal with redraw area properly */ rect->x0 = 0; rect->y0 = 0; rect->x1 = REDRAW_MAX; - if (tree->root->height > h) - rect->y1 = tree->root->height; + if (treeview__get_display_height(tree) + search_height > h) + rect->y1 = treeview__get_display_height(tree) + search_height; else rect->y1 = h; redraw = true; @@ -4106,7 +4247,8 @@ static void treeview_textarea_callback(void *data, struct textarea_msg *msg) /* Textarea drag started */ tree->drag.type = TV_DRAG_TEXTAREA; } - treeview__cw_drag_status(tree, tree->drag.type); + treeview__cw_drag_status(tree, + treeview__get_cw_drag_type(tree)); break; case TEXTAREA_MSG_REDRAW_REQUEST: @@ -4290,6 +4432,7 @@ struct treeview_mouse_action { int x; int y; int current_y; /* Y coordinate value of top of current node */ + int search_height; }; @@ -4477,7 +4620,8 @@ treeview_node_mouse_action_cb(treeview_node *node, if (((node->type == TREE_NODE_FOLDER) && (ma->mouse & BROWSER_MOUSE_DOUBLE_CLICK) && click) || (part == TV_NODE_PART_TOGGLE && click)) { - int h = ma->tree->root->height; + int h = treeview__get_display_height(ma->tree) + + ma->search_height; /* Clear any existing selection */ redraw |= treeview_clear_selection(ma->tree, &r); @@ -4495,7 +4639,13 @@ treeview_node_mouse_action_cb(treeview_node *node, /* Set up redraw */ if (!redraw || r.y0 > ma->current_y) r.y0 = ma->current_y; - r.y1 = h > ma->tree->root->height ? h : ma->tree->root->height; + if (h > treeview__get_display_height(ma->tree) + + ma->search_height) { + r.y1 = h; + } else { + r.y1 = treeview__get_display_height(ma->tree) + + ma->search_height; + } redraw = true; } else if ((node->type == TREE_NODE_ENTRY) && @@ -4576,8 +4726,7 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y) { struct rect r; bool redraw = false; - int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; + int search_height = treeview__get_search_height(tree); assert(tree != NULL); assert(tree->root != NULL); @@ -4592,9 +4741,7 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y) textarea_mouse_action(tree->edit.textarea, mouse, x - tree->edit.x, y - tree->edit.y); return; - } else if (tree->drag.type == TV_DRAG_SEARCH || - (y < search_height && - tree->drag.type == TV_DRAG_NONE)) { + } else if (tree->drag.type == TV_DRAG_SEARCH) { if (tree->search.active == false) { tree->search.active = true; if (treeview_clear_selection(tree, &r)) { @@ -4606,6 +4753,16 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y) y); return; } else if (mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2) && + y < search_height && tree->search.active == false) { + tree->search.active = true; + if (treeview_clear_selection(tree, &r)) { + treeview__cw_invalidate_area(tree, &r); + } + textarea_mouse_action(tree->search.textarea, mouse, + x - tree_g.window_padding - tree_g.icon_size, + y); + return; + } else if (mouse & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2) && tree->search.active == true) { tree->search.active = false; @@ -4734,13 +4891,14 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y) } else { /* On tree */ - struct treeview_mouse_action ma; - - ma.tree = tree; - ma.mouse = mouse; - ma.x = x; - ma.y = y; - ma.current_y = search_height; + struct treeview_mouse_action ma = { + .tree = tree, + .mouse = mouse, + .x = x, + .y = y, + .current_y = search_height, + .search_height = search_height, + }; treeview_walk_internal(tree, tree->root, TREEVIEW_WALK_MODE_DISPLAY, NULL, @@ -4748,12 +4906,10 @@ treeview_mouse_action(treeview *tree, browser_mouse_state mouse, int x, int y) } } - /* Exported interface, documented in treeview.h */ int treeview_get_height(treeview *tree) { - int search_height = (tree->flags & TREEVIEW_SEARCHABLE) ? - tree_g.line_height : 0; + int search_height = treeview__get_search_height(tree); int height = treeview__get_display_height(tree); assert(tree != NULL); @@ -4764,6 +4920,31 @@ int treeview_get_height(treeview *tree) return height + search_height; } +/* Exported interface, documented in treeview.h */ +nserror treeview_set_search_string( + treeview *tree, + const char *string) +{ + if (!(tree->flags & TREEVIEW_SEARCHABLE)) { + return NSERROR_BAD_PARAMETER; + } + + if (string == NULL || strlen(string) == 0) { + tree->search.active = false; + tree->search.search = false; + return treeview__search(tree, "", 0); + } + + tree->search.active = true; + tree->search.search = true; + if (!textarea_set_text(tree->search.textarea, string)) { + return NSERROR_UNKNOWN; + } + + treeview__cw_full_redraw(tree); + + return NSERROR_OK; +} /** * Initialise the plot styles from CSS system colour values. @@ -4773,75 +4954,45 @@ int treeview_get_height(treeview *tree) */ static nserror treeview_init_plot_styles(int font_pt_size) { - nserror res; - /* Background colour */ plot_style_even.bg.stroke_type = PLOT_OP_TYPE_NONE; plot_style_even.bg.stroke_width = 0; plot_style_even.bg.stroke_colour = 0; plot_style_even.bg.fill_type = PLOT_OP_TYPE_SOLID; - res = ns_system_colour_char("Window", &plot_style_even.bg.fill_colour); - if (res != NSERROR_OK) { - return res; - } + plot_style_even.bg.fill_colour = nscolours[NSCOLOUR_WIN_EVEN_BG]; /* Text colour */ plot_style_even.text.family = PLOT_FONT_FAMILY_SANS_SERIF; plot_style_even.text.size = font_pt_size; plot_style_even.text.weight = 400; plot_style_even.text.flags = FONTF_NONE; - res = ns_system_colour_char("WindowText", &plot_style_even.text.foreground); - if (res != NSERROR_OK) { - return res; - } - res = ns_system_colour_char("Window", &plot_style_even.text.background); - if (res != NSERROR_OK) { - return res; - } + plot_style_even.text.foreground = nscolours[NSCOLOUR_WIN_EVEN_FG]; + plot_style_even.text.background = nscolours[NSCOLOUR_WIN_EVEN_BG]; /* Entry field text colour */ plot_style_even.itext = plot_style_even.text; - plot_style_even.itext.foreground = mix_colour( - plot_style_even.text.foreground, - plot_style_even.text.background, - 255 * 10 / 16); + plot_style_even.itext.foreground = nscolours[NSCOLOUR_WIN_EVEN_FG_FADED]; /* Selected background colour */ plot_style_even.sbg = plot_style_even.bg; - res = ns_system_colour_char("Highlight", &plot_style_even.sbg.fill_colour); - if (res != NSERROR_OK) { - return res; - } + plot_style_even.sbg.fill_colour = nscolours[NSCOLOUR_SEL_BG]; /* Selected text colour */ plot_style_even.stext = plot_style_even.text; - res = ns_system_colour_char("HighlightText", &plot_style_even.stext.foreground); - if (res != NSERROR_OK) { - return res; - } - res = ns_system_colour_char("Highlight", &plot_style_even.stext.background); - if (res != NSERROR_OK) { - return res; - } + plot_style_even.stext.foreground = nscolours[NSCOLOUR_SEL_FG]; + plot_style_even.stext.background = nscolours[NSCOLOUR_SEL_BG]; /* Selected entry field text colour */ plot_style_even.sitext = plot_style_even.stext; - plot_style_even.sitext.foreground = mix_colour( - plot_style_even.stext.foreground, - plot_style_even.stext.background, - 255 * 25 / 32); + plot_style_even.sitext.foreground = nscolours[NSCOLOUR_SEL_FG_SUBTLE]; /* Odd numbered node styles */ plot_style_odd.bg = plot_style_even.bg; - plot_style_odd.bg.fill_colour = mix_colour( - plot_style_even.bg.fill_colour, - plot_style_even.text.foreground, 255 * 15 / 16); + plot_style_odd.bg.fill_colour = nscolours[NSCOLOUR_WIN_ODD_BG]; plot_style_odd.text = plot_style_even.text; plot_style_odd.text.background = plot_style_odd.bg.fill_colour; plot_style_odd.itext = plot_style_odd.text; - plot_style_odd.itext.foreground = mix_colour( - plot_style_odd.text.foreground, - plot_style_odd.text.background, 255 * 10 / 16); + plot_style_odd.itext.foreground = nscolours[NSCOLOUR_WIN_EVEN_FG_FADED]; plot_style_odd.sbg = plot_style_even.sbg; plot_style_odd.stext = plot_style_even.stext; @@ -4927,7 +5078,7 @@ treeview_generate_triangle_bitmap(colour bg, colour fg, int size) colour colour4 = fg; /* Create the bitmap */ - b = guit->bitmap->create(size, size, BITMAP_NEW | BITMAP_OPAQUE); + b = guit->bitmap->create(size, size, BITMAP_OPAQUE); if (b == NULL) return NULL; @@ -4941,58 +5092,68 @@ treeview_generate_triangle_bitmap(colour bg, colour fg, int size) if (y < size / 2) { /* Top half */ for (x = 0; x < y * 2; x++) { - *(pos++) = red_from_colour(colour4); - *(pos++) = green_from_colour(colour4); - *(pos++) = blue_from_colour(colour4); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour4); + pos[bitmap_layout.g] = green_from_colour(colour4); + pos[bitmap_layout.b] = blue_from_colour(colour4); + pos[bitmap_layout.a] = 0xff; + pos += 4; } - *(pos++) = red_from_colour(colour3); - *(pos++) = green_from_colour(colour3); - *(pos++) = blue_from_colour(colour3); - *(pos++) = 0xff; - *(pos++) = red_from_colour(colour1); - *(pos++) = green_from_colour(colour1); - *(pos++) = blue_from_colour(colour1); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour3); + pos[bitmap_layout.g] = green_from_colour(colour3); + pos[bitmap_layout.b] = blue_from_colour(colour3); + pos[bitmap_layout.a] = 0xff; + pos += 4; + pos[bitmap_layout.r] = red_from_colour(colour1); + pos[bitmap_layout.g] = green_from_colour(colour1); + pos[bitmap_layout.b] = blue_from_colour(colour1); + pos[bitmap_layout.a] = 0xff; + pos += 4; for (x = y * 2 + 2; x < size ; x++) { - *(pos++) = red_from_colour(colour0); - *(pos++) = green_from_colour(colour0); - *(pos++) = blue_from_colour(colour0); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour0); + pos[bitmap_layout.g] = green_from_colour(colour0); + pos[bitmap_layout.b] = blue_from_colour(colour0); + pos[bitmap_layout.a] = 0xff; + pos += 4; } } else if ((y == size / 2) && (size & 0x1)) { /* Middle row */ for (x = 0; x < size - 1; x++) { - *(pos++) = red_from_colour(colour4); - *(pos++) = green_from_colour(colour4); - *(pos++) = blue_from_colour(colour4); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour4); + pos[bitmap_layout.g] = green_from_colour(colour4); + pos[bitmap_layout.b] = blue_from_colour(colour4); + pos[bitmap_layout.a] = 0xff; + pos += 4; } - *(pos++) = red_from_colour(colour2); - *(pos++) = green_from_colour(colour2); - *(pos++) = blue_from_colour(colour2); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour2); + pos[bitmap_layout.g] = green_from_colour(colour2); + pos[bitmap_layout.b] = blue_from_colour(colour2); + pos[bitmap_layout.a] = 0xff; + pos += 4; } else { /* Bottom half */ for (x = 0; x < (size - y - 1) * 2; x++) { - *(pos++) = red_from_colour(colour4); - *(pos++) = green_from_colour(colour4); - *(pos++) = blue_from_colour(colour4); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour4); + pos[bitmap_layout.g] = green_from_colour(colour4); + pos[bitmap_layout.b] = blue_from_colour(colour4); + pos[bitmap_layout.a] = 0xff; + pos += 4; } - *(pos++) = red_from_colour(colour3); - *(pos++) = green_from_colour(colour3); - *(pos++) = blue_from_colour(colour3); - *(pos++) = 0xff; - *(pos++) = red_from_colour(colour1); - *(pos++) = green_from_colour(colour1); - *(pos++) = blue_from_colour(colour1); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour3); + pos[bitmap_layout.g] = green_from_colour(colour3); + pos[bitmap_layout.b] = blue_from_colour(colour3); + pos[bitmap_layout.a] = 0xff; + pos += 4; + pos[bitmap_layout.r] = red_from_colour(colour1); + pos[bitmap_layout.g] = green_from_colour(colour1); + pos[bitmap_layout.b] = blue_from_colour(colour1); + pos[bitmap_layout.a] = 0xff; + pos += 4; for (x = (size - y) * 2; x < size ; x++) { - *(pos++) = red_from_colour(colour0); - *(pos++) = green_from_colour(colour0); - *(pos++) = blue_from_colour(colour0); - *(pos++) = 0xff; + pos[bitmap_layout.r] = red_from_colour(colour0); + pos[bitmap_layout.g] = green_from_colour(colour0); + pos[bitmap_layout.b] = blue_from_colour(colour0); + pos[bitmap_layout.a] = 0xff; + pos += 4; } } @@ -5026,7 +5187,7 @@ treeview_generate_copy_bitmap(struct bitmap *orig, int size) assert(size == guit->bitmap->get_height(orig)); /* Create the bitmap */ - b = guit->bitmap->create(size, size, BITMAP_NEW | BITMAP_OPAQUE); + b = guit->bitmap->create(size, size, BITMAP_OPAQUE); if (b == NULL) return NULL; @@ -5074,7 +5235,7 @@ treeview_generate_rotate_bitmap(struct bitmap *orig, int size) assert(size == guit->bitmap->get_height(orig)); /* Create the bitmap */ - b = guit->bitmap->create(size, size, BITMAP_NEW | BITMAP_OPAQUE); + b = guit->bitmap->create(size, size, BITMAP_OPAQUE); if (b == NULL) return NULL; @@ -5195,7 +5356,7 @@ nserror treeview_init(void) 10 + 36) / 72; tree_g.line_height = (font_px_size * 8 + 3) / 6; - res = treeview_init_plot_styles(font_pt_size * FONT_SIZE_SCALE / 10); + res = treeview_init_plot_styles(font_pt_size * PLOT_STYLE_SCALE / 10); if (res != NSERROR_OK) { return res; } |