use itertools::Itertools;
use re_log_types::{DataCell, EntityPath, TimePoint};
use re_types::ComponentName;
use re_viewer_context::{UiVerbosity, ViewerContext};
mod annotation_context;
mod app_id;
mod blueprint_data;
mod component;
mod component_path;
mod component_ui_registry;
mod data;
mod data_source;
mod editors;
mod entity_db;
mod entity_path;
mod image;
mod image_meaning;
mod instance_path;
mod log_msg;
mod material;
mod pinhole;
mod rotation3d;
mod store_id;
mod transform3d;
pub mod item_ui;
pub use crate::image::{
show_zoomed_image_region, show_zoomed_image_region_area_outline,
tensor_summary_ui_grid_contents,
};
pub use component::EntityComponentWithInstances;
pub use component_ui_registry::{add_to_registry, create_component_ui_registry};
pub use image_meaning::image_meaning_for_entity;
pub fn ui_visible_components<'a>(
iter: impl IntoIterator<Item = &'a ComponentName> + 'a,
) -> Vec<ComponentName> {
let mut components: Vec<ComponentName> = iter
.into_iter()
.cloned()
.filter(is_component_visible_in_ui)
.collect();
components.sort_by_key(|c| (!c.is_indicator_component(), c.full_name()));
components
}
pub fn is_component_visible_in_ui(component_name: &ComponentName) -> bool {
const HIDDEN_COMPONENTS: &[&str] = &["rerun.components.InstanceKey"];
!HIDDEN_COMPONENTS.contains(&component_name.as_ref())
}
pub trait DataUi {
fn data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
);
}
pub trait EntityDataUi {
fn entity_data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
entity_path: &EntityPath,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
);
}
impl<T> EntityDataUi for T
where
T: DataUi,
{
fn entity_data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
entity: &EntityPath,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
) {
ui.push_id(entity.hash(), |ui| {
self.data_ui(ctx, ui, verbosity, query, store);
});
}
}
impl DataUi for TimePoint {
fn data_ui(
&self,
ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
_verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
ui.vertical(|ui| {
egui::Grid::new("time_point").num_columns(2).show(ui, |ui| {
ui.spacing_mut().item_spacing.x = 0.0;
for (timeline, value) in self.iter() {
item_ui::timeline_button_to(ctx, ui, format!("{}:", timeline.name()), timeline);
item_ui::time_button(ctx, ui, timeline, *value);
ui.end_row();
}
});
});
}
}
impl DataUi for [DataCell] {
fn data_ui(
&self,
_ctx: &ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: UiVerbosity,
_query: &re_data_store::LatestAtQuery,
_store: &re_data_store::DataStore,
) {
let mut sorted = self.to_vec();
sorted.sort_by_key(|cb| cb.component_name());
match verbosity {
UiVerbosity::Small => {
ui.label(sorted.iter().map(format_cell).join(", "));
}
UiVerbosity::Full | UiVerbosity::LimitHeight | UiVerbosity::Reduced => {
ui.vertical(|ui| {
for component_bundle in &sorted {
ui.label(format_cell(component_bundle));
}
});
}
}
}
}
fn format_cell(cell: &DataCell) -> String {
format!(
"{}x {}",
cell.num_instances(),
cell.component_name().short_name()
)
}
pub fn annotations(
ctx: &ViewerContext<'_>,
query: &re_data_store::LatestAtQuery,
entity_path: &re_entity_db::EntityPath,
) -> std::sync::Arc<re_viewer_context::Annotations> {
re_tracing::profile_function!();
let mut annotation_map = re_viewer_context::AnnotationMap::default();
annotation_map.load(ctx, query, std::iter::once(entity_path));
annotation_map.find(entity_path)
}
pub fn table_for_verbosity(
verbosity: UiVerbosity,
ui: &mut egui::Ui,
) -> egui_extras::TableBuilder<'_> {
let table = egui_extras::TableBuilder::new(ui);
match verbosity {
UiVerbosity::Small | UiVerbosity::Reduced => {
table.auto_shrink([true, true])
}
UiVerbosity::LimitHeight => {
table
.auto_shrink([false, true])
.vscroll(true)
.max_scroll_height(100.0)
}
UiVerbosity::Full => {
table.auto_shrink([false, true]).vscroll(false)
}
}
}