Skip to content

Commit 11c06b1

Browse files
authored
Implement save-view-as-screenshot on web (#8472)
### Related * Part of #8264 * Using emilk/egui#5438 Still missing: copy screenshot to clipboard Also fixes a crash when screenshotting graph views. ### Usage ![image](https://github.com/user-attachments/assets/88948342-8279-4bf6-9bc6-13722229dc44) ### Result ![Node-link diagram](https://github.com/user-attachments/assets/b2ff8dd5-ae55-436a-9cd2-263eeb72a0df)
1 parent a7acf15 commit 11c06b1

File tree

8 files changed

+33
-27
lines changed

8 files changed

+33
-27
lines changed

Cargo.lock

+11-11
Original file line numberDiff line numberDiff line change
@@ -1934,7 +1934,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
19341934
[[package]]
19351935
name = "ecolor"
19361936
version = "0.29.1"
1937-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
1937+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
19381938
dependencies = [
19391939
"bytemuck",
19401940
"color-hex",
@@ -1951,7 +1951,7 @@ checksum = "18aade80d5e09429040243ce1143ddc08a92d7a22820ac512610410a4dd5214f"
19511951
[[package]]
19521952
name = "eframe"
19531953
version = "0.29.1"
1954-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
1954+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
19551955
dependencies = [
19561956
"ahash",
19571957
"bytemuck",
@@ -1990,7 +1990,7 @@ dependencies = [
19901990
[[package]]
19911991
name = "egui"
19921992
version = "0.29.1"
1993-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
1993+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
19941994
dependencies = [
19951995
"accesskit",
19961996
"ahash",
@@ -2007,7 +2007,7 @@ dependencies = [
20072007
[[package]]
20082008
name = "egui-wgpu"
20092009
version = "0.29.1"
2010-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2010+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
20112011
dependencies = [
20122012
"ahash",
20132013
"bytemuck",
@@ -2026,7 +2026,7 @@ dependencies = [
20262026
[[package]]
20272027
name = "egui-winit"
20282028
version = "0.29.1"
2029-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2029+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
20302030
dependencies = [
20312031
"accesskit_winit",
20322032
"ahash",
@@ -2068,7 +2068,7 @@ dependencies = [
20682068
[[package]]
20692069
name = "egui_extras"
20702070
version = "0.29.1"
2071-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2071+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
20722072
dependencies = [
20732073
"ahash",
20742074
"egui",
@@ -2085,7 +2085,7 @@ dependencies = [
20852085
[[package]]
20862086
name = "egui_glow"
20872087
version = "0.29.1"
2088-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2088+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
20892089
dependencies = [
20902090
"ahash",
20912091
"bytemuck",
@@ -2102,7 +2102,7 @@ dependencies = [
21022102
[[package]]
21032103
name = "egui_kittest"
21042104
version = "0.29.1"
2105-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2105+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
21062106
dependencies = [
21072107
"dify",
21082108
"egui",
@@ -2171,7 +2171,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
21712171
[[package]]
21722172
name = "emath"
21732173
version = "0.29.1"
2174-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2174+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
21752175
dependencies = [
21762176
"bytemuck",
21772177
"serde",
@@ -2287,7 +2287,7 @@ dependencies = [
22872287
[[package]]
22882288
name = "epaint"
22892289
version = "0.29.1"
2290-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2290+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
22912291
dependencies = [
22922292
"ab_glyph",
22932293
"ahash",
@@ -2306,7 +2306,7 @@ dependencies = [
23062306
[[package]]
23072307
name = "epaint_default_fonts"
23082308
version = "0.29.1"
2309-
source = "git+https://github.com/emilk/egui.git?rev=f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b#f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b"
2309+
source = "git+https://github.com/emilk/egui.git?rev=0823a36952a6791a0e28e6e8eac4f35639ab3091#0823a36952a6791a0e28e6e8eac4f35639ab3091"
23102310

23112311
[[package]]
23122312
name = "equivalent"

Cargo.toml

+7-7
Original file line numberDiff line numberDiff line change
@@ -553,13 +553,13 @@ significant_drop_tightening = "allow" # An update of parking_lot made this trigg
553553
# As a last resport, patch with a commit to our own repository.
554554
# ALWAYS document what PR the commit hash is part of, or when it was merged into the upstream trunk.
555555

556-
ecolor = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
557-
eframe = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
558-
egui = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
559-
egui_extras = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
560-
egui_kittest = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
561-
egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
562-
emath = { git = "https://github.com/emilk/egui.git", rev = "f7efb2186d529ddc9e69f7173c6ae3ae5f403d0b" } # egui master 2024-12-16
556+
ecolor = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
557+
eframe = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
558+
egui = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
559+
egui_extras = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
560+
egui_kittest = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
561+
egui-wgpu = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
562+
emath = { git = "https://github.com/emilk/egui.git", rev = "0823a36952a6791a0e28e6e8eac4f35639ab3091" } # egui master 2024-12-16 15:08
563563

564564
# Useful while developing:
565565
# ecolor = { path = "../../egui/crates/ecolor" }

crates/viewer/re_context_menu/src/actions/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ pub(super) mod move_contents_to_new_container;
77
pub(super) mod remove;
88
pub(super) mod show_hide;
99

10-
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): screenshotting on web
1110
mod screenshot_action;
1211

13-
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): screenshotting on web
1412
pub use screenshot_action::ScreenshotAction;

crates/viewer/re_context_menu/src/actions/screenshot_action.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use re_viewer_context::{Item, PublishedViewInfo, ScreenshotTarget, ViewId, ViewR
33
use crate::{ContextMenuAction, ContextMenuContext};
44

55
/// View screenshot action.
6-
#[cfg(not(target_arch = "wasm32"))]
76
pub enum ScreenshotAction {
87
/// Screenshot the view, and copy the results to clipboard.
8+
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): copy-to-screenshot on web
99
CopyScreenshot,
1010

1111
/// Screenshot the view, and save the results to disk.
@@ -39,6 +39,7 @@ impl ContextMenuAction for ScreenshotAction {
3939

4040
fn label(&self, _ctx: &ContextMenuContext<'_>) -> String {
4141
match self {
42+
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): copy-to-screenshot on web
4243
Self::CopyScreenshot => "Copy screenshot".to_owned(),
4344
Self::SaveScreenshot => "Save screenshot…".to_owned(),
4445
}
@@ -56,9 +57,15 @@ impl ContextMenuAction for ScreenshotAction {
5657

5758
let PublishedViewInfo { name, rect } = view_info;
5859

59-
let rect = rect.shrink(1.75); // Hacky: Shrink so we don't accidentally include the border of the view.
60+
let rect = rect.shrink(2.5); // Hacky: Shrink so we don't accidentally include the border of the view.
61+
62+
if !rect.is_positive() {
63+
re_log::info!("View too small for a screenshot");
64+
return;
65+
}
6066

6167
let target = match self {
68+
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): copy-to-screenshot on web
6269
Self::CopyScreenshot => ScreenshotTarget::CopyToClipboard,
6370
Self::SaveScreenshot => ScreenshotTarget::SaveToDisk,
6471
};

crates/viewer/re_context_menu/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ fn action_list(
113113
Box::new(HideAction),
114114
Box::new(RemoveAction),
115115
],
116-
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): screenshotting on web
117116
vec![
117+
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): copy-to-screenshot on web
118118
Box::new(actions::ScreenshotAction::CopyScreenshot),
119119
Box::new(actions::ScreenshotAction::SaveScreenshot),
120120
],

crates/viewer/re_viewer/src/app.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,7 @@ impl App {
15961596
false
15971597
}
15981598

1599-
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): screenshotting on web
1599+
#[allow(clippy::needless_pass_by_ref_mut)] // False positive on wasm
16001600
fn process_screenshot_result(
16011601
&mut self,
16021602
image: &Arc<egui::ColorImage>,
@@ -1623,8 +1623,8 @@ impl App {
16231623
};
16241624

16251625
match target {
1626+
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): copy-to-screenshot on web
16261627
re_viewer_context::ScreenshotTarget::CopyToClipboard => {
1627-
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): screenshotting on web
16281628
re_viewer_context::Clipboard::with(|clipboard| {
16291629
clipboard.set_image(
16301630
[rgba.width(), rgba.height()],
@@ -1656,6 +1656,7 @@ impl App {
16561656
}
16571657
}
16581658
} else {
1659+
#[cfg(not(target_arch = "wasm32"))] // no full-app screenshotting on web
16591660
self.screenshotter.save(image);
16601661
}
16611662
}
@@ -1951,7 +1952,6 @@ impl eframe::App for App {
19511952
self.store_hub = Some(store_hub);
19521953

19531954
// Check for returned screenshot:
1954-
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): screenshotting on web
19551955
egui_ctx.input(|i| {
19561956
for event in &i.raw.events {
19571957
if let egui::Event::Screenshot {

crates/viewer/re_viewer_context/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ pub struct ScreenshotInfo {
150150
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
151151
pub enum ScreenshotTarget {
152152
/// The screenshot will be copied to the clipboard.
153+
#[cfg(not(target_arch = "wasm32"))] // TODO(#8264): copy-to-screenshot on web
153154
CopyToClipboard,
154155

155156
/// The screenshot will be saved to disk.

crates/viewer/re_viewport/src/viewport_ui.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ impl<'a> egui_tiles::Behavior<ViewId> for TilesDelegate<'a, '_> {
544544
*view_id,
545545
PublishedViewInfo {
546546
name: view_blueprint.display_name_or_default().as_ref().to_owned(),
547-
rect: ui.min_rect(),
547+
rect: ui.max_rect(),
548548
},
549549
);
550550
});

0 commit comments

Comments
 (0)