From 4f02ad8cace631df810a54f3bd4d8e3a32a92994 Mon Sep 17 00:00:00 2001 From: Dimitri Belopopsky Date: Sun, 20 Dec 2020 00:59:08 +0100 Subject: [PATCH] Add basic drag and drop support --- Cargo.toml | 4 ++++ crates/bevy_window/src/event.rs | 19 +++++++++++++++++ crates/bevy_window/src/lib.rs | 7 +++++-- crates/bevy_winit/src/lib.rs | 35 +++++++++++++++++++++++++++++-- examples/README.md | 1 + examples/app/draganddrop.rs | 37 +++++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 examples/app/draganddrop.rs diff --git a/Cargo.toml b/Cargo.toml index 207cd12341165..3cee9dd9e1676 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -165,6 +165,10 @@ path = "examples/app/return_after_run.rs" name = "thread_pool_resources" path = "examples/app/thread_pool_resources.rs" +[[example]] +name = "draganddrop" +path = "examples/app/draganddrop.rs" + [[example]] name = "hot_asset_reloading" path = "examples/asset/hot_asset_reloading.rs" diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index ddb77f666cdc0..7b7328ce6de26 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use super::{WindowDescriptor, WindowId}; use bevy_math::Vec2; @@ -64,3 +66,20 @@ pub struct WindowFocused { pub id: WindowId, pub focused: bool, } + +#[derive(Debug, Clone)] +pub struct DroppedFile { + pub id: WindowId, + pub path_buf: PathBuf, +} + +#[derive(Debug, Clone)] +pub struct HoveredFile { + pub id: WindowId, + pub path_buf: PathBuf, +} + +#[derive(Debug, Clone)] +pub struct HoveredFileCancelled { + pub id: WindowId, +} diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 0ebfe3ad576b6..c699d9910fe35 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -11,8 +11,8 @@ pub use windows::*; pub mod prelude { pub use crate::{ - CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter, Window, WindowDescriptor, - Windows, + CursorEntered, CursorLeft, CursorMoved, DroppedFile, HoveredFile, HoveredFileCancelled, + ReceivedCharacter, Window, WindowDescriptor, Windows, }; } @@ -44,6 +44,9 @@ impl Plugin for WindowPlugin { .add_event::() .add_event::() .add_event::() + .add_event::() + .add_event::() + .add_event::() .init_resource::(); if self.add_primary_window { diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 9302bf46696d9..71380735577c6 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -14,8 +14,9 @@ use bevy_ecs::{IntoSystem, Resources, World}; use bevy_math::Vec2; use bevy_utils::tracing::{error, trace}; use bevy_window::{ - CreateWindow, CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter, WindowCloseRequested, - WindowCreated, WindowFocused, WindowResized, Windows, + CreateWindow, CursorEntered, CursorLeft, CursorMoved, DroppedFile, HoveredFile, + HoveredFileCancelled, ReceivedCharacter, WindowCloseRequested, WindowCreated, WindowFocused, + WindowResized, Windows, }; use winit::{ event::{self, DeviceEvent, Event, WindowEvent}, @@ -350,6 +351,35 @@ pub fn winit_runner(mut app: App) { ), } } + WindowEvent::DroppedFile(path_buf) => { + let mut cursor_left_events = + app.resources.get_mut::>().unwrap(); + let winit_windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + cursor_left_events.send(DroppedFile { + id: window_id, + path_buf, + }); + } + WindowEvent::HoveredFile(path_buf) => { + let mut cursor_left_events = + app.resources.get_mut::>().unwrap(); + let winit_windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + cursor_left_events.send(HoveredFile { + id: window_id, + path_buf, + }); + } + WindowEvent::HoveredFileCancelled => { + let mut cursor_left_events = app + .resources + .get_mut::>() + .unwrap(); + let winit_windows = app.resources.get_mut::().unwrap(); + let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); + cursor_left_events.send(HoveredFileCancelled { id: window_id }); + } _ => {} }, event::Event::DeviceEvent { @@ -370,6 +400,7 @@ pub fn winit_runner(mut app: App) { ); app.update(); } + _ => (), } }; diff --git a/examples/README.md b/examples/README.md index ae229238f9776..5f6fbe2000264 100644 --- a/examples/README.md +++ b/examples/README.md @@ -80,6 +80,7 @@ Example | File | Description Example | File | Description --- | --- | --- `custom_loop` | [`app/custom_loop.rs`](./app/custom_loop.rs) | Demonstrates how to create a custom runner (to update an app manually). +`draganddrop` | [`app/empty_defaults.rs`](./app/draganddrop.rs) | An example that shows how to handle drag and drop in an app. `empty_defaults` | [`app/empty_defaults.rs`](./app/empty_defaults.rs) | An empty application with default plugins `empty` | [`app/empty.rs`](./app/empty.rs) | An empty application (does nothing) `headless` | [`app/headless.rs`](./app/headless.rs) | An application that runs without default plugins diff --git a/examples/app/draganddrop.rs b/examples/app/draganddrop.rs new file mode 100644 index 0000000000000..f68fb78a5d52b --- /dev/null +++ b/examples/app/draganddrop.rs @@ -0,0 +1,37 @@ +use bevy::prelude::*; + +#[derive(Default)] +struct DroppedFileSystemState { + dropped_filed_event_reader: EventReader, + hovered_file_event_reader: EventReader, + hovered_file_canceled_event_reader: EventReader, +} + +fn main() { + App::build() + .add_plugins(DefaultPlugins) + .add_system(dropped_file_system.system()) + .run(); +} + +fn dropped_file_system( + mut state: Local, + dropped_file_events: Res>, + hovered_file_events: Res>, + hovered_file_canceled_events: Res>, +) { + for event in state.dropped_filed_event_reader.iter(&dropped_file_events) { + println!("Dropped file{:?}", event); + } + + for event in state.hovered_file_event_reader.iter(&hovered_file_events) { + println!("Hovered file{:?}", event); + } + + for event in state + .hovered_file_canceled_event_reader + .iter(&hovered_file_canceled_events) + { + println!("Dropped file{:?}", event); + } +}