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

Click a recording to select it #4761

Merged
merged 8 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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