diff options
author | Jacques Lucke <jacques@blender.org> | 2021-03-15 14:19:48 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-03-15 14:23:03 +0300 |
commit | 5ad4713cd8ed2943d96a020ba63ed4d611d14007 (patch) | |
tree | 7ef0da55a2c97f33422547608402795ae6df1212 /source/blender/editors/space_spreadsheet | |
parent | 4ed208bcd82e912fa9a0da6137af6e87004e9365 (diff) |
Spreadsheet: improve separation of drawing and data generation
This is a refactor and no functional changes are expected.
The goal is to make it simpler to add other data sources without having
to repeat the drawing code everywhere. Also, having the `CellValue` class
allows us to implement filtering and sorting in a more generic way.
Diffstat (limited to 'source/blender/editors/space_spreadsheet')
6 files changed, 359 insertions, 259 deletions
diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt index e270ce9676c..a77e74ffd93 100644 --- a/source/blender/editors/space_spreadsheet/CMakeLists.txt +++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt @@ -33,11 +33,13 @@ set(INC set(SRC space_spreadsheet.cc + spreadsheet_column_layout.cc spreadsheet_draw.cc spreadsheet_from_geometry.cc spreadsheet_ops.cc spreadsheet_draw.hh + spreadsheet_column_layout.hh spreadsheet_from_geometry.hh spreadsheet_intern.hh ) diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index e3ab87583ce..e4bb19d67bf 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -17,6 +17,7 @@ #include <cstring> #include "BLI_listbase.h" +#include "BLI_resource_collector.hh" #include "BKE_screen.h" @@ -42,6 +43,7 @@ #include "spreadsheet_intern.hh" +#include "spreadsheet_column_layout.hh" #include "spreadsheet_from_geometry.hh" #include "spreadsheet_intern.hh" @@ -134,39 +136,44 @@ static ID *get_used_id(const bContext *C) class FallbackSpreadsheetDrawer : public SpreadsheetDrawer { }; -static std::unique_ptr<SpreadsheetDrawer> generate_spreadsheet_drawer(const bContext *C) +static void gather_spreadsheet_columns(const bContext *C, + SpreadsheetColumnLayout &column_layout, + blender::ResourceCollector &resources) { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); ID *used_id = get_used_id(C); if (used_id == nullptr) { - return {}; + return; } const ID_Type id_type = GS(used_id->name); if (id_type != ID_OB) { - return {}; + return; } Object *object_orig = (Object *)used_id; if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD)) { - return {}; + return; } Object *object_eval = DEG_get_evaluated_object(depsgraph, object_orig); if (object_eval == nullptr) { - return {}; + return; } - return spreadsheet_drawer_from_geometry_attributes(C, object_eval); + return spreadsheet_columns_from_geometry(C, object_eval, column_layout, resources); } static void spreadsheet_main_region_draw(const bContext *C, ARegion *region) { SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); - std::unique_ptr<SpreadsheetDrawer> drawer = generate_spreadsheet_drawer(C); - if (!drawer) { - sspreadsheet->runtime->visible_rows = 0; - sspreadsheet->runtime->tot_columns = 0; - sspreadsheet->runtime->tot_rows = 0; - drawer = std::make_unique<FallbackSpreadsheetDrawer>(); - } + + blender::ResourceCollector resources; + SpreadsheetColumnLayout column_layout; + gather_spreadsheet_columns(C, column_layout, resources); + + sspreadsheet->runtime->visible_rows = column_layout.row_indices.size(); + sspreadsheet->runtime->tot_columns = column_layout.columns.size(); + sspreadsheet->runtime->tot_rows = column_layout.tot_rows; + + std::unique_ptr<SpreadsheetDrawer> drawer = spreadsheet_drawer_from_column_layout(column_layout); draw_spreadsheet_in_region(C, region, *drawer); /* Tag footer for redraw, because the main region updates data for the footer. */ diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc new file mode 100644 index 00000000000..c90cf1a2955 --- /dev/null +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc @@ -0,0 +1,189 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <iomanip> +#include <sstream> + +#include "spreadsheet_column_layout.hh" + +#include "DNA_userdef_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "BLF_api.h" + +namespace blender::ed::spreadsheet { + +class ColumnLayoutDrawer : public SpreadsheetDrawer { + private: + const SpreadsheetColumnLayout &column_layout_; + Vector<int> column_widths_; + + public: + ColumnLayoutDrawer(const SpreadsheetColumnLayout &column_layout) : column_layout_(column_layout) + { + tot_columns = column_layout.columns.size(); + tot_rows = column_layout.row_indices.size(); + + const int fontid = UI_style_get()->widget.uifont_id; + /* Use a consistent font size for the width calculation. */ + BLF_size(fontid, 11 * U.pixelsize, U.dpi); + + /* The width of the index column depends on the maximum row index. */ + left_column_width = std::to_string(std::max(0, column_layout_.tot_rows - 1)).size() * + BLF_width(fontid, "0", 1) + + UI_UNIT_X * 0.75; + + /* The column widths depend on the column name widths. */ + const int minimum_column_width = 3 * UI_UNIT_X; + const int header_name_padding = UI_UNIT_X; + for (const SpreadsheetColumn *column : column_layout_.columns) { + StringRefNull name = column->name(); + const int name_width = BLF_width(fontid, name.data(), name.size()); + const int width = std::max(name_width + header_name_padding, minimum_column_width); + column_widths_.append(width); + } + } + + void draw_top_row_cell(int column_index, const CellDrawParams ¶ms) const final + { + const StringRefNull name = column_layout_.columns[column_index]->name(); + uiBut *but = uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_NONE, + name.c_str(), + params.xmin, + params.ymin, + params.width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + /* Center-align column headers. */ + UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); + UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT); + } + + void draw_left_column_cell(int row_index, const CellDrawParams ¶ms) const final + { + const int real_index = column_layout_.row_indices[row_index]; + std::string index_str = std::to_string(real_index); + uiBut *but = uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_NONE, + index_str.c_str(), + params.xmin, + params.ymin, + params.width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + /* Right-align indices. */ + UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT); + UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); + } + + void draw_content_cell(int row_index, int column_index, const CellDrawParams ¶ms) const final + { + const int real_index = column_layout_.row_indices[row_index]; + const SpreadsheetColumn &column = *column_layout_.columns[column_index]; + CellValue cell_value; + column.get_value(real_index, cell_value); + + if (std::holds_alternative<int>(cell_value.value)) { + const int value = std::get<int>(cell_value.value); + const std::string value_str = std::to_string(value); + uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_NONE, + value_str.c_str(), + params.xmin, + params.ymin, + params.width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + } + else if (std::holds_alternative<float>(cell_value.value)) { + const float value = std::get<float>(cell_value.value); + std::stringstream ss; + ss << std::fixed << std::setprecision(3) << value; + const std::string value_str = ss.str(); + uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_NONE, + value_str.c_str(), + params.xmin, + params.ymin, + params.width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + } + else if (std::holds_alternative<bool>(cell_value.value)) { + const bool value = std::get<bool>(cell_value.value); + const int icon = value ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT; + uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + icon, + "", + params.xmin, + params.ymin, + params.width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + } + } + + int column_width(int column_index) const final + { + return column_widths_[column_index]; + } +}; + +std::unique_ptr<SpreadsheetDrawer> spreadsheet_drawer_from_column_layout( + const SpreadsheetColumnLayout &column_layout) +{ + return std::make_unique<ColumnLayoutDrawer>(column_layout); +} + +} // namespace blender::ed::spreadsheet diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh new file mode 100644 index 00000000000..a3832f42f30 --- /dev/null +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh @@ -0,0 +1,97 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include <variant> + +#include "spreadsheet_draw.hh" + +namespace blender::ed::spreadsheet { + +/** + * This is a small type that can hold the value of a cell in a spreadsheet. This type allows us to + * decouple the drawing of individual cells from the code that generates the data to be displayed. + */ +class CellValue { + public: + /* The implementation just uses a `std::variant` for simplicity. It can be encapsulated better, + * but it's not really worth the complixity for now. */ + using VariantType = std::variant<std::monostate, int, float, bool>; + + VariantType value; +}; + +/** + * This represents a column in a spreadsheet. It has a name and provides a value for all the cells + * in the column. + */ +class SpreadsheetColumn { + protected: + std::string name_; + + public: + SpreadsheetColumn(std::string name) : name_(std::move(name)) + { + } + + virtual ~SpreadsheetColumn() = default; + + virtual void get_value(int index, CellValue &r_cell_value) const = 0; + + StringRefNull name() const + { + return name_; + } +}; + +/* Utility class for the function below. */ +template<typename GetValueF> class LambdaSpreadsheetColumn : public SpreadsheetColumn { + private: + GetValueF get_value_; + + public: + LambdaSpreadsheetColumn(std::string name, GetValueF get_value) + : SpreadsheetColumn(std::move(name)), get_value_(std::move(get_value)) + { + } + + void get_value(int index, CellValue &r_cell_value) const final + { + get_value_(index, r_cell_value); + } +}; + +/* Utility function that simplifies creating a spreadsheet column from a lambda function. */ +template<typename GetValueF> +std::unique_ptr<SpreadsheetColumn> spreadsheet_column_from_function(std::string name, + GetValueF get_value) +{ + return std::make_unique<LambdaSpreadsheetColumn<GetValueF>>(std::move(name), + std::move(get_value)); +} + +/* This contains information required to create a spreadsheet drawer from columns. */ +struct SpreadsheetColumnLayout { + Vector<const SpreadsheetColumn *> columns; + Span<int64_t> row_indices; + int tot_rows = 0; +}; + +std::unique_ptr<SpreadsheetDrawer> spreadsheet_drawer_from_column_layout( + const SpreadsheetColumnLayout &column_layout); + +} // namespace blender::ed::spreadsheet diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc index b60a1478352..0ba405d97e0 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc @@ -14,14 +14,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include <iomanip> -#include <sstream> - -#include "UI_interface.h" -#include "UI_resources.h" - -#include "BLF_api.h" - #include "BKE_context.h" #include "BKE_editmesh.h" #include "BKE_lib_id.h" @@ -46,137 +38,6 @@ namespace blender::ed::spreadsheet { using blender::bke::ReadAttribute; using blender::bke::ReadAttributePtr; -class AttributeColumn { - public: - std::string name; - int width; - - AttributeColumn(std::string column_name) : name(std::move(column_name)) - { - /* Compute the column width based on its name. */ - const int fontid = UI_style_get()->widget.uifont_id; - const int header_name_padding = UI_UNIT_X; - const int minimum_column_width = 3 * UI_UNIT_X; - /* Use a consistent font size for the width calculation. */ - BLF_size(fontid, 11 * U.pixelsize, U.dpi); - const int text_width = BLF_width(fontid, name.data(), name.size()); - width = std::max(text_width + header_name_padding, minimum_column_width); - } - - virtual ~AttributeColumn() = default; - virtual void draw(const int index, const CellDrawParams ¶ms) const = 0; -}; - -class GeometryAttributeSpreadsheetDrawer : public SpreadsheetDrawer { - private: - /* Contains resources that are used during drawing. They will be freed automatically. */ - std::unique_ptr<ResourceCollector> resources_; - /* Information about how to draw the individual columns. */ - Vector<std::unique_ptr<AttributeColumn>> columns_; - /* This is used to filter the selected rows. The referenced data lives at least as long as the - * resource collector above. */ - Span<int64_t> visible_rows_; - - public: - GeometryAttributeSpreadsheetDrawer(std::unique_ptr<ResourceCollector> resources, - Vector<std::unique_ptr<AttributeColumn>> columns, - Span<int64_t> visible_rows, - const int domain_size) - : resources_(std::move(resources)), columns_(std::move(columns)), visible_rows_(visible_rows) - { - tot_columns = columns_.size(); - tot_rows = visible_rows.size(); - - /* Compute index column width based on number of digits. */ - const int fontid = UI_style_get()->widget.uifont_id; - left_column_width = std::to_string(std::max(domain_size - 1, 0)).size() * - BLF_width(fontid, "0", 1) + - UI_UNIT_X * 0.75; - } - - void draw_top_row_cell(int column_index, const CellDrawParams ¶ms) const final - { - uiBut *but = uiDefIconTextBut(params.block, - UI_BTYPE_LABEL, - 0, - ICON_NONE, - columns_[column_index]->name.c_str(), - params.xmin, - params.ymin, - params.width, - params.height, - nullptr, - 0, - 0, - 0, - 0, - nullptr); - /* Center-align column headers. */ - UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); - UI_but_drawflag_disable(but, UI_BUT_TEXT_RIGHT); - } - - void draw_left_column_cell(int row_index, const CellDrawParams ¶ms) const final - { - const int real_index = visible_rows_[row_index]; - std::string index_str = std::to_string(real_index); - uiBut *but = uiDefIconTextBut(params.block, - UI_BTYPE_LABEL, - 0, - ICON_NONE, - index_str.c_str(), - params.xmin, - params.ymin, - params.width, - params.height, - nullptr, - 0, - 0, - 0, - 0, - nullptr); - /* Right-align indices. */ - UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT); - UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); - } - - void draw_content_cell(int row_index, int column_index, const CellDrawParams ¶ms) const final - { - const int real_index = visible_rows_[row_index]; - columns_[column_index]->draw(real_index, params); - } - - int column_width(int column_index) const final - { - return columns_[column_index]->width; - } -}; - -/* Utility to make writing column drawing code more concise. */ -template<typename DrawF> class CustomAttributeColumn : public AttributeColumn { - private: - DrawF draw_; - - public: - CustomAttributeColumn(std::string attribute_name, DrawF draw) - : AttributeColumn(std::move(attribute_name)), draw_(std::move(draw)) - { - } - - void draw(const int index, const CellDrawParams ¶ms) const final - { - draw_(index, params); - } -}; - -template<typename DrawF> -std::unique_ptr<CustomAttributeColumn<DrawF>> create_attribute_column(std::string attribute_name, - DrawF draw) -{ - return std::make_unique<CustomAttributeColumn<DrawF>>(std::move(attribute_name), - std::move(draw)); -} - static Vector<std::string> get_sorted_attribute_names_to_display( const GeometryComponent &component, const AttributeDomain domain) { @@ -196,92 +57,30 @@ static Vector<std::string> get_sorted_attribute_names_to_display( return attribute_names; } -static void draw_float_in_cell(const CellDrawParams ¶ms, const float value) -{ - std::stringstream ss; - ss << std::fixed << std::setprecision(3) << value; - const std::string value_str = ss.str(); - uiDefIconTextBut(params.block, - UI_BTYPE_LABEL, - 0, - ICON_NONE, - value_str.c_str(), - params.xmin, - params.ymin, - params.width, - params.height, - nullptr, - 0, - 0, - 0, - 0, - nullptr); -} - -static void draw_int_in_cell(const CellDrawParams ¶ms, const int value) -{ - const std::string value_str = std::to_string(value); - uiDefIconTextBut(params.block, - UI_BTYPE_LABEL, - 0, - ICON_NONE, - value_str.c_str(), - params.xmin, - params.ymin, - params.width, - params.height, - nullptr, - 0, - 0, - 0, - 0, - nullptr); -} - -static void draw_bool_in_cell(const CellDrawParams ¶ms, const bool value) -{ - const int icon = value ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT; - uiDefIconTextBut(params.block, - UI_BTYPE_LABEL, - 0, - icon, - "", - params.xmin, - params.ymin, - params.width, - params.height, - nullptr, - 0, - 0, - 0, - 0, - nullptr); -} - static void add_columns_for_attribute(const ReadAttribute *attribute, const StringRefNull attribute_name, - Vector<std::unique_ptr<AttributeColumn>> &columns) + Vector<std::unique_ptr<SpreadsheetColumn>> &columns) { const CustomDataType data_type = attribute->custom_data_type(); switch (data_type) { case CD_PROP_FLOAT: { - columns.append(create_attribute_column(attribute_name, - [attribute](int index, const CellDrawParams ¶ms) { - float value; - attribute->get(index, &value); - draw_float_in_cell(params, value); - })); + columns.append(spreadsheet_column_from_function( + attribute_name, [attribute](int index, CellValue &r_cell_value) { + float value; + attribute->get(index, &value); + r_cell_value.value = value; + })); break; } case CD_PROP_FLOAT2: { static std::array<char, 2> axis_char = {'X', 'Y'}; for (const int i : {0, 1}) { std::string name = attribute_name + " " + axis_char[i]; - columns.append( - create_attribute_column(name, [attribute, i](int index, const CellDrawParams ¶ms) { + columns.append(spreadsheet_column_from_function( + name, [attribute, i](int index, CellValue &r_cell_value) { float2 value; attribute->get(index, &value); - draw_float_in_cell(params, value[i]); + r_cell_value.value = value[i]; })); } break; @@ -290,11 +89,11 @@ static void add_columns_for_attribute(const ReadAttribute *attribute, static std::array<char, 3> axis_char = {'X', 'Y', 'Z'}; for (const int i : {0, 1, 2}) { std::string name = attribute_name + " " + axis_char[i]; - columns.append( - create_attribute_column(name, [attribute, i](int index, const CellDrawParams ¶ms) { + columns.append(spreadsheet_column_from_function( + name, [attribute, i](int index, CellValue &r_cell_value) { float3 value; attribute->get(index, &value); - draw_float_in_cell(params, value[i]); + r_cell_value.value = value[i]; })); } break; @@ -303,31 +102,31 @@ static void add_columns_for_attribute(const ReadAttribute *attribute, static std::array<char, 4> axis_char = {'R', 'G', 'B', 'A'}; for (const int i : {0, 1, 2, 3}) { std::string name = attribute_name + " " + axis_char[i]; - columns.append( - create_attribute_column(name, [attribute, i](int index, const CellDrawParams ¶ms) { + columns.append(spreadsheet_column_from_function( + name, [attribute, i](int index, CellValue &r_cell_value) { Color4f value; attribute->get(index, &value); - draw_float_in_cell(params, value[i]); + r_cell_value.value = value[i]; })); } break; } case CD_PROP_INT32: { - columns.append(create_attribute_column(attribute_name, - [attribute](int index, const CellDrawParams ¶ms) { - int value; - attribute->get(index, &value); - draw_int_in_cell(params, value); - })); + columns.append(spreadsheet_column_from_function( + attribute_name, [attribute](int index, CellValue &r_cell_value) { + int value; + attribute->get(index, &value); + r_cell_value.value = value; + })); break; } case CD_PROP_BOOL: { - columns.append(create_attribute_column(attribute_name, - [attribute](int index, const CellDrawParams ¶ms) { - bool value; - attribute->get(index, &value); - draw_bool_in_cell(params, value); - })); + columns.append(spreadsheet_column_from_function( + attribute_name, [attribute](int index, CellValue &r_cell_value) { + bool value; + attribute->get(index, &value); + r_cell_value.value = value; + })); break; } default: @@ -526,52 +325,56 @@ static GeometryComponentType get_display_component_type(const bContext *C, Objec return GEO_COMPONENT_TYPE_MESH; } -std::unique_ptr<SpreadsheetDrawer> spreadsheet_drawer_from_geometry_attributes(const bContext *C, - Object *object_eval) +void spreadsheet_columns_from_geometry(const bContext *C, + Object *object_eval, + SpreadsheetColumnLayout &column_layout, + ResourceCollector &resources) { SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); const AttributeDomain domain = (AttributeDomain)sspreadsheet->attribute_domain; const GeometryComponentType component_type = get_display_component_type(C, object_eval); /* Create a resource collector that owns stuff that needs to live until drawing is done. */ - std::unique_ptr<ResourceCollector> resources = std::make_unique<ResourceCollector>(); - GeometrySet &geometry_set = resources->add_value( + GeometrySet &geometry_set = resources.add_value( get_display_geometry_set(sspreadsheet, object_eval, component_type), "geometry set"); const GeometryComponent *component = geometry_set.get_component_for_read(component_type); if (component == nullptr) { - return {}; + return; } if (!component->attribute_domain_supported(domain)) { - return {}; + return; } Vector<std::string> attribute_names = get_sorted_attribute_names_to_display(*component, domain); - Vector<std::unique_ptr<AttributeColumn>> columns; + Vector<std::unique_ptr<SpreadsheetColumn>> &columns = + resources.construct<Vector<std::unique_ptr<SpreadsheetColumn>>>("columns"); + for (StringRefNull attribute_name : attribute_names) { ReadAttributePtr attribute_ptr = component->attribute_try_get_for_read(attribute_name); ReadAttribute &attribute = *attribute_ptr; - resources->add(std::move(attribute_ptr), "attribute"); + resources.add(std::move(attribute_ptr), "attribute"); add_columns_for_attribute(&attribute, attribute_name, columns); } + for (std::unique_ptr<SpreadsheetColumn> &column : columns) { + column_layout.columns.append(column.get()); + } + /* The filter below only works for mesh vertices currently. */ Span<int64_t> visible_rows; if (component_type == GEO_COMPONENT_TYPE_MESH) { visible_rows = filter_mesh_elements_by_selection( - C, object_eval, static_cast<const MeshComponent *>(component), domain, *resources); + C, object_eval, static_cast<const MeshComponent *>(component), domain, resources); } else { visible_rows = IndexRange(component->attribute_domain_size(domain)).as_span(); } const int domain_size = component->attribute_domain_size(domain); - sspreadsheet->runtime->tot_rows = domain_size; - sspreadsheet->runtime->visible_rows = visible_rows.size(); - sspreadsheet->runtime->tot_columns = columns.size(); - return std::make_unique<GeometryAttributeSpreadsheetDrawer>( - std::move(resources), std::move(columns), visible_rows, domain_size); + column_layout.row_indices = visible_rows; + column_layout.tot_rows = domain_size; } } // namespace blender::ed::spreadsheet diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.hh index 32d18254439..cef731517b9 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.hh +++ b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.hh @@ -20,13 +20,15 @@ #include "BLI_resource_collector.hh" -#include "spreadsheet_draw.hh" +#include "spreadsheet_column_layout.hh" struct bContext; namespace blender::ed::spreadsheet { -std::unique_ptr<SpreadsheetDrawer> spreadsheet_drawer_from_geometry_attributes( - const bContext *C, Object *object_eval); +void spreadsheet_columns_from_geometry(const bContext *C, + Object *object_eval, + SpreadsheetColumnLayout &column_layout, + ResourceCollector &resources); } // namespace blender::ed::spreadsheet |