From ffcce305d3452eba5999a8cb76307854fdf54d31 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 10 Dec 2024 14:58:42 +0100 Subject: [PATCH 1/3] Simplify zoom-and-pan area --- crates/viewer/re_ui/src/zoom_pan_area.rs | 67 +++++++++++------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/crates/viewer/re_ui/src/zoom_pan_area.rs b/crates/viewer/re_ui/src/zoom_pan_area.rs index e3c6114e99d2..9dac80ce4130 100644 --- a/crates/viewer/re_ui/src/zoom_pan_area.rs +++ b/crates/viewer/re_ui/src/zoom_pan_area.rs @@ -5,7 +5,7 @@ //! * `view`-space: The space where the pan-and-zoom area is drawn. //! * `scene`-space: The space where the actual content is drawn. -use egui::{emath::TSTransform, Area, Order, Rect, Response, Ui, UiKind}; +use egui::{emath::TSTransform, Rect, Response, Ui, UiBuilder}; /// Helper function to handle pan and zoom interactions on a response. fn register_pan_and_zoom(ui: &Ui, resp: &Response, ui_from_scene: &mut TSTransform) { @@ -58,45 +58,42 @@ pub fn fit_to_rect_in_scene(rect_in_ui: Rect, rect_in_scene: Rect) -> TSTransfor /// Provides a zoom-pan area for a given view. pub fn zoom_pan_area( - ui: &Ui, + ui: &mut Ui, view_bounds_in_ui: Rect, ui_from_scene: &mut TSTransform, draw_contents: impl FnOnce(&mut Ui), ) -> Response { - let area_resp = Area::new(ui.id().with("zoom_pan_area")) - .constrain_to(view_bounds_in_ui) - .order(Order::Middle) - .kind(UiKind::GenericArea) - .show(ui.ctx(), |ui| { - // Transform to the scene space: - let visible_rect_in_scene = ui_from_scene.inverse() * view_bounds_in_ui; - - // set proper clip-rect so we can interact with the background. - ui.set_clip_rect(visible_rect_in_scene); - - // A Ui for sensing drag-to-pan, scroll-to-zoom, etc - let mut drag_sense_ui = ui.new_child( - egui::UiBuilder::new() - .sense(egui::Sense::click_and_drag()) - .max_rect(visible_rect_in_scene), - ); - drag_sense_ui.set_min_size(visible_rect_in_scene.size()); - let pan_response = drag_sense_ui.response(); - - // Update the transform based on the interactions: - register_pan_and_zoom(ui, &pan_response, ui_from_scene); - - // Update the clip-rect with the new transform, to avoid frame-delays - ui.set_clip_rect(ui_from_scene.inverse() * view_bounds_in_ui); - - // Add the actual contents to the area: - draw_contents(ui); - - pan_response - }); + let zoom_pan_layer_id = egui::LayerId::new(ui.layer_id().order, ui.id().with("zoom_pan_area")); + + // Put the layer directly on-top of the main layer of the ui: + ui.ctx().set_sublayer(ui.layer_id(), zoom_pan_layer_id); + + let mut ui = ui.new_child( + UiBuilder::new() + .layer_id(zoom_pan_layer_id) + .max_rect(view_bounds_in_ui) + .sense(egui::Sense::click_and_drag()), + ); + + // Transform to the scene space: + let visible_rect_in_scene = ui_from_scene.inverse() * view_bounds_in_ui; + + // set proper clip-rect so we can interact with the background: + ui.set_clip_rect(visible_rect_in_scene); + + let pan_response = ui.response(); + + // Update the transform based on the interactions: + register_pan_and_zoom(&ui, &pan_response, ui_from_scene); + + // Update the clip-rect with the new transform, to avoid frame-delays + ui.set_clip_rect(ui_from_scene.inverse() * view_bounds_in_ui); + + // Add the actual contents to the area: + draw_contents(&mut ui); ui.ctx() - .set_transform_layer(area_resp.response.layer_id, *ui_from_scene); + .set_transform_layer(zoom_pan_layer_id, *ui_from_scene); - area_resp.inner + pan_response } From 9ce494828ebeceb966824fe5a931d75342e0eccb Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 10 Dec 2024 14:59:30 +0100 Subject: [PATCH 2/3] Make sure the spaceview highlight rectangle covers the content --- crates/viewer/re_viewport/src/viewport_ui.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/viewer/re_viewport/src/viewport_ui.rs b/crates/viewer/re_viewport/src/viewport_ui.rs index ff03ad6cc05a..9221fe3df20d 100644 --- a/crates/viewer/re_viewport/src/viewport_ui.rs +++ b/crates/viewer/re_viewport/src/viewport_ui.rs @@ -126,8 +126,15 @@ impl ViewportUi { continue; }; - ui.painter() - .rect_stroke(rect.shrink(stroke.width / 2.0), 0.0, stroke); + // We want the rectangle to be on top of everything in the viewport, + // including stuff in "zoom-pan areas", like we use in the graph view. + let top_layer_id = egui::LayerId::new(ui.layer_id().order, ui.id().with("child_id")); + ui.ctx().set_sublayer(ui.layer_id(), top_layer_id); // Make sure it is directly on top of the ui layer + + // We need to shrink a bit so the panel-resize lines don't cover the highlight rectangle. + // This is hacky. + ui.painter().clone().with_layer_id(top_layer_id) + .rect_stroke(rect.shrink(stroke.width), 0.0, stroke); } } From 394055420deaf0a5634ffb8451c7f0a3737e285e Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 10 Dec 2024 14:59:50 +0100 Subject: [PATCH 3/3] Clarify that an assert is only in debug builds --- crates/store/re_chunk_store/src/writes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/store/re_chunk_store/src/writes.rs b/crates/store/re_chunk_store/src/writes.rs index d3dd66f47776..5b9bb545cfa7 100644 --- a/crates/store/re_chunk_store/src/writes.rs +++ b/crates/store/re_chunk_store/src/writes.rs @@ -41,7 +41,7 @@ impl ChunkStore { for (component_name, per_desc) in chunk.components().iter() { assert!( per_desc.len() <= 1, - "Insert Chunk with multiple values for component named `{component_name}`: this is currently UB", + "[DEBUG ONLY] Insert Chunk with multiple values for component named `{component_name}`: this is currently UB", ); }