|
| 1 | +//! This test logs a few boxes and performs the following focus checks: |
| 2 | +//! |
| 3 | +//! - Double-click on a box in the first view |
| 4 | +//! - check ONLY the corresponding view expands and scrolls |
| 5 | +//! - check the streams view expands and scrolls |
| 6 | +//! - Double-click on the leaf "boxes3d" entity in the streams view, check both views expand (manual scrolling might be needed). |
| 7 | +
|
| 8 | +use re_integration_test::HarnessExt as _; |
| 9 | +use re_sdk::TimePoint; |
| 10 | +use re_sdk::log::RowId; |
| 11 | +use re_viewer::external::re_viewer_context::ViewClass as _; |
| 12 | +use re_viewer::external::{re_types, re_view_spatial}; |
| 13 | +use re_viewer::viewer_test_utils::{self, HarnessOptions}; |
| 14 | +use re_viewport_blueprint::ViewBlueprint; |
| 15 | + |
| 16 | +fn make_test_harness<'a>() -> egui_kittest::Harness<'a, re_viewer::App> { |
| 17 | + let mut harness = viewer_test_utils::viewer_harness(&HarnessOptions { |
| 18 | + window_size: Some(egui::vec2(1024.0, 768.0)), |
| 19 | + max_steps: Some(200), // Allow animations to finish. |
| 20 | + step_dt: Some(1.0 / 60.0), // Allow double clicks to go through. |
| 21 | + }); |
| 22 | + harness.init_recording(); |
| 23 | + harness.set_selection_panel_opened(false); |
| 24 | + |
| 25 | + // Log some data. |
| 26 | + harness.log_entity("group/boxes3d", |builder| { |
| 27 | + builder.with_archetype( |
| 28 | + RowId::new(), |
| 29 | + TimePoint::default(), |
| 30 | + &re_types::archetypes::Boxes3D::from_centers_and_half_sizes( |
| 31 | + [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 1.0, 0.0)], |
| 32 | + [(0.2, 0.4, 0.2), (0.2, 0.2, 0.4), (0.4, 0.2, 0.2)], |
| 33 | + ) |
| 34 | + .with_colors([0xFF0000FF, 0x00FF00FF, 0x0000FFFF]) |
| 35 | + .with_fill_mode(re_types::components::FillMode::Solid), |
| 36 | + ) |
| 37 | + }); |
| 38 | + harness.log_entity("txt/hello", |builder| { |
| 39 | + builder.with_archetype( |
| 40 | + RowId::new(), |
| 41 | + TimePoint::STATIC, |
| 42 | + &re_types::archetypes::TextDocument::new("Hello World!"), |
| 43 | + ) |
| 44 | + }); |
| 45 | + |
| 46 | + harness |
| 47 | +} |
| 48 | + |
| 49 | +fn setup_single_view_blueprint(harness: &mut egui_kittest::Harness<'_, re_viewer::App>) { |
| 50 | + harness.clear_current_blueprint(); |
| 51 | + |
| 52 | + let root_cid = harness.add_blueprint_container(egui_tiles::ContainerKind::Horizontal, None); |
| 53 | + let tab_cid = harness.add_blueprint_container(egui_tiles::ContainerKind::Tabs, Some(root_cid)); |
| 54 | + let vertical_cid = |
| 55 | + harness.add_blueprint_container(egui_tiles::ContainerKind::Vertical, Some(root_cid)); |
| 56 | + |
| 57 | + let mut view_1 = |
| 58 | + ViewBlueprint::new_with_root_wildcard(re_view_spatial::SpatialView3D::identifier()); |
| 59 | + view_1.display_name = Some("3D view 1".into()); |
| 60 | + let mut view_2 = |
| 61 | + ViewBlueprint::new_with_root_wildcard(re_view_spatial::SpatialView3D::identifier()); |
| 62 | + view_2.display_name = Some("3D view 2".into()); |
| 63 | + |
| 64 | + harness.setup_viewport_blueprint(move |_viewer_context, blueprint| { |
| 65 | + let text_views = (0..20).map(|i| { |
| 66 | + let mut view = ViewBlueprint::new_with_root_wildcard( |
| 67 | + re_view_text_document::TextDocumentView::identifier(), |
| 68 | + ); |
| 69 | + view.display_name = Some(format!("Text view {i}")); |
| 70 | + view |
| 71 | + }); |
| 72 | + blueprint.add_views(text_views, Some(tab_cid), None); |
| 73 | + blueprint.add_views([view_1, view_2].into_iter(), Some(vertical_cid), None); |
| 74 | + }); |
| 75 | +} |
| 76 | + |
| 77 | +#[tokio::test(flavor = "multi_thread")] |
| 78 | +pub async fn test_check_focus() { |
| 79 | + let mut harness = make_test_harness(); |
| 80 | + setup_single_view_blueprint(&mut harness); |
| 81 | + |
| 82 | + // Make the left panel wider. |
| 83 | + let centerline = harness.get_panel_position("Text view 0").left_center(); |
| 84 | + let target_pos = centerline + egui::vec2(100.0, 0.0); |
| 85 | + harness.drag_at(centerline); |
| 86 | + harness.snapshot_app("check_focus_1"); |
| 87 | + harness.hover_at(target_pos); |
| 88 | + harness.snapshot_app("check_focus_2"); |
| 89 | + harness.drop_at(target_pos); |
| 90 | + harness.snapshot_app("check_focus_3"); |
| 91 | + |
| 92 | + // One of the boxes is at the center of the view. |
| 93 | + let pixel_of_a_box = harness.get_panel_position("3D view 1").center(); |
| 94 | + |
| 95 | + // Hover over the box. |
| 96 | + harness.hover_at(pixel_of_a_box); |
| 97 | + |
| 98 | + // Let the app render. This will run the picking logic which needs the GPU |
| 99 | + // and lets the app find the hovered box. |
| 100 | + harness.render().expect("Cannot render app"); |
| 101 | + harness.run(); |
| 102 | + harness.snapshot_app("check_focus_4"); |
| 103 | + |
| 104 | + // Double click on the box, see how it expands the view. |
| 105 | + harness.click_at(pixel_of_a_box); |
| 106 | + harness.click_at(pixel_of_a_box); |
| 107 | + harness.snapshot_app("check_focus_5"); |
| 108 | + |
| 109 | + // Scroll down to see the second view stays collapsed. |
| 110 | + harness.blueprint_tree().hover_label("3D view 1"); |
| 111 | + harness.event(egui::Event::MouseWheel { |
| 112 | + unit: egui::MouseWheelUnit::Page, |
| 113 | + delta: egui::vec2(0.0, -1.0), |
| 114 | + modifiers: egui::Modifiers::NONE, |
| 115 | + }); |
| 116 | + harness.snapshot_app("check_focus_6"); |
| 117 | + |
| 118 | + // Double click the entity on the streams tree and see all views expand. |
| 119 | + harness.streams_tree().hover_label("boxes3d"); |
| 120 | + harness.streams_tree().click_label("boxes3d"); |
| 121 | + harness.streams_tree().click_label("boxes3d"); |
| 122 | + harness.snapshot_app("check_focus_7"); |
| 123 | + |
| 124 | + // Scroll down to see the second view is entirely expanded. |
| 125 | + harness.blueprint_tree().hover_label("3D view 1"); |
| 126 | + harness.event(egui::Event::MouseWheel { |
| 127 | + unit: egui::MouseWheelUnit::Page, |
| 128 | + delta: egui::vec2(0.0, -1.0), |
| 129 | + modifiers: egui::Modifiers::NONE, |
| 130 | + }); |
| 131 | + harness.snapshot_app("check_focus_8"); |
| 132 | +} |
0 commit comments