From d07af4d6cc1161636c3fb5ad35e8982c9113a25d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 3 Jun 2024 12:29:19 +0200 Subject: [PATCH 1/4] Update to latest egui, with support for interactive tooltips --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 14 +++++++------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19c68a4241ec..115e0a8212b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1564,7 +1564,7 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "ecolor" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "bytemuck", "serde", @@ -1573,7 +1573,7 @@ dependencies = [ [[package]] name = "eframe" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "ahash", "bytemuck", @@ -1609,7 +1609,7 @@ dependencies = [ [[package]] name = "egui" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "accesskit", "ahash", @@ -1626,7 +1626,7 @@ dependencies = [ [[package]] name = "egui-wgpu" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "ahash", "bytemuck", @@ -1645,7 +1645,7 @@ dependencies = [ [[package]] name = "egui-winit" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "accesskit_winit", "ahash", @@ -1685,7 +1685,7 @@ dependencies = [ [[package]] name = "egui_extras" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "ahash", "egui", @@ -1701,7 +1701,7 @@ dependencies = [ [[package]] name = "egui_glow" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "ahash", "bytemuck", @@ -1719,7 +1719,7 @@ dependencies = [ [[package]] name = "egui_plot" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "ahash", "egui", @@ -1762,7 +1762,7 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "emath" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "bytemuck", "serde", @@ -1863,7 +1863,7 @@ dependencies = [ [[package]] name = "epaint" version = "0.27.2" -source = "git+https://github.com/emilk/egui.git?rev=86560554bcb16e90530f58c120dc29b7a24b1486#86560554bcb16e90530f58c120dc29b7a24b1486" +source = "git+https://github.com/emilk/egui.git?rev=c0a9800d051f2d23fb63e26cbc87d35e7e17d13e#c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" dependencies = [ "ab_glyph", "ahash", diff --git a/Cargo.toml b/Cargo.toml index 2e628de1d882..6c15d63c478f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -454,13 +454,13 @@ missing_errors_doc = "allow" # As a last resport, patch with a commit to our own repository. # ALWAYS document what PR the commit hash is part of, or when it was merged into the upstream trunk. -ecolor = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 -eframe = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 -egui = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 -egui_extras = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 -egui_plot = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 -egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 -emath = { git = "https://github.com/emilk/egui.git", rev = "86560554bcb16e90530f58c120dc29b7a24b1486" } # egui master 2024-05-31 +ecolor = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 +eframe = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 +egui = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 +egui_extras = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 +egui_plot = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 +egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 +emath = { git = "https://github.com/emilk/egui.git", rev = "c0a9800d051f2d23fb63e26cbc87d35e7e17d13e" } # egui master 2024-06-03 # Useful while developing: # ecolor = { path = "../../egui/crates/ecolor" } From 271b38a8cf77e6c34d30cbf44232da9c38aca4c4 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 3 Jun 2024 12:38:29 +0200 Subject: [PATCH 2/4] Link to docs for components in their tooltips --- Cargo.lock | 1 + crates/re_data_ui/src/item_ui.rs | 15 ++++++++------- crates/re_types_core/Cargo.toml | 1 + crates/re_types_core/src/loggable.rs | 25 +++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 115e0a8212b7..249f4419d0f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5156,6 +5156,7 @@ dependencies = [ "itertools 0.13.0", "once_cell", "re_arrow2", + "re_case", "re_error", "re_string_interner", "re_tracing", diff --git a/crates/re_data_ui/src/item_ui.rs b/crates/re_data_ui/src/item_ui.rs index 82fb0d74962a..c77397c09921 100644 --- a/crates/re_data_ui/src/item_ui.rs +++ b/crates/re_data_ui/src/item_ui.rs @@ -409,9 +409,7 @@ pub fn component_path_button_to( ); let response = response.on_hover_ui(|ui| { - // TODO(egui#4471): better tooltip size management - ui.set_max_width(250.0); - ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); + ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); // Make tooltip as wide as needed // wrap lone item list_item::list_item_scope(ui, "component_path_tooltip", |ui| { @@ -429,10 +427,13 @@ pub fn component_path_button_to( ); }); - ui.label(format!( - "Full name: {}", - component_path.component_name.full_name() - )); + let component_name = component_path.component_name; + + ui.label(format!("Full name: {}", component_name.full_name())); + + if let Some(url) = component_name.doc_url() { + ui.hyperlink_to("Documentation", url); + } }); cursor_interact_with_selectable(ctx, response, item) diff --git a/crates/re_types_core/Cargo.toml b/crates/re_types_core/Cargo.toml index 0390645a315b..efd3fff3e3a3 100644 --- a/crates/re_types_core/Cargo.toml +++ b/crates/re_types_core/Cargo.toml @@ -29,6 +29,7 @@ serde = ["dep:serde", "re_string_interner/serde"] [dependencies] # Rerun +re_case.workspace = true re_error.workspace = true re_string_interner.workspace = true re_tracing.workspace = true diff --git a/crates/re_types_core/src/loggable.rs b/crates/re_types_core/src/loggable.rs index c2734fb015c3..914ecdd71cee 100644 --- a/crates/re_types_core/src/loggable.rs +++ b/crates/re_types_core/src/loggable.rs @@ -206,6 +206,31 @@ impl ComponentName { } None } + + /// Web URL to the Rerun documentation for this component. + #[inline] + pub fn doc_url(&self) -> Option { + if let Some(archetype_name_pascal_case) = self.indicator_component_archetype() { + // Link indicator components to their archetype. + // This code should be correct as long as this url passes our link checker: + // https://rerun.io/docs/reference/types/archetypes/line_strips3d + + let archetype_name_snake_case = re_case::to_snake_case(&archetype_name_pascal_case); + let base_url = "https://rerun.io/docs/reference/types/archetypes"; + Some(format!("{base_url}/{archetype_name_snake_case}")) + } else if let Some(component_name_pascal_case) = + self.full_name().strip_prefix("rerun.components.") + { + // This code should be correct as long as this url passes our link checker: + // https://rerun.io/docs/reference/types/components/half_sizes2d + + let component_name_snake_case = re_case::to_snake_case(component_name_pascal_case); + let base_url = "https://rerun.io/docs/reference/types/components"; + Some(format!("{base_url}/{component_name_snake_case}")) + } else { + None // A user component + } + } } // --- From e25c4ae2de0813d849c66ab4decadf480b00db4d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 3 Jun 2024 12:56:13 +0200 Subject: [PATCH 3/4] Use a `ListItem` for the link --- .../re_blueprint_tree/src/blueprint_tree.rs | 2 +- crates/re_data_ui/src/item_ui.rs | 45 ++++++++++--------- crates/re_ui/src/icons.rs | 5 ++- crates/re_ui/src/list_item/mod.rs | 21 +++++++++ 4 files changed, 50 insertions(+), 23 deletions(-) diff --git a/crates/re_blueprint_tree/src/blueprint_tree.rs b/crates/re_blueprint_tree/src/blueprint_tree.rs index cc07858f26ed..7758d21135fd 100644 --- a/crates/re_blueprint_tree/src/blueprint_tree.rs +++ b/crates/re_blueprint_tree/src/blueprint_tree.rs @@ -469,7 +469,7 @@ impl BlueprintTree { list_item::LabelContent::new("$origin") .subdued(true) .italics(true) - .with_icon(&re_ui::icons::LINK), + .with_icon(&re_ui::icons::INTERNAL_LINK), ) .on_hover_text( "This subtree corresponds to the Space View's origin, and is displayed above \ diff --git a/crates/re_data_ui/src/item_ui.rs b/crates/re_data_ui/src/item_ui.rs index c77397c09921..1991ff8a9c12 100644 --- a/crates/re_data_ui/src/item_ui.rs +++ b/crates/re_data_ui/src/item_ui.rs @@ -411,29 +411,32 @@ pub fn component_path_button_to( let response = response.on_hover_ui(|ui| { ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend); // Make tooltip as wide as needed - // wrap lone item + let background_x_range = (ui.max_rect() + ui.spacing().menu_margin).x_range(); + list_item::list_item_scope(ui, "component_path_tooltip", |ui| { - list_item::ListItem::new(ctx.re_ui) - .interactive(false) - .show_flat( - ui, - list_item::LabelContent::new(if is_static { - "Static component" - } else { - "Temporal component" - }) - .with_icon(icon) - .exact_width(true), - ); + re_ui::full_span::full_span_scope(ui, background_x_range, |ui| { + list_item::ListItem::new(ctx.re_ui) + .interactive(false) + .show_flat( + ui, + list_item::LabelContent::new(if is_static { + "Static component" + } else { + "Temporal component" + }) + .with_icon(icon) + .exact_width(true), + ); + + let component_name = component_path.component_name; + + ui.label(format!("Full name: {}", component_name.full_name())); + + if let Some(url) = component_name.doc_url() { + list_item::hyperlink_to_ui(ctx.re_ui, ui, "Documentation", url); + } + }); }); - - let component_name = component_path.component_name; - - ui.label(format!("Full name: {}", component_name.full_name())); - - if let Some(url) = component_name.doc_url() { - ui.hyperlink_to("Documentation", url); - } }); cursor_interact_with_selectable(ctx, response, item) diff --git a/crates/re_ui/src/icons.rs b/crates/re_ui/src/icons.rs index dca5166f58d7..29debfe2d096 100644 --- a/crates/re_ui/src/icons.rs +++ b/crates/re_ui/src/icons.rs @@ -147,7 +147,10 @@ pub const ENTITY_EMPTY: Icon = Icon::new( "entity_empty", include_bytes!("../data/icons/entity_empty.png"), ); -pub const LINK: Icon = Icon::new("link", include_bytes!("../data/icons/link.png")); + +/// Link within the viewer +pub const INTERNAL_LINK: Icon = Icon::new("link", include_bytes!("../data/icons/link.png")); + pub const COMPONENT_TEMPORAL: Icon = Icon::new("component", include_bytes!("../data/icons/component.png")); pub const COMPONENT_STATIC: Icon = Icon::new( diff --git a/crates/re_ui/src/list_item/mod.rs b/crates/re_ui/src/list_item/mod.rs index 4062308b6e3b..708ca5d993ce 100644 --- a/crates/re_ui/src/list_item/mod.rs +++ b/crates/re_ui/src/list_item/mod.rs @@ -76,3 +76,24 @@ pub trait ListItemContent { DesiredWidth::AtLeast(0.0) } } + +/// Helper for adding a list-item hyperlink. +pub fn hyperlink_to_ui( + re_ui: &crate::ReUi, + ui: &mut egui::Ui, + text: impl Into, + url: impl ToString, +) -> egui::Response { + let response = ListItem::new(re_ui) + .show_flat( + ui, + LabelContent::new(text) + .with_icon(&crate::icons::EXTERNAL_LINK) + .exact_width(true), + ) + .on_hover_cursor(egui::CursorIcon::PointingHand); + if response.clicked() { + ui.ctx().open_url(egui::OpenUrl::new_tab(url)); + } + response +} From 41d1195b6725d1086d630a426278fb910296f9f5 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Mon, 3 Jun 2024 15:11:17 +0200 Subject: [PATCH 4/4] No inlining --- crates/re_types_core/src/loggable.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/re_types_core/src/loggable.rs b/crates/re_types_core/src/loggable.rs index 914ecdd71cee..cb259847480d 100644 --- a/crates/re_types_core/src/loggable.rs +++ b/crates/re_types_core/src/loggable.rs @@ -208,7 +208,6 @@ impl ComponentName { } /// Web URL to the Rerun documentation for this component. - #[inline] pub fn doc_url(&self) -> Option { if let Some(archetype_name_pascal_case) = self.indicator_component_archetype() { // Link indicator components to their archetype.