From c478f35c81478e48d3a86ac57e7bb7c34a3ce107 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sun, 10 Sep 2017 13:12:35 +0100 Subject: Treeview: Split tree-style treeview rendering out into helper. --- desktop/treeview.c | 272 +++++++++++++++++++++++++++++------------------------ 1 file changed, 150 insertions(+), 122 deletions(-) (limited to 'desktop') 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; -- cgit v1.2.3