Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-03-15 14:19:48 +0300
committerJacques Lucke <jacques@blender.org>2021-03-15 14:23:03 +0300
commit5ad4713cd8ed2943d96a020ba63ed4d611d14007 (patch)
tree7ef0da55a2c97f33422547608402795ae6df1212 /source/blender/editors/space_spreadsheet
parent4ed208bcd82e912fa9a0da6137af6e87004e9365 (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')
-rw-r--r--source/blender/editors/space_spreadsheet/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc33
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc189
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh97
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc289
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.hh8
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 &params) 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 &params) 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 &params) 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 &params) 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 &params) 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 &params) 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 &params) 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 &params) 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 &params, 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 &params, 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 &params, 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 &params) {
- 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 &params) {
+ 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 &params) {
+ 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 &params) {
+ 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 &params) {
- 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 &params) {
- 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