Skip to content

Commit

Permalink
Clickable path parts in selection-panel (#5220)
Browse files Browse the repository at this point in the history
UPDATE: Cleaned it up with @abey79!

Just a proof-of-concept as I have no clue how to do things correctly and
no time to dig right now.

But UX wise, man, it's _awesome_!



https://github.com/rerun-io/rerun/assets/2910679/2360e249-8ebd-4a33-a6dd-f732daddec92

---------

Co-authored-by: Antoine Beyeler <antoine@rerun.io>
  • Loading branch information
teh-cmc and abey79 authored Feb 19, 2024
1 parent bf9a821 commit 46d6854
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 26 deletions.
75 changes: 75 additions & 0 deletions crates/re_data_ui/src/item_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,37 @@ pub fn entity_path_button(
)
}

/// Show the different parts of an entity path and make them selectable.
pub fn entity_path_parts_buttons(
ctx: &ViewerContext<'_>,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
ui: &mut egui::Ui,
space_view_id: Option<SpaceViewId>,
entity_path: &EntityPath,
) -> egui::Response {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 4.0;

let mut accumulated = Vec::new();
for part in entity_path.iter() {
accumulated.push(part.clone());

ui.strong("/");
entity_path_button_to(
ctx,
query,
store,
ui,
space_view_id,
&accumulated.clone().into(),
part.syntax_highlighted(ui.style()),
);
}
})
.response
}

/// Show an entity path and make it selectable.
pub fn entity_path_button_to(
ctx: &ViewerContext<'_>,
Expand Down Expand Up @@ -119,6 +150,50 @@ pub fn instance_path_button_to(
cursor_interact_with_selectable(ctx, response, item)
}

/// Show the different parts of an instance path and make them selectable.
pub fn instance_path_parts_buttons(
ctx: &ViewerContext<'_>,
query: &re_data_store::LatestAtQuery,
store: &re_data_store::DataStore,
ui: &mut egui::Ui,
space_view_id: Option<SpaceViewId>,
instance_path: &InstancePath,
) -> egui::Response {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 4.0;

let mut accumulated = Vec::new();
for part in instance_path.entity_path.iter() {
accumulated.push(part.clone());

ui.strong("/");
entity_path_button_to(
ctx,
query,
store,
ui,
space_view_id,
&accumulated.clone().into(),
part.syntax_highlighted(ui.style()),
);
}

if !instance_path.instance_key.is_splat() {
ui.strong("/");
instance_path_button_to(
ctx,
query,
store,
ui,
space_view_id,
instance_path,
instance_path.instance_key.syntax_highlighted(ui.style()),
);
}
})
.response
}

fn entity_tree_stats_ui(ui: &mut egui::Ui, timeline: &Timeline, tree: &EntityTree) {
use re_format::format_bytes;

Expand Down
14 changes: 10 additions & 4 deletions crates/re_ui/src/syntax_highlighting.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use re_entity_db::InstancePath;
use re_log_types::{EntityPath, EntityPathPart};
use re_log_types::{external::re_types_core::components::InstanceKey, EntityPath, EntityPathPart};

use egui::{text::LayoutJob, Color32, Style, TextFormat};

Expand Down Expand Up @@ -39,6 +39,14 @@ impl SyntaxHighlighting for EntityPathPart {
}
}

impl SyntaxHighlighting for InstanceKey {
fn syntax_highlight_into(&self, style: &Style, job: &mut LayoutJob) {
job.append("[", 0.0, faint_text_format(style));
job.append(&self.to_string(), 0.0, text_format(style));
job.append("]", 0.0, faint_text_format(style));
}
}

