diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index d57709d1351..b6b6464806c 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -384,15 +384,11 @@ static void update_visible_columns(SpreadsheetTable &table, DataSource &data_sou Set> handled_columns; Vector new_columns; for (SpreadsheetColumn *column : Span{table.columns, table.num_columns}) { - const bool still_exists = data_source.get_column_values(*column->id) != nullptr; - if (still_exists) { - if (handled_columns.add(*column->id)) { - new_columns.append(column); - continue; - } + if (handled_columns.add(*column->id)) { + const bool has_data = data_source.get_column_values(*column->id) != nullptr; + SET_FLAG_FROM_TEST(column->flag, !has_data, SPREADSHEET_COLUMN_FLAG_UNAVAILABLE); + new_columns.append(column); } - /* Free columns that don't exist anymore or are duplicates for some reason. */ - spreadsheet_column_free(column); } data_source.foreach_default_column_ids( @@ -468,8 +464,9 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region) for (SpreadsheetColumn *column : Span{table->columns, table->num_columns}) { std::unique_ptr values_ptr = data_source->get_column_values(*column->id); - /* Should have been removed before if it does not exist anymore. */ - BLI_assert(values_ptr); + if (!values_ptr) { + continue; + } const ColumnValues *values = scope.add(std::move(values_ptr)); if (column->width <= 0.0f) { diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc index 8ab019449bd..2ed6e4c2e25 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_ops.cc @@ -196,6 +196,9 @@ SpreadsheetColumn *find_hovered_column_edge(SpaceSpreadsheet &sspreadsheet, } const float cursor_x_view = UI_view2d_region_to_view_x(®ion.v2d, cursor_re.x); for (SpreadsheetColumn *column : Span{table->columns, table->num_columns}) { + if (column->flag & SPREADSHEET_COLUMN_FLAG_UNAVAILABLE) { + continue; + } if (std::abs(cursor_x_view - column->runtime->right_x) < SPREADSHEET_EDGE_ACTION_ZONE) { return column; } @@ -213,6 +216,9 @@ SpreadsheetColumn *find_hovered_column(SpaceSpreadsheet &sspreadsheet, } const float cursor_x_view = UI_view2d_region_to_view_x(®ion.v2d, cursor_re.x); for (SpreadsheetColumn *column : Span{table->columns, table->num_columns}) { + if (column->flag & SPREADSHEET_COLUMN_FLAG_UNAVAILABLE) { + continue; + } if (cursor_x_view > column->runtime->left_x && cursor_x_view <= column->runtime->right_x) { return column; } @@ -321,6 +327,26 @@ struct ReorderColumnData { View2DEdgePanData pan_data{}; }; +static std::optional find_first_available_column_index(const SpreadsheetTable &table) +{ + for (int i = 0; i < table.num_columns; i++) { + if (!(table.columns[i]->flag & SPREADSHEET_COLUMN_FLAG_UNAVAILABLE)) { + return i; + } + } + return std::nullopt; +} + +static std::optional find_last_available_column_index(const SpreadsheetTable &table) +{ + for (int i = table.num_columns - 1; i >= 0; i--) { + if (!(table.columns[i]->flag & SPREADSHEET_COLUMN_FLAG_UNAVAILABLE)) { + return i; + } + } + return std::nullopt; +} + static wmOperatorStatus reorder_columns_invoke(bContext *C, wmOperator *op, const wmEvent *event) { SpaceSpreadsheet &sspreadsheet = *CTX_wm_space_spreadsheet(C); @@ -384,10 +410,10 @@ static wmOperatorStatus reorder_columns_modal(bContext *C, wmOperator *op, const } else { if (cursor_re.x > sspreadsheet.runtime->left_column_width) { - new_index = columns.size() - 1; + new_index = *find_last_available_column_index(table); } else { - new_index = 0; + new_index = *find_first_available_column_index(table); } } diff --git a/source/blender/makesdna/DNA_space_enums.h b/source/blender/makesdna/DNA_space_enums.h index 13befddb5d5..4f4c007002a 100644 --- a/source/blender/makesdna/DNA_space_enums.h +++ b/source/blender/makesdna/DNA_space_enums.h @@ -1019,6 +1019,15 @@ typedef enum eSpreadsheetColumnValueType { SPREADSHEET_VALUE_TYPE_FLOAT4X4 = 12, } eSpreadsheetColumnValueType; +typedef enum eSpreadsheetColumnFlag { + /** + * There is no data for this column currently, so it's not displayed. However, it is still kept + * around so that the column remembers its position and width when the data becomes available + * again. + */ + SPREADSHEET_COLUMN_FLAG_UNAVAILABLE = (1 << 0), +} eSpreadsheetColumnFlag; + typedef enum eSpreadsheetTableIDType { /** This table uses the #SpreadsheetTableIDGeometry key. */ SPREADSHEET_TABLE_ID_TYPE_GEOMETRY = 0, diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 37fc65d1eb1..8645d1f2f72 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1091,7 +1091,9 @@ typedef struct SpreadsheetColumn { * #eSpreadsheetColumnValueType. */ uint8_t data_type; - char _pad0[3]; + char _pad0[1]; + /** #eSpreadsheetColumnFlag. */ + uint16_t flag; /** Width in SPREADSHEET_WIDTH_UNIT. */ float width;