From 4993f8915382ae3e9584522f864ac04280622d2f Mon Sep 17 00:00:00 2001 From: mvlabat Date: Mon, 21 Feb 2022 01:48:43 +0200 Subject: [PATCH] Add side panel example --- .github/workflows/check.yml | 15 ++--- Cargo.toml | 7 +- examples/side_panel.rs | 126 ++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 15 deletions(-) create mode 100644 examples/side_panel.rs diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index a33c84376..76a105423 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -54,16 +54,13 @@ jobs: restore-keys: | cache-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }} cache-${{ runner.os }}-cargo - - name: Simple example - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --example simple --no-default-features --features=${{ matrix.features }} -- -D warnings - - name: UI example - uses: actions-rs/cargo@v1 + - name: Install dependencies + if: runner.os == 'Linux' + run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev + - uses: actions-rs/cargo@v1 with: command: clippy - args: --example ui --no-default-features --features=${{ matrix.features }} -- -D warnings + args: --no-default-features --all-targets --features=${{ matrix.features }} -- -D warnings clippy_wasm32: name: Clippy check (wasm32) @@ -99,7 +96,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: clippy - args: --no-default-features --target=wasm32-unknown-unknown --features=${{ matrix.features }} -- -D warnings + args: --no-default-features --target=wasm32-unknown-unknown --all-targets --features=${{ matrix.features }} -- -D warnings doc: name: Check documentation diff --git a/Cargo.toml b/Cargo.toml index b0898fa57..ef7e4b04f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,11 +35,6 @@ arboard = { version = "2.0.1", optional = true } thread_local = { version = "1.1.0", optional = true } [dev-dependencies] +bevy = "0.6" once_cell = "1.9.0" version-sync = "0.9.2" - -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -bevy = { version = "0.6", default-features = false, features = [ - "x11", - "png" -] } diff --git a/examples/side_panel.rs b/examples/side_panel.rs new file mode 100644 index 000000000..b3f0da46d --- /dev/null +++ b/examples/side_panel.rs @@ -0,0 +1,126 @@ +use bevy::prelude::*; +use bevy_egui::{egui, EguiContext, EguiPlugin}; + +#[derive(Default)] +struct OccupiedScreenSpace { + left: f32, + top: f32, + right: f32, + bottom: f32, +} + +const CAMERA_TARGET: Vec3 = Vec3::ZERO; + +struct OriginalCameraTransform(Transform); + +fn main() { + App::new() + .add_plugins(DefaultPlugins) + .add_plugin(EguiPlugin) + .init_resource::() + .add_startup_system(setup_system) + .add_system(ui_example_system) + .add_system(update_camera_transform_system) + .run(); +} + +fn ui_example_system( + mut egui_context: ResMut, + mut occupied_screen_space: ResMut, +) { + occupied_screen_space.left = egui::SidePanel::left("left_panel") + .resizable(true) + .show(egui_context.ctx_mut(), |ui| { + ui.allocate_rect(ui.available_rect_before_wrap(), egui::Sense::hover()); + }) + .response + .rect + .width(); + occupied_screen_space.right = egui::SidePanel::right("right_panel") + .resizable(true) + .show(egui_context.ctx_mut(), |ui| { + ui.allocate_rect(ui.available_rect_before_wrap(), egui::Sense::hover()); + }) + .response + .rect + .width(); + occupied_screen_space.top = egui::TopBottomPanel::top("top_panel") + .resizable(true) + .show(egui_context.ctx_mut(), |ui| { + ui.allocate_rect(ui.available_rect_before_wrap(), egui::Sense::hover()); + }) + .response + .rect + .height(); + occupied_screen_space.bottom = egui::TopBottomPanel::bottom("bottom_panel") + .resizable(true) + .show(egui_context.ctx_mut(), |ui| { + ui.allocate_rect(ui.available_rect_before_wrap(), egui::Sense::hover()); + }) + .response + .rect + .height(); +} + +fn setup_system( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + commands.spawn_bundle(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })), + material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), + ..Default::default() + }); + commands.spawn_bundle(PbrBundle { + mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), + material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), + transform: Transform::from_xyz(0.0, 0.5, 0.0), + ..Default::default() + }); + commands.spawn_bundle(PointLightBundle { + point_light: PointLight { + intensity: 1500.0, + shadows_enabled: true, + ..Default::default() + }, + transform: Transform::from_xyz(4.0, 8.0, 4.0), + ..Default::default() + }); + + let camera_pos = Vec3::new(-2.0, 2.5, 5.0); + let camera_transform = + Transform::from_translation(camera_pos).looking_at(CAMERA_TARGET, Vec3::Y); + commands.insert_resource(OriginalCameraTransform(camera_transform)); + + commands.spawn_bundle(PerspectiveCameraBundle { + transform: camera_transform, + ..Default::default() + }); +} + +fn update_camera_transform_system( + occupied_screen_space: Res, + original_camera_transform: Res, + windows: Res, + mut camera_query: Query<(&PerspectiveProjection, &mut Transform)>, +) { + let (camera_projection, mut transform) = camera_query.get_single_mut().unwrap(); + + let distance_to_target = (CAMERA_TARGET - original_camera_transform.0.translation).length(); + let frustum_height = 2.0 * distance_to_target * (camera_projection.fov * 0.5).tan(); + let frustum_width = frustum_height * camera_projection.aspect_ratio; + + let window = windows.get_primary().unwrap(); + + let left_taken = occupied_screen_space.left / window.width(); + let right_taken = occupied_screen_space.right / window.width(); + let top_taken = occupied_screen_space.top / window.height(); + let bottom_taken = occupied_screen_space.bottom / window.height(); + transform.translation = original_camera_transform.0.translation + + transform.rotation.mul_vec3(Vec3::new( + (right_taken - left_taken) * frustum_width * 0.5, + (top_taken - bottom_taken) * frustum_height * 0.5, + 0.0, + )); +}