Skip to content

Commit 72ac4cb

Browse files
authored
Add copy button to the recording link table item (#11242)
### Related Part of #10815 ### What Adds a copy button that's shown on hover in table url entries <img width="322" height="394" alt="image" src="https://github.com/user-attachments/assets/63e0ce09-01ec-419b-b3e1-b4cfe3bf2fd6" /> - [x] look into if it's possible to not have to define the copy button rect
1 parent eef2224 commit 72ac4cb

File tree

4 files changed

+58
-15
lines changed

4 files changed

+58
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7530,6 +7530,7 @@ dependencies = [
75307530
"re_arrow_util",
75317531
"re_data_ui",
75327532
"re_format",
7533+
"re_log",
75337534
"re_log_types",
75347535
"re_protos",
75357536
"re_test_context",

crates/viewer/re_component_ui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ all-features = true
2222
re_arrow_util.workspace = true
2323
re_data_ui.workspace = true # Needed for `item_ui`.
2424
re_format.workspace = true
25+
re_log.workspace = true
2526
re_log_types.workspace = true
2627
re_protos.workspace = true
2728
re_tracing.workspace = true

crates/viewer/re_component_ui/src/variant_uis/redap_uri_button.rs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use egui::{Align, Layout, Link, Ui, UiBuilder};
55
use re_types_core::{ComponentDescriptor, RowId};
66
use re_ui::UiExt as _;
77
use re_uri::RedapUri;
8-
use re_viewer_context::{SystemCommand, SystemCommandSender as _, ViewerContext};
8+
use re_viewer_context::{
9+
SystemCommand, SystemCommandSender as _, ViewerContext, open_url::ViewerOpenUrl,
10+
};
911

1012
/// Display an URL as an `Open` button (instead of spelling the full URL).
1113
///
@@ -52,22 +54,50 @@ pub fn redap_uri_button(
5254
.iter()
5355
.any(|source| source.stripped_redap_uri().as_ref() == Some(&uri));
5456

55-
// Show the link left aligned and justified, so the whole cell is clickable.
56-
let put_justified_left_aligned = |ui: &mut Ui, link| {
57-
ui.scope_builder(
58-
UiBuilder::new().max_rect(ui.max_rect()).layout(
59-
Layout::left_to_right(Align::Center)
60-
.with_main_justify(true)
61-
.with_cross_justify(true)
62-
.with_main_align(Align::Min),
63-
),
64-
|ui| ui.add(link),
65-
)
66-
.inner
57+
let uri_clone = uri.clone();
58+
// Show the link left aligned and justified so the whole cell is clickable.
59+
//
60+
// And add a button to copy the link.
61+
let link_with_copy = |ui: &mut Ui, link| {
62+
let rect = ui.max_rect();
63+
let contains_pointer = ui.rect_contains_pointer(rect);
64+
egui::Sides::new()
65+
.shrink_left()
66+
.height(ui.max_rect().height())
67+
.show(
68+
ui,
69+
|ui| {
70+
ui.scope_builder(
71+
UiBuilder::new().max_rect(ui.max_rect()).layout(
72+
Layout::left_to_right(Align::Center)
73+
.with_main_justify(true)
74+
.with_cross_justify(true)
75+
.with_main_align(Align::Min),
76+
),
77+
|ui| ui.add(link),
78+
)
79+
.inner
80+
},
81+
|ui| {
82+
if contains_pointer
83+
&& ui
84+
.small_icon_button(&re_ui::icons::COPY, "Copy link")
85+
.clicked()
86+
{
87+
if let Ok(url) = ViewerOpenUrl::from(uri_clone).sharable_url(None) {
88+
ctx.command_sender()
89+
.send_system(SystemCommand::CopyViewerUrl(url));
90+
} else {
91+
re_log::error!("Failed to create a sharable url for recording");
92+
}
93+
}
94+
},
95+
)
96+
.0
6797
};
6898

6999
if let Some(loaded_recording_id) = loaded_recording_id {
70-
let response = put_justified_left_aligned(ui, Link::new("Switch to")).on_hover_ui(|ui| {
100+
let response = link_with_copy(ui, Link::new("Switch to")).on_hover_ui(|ui| {
71101
ui.label("This recording is already loaded. Click to switch to it.");
72102
});
73103

@@ -91,7 +121,7 @@ pub fn redap_uri_button(
91121
}
92122
});
93123
} else {
94-
let response = put_justified_left_aligned(ui, Link::new("Open")).on_hover_ui(|ui| {
124+
let response = link_with_copy(ui, Link::new("Open")).on_hover_ui(|ui| {
95125
ui.label(uri.to_string());
96126
});
97127

crates/viewer/re_viewer_context/src/open_url.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,17 @@ pub enum ViewerOpenUrl {
8686
},
8787
}
8888

89+
impl From<re_uri::RedapUri> for ViewerOpenUrl {
90+
fn from(value: re_uri::RedapUri) -> Self {
91+
match value {
92+
re_uri::RedapUri::Catalog(uri) => Self::RedapCatalog(uri),
93+
re_uri::RedapUri::Entry(uri) => Self::RedapEntry(uri),
94+
re_uri::RedapUri::DatasetData(uri) => Self::RedapDatasetPartition(uri),
95+
re_uri::RedapUri::Proxy(uri) => Self::RedapProxy(uri),
96+
}
97+
}
98+
}
99+
89100
impl std::str::FromStr for ViewerOpenUrl {
90101
type Err = anyhow::Error;
91102

0 commit comments

Comments
 (0)