1#![warn(clippy::iter_over_hash_type)] use re_log_types::EntityPath;
8use re_types::reflection::ComponentDescriptorExt as _;
9use re_types::{ComponentDescriptor, RowId};
10use re_ui::UiExt as _;
11use re_viewer_context::{UiLayout, ViewerContext};
12
13mod annotation_context;
14mod app_id;
15mod blob;
16mod component;
17mod component_path;
18mod component_type;
19mod component_ui_registry;
20mod data_source;
21mod entity_db;
22mod entity_path;
23mod image;
24mod instance_path;
25mod store_id;
26mod tensor;
27mod video;
28
29mod extra_data_ui;
30pub mod item_ui;
31
32pub use crate::tensor::tensor_summary_ui_grid_contents;
33pub use component::ComponentPathLatestAtResults;
34pub use component_ui_registry::{add_to_registry, register_component_uis};
35pub use image::image_preview_ui;
36pub use instance_path::archetype_label_list_item_ui;
37use re_chunk_store::UnitChunkShared;
38use re_types_core::reflection::Reflection;
39use re_types_core::{ArchetypeName, Component};
40
41pub type ArchetypeComponentMap =
42 std::collections::BTreeMap<Option<ArchetypeName>, Vec<ComponentDescriptor>>;
43
44pub fn sorted_component_list_by_archetype_for_ui(
46 reflection: &Reflection,
47 iter: impl IntoIterator<Item = ComponentDescriptor>,
48) -> ArchetypeComponentMap {
49 let mut map = iter
50 .into_iter()
51 .fold(ArchetypeComponentMap::default(), |mut acc, descriptor| {
52 acc.entry(descriptor.archetype)
53 .or_default()
54 .push(descriptor);
55 acc
56 });
57
58 for (archetype, components) in &mut map {
59 if let Some(reflection) = archetype
60 .as_ref()
61 .and_then(|a| reflection.archetypes.get(a))
62 {
63 components.sort_by_key(|c| {
65 reflection
66 .fields
67 .iter()
68 .position(|field| field.name == c.archetype_field_name())
69 .unwrap_or(usize::MAX)
70 });
71 } else {
72 components.sort_by_key(|c| c.display_name().to_owned());
74 }
75 }
76
77 map
78}
79
80pub trait DataUi {
82 fn data_ui(
84 &self,
85 ctx: &ViewerContext<'_>,
86 ui: &mut egui::Ui,
87 ui_layout: UiLayout,
88 query: &re_chunk_store::LatestAtQuery,
89 db: &re_entity_db::EntityDb,
90 );
91
92 fn data_ui_recording(&self, ctx: &ViewerContext<'_>, ui: &mut egui::Ui, ui_layout: UiLayout) {
94 ui.sanity_check();
95 self.data_ui(ctx, ui, ui_layout, &ctx.current_query(), ctx.recording());
96 ui.sanity_check();
97 }
98}
99
100pub trait EntityDataUi {
104 #[expect(clippy::too_many_arguments)]
106 fn entity_data_ui(
107 &self,
108 ctx: &ViewerContext<'_>,
109 ui: &mut egui::Ui,
110 ui_layout: UiLayout,
111 entity_path: &EntityPath,
112 component_descriptor: &ComponentDescriptor,
113 row_id: Option<RowId>,
114 query: &re_chunk_store::LatestAtQuery,
115 db: &re_entity_db::EntityDb,
116 );
117}
118
119impl<T> EntityDataUi for T
120where
121 T: DataUi,
122{
123 fn entity_data_ui(
124 &self,
125 ctx: &ViewerContext<'_>,
126 ui: &mut egui::Ui,
127 ui_layout: UiLayout,
128 entity_path: &EntityPath,
129 _component_descriptor: &ComponentDescriptor,
130 _row_id: Option<RowId>,
131 query: &re_chunk_store::LatestAtQuery,
132 db: &re_entity_db::EntityDb,
133 ) {
134 ui.push_id(entity_path.hash(), |ui| {
137 self.data_ui(ctx, ui, ui_layout, query, db);
138 });
139 }
140}
141
142pub fn annotations(
145 ctx: &ViewerContext<'_>,
146 query: &re_chunk_store::LatestAtQuery,
147 entity_path: &re_entity_db::EntityPath,
148) -> std::sync::Arc<re_viewer_context::Annotations> {
149 re_tracing::profile_function!();
150 let mut annotation_map = re_viewer_context::AnnotationMap::default();
151 annotation_map.load(ctx, query);
152 annotation_map.find(entity_path)
153}
154
155fn find_and_deserialize_archetype_mono_component<C: Component>(
157 components: &[(ComponentDescriptor, UnitChunkShared)],
158 archetype_name: Option<ArchetypeName>,
159) -> Option<C> {
160 components.iter().find_map(|(descr, chunk)| {
161 (descr.component_type == Some(C::name()) && descr.archetype == archetype_name)
162 .then(|| chunk.component_mono::<C>(descr.component)?.ok())
163 .flatten()
164 })
165}