mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-26 22:20:19 +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},
|
config::{Config, WindowCloseBehaviour},
|
||||||
element::DesktopElement,
|
element::DesktopElement,
|
||||||
event_handlers::WindowEventHandlers,
|
event_handlers::WindowEventHandlers,
|
||||||
file_upload::{DesktopFileUploadForm, FileDialogRequest},
|
file_upload::{DesktopFileDragEvent, DesktopFileUploadForm, FileDialogRequest},
|
||||||
ipc::{EventData, IpcMessage, UserWindowEvent},
|
ipc::{EventData, IpcMessage, UserWindowEvent},
|
||||||
query::QueryResult,
|
query::QueryResult,
|
||||||
shortcut::{GlobalHotKeyEvent, ShortcutRegistry},
|
shortcut::{GlobalHotKeyEvent, ShortcutRegistry},
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
use dioxus_core::VirtualDom;
|
use dioxus_core::VirtualDom;
|
||||||
use dioxus_html::{native_bind::NativeFileEngine, HtmlEvent, PlatformEventData};
|
use dioxus_html::{native_bind::NativeFileEngine, HasFileData, HtmlEvent, PlatformEventData};
|
||||||
use std::{
|
use std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
@ -231,6 +231,7 @@ impl App {
|
||||||
|
|
||||||
let view = self.webviews.get_mut(&id).unwrap();
|
let view = self.webviews.get_mut(&id).unwrap();
|
||||||
let query = view.desktop_context.query.clone();
|
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
|
// check for a mounted event placeholder and replace it with a desktop specific element
|
||||||
let as_any = match data {
|
let as_any = match data {
|
||||||
|
@ -238,6 +239,25 @@ impl App {
|
||||||
let element = DesktopElement::new(element, view.desktop_context.clone(), query);
|
let element = DesktopElement::new(element, view.desktop_context.clone(), query);
|
||||||
Rc::new(PlatformEventData::new(Box::new(element)))
|
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(),
|
_ => data.into_any(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
//! Convert a serialized event to an event trigger
|
//! 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::*;
|
use dioxus_html::*;
|
||||||
|
|
||||||
pub(crate) struct SerializedHtmlEventConverter;
|
pub(crate) struct SerializedHtmlEventConverter;
|
||||||
|
@ -31,8 +34,14 @@ impl HtmlEventConverter for SerializedHtmlEventConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_drag_data(&self, event: &PlatformEventData) -> DragData {
|
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
|
event
|
||||||
.downcast::<SerializedDragData>()
|
.downcast::<DesktopFileDragEvent>()
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into()
|
.into()
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
#![allow(unused)]
|
#![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 serde::Deserialize;
|
||||||
use std::{cell::Cell, path::PathBuf, rc::Rc, str::FromStr, sync::Arc};
|
use std::{cell::Cell, path::PathBuf, rc::Rc, str::FromStr, sync::Arc};
|
||||||
use wry::FileDropEvent;
|
use wry::FileDropEvent;
|
||||||
|
@ -152,4 +162,72 @@ impl NativeFileHover {
|
||||||
pub fn set(&self, event: FileDropEvent) {
|
pub fn set(&self, event: FileDropEvent) {
|
||||||
self.event.set(Some(event));
|
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
|
/// A serialized version of DragData
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
|
||||||
pub struct SerializedDragData {
|
pub struct SerializedDragData {
|
||||||
mouse: crate::point_interaction::SerializedPointInteraction,
|
pub mouse: crate::point_interaction::SerializedPointInteraction,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
files: Option<crate::file_data::SerializedFileEngine>,
|
files: Option<crate::file_data::SerializedFileEngine>,
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub trait ModifiersInteraction {
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone, Default)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone, Default)]
|
||||||
pub(crate) struct SerializedPointInteraction {
|
pub struct SerializedPointInteraction {
|
||||||
pub alt_key: bool,
|
pub alt_key: bool,
|
||||||
|
|
||||||
/// The button number that was pressed (if applicable) when the mouse event was fired.
|
/// The button number that was pressed (if applicable) when the mouse event was fired.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2617078454438840343
|
13140749608285001344
|
Loading…
Reference in a new issue