diff --git a/crates/viewer/re_space_view_dataframe/src/dataframe_ui.rs b/crates/viewer/re_space_view_dataframe/src/dataframe_ui.rs index 6a36c006c7c0..dd7eb92d3c6e 100644 --- a/crates/viewer/re_space_view_dataframe/src/dataframe_ui.rs +++ b/crates/viewer/re_space_view_dataframe/src/dataframe_ui.rs @@ -297,6 +297,7 @@ impl<'a> egui_table::TableDelegate for DataframeTableDelegate<'a> { .take(row_expansion as usize + 1); for (sub_cell_index, instance_index) in instance_indices.enumerate() { + // TODO: have an helper to split UIs that way let sub_cell_rect = egui::Rect::from_min_size( ui.cursor().min + egui::vec2( @@ -323,35 +324,62 @@ impl<'a> egui_table::TableDelegate for DataframeTableDelegate<'a> { if cell_clicked { if instance_count == row_expansion { - self.expanded_rows.expand_row(cell.row_nr, 0); + self.expanded_rows.collapse_row(cell.row_nr); } else { self.expanded_rows.expand_row(cell.row_nr, instance_count); } } } else { - let has_collapse_button = if let Some(instance_index) = instance_index { - instance_index < instance_count + let has_collapse_button = instance_index + .is_some_and(|instance_index| instance_index < instance_count); + + let remaining_instances = if sub_cell_index as u64 == row_expansion { + instance_index.and_then(|instance_index| { + let remaining = instance_count + .saturating_sub(instance_index) + .saturating_sub(1); + if remaining > 0 { + // +1 is because the "X more…" line takes one instance spot + Some(remaining + 1) + } else { + None + } + }) } else { - false + None }; - let cell_clicked = cell_with_hover_button_ui( - &mut sub_cell_ui, - has_collapse_button.then_some(&re_ui::icons::COLLAPSE), - |ui| { - column.data_ui( - self.ctx, - ui, - row_id, - &latest_at_query, - row_idx, - instance_index, - ); - }, - ); + if let Some(remaining_instances) = remaining_instances { + let cell_clicked = cell_with_hover_button_ui( + &mut sub_cell_ui, + Some(&re_ui::icons::EXPAND), + |ui| { + ui.label(format!("{remaining_instances} more…")); + }, + ); - if cell_clicked { - self.expanded_rows.expand_row(cell.row_nr, 0); + if cell_clicked { + self.expanded_rows.expand_row(cell.row_nr, instance_count); + } + } else { + let cell_clicked = cell_with_hover_button_ui( + &mut sub_cell_ui, + has_collapse_button.then_some(&re_ui::icons::COLLAPSE), + |ui| { + column.data_ui( + self.ctx, + ui, + row_id, + &latest_at_query, + row_idx, + instance_index, + ); + }, + ); + + if cell_clicked { + self.expanded_rows.collapse_row(cell.row_nr); + } } } } diff --git a/crates/viewer/re_space_view_dataframe/src/expanded_rows.rs b/crates/viewer/re_space_view_dataframe/src/expanded_rows.rs index 633c3c673de3..2df8419c129c 100644 --- a/crates/viewer/re_space_view_dataframe/src/expanded_rows.rs +++ b/crates/viewer/re_space_view_dataframe/src/expanded_rows.rs @@ -89,6 +89,10 @@ impl<'a> ExpandedRows<'a> { + row_nr as f32 * self.row_height } + pub(crate) fn collapse_row(&mut self, row_nr: u64) { + self.expand_row(row_nr, 0); + } + pub(crate) fn expand_row(&mut self, row_nr: u64, additional_row_space: u64) { if additional_row_space == 0 { self.cache.expanded_rows.remove(&row_nr);