Spreadsheet: support restoring temporarily unavailable data columns
Previously, columns were removed from a table in the spreadsheet if they are not available anymore. This also meant that their position and width was lost. When the same column became available again, it was inserted at the end. This patch makes it so that each table also remembers the columns that are not available currently (and flags them accordingly). This way, the position and width can be restored once the data becomes available again. Pull Request: https://projects.blender.org/blender/blender/pulls/139440
This commit is contained in:
@@ -384,15 +384,11 @@ static void update_visible_columns(SpreadsheetTable &table, DataSource &data_sou
|
||||
Set<std::reference_wrapper<const SpreadsheetColumnID>> handled_columns;
|
||||
Vector<SpreadsheetColumn *, 32> 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<ColumnValues> 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) {
|
||||
|
||||
@@ -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<int> 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<int> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user