Skip to content

Commit

Permalink
Click a recording to select it (#4761)
Browse files Browse the repository at this point in the history
### What
* Closes #4647
* Closes #4649

You can now click a recording to select it (show info about it in the
selection panel).


![select-recording](https://github.com/rerun-io/rerun/assets/1148717/c0928e97-a538-4f60-9308-da65f33c51a6)

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using newly built examples:
[app.rerun.io](https://app.rerun.io/pr/4761/index.html)
* Using examples from latest `main` build:
[app.rerun.io](https://app.rerun.io/pr/4761/index.html?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[app.rerun.io](https://app.rerun.io/pr/4761/index.html?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG

- [PR Build Summary](https://build.rerun.io/pr/4761)
- [Docs
preview](https://rerun.io/preview/482599187dd686bfa0e1c4709ed090d6e84c3c9d/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/482599187dd686bfa0e1c4709ed090d6e84c3c9d/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)
  • Loading branch information
emilk authored Jan 10, 2024
1 parent 74b5ffa commit 48f64a7
Show file tree
Hide file tree
Showing 21 changed files with 312 additions and 204 deletions.
65 changes: 65 additions & 0 deletions crates/re_data_ui/src/entity_db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
impl crate::DataUi for re_entity_db::EntityDb {
fn data_ui(
&self,
ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: re_viewer_context::UiVerbosity,
_query: &re_data_store::LatestAtQuery,
) {
let re_ui = &ctx.re_ui;

if verbosity == re_viewer_context::UiVerbosity::Small {
let mut string = self.store_id().to_string();
if let Some(data_source) = &self.data_source {
string += &format!(", {data_source}");
}
if let Some(store_info) = self.store_info() {
string += &format!(", {}", store_info.application_id);
}
ui.label(string);
return;
}

egui::Grid::new("entity_db").num_columns(2).show(ui, |ui| {
re_ui.grid_left_hand_label(ui, &format!("{} ID", self.store_id().kind));
ui.label(self.store_id().to_string());
ui.end_row();

if let Some(data_source) = &self.data_source {
re_ui.grid_left_hand_label(ui, "Data source");
ui.label(data_source.to_string());
ui.end_row();
}

if let Some(store_info) = self.store_info() {
let re_log_types::StoreInfo {
application_id,
store_id: _,
is_official_example: _,
started,
store_source,
store_kind,
} = store_info;

re_ui.grid_left_hand_label(ui, "Application ID");
ui.label(application_id.to_string());
ui.end_row();

re_ui.grid_left_hand_label(ui, "Recording started");
ui.label(started.format(ctx.app_options.time_zone_for_timestamps));
ui.end_row();

re_ui.grid_left_hand_label(ui, "Source");
ui.label(store_source.to_string());
ui.end_row();

// We are in the recordings menu, we know the kind
if false {
re_ui.grid_left_hand_label(ui, "Kind");
ui.label(store_kind.to_string());
ui.end_row();
}
}
});
}
}
26 changes: 0 additions & 26 deletions crates/re_data_ui/src/item.rs

This file was deleted.

3 changes: 2 additions & 1 deletion crates/re_data_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ mod component;
mod component_path;
mod component_ui_registry;
mod data;
mod entity_db;
mod entity_path;
mod image;
mod image_meaning;
mod instance_path;
mod item;
pub mod item_ui;
mod log_msg;
mod pinhole;
mod rotation3d;
mod store_id;
mod transform3d;

pub use crate::image::{
Expand Down
15 changes: 15 additions & 0 deletions crates/re_data_ui/src/store_id.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
impl crate::DataUi for re_log_types::StoreId {
fn data_ui(
&self,
ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
verbosity: re_viewer_context::UiVerbosity,
query: &re_data_store::LatestAtQuery,
) {
if let Some(entity_db) = ctx.store_context.recording(self) {
entity_db.data_ui(ctx, ui, verbosity, query);
} else {
ui.label(format!("{} ID {} (not found)", self.kind, self.id));
}
}
}
4 changes: 2 additions & 2 deletions crates/re_log_types/src/path/component_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::path::EntityPath;

/// A [`EntityPath`] plus a [`ComponentName`].
///
/// Example: `camera / "left" / points / #42`.`color`
/// Example: `camera/left/points:Color`
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct ComponentPath {
Expand Down Expand Up @@ -38,7 +38,7 @@ impl ComponentPath {
impl std::fmt::Display for ComponentPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.entity_path.fmt(f)?;
f.write_str(".")?;
f.write_str(":")?;
self.component_name.fmt(f)?;
Ok(())
}
Expand Down
14 changes: 14 additions & 0 deletions crates/re_smart_channel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,20 @@ pub enum SmartChannelSource {
Stdin,
}

impl std::fmt::Display for SmartChannelSource {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::File(path) => path.display().fmt(f),
Self::RrdHttpStream { url } => url.fmt(f),
Self::RrdWebEventListener => "Web Event Listener".fmt(f),
Self::Sdk => "SDK".fmt(f),
Self::WsClient { ws_server_url } => ws_server_url.fmt(f),
Self::TcpServer { port } => write!(f, "TCP Server, port {port}"),
Self::Stdin => "Standard Input".fmt(f),
}
}
}

impl SmartChannelSource {
pub fn is_network(&self) -> bool {
match self {
Expand Down
52 changes: 29 additions & 23 deletions crates/re_time_panel/src/data_density_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use std::ops::RangeInclusive;
use egui::emath::Rangef;
use egui::{epaint::Vertex, lerp, pos2, remap, Color32, NumExt as _, Rect, Shape};

use re_data_ui::{item_ui, DataUi};
use re_data_ui::item_ui;
use re_entity_db::TimeHistogram;
use re_log_types::{TimeInt, TimeRange, TimeReal};
use re_log_types::{ComponentPath, TimeInt, TimeRange, TimeReal};
use re_viewer_context::{Item, TimeControl, UiVerbosity, ViewerContext};

use crate::TimePanelItem;

use super::time_ranges_ui::TimeRangesUi;

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -376,7 +378,7 @@ pub fn data_density_graph_ui(
time_histogram: &TimeHistogram,
row_rect: Rect,
time_ranges_ui: &TimeRangesUi,
item: &Item,
item: &TimePanelItem,
) {
re_tracing::profile_function!();

Expand Down Expand Up @@ -476,15 +478,15 @@ pub fn data_density_graph_ui(
data_dentity_graph_painter,
row_rect.y_range(),
time_area_painter,
graph_color(ctx, item, ui),
graph_color(ctx, &item.to_item(), ui),
hovered_x_range,
);

if 0 < num_hovered_messages {
ctx.selection_state().set_hovered(item.clone());
ctx.selection_state().set_hovered(item.to_item());

if time_area_response.clicked_by(egui::PointerButton::Primary) {
ctx.selection_state().set_selection(item.clone());
ctx.selection_state().set_selection(item.to_item());
time_ctrl.set_time(hovered_time_range.min);
time_ctrl.pause();
} else if !ui.ctx().memory(|mem| mem.is_anything_being_dragged()) {
Expand Down Expand Up @@ -523,10 +525,12 @@ fn show_row_ids_tooltip(
ctx: &ViewerContext<'_>,
time_ctrl: &TimeControl,
egui_ctx: &egui::Context,
item: &Item,
item: &TimePanelItem,
time_range: TimeRange,
num_events: usize,
) {
use re_data_ui::DataUi as _;

if num_events == 0 {
return;
}
Expand All @@ -538,22 +542,24 @@ fn show_row_ids_tooltip(
ui.label(format!("{num_events} events"));
}

match item {
Item::ComponentPath(path) => {
item_ui::component_path_button(ctx, ui, path);
}
Item::InstancePath(_, path) => {
item_ui::instance_path_button(ctx, ui, None, path);
}
Item::SpaceView(_) | Item::DataBlueprintGroup(_, _, _) | Item::Container(_) => {
// No extra info. This should never happen, but not worth printing a warning over.
// Even if it does go here, the ui after will still look ok.
}
}

ui.add_space(8.0);

let query = re_data_store::LatestAtQuery::new(*time_ctrl.timeline(), time_range.max);
item.data_ui(ctx, ui, UiVerbosity::Reduced, &query);
let verbosity = UiVerbosity::Reduced;

let TimePanelItem {
entity_path,
component_name,
} = item;

if let Some(component_name) = component_name {
let component_path = ComponentPath::new(entity_path.clone(), *component_name);
item_ui::component_path_button(ctx, ui, &component_path);
ui.add_space(8.0);
component_path.data_ui(ctx, ui, verbosity, &query);
} else {
let instance_path = re_entity_db::InstancePath::entity_splat(entity_path.clone());
item_ui::instance_path_button(ctx, ui, None, &instance_path);
ui.add_space(8.0);
instance_path.data_ui(ctx, ui, verbosity, &query);
}
});
}
69 changes: 57 additions & 12 deletions crates/re_time_panel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,56 @@ use egui::{pos2, Color32, CursorIcon, NumExt, Painter, PointerButton, Rect, Shap

use re_data_ui::item_ui;
use re_entity_db::{EntityTree, InstancePath, TimeHistogram};
use re_log_types::{ComponentPath, EntityPathPart, TimeInt, TimeRange, TimeReal};
use re_log_types::{
external::re_types_core::ComponentName, ComponentPath, EntityPath, EntityPathPart, TimeInt,
TimeRange, TimeReal,
};
use re_ui::list_item::{ListItem, WidthAllocationMode};
use re_viewer_context::{HoverHighlight, Item, TimeControl, TimeView, ViewerContext};

use time_axis::TimelineAxis;
use time_control_ui::TimeControlUi;
use time_ranges_ui::TimeRangesUi;

#[derive(Clone)]
struct TimePanelItem {
pub entity_path: EntityPath,
pub component_name: Option<ComponentName>,
}

impl TimePanelItem {
pub fn entity_path(entity_path: EntityPath) -> Self {
Self {
entity_path,
component_name: None,
}
}

pub fn component_path(component_path: ComponentPath) -> Self {
let ComponentPath {
entity_path,
component_name,
} = component_path;
Self {
entity_path,
component_name: Some(component_name),
}
}

pub fn to_item(&self) -> Item {
let Self {
entity_path,
component_name,
} = self;

if let Some(component_name) = component_name {
Item::ComponentPath(ComponentPath::new(entity_path.clone(), *component_name))
} else {
Item::InstancePath(None, InstancePath::entity_splat(entity_path.clone()))
}
}
}

/// A panel that shows entity names to the left, time on the top.
///
/// This includes the timeline controls and streams view.
Expand Down Expand Up @@ -483,10 +525,12 @@ impl TimePanel {
let collapsing_header_id = ui.make_persistent_id(&tree.path);
let default_open = tree.path.len() <= 1 && !tree.is_leaf();

let item = Item::InstancePath(None, InstancePath::entity_splat(tree.path.clone()));
let is_selected = ctx.selection().contains_item(&item);
let is_item_hovered =
ctx.selection_state().highlight_for_ui_element(&item) == HoverHighlight::Hovered;
let item = TimePanelItem::entity_path(tree.path.clone());
let is_selected = ctx.selection().contains_item(&item.to_item());
let is_item_hovered = ctx
.selection_state()
.highlight_for_ui_element(&item.to_item())
== HoverHighlight::Hovered;

let clip_rect_save = ui.clip_rect();
let mut clip_rect = clip_rect_save;
Expand Down Expand Up @@ -517,7 +561,7 @@ impl TimePanel {
let response = response
.on_hover_ui(|ui| re_data_ui::item_ui::entity_hover_card_ui(ui, ctx, &tree.path));

item_ui::select_hovered_on_click(ctx, &response, item.clone());
item_ui::select_hovered_on_click(ctx, &response, item.to_item());

let is_closed = body_response.is_none();
let response_rect = response.rect;
Expand All @@ -538,7 +582,7 @@ impl TimePanel {
let row_rect =
Rect::from_x_y_ranges(time_area_response.rect.x_range(), response_rect.y_range());

highlight_timeline_row(ui, ctx, time_area_painter, &item, &row_rect);
highlight_timeline_row(ui, ctx, time_area_painter, &item.to_item(), &row_rect);

// show the density graph only if that item is closed
if is_closed {
Expand Down Expand Up @@ -602,7 +646,7 @@ impl TimePanel {
ctx.component_has_data_in_current_timeline(data);
let component_path = ComponentPath::new(tree.path.clone(), *component_name);
let short_component_name = component_path.component_name.short_name();
let item = Item::ComponentPath(component_path);
let item = TimePanelItem::component_path(component_path);

let mut clip_rect = clip_rect_save;
clip_rect.max.x = tree_max_y;
Expand All @@ -611,10 +655,11 @@ impl TimePanel {
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))
.selected(ctx.selection().contains_item(&item.to_item()))
.width_allocation_mode(WidthAllocationMode::Compact)
.force_hovered(
ctx.selection_state().highlight_for_ui_element(&item)
ctx.selection_state()
.highlight_for_ui_element(&item.to_item())
== HoverHighlight::Hovered,
)
.with_icon_fn(|_, ui, rect, visual| {
Expand All @@ -626,7 +671,7 @@ impl TimePanel {

ui.set_clip_rect(clip_rect_save);

re_data_ui::item_ui::select_hovered_on_click(ctx, &response, item.clone());
re_data_ui::item_ui::select_hovered_on_click(ctx, &response, item.to_item());

let response_rect = response.rect;

Expand Down Expand Up @@ -664,7 +709,7 @@ impl TimePanel {
response_rect.y_range(),
);

highlight_timeline_row(ui, ctx, time_area_painter, &item, &row_rect);
highlight_timeline_row(ui, ctx, time_area_painter, &item.to_item(), &row_rect);

data_density_graph::data_density_graph_ui(
&mut self.data_density_graph_painter,
Expand Down
Binary file added crates/re_ui/data/icons/store.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 48f64a7

Please sign in to comment.