Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a side_panel example for 2D #253

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

weberja
Copy link

@weberja weberja commented Jan 28, 2024

This PR creates an example for the use of the bevy camera in the centre of resizeable side panels. As this was round about 4 hours of research, I want to save people time with this example.

The centre of the camera stays the same, while resizing the panels

@vladbat00
Copy link
Owner

I apologise for neglecting this PR for so long. If you can update it to the latest bevy_egui version, I'll happily merge it.

@RJ
Copy link

RJ commented Jan 4, 2025

I used this example to get myself a simple sidebar with a 2d camera working, with one change - you need to multiply the reported egui sizes by the window scale factor, since the reported width of an egui sidebar is presumably in logical not physical units.

pub struct UiPlugin;

impl Plugin for UiPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Update, ui_system);
    }
}

fn ui_system(
    mut is_last_selected: Local<bool>,
    mut contexts: EguiContexts,
    mut cameras: Query<&mut Camera>,
    q_window: Query<&mut Window, With<PrimaryWindow>>,
) {
    let ctx = contexts.ctx_mut();
    let mut camera = cameras.get_single_mut().expect("No camera found");
    let window = q_window.get_single().expect("No primary window found");

    let right = egui::SidePanel::right("right_panel")
        .resizable(true)
        .default_width(200.0)
        .show(ctx, |ui| {
            ui.label("Rightresizeable panel");
            if ui
                .add(egui::widgets::Button::new("A button").selected(!*is_last_selected))
                .clicked()
            {
                *is_last_selected = false;
            }
            if ui
                .add(egui::widgets::Button::new("Another button").selected(*is_last_selected))
                .clicked()
            {
                *is_last_selected = true;
            }
            ui.allocate_rect(ui.available_rect_before_wrap(), egui::Sense::hover());
        })
        .response
        .rect
        .width();

    let top = 0.0;
    let left = 0.0;
    let bottom = 0.0;

    let right = right * window.scale_factor();

    let pos = UVec2::new(left as u32, top as u32);
    let size = UVec2::new(window.physical_width(), window.physical_height())
        - pos
        - UVec2::new(right as u32, bottom as u32);

    camera.viewport = Some(Viewport {
        physical_position: pos,
        physical_size: size,
        ..default()
    });
}

EDIT: For a slightly bigger example, and how to compensate for a moved viewport when detecting click positions, see my comment here: johanhelsing/bevy_pancam#70

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants