summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/treeview.c272
1 files changed, 150 insertions, 122 deletions
diff --git a/desktop/treeview.c b/desktop/treeview.c
index 46772c28f..8b66730d5 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -2243,38 +2243,40 @@ nserror treeview_expand(treeview *tree, bool only_folders)
}
-/* Exported interface, documented in treeview.h */
-void
-treeview_redraw(treeview *tree,
+/**
+ * Draw a treeview normally, in tree mode.
+ *
+ * \param[in] tree The treeview we're rendering.
+ * \param[in] x X coordinate we're rendering the treeview at.
+ * \param[in] y Y coordinate we're rendering the treeview at.
+ * \param[in,out] render_y Current vertical position in tree, updated on exit.
+ * \param[in] r Clip rectangle.
+ * \param[in] data Redraw data for rendering contents.
+ * \param[in] ctx Current render context.
+ */
+static void treeview_redraw_tree(
+ treeview *tree,
const int x,
const int y,
- struct rect *clip,
+ int *render_y_in_out,
+ struct rect *r,
+ struct content_redraw_data *data,
const struct redraw_context *ctx)
{
- struct redraw_context new_ctx = *ctx;
- treeview_node *node, *root, *next;
- struct treeview_node_entry *entry;
struct treeview_node_style *style = &plot_style_odd;
- struct content_redraw_data data;
- struct rect r;
- struct rect rect;
- uint32_t count = 0;
- int render_y = y;
- int inset;
- int x0;
- int baseline = (tree_g.line_height * 3 + 2) / 4;
enum treeview_resource_id res = TREE_RES_CONTENT;
- plot_style_t *bg_style;
- plot_font_style_t *text_style;
+ int baseline = (tree_g.line_height * 3 + 2) / 4;
plot_font_style_t *infotext_style;
- struct bitmap *furniture;
- int height;
+ treeview_node *root = tree->root;
+ treeview_node *node = tree->root;
+ int render_y = *render_y_in_out;
+ plot_font_style_t *text_style;
+ plot_style_t *bg_style;
int sel_min, sel_max;
- bool invert_selection;
-
- assert(tree != NULL);
- assert(tree->root != NULL);
- assert(tree->root->flags & TV_NFLAGS_EXPANDED);
+ uint32_t count = 0;
+ struct rect rect;
+ int inset;
+ int x0;
if (tree->drag.start.y > tree->drag.prev.y) {
sel_min = tree->drag.prev.y;
@@ -2284,64 +2286,14 @@ treeview_redraw(treeview *tree,
sel_max = tree->drag.prev.y;
}
- /* Start knockout rendering if it's available for this plotter */
- if (ctx->plot->option_knockout) {
- knockout_plot_start(ctx, &new_ctx);
- }
-
- /* Set up clip rectangle */
- r.x0 = clip->x0 + x;
- r.y0 = clip->y0 + y;
- r.x1 = clip->x1 + x;
- r.y1 = clip->y1 + y;
- new_ctx.plot->clip(&new_ctx, &r);
-
- /* Draw the tree */
- node = root = tree->root;
-
- /* Setup common content redraw data */
- data.width = tree_g.icon_size;
- data.height = tree_g.icon_size;
- data.scale = 1;
- data.repeat_x = false;
- data.repeat_y = false;
-
- if (tree->flags & TREEVIEW_SEARCHABLE) {
- if (render_y < r.y1) {
- enum treeview_resource_id icon = TREE_RES_SEARCH;
-
- /* Fill the blank area at the bottom */
- rect.x0 = r.x0;
- rect.y0 = render_y;
- rect.x1 = r.x1;
- rect.y1 = render_y + tree_g.line_height;
- new_ctx.plot->rectangle(&new_ctx, &plot_style_even.bg,
- &rect);
-
- if (treeview_res[icon].ready) {
- /* Icon resource is available */
- data.x = tree_g.window_padding;
- data.y = render_y + ((tree_g.line_height -
- treeview_res[icon].height + 1) /
- 2);
- data.background_colour = plot_style_even.bg.
- fill_colour;
-
- content_redraw(treeview_res[icon].c,
- &data, &r, &new_ctx);
- }
-
- textarea_redraw(tree->search.textarea,
- x + tree_g.window_padding +
- tree_g.icon_step, y,
- plot_style_even.bg.fill_colour, 1.0,
- &r, &new_ctx);
- }
- render_y += tree_g.line_height;
- }
-
while (node != NULL) {
+ struct treeview_node_entry *entry;
+ struct bitmap *furniture;
+ bool invert_selection;
+ treeview_node *next;
+ int height;
int i;
+
next = (node->flags & TV_NFLAGS_EXPANDED) ?
node->children : NULL;
@@ -2374,7 +2326,7 @@ treeview_redraw(treeview *tree,
height = (node->type == TREE_NODE_ENTRY) ? node->height :
tree_g.line_height;
- if ((render_y + height) < r.y0) {
+ if ((render_y + height) < r->y0) {
/* This node's line is above clip region */
render_y += height;
continue;
@@ -2407,21 +2359,21 @@ treeview_redraw(treeview *tree,
}
/* Render background */
- rect.x0 = r.x0;
+ rect.x0 = r->x0;
rect.y0 = render_y;
- rect.x1 = r.x1;
+ rect.x1 = r->x1;
rect.y1 = render_y + height;
- new_ctx.plot->rectangle(&new_ctx, bg_style, &rect);
+ ctx->plot->rectangle(ctx, bg_style, &rect);
/* Render toggle */
- new_ctx.plot->bitmap(&new_ctx,
- furniture,
- inset,
- render_y + tree_g.line_height / 4,
- style->furn[TREE_FURN_EXPAND].size,
- style->furn[TREE_FURN_EXPAND].size,
- bg_style->fill_colour,
- BITMAPF_NONE);
+ ctx->plot->bitmap(ctx,
+ furniture,
+ inset,
+ render_y + tree_g.line_height / 4,
+ style->furn[TREE_FURN_EXPAND].size,
+ style->furn[TREE_FURN_EXPAND].size,
+ bg_style->fill_colour,
+ BITMAPF_NONE);
/* Render icon */
if (node->type == TREE_NODE_ENTRY) {
@@ -2434,26 +2386,25 @@ treeview_redraw(treeview *tree,
if (treeview_res[res].ready) {
/* Icon resource is available */
- data.x = inset + tree_g.step_width;
- data.y = render_y + ((tree_g.line_height -
+ data->x = inset + tree_g.step_width;
+ data->y = render_y + ((tree_g.line_height -
treeview_res[res].height + 1) / 2);
- data.background_colour = bg_style->fill_colour;
+ data->background_colour = bg_style->fill_colour;
- content_redraw(treeview_res[res].c,
- &data, &r, &new_ctx);
+ content_redraw(treeview_res[res].c, data, r, ctx);
}
/* Render text */
x0 = inset + tree_g.step_width + tree_g.icon_step;
- new_ctx.plot->text(&new_ctx,
- text_style,
- x0, render_y + baseline,
- node->text.data,
- node->text.len);
+ ctx->plot->text(ctx,
+ text_style,
+ x0, render_y + baseline,
+ node->text.data,
+ node->text.len);
/* Rendered the node */
render_y += tree_g.line_height;
- if (render_y > r.y1) {
+ if (render_y > r->y1) {
/* Passed the bottom of what's in the clip region.
* Done. */
break;
@@ -2473,25 +2424,25 @@ treeview_redraw(treeview *tree,
if (ef->flags & TREE_FLAG_SHOW_NAME) {
int max_width = tree->field_width;
- new_ctx.plot->text(&new_ctx,
- infotext_style,
- x0 + max_width - ef->value.width - tree_g.step_width,
- render_y + baseline,
- ef->value.data,
- ef->value.len);
-
- new_ctx.plot->text(&new_ctx,
- infotext_style,
- x0 + max_width,
- render_y + baseline,
- entry->fields[i].value.data,
- entry->fields[i].value.len);
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0 + max_width - ef->value.width - tree_g.step_width,
+ render_y + baseline,
+ ef->value.data,
+ ef->value.len);
+
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0 + max_width,
+ render_y + baseline,
+ entry->fields[i].value.data,
+ entry->fields[i].value.len);
} else {
- new_ctx.plot->text(&new_ctx,
- infotext_style,
- x0, render_y + baseline,
- entry->fields[i].value.data,
- entry->fields[i].value.len);
+ ctx->plot->text(ctx,
+ infotext_style,
+ x0, render_y + baseline,
+ entry->fields[i].value.data,
+ entry->fields[i].value.len);
}
/* Rendered the expanded entry field */
@@ -2500,13 +2451,90 @@ treeview_redraw(treeview *tree,
/* Finished rendering expanded entry */
- if (render_y > r.y1) {
+ if (render_y > r->y1) {
/* Passed the bottom of what's in the clip region.
* Done. */
break;
}
}
+ *render_y_in_out = render_y;
+}
+
+
+/* Exported interface, documented in treeview.h */
+void
+treeview_redraw(treeview *tree,
+ const int x,
+ const int y,
+ struct rect *clip,
+ const struct redraw_context *ctx)
+{
+ struct redraw_context new_ctx = *ctx;
+ struct content_redraw_data data;
+ struct rect r;
+ struct rect rect;
+ int render_y = y;
+
+ assert(tree != NULL);
+ assert(tree->root != NULL);
+ assert(tree->root->flags & TV_NFLAGS_EXPANDED);
+
+ /* Start knockout rendering if it's available for this plotter */
+ if (ctx->plot->option_knockout) {
+ knockout_plot_start(ctx, &new_ctx);
+ }
+
+ /* Set up clip rectangle */
+ r.x0 = clip->x0 + x;
+ r.y0 = clip->y0 + y;
+ r.x1 = clip->x1 + x;
+ r.y1 = clip->y1 + y;
+ new_ctx.plot->clip(&new_ctx, &r);
+
+ /* Setup common content redraw data */
+ data.width = tree_g.icon_size;
+ data.height = tree_g.icon_size;
+ data.scale = 1;
+ data.repeat_x = false;
+ data.repeat_y = false;
+
+ if (tree->flags & TREEVIEW_SEARCHABLE) {
+ if (render_y < r.y1) {
+ enum treeview_resource_id icon = TREE_RES_SEARCH;
+
+ /* Fill the blank area at the bottom */
+ rect.x0 = r.x0;
+ rect.y0 = render_y;
+ rect.x1 = r.x1;
+ rect.y1 = render_y + tree_g.line_height;
+ new_ctx.plot->rectangle(&new_ctx, &plot_style_even.bg,
+ &rect);
+
+ if (treeview_res[icon].ready) {
+ /* Icon resource is available */
+ data.x = tree_g.window_padding;
+ data.y = render_y + ((tree_g.line_height -
+ treeview_res[icon].height + 1) /
+ 2);
+ data.background_colour = plot_style_even.bg.
+ fill_colour;
+
+ content_redraw(treeview_res[icon].c,
+ &data, &r, &new_ctx);
+ }
+
+ textarea_redraw(tree->search.textarea,
+ x + tree_g.window_padding +
+ tree_g.icon_step, y,
+ plot_style_even.bg.fill_colour, 1.0,
+ &r, &new_ctx);
+ }
+ render_y += tree_g.line_height;
+ }
+
+ treeview_redraw_tree(tree, x, y, &render_y, &r, &data, &new_ctx);
+
if (render_y < r.y1) {
/* Fill the blank area at the bottom */
rect.x0 = r.x0;