impl SyntaxHighlighting for EntityPath {
fn syntax_highlight_into(&self, style: &Style, job: &mut LayoutJob) {
job.append("/", 0.0, faint_text_format(style));
Expand All @@ -56,9 +64,7 @@ impl SyntaxHighlighting for InstancePath {
fn syntax_highlight_into(&self, style: &Style, job: &mut LayoutJob) {
self.entity_path.syntax_highlight_into(style, job);
if !self.instance_key.is_splat() {
job.append("[", 0.0, faint_text_format(style));
job.append(&self.instance_key.to_string(), 0.0, text_format(style));
job.append("]", 0.0, faint_text_format(style));
self.instance_key.syntax_highlight_into(style, job);
}
}
}
61 changes: 39 additions & 22 deletions crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ use re_types::{
};
use re_types_core::components::InstanceKey;
use re_ui::list_item::ListItem;
use re_ui::ReUi;
use re_ui::SyntaxHighlighting as _;
use re_ui::{ReUi, SyntaxHighlighting as _};
use re_viewer_context::{
blueprint_timepoint_for_writes, gpu_bridge::colormap_dropdown_button_ui, ContainerId,
DataQueryId, HoverHighlight, Item, SpaceViewClass, SpaceViewClassIdentifier, SpaceViewId,
Expand Down Expand Up @@ -410,13 +409,23 @@ fn what_is_selected_ui(
}
}
Item::InstancePath(space_view_id, instance_path) => {
let typ = if instance_path.instance_key.is_splat() {
"Entity"
} else {
let is_instance = !instance_path.instance_key.is_splat();

let typ = if is_instance {
"Entity instance"
} else {
"Entity"
};

let (query, store) =
guess_query_and_store_for_selected_entity(ctx, &instance_path.entity_path);

let name = instance_path.syntax_highlighted(ui.style());
let parent = if is_instance {
Some(instance_path.entity_path.clone())
} else {
instance_path.entity_path.parent()
};

if let Some(space_view_id) = space_view_id {
if let Some(space_view) = viewport.space_view(space_view_id) {
Expand All @@ -431,6 +440,20 @@ fn what_is_selected_ui(
),
);

if let Some(parent) = parent {
ui.horizontal(|ui| {
ui.label("path");
item_ui::entity_path_parts_buttons(
ctx,
&query,
store,
ui,
Some(*space_view_id),
&parent,
);
});
}

ui.horizontal(|ui| {
ui.label("in");
space_view_button(ctx, ui, space_view);
Expand All @@ -445,6 +468,13 @@ fn what_is_selected_ui(
&format!("{typ} '{instance_path}'"),
);

if let Some(parent) = parent {
ui.horizontal(|ui| {
ui.label("path");
item_ui::entity_path_parts_buttons(ctx, &query, store, ui, None, &parent);
});
}

list_existing_data_blueprints(ui, ctx, &instance_path.entity_path, viewport);
}
}
Expand Down Expand Up @@ -764,7 +794,9 @@ fn show_list_item_for_container_child(
fn has_blueprint_section(item: &Item) -> bool {
match item {
Item::ComponentPath(_) | Item::Container(_) => false,
Item::InstancePath(space_view_id, _) => space_view_id.is_some(),
Item::InstancePath(space_view_id, instance_path) => {
space_view_id.is_some() && instance_path.instance_key.is_splat()
}
_ => true,
}
}
Expand Down Expand Up @@ -915,22 +947,7 @@ fn blueprint_ui_for_instance_path(
) {
if let Some(space_view_id) = space_view_id {
if let Some(space_view) = viewport.blueprint.space_view(space_view_id) {
if instance_path.instance_key.is_specific() {
let (query, store) =
guess_query_and_store_for_selected_entity(ctx, &instance_path.entity_path);
ui.horizontal(|ui| {
ui.label("Part of");
item_ui::entity_path_button(
ctx,
&query,
store,
ui,
Some(*space_view_id),
&instance_path.entity_path,
);
});
// TODO(emilk): show the values of this specific instance (e.g. point in the point cloud)!
} else {
if instance_path.instance_key.is_splat() {
// splat - the whole entity
let space_view_class = *space_view.class_identifier();
let entity_path = &instance_path.entity_path;
Expand Down

0 comments on commit 46d6854

Please sign in to comment.