Skip to content

Commit ad0aa52

Browse files
authored
Implement basic UI to display recording properties (#9381)
### Related * Closes #9188 ### What This crates a basic _Properties_ section in the `re_selection_panel` to show the recording properties. > [!IMPORTANT] > The truncation in the screenshot below will be handled by: > > * #9391 <img width="355" alt="image" src="https://github.com/user-attachments/assets/a1d30aa4-8564-4f9c-a4bc-9cb043084d70" />
1 parent dd588b9 commit ad0aa52

File tree

9 files changed

+67
-28
lines changed

9 files changed

+67
-28
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6629,6 +6629,7 @@ dependencies = [
66296629
"egui_tiles",
66306630
"itertools 0.14.0",
66316631
"nohash-hasher",
6632+
"re_case",
66326633
"re_chunk",
66336634
"re_chunk_store",
66346635
"re_context_menu",

crates/viewer/re_component_ui/src/datatype_uis/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod range1d;
66
mod singleline_string;
77
mod vec;
88
mod view_id;
9+
mod view_timestamp;
910
mod view_uuid;
1011

1112
pub use bool_toggle::edit_bool;
@@ -23,4 +24,5 @@ pub use range1d::edit_view_range1d;
2324
pub use singleline_string::{edit_multiline_string, edit_singleline_string};
2425
pub use vec::{edit_or_view_vec2d, edit_or_view_vec3d, edit_or_view_vec3d_raw};
2526
pub use view_id::view_view_id;
27+
pub use view_timestamp::view_timestamp;
2628
pub use view_uuid::view_uuid;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use re_log_types::Timestamp;
2+
use re_types::datatypes;
3+
use re_ui::UiLayout;
4+
use re_viewer_context::MaybeMutRef;
5+
6+
pub fn view_timestamp(
7+
ctx: &re_viewer_context::ViewerContext<'_>,
8+
ui: &mut egui::Ui,
9+
value: &mut MaybeMutRef<'_, impl std::ops::DerefMut<Target = datatypes::TimeInt>>,
10+
) -> egui::Response {
11+
let value: &datatypes::TimeInt = value;
12+
UiLayout::List.data_label(
13+
ui,
14+
Timestamp::from(*value).format(ctx.app_options().timestamp_format),
15+
)
16+
}

crates/viewer/re_component_ui/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ use datatype_uis::{
2929
edit_bool, edit_f32_min_to_max_float, edit_f32_zero_to_max, edit_f32_zero_to_one,
3030
edit_f64_min_to_max_float, edit_f64_zero_to_max, edit_multiline_string, edit_or_view_vec2d,
3131
edit_or_view_vec3d, edit_singleline_string, edit_u64_range, edit_ui_points, edit_view_enum,
32-
edit_view_enum_with_variant_available, edit_view_range1d, view_uuid, view_view_id,
32+
edit_view_enum_with_variant_available, edit_view_range1d, view_timestamp, view_uuid,
33+
view_view_id,
3334
};
3435

3536
use re_types::blueprint::components::{RootContainer, ViewMaximized};
36-
use re_types::components::SeriesVisible;
37+
use re_types::components::{SeriesVisible, Timestamp};
3738
use re_types::{
3839
blueprint::components::{
3940
BackgroundKind, Corner2D, Enabled, ForceDistance, ForceIterations, ForceStrength,
@@ -98,6 +99,9 @@ pub fn create_component_ui_registry() -> re_viewer_context::ComponentUiRegistry
9899
registry.add_singleline_edit_or_view::<Visible>(edit_bool);
99100
registry.add_singleline_edit_or_view::<SeriesVisible>(edit_bool);
100101

102+
// Date components:
103+
registry.add_singleline_edit_or_view::<Timestamp>(view_timestamp);
104+
101105
// Text components:
102106
registry.add_singleline_edit_or_view::<Text>(edit_singleline_string);
103107
registry.add_multiline_edit_or_view::<Text>(edit_multiline_string);
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading

crates/viewer/re_data_ui/src/entity_db.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use re_byte_size::SizeBytes as _;
22
use re_chunk_store::ChunkStoreConfig;
33
use re_entity_db::EntityDb;
4-
use re_log_types::{StoreKind, Timestamp};
5-
use re_types::components;
4+
use re_log_types::StoreKind;
65
use re_ui::UiExt as _;
76
use re_viewer_context::{UiLayout, ViewerContext};
87

@@ -15,7 +14,7 @@ impl crate::DataUi for EntityDb {
1514
ui: &mut egui::Ui,
1615
ui_layout: UiLayout,
1716
_query: &re_chunk_store::LatestAtQuery,
18-
db: &re_entity_db::EntityDb,
17+
_db: &re_entity_db::EntityDb,
1918
) {
2019
if ui_layout.is_single_line() {
2120
// TODO(emilk): standardize this formatting with that in `entity_db_button_ui`
@@ -73,18 +72,6 @@ impl crate::DataUi for EntityDb {
7372
ui.grid_left_hand_label("Kind");
7473
ui.label(store_id.kind.to_string());
7574
ui.end_row();
76-
77-
if let Some(name) = db.recording_property::<components::Name>() {
78-
ui.grid_left_hand_label("Name");
79-
ui.label(name.to_string());
80-
ui.end_row();
81-
}
82-
83-
if let Some(started) = db.recording_property::<components::Timestamp>() {
84-
ui.grid_left_hand_label("Created");
85-
ui.label(Timestamp::from(started.0).format(ctx.app_options().timestamp_format));
86-
ui.end_row();
87-
}
8875
}
8976

9077
if let Some(latest_row_id) = self.latest_row_id() {
@@ -174,10 +161,9 @@ impl crate::DataUi for EntityDb {
174161

175162
match self.store_kind() {
176163
StoreKind::Recording => {
177-
// TODO(#9188): Create a dedicated UI for the recording properties.
178164
if store_id.as_ref() == hub.active_recording_id() {
179165
ui.add_space(8.0);
180-
ui.label("This is the active recording");
166+
ui.label("This is the active recording.");
181167
}
182168
}
183169
StoreKind::Blueprint => {

crates/viewer/re_selection_panel/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ workspace = true
1919
all-features = true
2020

2121
[dependencies]
22+
re_case.workspace = true
2223
re_chunk_store.workspace = true
2324
re_chunk.workspace = true
2425
re_context_menu.workspace = true

crates/viewer/re_selection_panel/src/selection_panel.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,17 +281,46 @@ impl SelectionPanel {
281281
_ => {}
282282
}
283283

284+
let (query, db) = if let Some(entity_path) = item.entity_path() {
285+
guess_query_and_db_for_selected_entity(ctx, entity_path)
286+
} else {
287+
(ctx.current_query(), ctx.recording())
288+
};
289+
284290
if let Some(data_ui_item) = data_section_ui(item) {
285291
ui.section_collapsing_header("Data").show(ui, |ui| {
286292
// TODO(#6075): Because `list_item_scope` changes it. Temporary until everything is `ListItem`.
287293
ui.spacing_mut().item_spacing.y = ui.ctx().style().spacing.item_spacing.y;
294+
data_ui_item.data_ui(ctx, ui, ui_layout, &query, db);
295+
});
296+
}
288297

289-
let (query, db) = if let Some(entity_path) = item.entity_path() {
290-
guess_query_and_db_for_selected_entity(ctx, entity_path)
298+
if let Item::StoreId(_) = item {
299+
ui.section_collapsing_header("Properties").show(ui, |ui| {
300+
let filtered = db
301+
.entity_paths()
302+
.into_iter()
303+
.filter(|entity_path| {
304+
// Only check for properties, but skip the recording properties,
305+
// because we display them already elsewhere in the UI.
306+
entity_path.is_descendant_of(&EntityPath::properties())
307+
})
308+
.collect::<Vec<_>>();
309+
310+
if filtered.is_empty() {
311+
ui.label("No properties found for this recording.");
291312
} else {
292-
(ctx.current_query(), ctx.recording())
293-
};
294-
data_ui_item.data_ui(ctx, ui, ui_layout, &query, db);
313+
for entity_path in filtered {
314+
// We strip the property part
315+
let name = entity_path
316+
.to_string()
317+
.strip_prefix(format!("{}/", EntityPath::properties()).as_str())
318+
.map(re_case::to_human_case)
319+
.unwrap_or("<unknown>".to_owned());
320+
ui.label(name);
321+
entity_path.data_ui(ctx, ui, ui_layout, &query, db);
322+
}
323+
}
295324
});
296325
}
297326

0 commit comments

Comments
 (0)