Skip to content

egui_dnd The dragged item in a Scene can have incorrect positioning #61

Open
@Si1veR123

Description

@Si1veR123

When using egui_dnd in a egui::Scene, the positioning of the dragged item can be off. This seems to be because the dnd uses the local coordinates of the scene, and then draws the dragged item in screen space coordinates.

In my current project, when dragging an item from the top left of the Scene, it teleports to the top left of the screen.

I can't reproduce the issue completely in a simple app, but it can be seen in this simple app that after releasing drag, the item returns to the incorrect location.

use eframe::egui;

fn main() {
    let mut native_options = eframe::NativeOptions::default();
    native_options.viewport = native_options.viewport.with_inner_size((600.0, 400.0));
    eframe::run_native("Scene DND test", native_options, Box::new(
        |cc| {
            Ok(Box::new(DndTest::new()))
        }
    )).expect("Failed to run app");
}

pub struct DndTest {
    scene_rect: egui::Rect,
    items: Vec<String>,
}

impl DndTest {
    pub fn new() -> Self {
        Self {
            scene_rect: egui::Rect::ZERO,
            items: vec!["Item 1".to_string(), "Item 2".to_string(), "Item 3".to_string()],
        }
    }
}

impl eframe::App for DndTest {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.label("Drag and drop test");

            ui.add_space(200.0);

            egui::Scene::new().show(ui, &mut self.scene_rect, |ui| {
                ui.painter().rect_filled(ui.available_rect_before_wrap(), 5.0, egui::Color32::RED);

                ui.horizontal_wrapped(|ui| {
                    let dnd = egui_dnd::dnd(ui, "dnd").show_sized(self.items.iter(), egui::Vec2::new(50.0, 20.0), |ui, item, handle, state| {
                        handle.ui(ui, |ui| {
                            ui.add(egui::Button::new(item));
                        });
                    });
                    dnd.update_vec(&mut self.items);
                })
            });
        });
    }
}

It works after transforming the Scene position to screen positions with Context::layer_transform_to_global in the various places it is used, but this is not thoroughly tested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions