Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve preview UI for Component data #5093

Merged
merged 3 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 61 additions & 52 deletions crates/re_data_ui/src/instance_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,63 +36,72 @@ impl DataUi for InstancePath {
return;
};

let all_are_indicators = components.iter().all(|c| c.is_indicator_component());
let mut components = crate::ui_visible_components(&components);

egui::Grid::new("entity_instance")
.num_columns(2)
.show(ui, |ui| {
for &component_name in crate::ui_visible_components(&components) {
match verbosity {
UiVerbosity::Small | UiVerbosity::Reduced => {
// Skip indicator components in hover ui (unless there are no other
// types of components).
if component_name.is_indicator_component() && !all_are_indicators {
continue;
}
}
UiVerbosity::LimitHeight | UiVerbosity::Full => {}
}
// Put indicator components first:
components.sort_by_key(|c| !c.is_indicator_component());

let Some((_, _, component_data)) =
get_component_with_instances(store, query, entity_path, component_name)
else {
continue; // no need to show components that are unset at this point in time
};
let split = components.partition_point(|c| c.is_indicator_component());
let normal_components = components.split_off(split);
let indicator_components = components;

crate::temporary_style_ui_for_component(ui, &component_name, |ui| {
item_ui::component_path_button(
ctx,
ui,
&ComponentPath::new(entity_path.clone(), component_name),
);
});
let show_indicator_comps = match verbosity {
UiVerbosity::Small | UiVerbosity::Reduced => {
// Skip indicator components in hover ui (unless there are no other
// types of components).
!normal_components.is_empty()
}
UiVerbosity::LimitHeight | UiVerbosity::Full => true,
};

if let Some(archetype_name) = component_name.indicator_component_archetype() {
ui.weak(format!(
"Indicator component for the {archetype_name} archetype"
));
} else if instance_key.is_splat() {
super::component::EntityComponentWithInstances {
entity_path: entity_path.clone(),
component_data,
}
.data_ui(ctx, ui, UiVerbosity::Small, query, store);
} else {
ctx.component_ui_registry.ui(
ctx,
ui,
UiVerbosity::Small,
query,
store,
entity_path,
&component_data,
instance_key,
);
}
// First show indicator components, outside the grid:
if show_indicator_comps {
for component_name in indicator_components {
item_ui::component_path_button(
ctx,
ui,
&ComponentPath::new(entity_path.clone(), component_name),
);
}
}

ui.end_row();
// Now show the rest of the components:
egui::Grid::new("components").num_columns(2).show(ui, |ui| {
for component_name in normal_components {
let Some((_, _, component_data)) =
get_component_with_instances(store, query, entity_path, component_name)
else {
continue; // no need to show components that are unset at this point in time
};

item_ui::component_path_button(
ctx,
ui,
&ComponentPath::new(entity_path.clone(), component_name),
);

if instance_key.is_splat() {
super::component::EntityComponentWithInstances {
entity_path: entity_path.clone(),
component_data,
}
.data_ui(ctx, ui, UiVerbosity::Small, query, store);
} else {
ctx.component_ui_registry.ui(
ctx,
ui,
UiVerbosity::Small,
query,
store,
entity_path,
&component_data,
instance_key,
);
}
Some(())
});

ui.end_row();
}
Some(())
});
}
}
31 changes: 5 additions & 26 deletions crates/re_data_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ pub use image_meaning::image_meaning_for_entity;
/// and order the other components in a cosnsiten way.
pub fn ui_visible_components<'a>(
iter: impl IntoIterator<Item = &'a ComponentName> + 'a,
) -> impl Iterator<Item = &'a ComponentName> {
let mut components: Vec<&ComponentName> = iter
) -> Vec<ComponentName> {
let mut components: Vec<ComponentName> = iter
.into_iter()
.filter(|c| is_component_visible_in_ui(c))
.cloned()
.filter(is_component_visible_in_ui)
.collect();

// Put indicator components first:
components.sort_by_key(|c| (!c.is_indicator_component(), c.full_name()));

components.into_iter()
components
}

/// Show this component in the UI.
Expand All @@ -59,28 +60,6 @@ pub fn is_component_visible_in_ui(component_name: &ComponentName) -> bool {
!HIDDEN_COMPONENTS.contains(&component_name.as_ref())
}

pub fn temporary_style_ui_for_component<R>(
ui: &mut egui::Ui,
component_name: &ComponentName,
add_contents: impl FnOnce(&mut egui::Ui) -> R,
) -> R {
let old_style: egui::Style = (**ui.style()).clone();

if component_name.is_indicator_component() {
// Make indicator components stand out by making them slightly fainter:

let inactive = &mut ui.style_mut().visuals.widgets.inactive;
// TODO(emilk): get a color from the design-tokens
inactive.fg_stroke.color = inactive.fg_stroke.color.linear_multiply(0.45);
}

let ret = add_contents(ui);

ui.set_style(old_style);

ret
}

/// Types implementing [`DataUi`] can display themselves in an [`egui::Ui`].
pub trait DataUi {
/// If you need to lookup something in the data store, use the given query to do so.
Expand Down
33 changes: 15 additions & 18 deletions crates/re_time_panel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,34 +681,31 @@ impl TimePanel {
let clip_rect_save = ui.clip_rect();

for component_name in re_data_ui::ui_visible_components(tree.entity.components.keys()) {
let data = &tree.entity.components[component_name];
let data = &tree.entity.components[&component_name];

let component_has_data_in_current_timeline =
time_ctrl.component_has_data_in_current_timeline(data);
let component_path = ComponentPath::new(tree.path.clone(), *component_name);
let component_path = ComponentPath::new(tree.path.clone(), component_name);
let short_component_name = component_path.component_name.short_name();
let item = TimePanelItem::component_path(component_path);

let mut clip_rect = clip_rect_save;
clip_rect.max.x = tree_max_y;
ui.set_clip_rect(clip_rect);

let response =
re_data_ui::temporary_style_ui_for_component(ui, component_name, |ui| {
ListItem::new(ctx.re_ui, short_component_name)
.selected(ctx.selection().contains_item(&item.to_item()))
.width_allocation_mode(WidthAllocationMode::Compact)
.force_hovered(
ctx.selection_state()
.highlight_for_ui_element(&item.to_item())
== HoverHighlight::Hovered,
)
.with_icon_fn(|_, ui, rect, visual| {
ui.painter()
.circle_filled(rect.center(), 2.0, visual.text_color());
})
.show(ui)
});
let response = ListItem::new(ctx.re_ui, short_component_name)
.selected(ctx.selection().contains_item(&item.to_item()))
.width_allocation_mode(WidthAllocationMode::Compact)
.force_hovered(
ctx.selection_state()
.highlight_for_ui_element(&item.to_item())
== HoverHighlight::Hovered,
)
.with_icon_fn(|_, ui, rect, visual| {
ui.painter()
.circle_filled(rect.center(), 2.0, visual.text_color());
})
.show(ui);

ui.set_clip_rect(clip_rect_save);

Expand Down
12 changes: 5 additions & 7 deletions crates/re_viewer/src/ui/override_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
use itertools::Itertools;

use re_data_store::{DataStore, LatestAtQuery};
use re_data_ui::{is_component_visible_in_ui, temporary_style_ui_for_component};
use re_data_ui::is_component_visible_in_ui;
use re_entity_db::{EntityDb, InstancePath};
use re_log_types::{DataCell, DataRow, RowId, StoreKind};
use re_query_cache::external::re_query::get_component_with_instances;
Expand Down Expand Up @@ -132,12 +132,10 @@ pub fn override_ui(
});
// Component label
row.col(|ui| {
temporary_style_ui_for_component(ui, component_name, |ui| {
// NOTE: this is not a component button because it is not a component that exists in the recording, just in the blueprint.
// So we don't allow users to select it.
ui.label(component_name.short_name())
.on_hover_text(component_name.full_name());
});
// NOTE: this is not a component button because it is not a component that exists in the recording, just in the blueprint.
// So we don't allow users to select it.
ui.label(component_name.short_name())
.on_hover_text(component_name.full_name());
});
// Editor last to take up remainder of space
row.col(|ui| {
Expand Down
12 changes: 6 additions & 6 deletions crates/re_viewer/src/ui/visible_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 +470,10 @@ fn visible_history_boundary_ui(
let response = match visible_history_boundary {
VisibleHistoryBoundary::RelativeToTimeCursor(value) => {
// see note above
let low_bound_override = if !low_bound {
Some(other_boundary_absolute.saturating_sub(current_time))
} else {
let low_bound_override = if low_bound {
None
} else {
Some(other_boundary_absolute.saturating_sub(current_time))
};

match time_type {
Expand Down Expand Up @@ -504,10 +504,10 @@ fn visible_history_boundary_ui(
}
VisibleHistoryBoundary::Absolute(value) => {
// see note above
let low_bound_override = if !low_bound {
Some(other_boundary_absolute)
} else {
let low_bound_override = if low_bound {
None
} else {
Some(other_boundary_absolute)
};

match time_type {
Expand Down
2 changes: 1 addition & 1 deletion crates/re_viewer_context/src/app_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Default for AppOptions {
low_latency: 0.100,
warn_latency: 0.200,

show_metrics: false,
show_metrics: cfg!(debug_assertions),

#[cfg(not(target_arch = "wasm32"))]
experimental_space_view_screenshots: false,
Expand Down
Loading