mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-26 14:10:20 +00:00
native file drop
This commit is contained in:
parent
78d16536a7
commit
624e58bd78
6 changed files with 115 additions and 8 deletions
|
@ -2,7 +2,7 @@ use crate::{
|
|||
config::{Config, WindowCloseBehaviour},
|
||||
element::DesktopElement,
|
||||
event_handlers::WindowEventHandlers,
|
||||
file_upload::{DesktopFileUploadForm, FileDialogRequest},
|
||||
file_upload::{DesktopFileDragEvent, DesktopFileUploadForm, FileDialogRequest},
|
||||
ipc::{EventData, IpcMessage, UserWindowEvent},
|
||||
query::QueryResult,
|
||||
shortcut::{GlobalHotKeyEvent, ShortcutRegistry},
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||
use crossbeam_channel::Receiver;
|
||||
use dioxus_core::ElementId;
|
||||
use dioxus_core::VirtualDom;
|
||||
use dioxus_html::{native_bind::NativeFileEngine, HtmlEvent, PlatformEventData};
|
||||
use dioxus_html::{native_bind::NativeFileEngine, HasFileData, HtmlEvent, PlatformEventData};
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
collections::HashMap,
|
||||
|
@ -231,6 +231,7 @@ impl App {
|
|||
|
||||
let view = self.webviews.get_mut(&id).unwrap();
|
||||
let query = view.desktop_context.query.clone();
|
||||
let recent_file = view.desktop_context.file_hover.clone();
|
||||
|
||||
// check for a mounted event placeholder and replace it with a desktop specific element
|
||||
let as_any = match data {
|
||||
|
@ -238,6 +239,25 @@ impl App {
|
|||
let element = DesktopElement::new(element, view.desktop_context.clone(), query);
|
||||
Rc::new(PlatformEventData::new(Box::new(element)))
|
||||
}
|
||||
dioxus_html::EventData::Drag(ref drag) => {
|
||||
// we want to override this with a native file engine, provided by the most recent drag event
|
||||
if drag.files().is_some() {
|
||||
let file_event = recent_file.current().unwrap();
|
||||
let paths = match file_event {
|
||||
wry::FileDropEvent::Hovered { paths, position } => paths,
|
||||
wry::FileDropEvent::Dropped { paths, position } => paths,
|
||||
_ => vec![],
|
||||
};
|
||||
let files = Arc::new(NativeFileEngine::new(paths));
|
||||
let event = DesktopFileDragEvent {
|
||||
mouse: drag.mouse.clone(),
|
||||
files,
|
||||
};
|
||||
Rc::new(PlatformEventData::new(Box::new(event)))
|
||||
} else {
|
||||
data.into_any()
|
||||
}
|
||||
}
|
||||
_ => data.into_any(),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
//! Convert a serialized event to an event trigger
|
||||
|
||||
use crate::{element::DesktopElement, file_upload::DesktopFileUploadForm};
|
||||
use crate::{
|
||||
element::DesktopElement,
|
||||
file_upload::{DesktopFileDragEvent, DesktopFileUploadForm},
|
||||
};
|
||||
use dioxus_html::*;
|
||||
|
||||
pub(crate) struct SerializedHtmlEventConverter;
|
||||
|
@ -31,8 +34,14 @@ impl HtmlEventConverter for SerializedHtmlEventConverter {
|
|||
}
|
||||
|
||||
fn convert_drag_data(&self, event: &PlatformEventData) -> DragData {
|
||||
// Attempt a simple serialized data conversion
|
||||
if let Some(_data) = event.downcast::<SerializedDragData>() {
|
||||
return _data.clone().into();
|
||||
}
|
||||
|
||||
// If that failed then it's a file drag form
|
||||
event
|
||||
.downcast::<SerializedDragData>()
|
||||
.downcast::<DesktopFileDragEvent>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use dioxus_html::{native_bind::NativeFileEngine, FileEngine, HasFileData, HasFormData};
|
||||
use dioxus_html::{
|
||||
geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint},
|
||||
input_data::{MouseButton, MouseButtonSet},
|
||||
native_bind::NativeFileEngine,
|
||||
point_interaction::{
|
||||
InteractionElementOffset, InteractionLocation, ModifiersInteraction, PointerInteraction,
|
||||
},
|
||||
prelude::{SerializedMouseData, SerializedPointInteraction},
|
||||
FileEngine, HasDragData, HasFileData, HasFormData, HasMouseData,
|
||||
};
|
||||
use muda::accelerator::Modifiers;
|
||||
use serde::Deserialize;
|
||||
use std::{cell::Cell, path::PathBuf, rc::Rc, str::FromStr, sync::Arc};
|
||||
use wry::FileDropEvent;
|
||||
|
@ -152,4 +162,72 @@ impl NativeFileHover {
|
|||
pub fn set(&self, event: FileDropEvent) {
|
||||
self.event.set(Some(event));
|
||||
}
|
||||
|
||||
pub fn current(&self) -> Option<FileDropEvent> {
|
||||
self.event.as_ref().clone().take()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct DesktopFileDragEvent {
|
||||
pub mouse: SerializedPointInteraction,
|
||||
pub files: Arc<NativeFileEngine>,
|
||||
}
|
||||
|
||||
impl HasFileData for DesktopFileDragEvent {
|
||||
fn files(&self) -> Option<Arc<dyn FileEngine>> {
|
||||
Some(self.files.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl HasDragData for DesktopFileDragEvent {
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl HasMouseData for DesktopFileDragEvent {
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl InteractionLocation for DesktopFileDragEvent {
|
||||
fn client_coordinates(&self) -> ClientPoint {
|
||||
self.mouse.client_coordinates()
|
||||
}
|
||||
|
||||
fn page_coordinates(&self) -> PagePoint {
|
||||
self.mouse.page_coordinates()
|
||||
}
|
||||
|
||||
fn screen_coordinates(&self) -> ScreenPoint {
|
||||
self.mouse.screen_coordinates()
|
||||
}
|
||||
}
|
||||
|
||||
impl InteractionElementOffset for DesktopFileDragEvent {
|
||||
fn element_coordinates(&self) -> ElementPoint {
|
||||
self.mouse.element_coordinates()
|
||||
}
|
||||
|
||||
fn coordinates(&self) -> Coordinates {
|
||||
self.mouse.coordinates()
|
||||
}
|
||||
}
|
||||
|
||||
impl ModifiersInteraction for DesktopFileDragEvent {
|
||||
fn modifiers(&self) -> Modifiers {
|
||||
self.mouse.modifiers()
|
||||
}
|
||||
}
|
||||
|
||||
impl PointerInteraction for DesktopFileDragEvent {
|
||||
fn held_buttons(&self) -> MouseButtonSet {
|
||||
self.mouse.held_buttons()
|
||||
}
|
||||
|
||||
fn trigger_button(&self) -> Option<MouseButton> {
|
||||
self.mouse.trigger_button()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ impl PointerInteraction for DragData {
|
|||
/// A serialized version of DragData
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
||||
pub struct SerializedDragData {
|
||||
mouse: crate::point_interaction::SerializedPointInteraction,
|
||||
pub mouse: crate::point_interaction::SerializedPointInteraction,
|
||||
|
||||
#[serde(default)]
|
||||
files: Option<crate::file_data::SerializedFileEngine>,
|
||||
|
|
|
@ -50,7 +50,7 @@ pub trait ModifiersInteraction {
|
|||
|
||||
#[cfg(feature = "serialize")]
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone, Default)]
|
||||
pub(crate) struct SerializedPointInteraction {
|
||||
pub struct SerializedPointInteraction {
|
||||
pub alt_key: bool,
|
||||
|
||||
/// The button number that was pressed (if applicable) when the mouse event was fired.
|
||||
|
|
|
@ -1 +1 @@
|
|||
2617078454438840343
|
||||
13140749608285001344
|
Loading…
Reference in a new issue