summaryrefslogtreecommitdiff
path: root/desktop/treeview.c
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/treeview.c')
-rw-r--r--desktop/treeview.c501
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;
}