wip: native file handles when dropping 🎉
This commit is contained in:
11 files changed
+134
-76
No files matched your search
@@ -262,6 +262,8 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_file_drag(&mut self, msg: IpcMessage, window: WindowId) {}
|
||||
|
||||
pub fn handle_file_dialog_msg(&mut self, msg: IpcMessage, window: WindowId) {
|
||||
let Ok(file_dialog) = serde_json::from_value::<FileDialogRequest>(msg.params()) else {
|
||||
return;
|
||||
|
||||
@@ -118,15 +118,6 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a file drop handler. If this is enabled, html drag events will be disabled.
|
||||
pub fn with_file_drop_handler(
|
||||
mut self,
|
||||
handler: impl Fn(WindowId, FileDropEvent) -> bool + 'static,
|
||||
) -> Self {
|
||||
self.file_drop_handler = Some(Box::new(handler));
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a custom protocol
|
||||
pub fn with_custom_protocol<F>(mut self, name: String, handler: F) -> Self
|
||||
where
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::{
|
||||
app::SharedContext,
|
||||
assets::AssetHandlerRegistry,
|
||||
edits::EditQueue,
|
||||
file_upload::NativeFileHover,
|
||||
ipc::{EventData, UserWindowEvent},
|
||||
query::QueryEngine,
|
||||
shortcut::{HotKey, ShortcutHandle, ShortcutRegistryError},
|
||||
@@ -13,13 +14,17 @@ use dioxus_core::{
|
||||
VirtualDom,
|
||||
};
|
||||
use dioxus_interpreter_js::MutationState;
|
||||
use std::{cell::RefCell, rc::Rc, rc::Weak};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
rc::{Rc, Weak},
|
||||
sync::Arc,
|
||||
};
|
||||
use tao::{
|
||||
event::Event,
|
||||
event_loop::EventLoopWindowTarget,
|
||||
window::{Fullscreen as WryFullscreen, Window, WindowId},
|
||||
};
|
||||
use wry::{RequestAsyncResponder, WebView};
|
||||
use wry::{FileDropEvent, RequestAsyncResponder, WebView};
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
use tao::platform::ios::WindowExtIOS;
|
||||
@@ -62,6 +67,7 @@ pub struct DesktopService {
|
||||
pub(crate) edit_queue: EditQueue,
|
||||
pub(crate) mutation_state: RefCell<MutationState>,
|
||||
pub(crate) asset_handlers: AssetHandlerRegistry,
|
||||
pub(crate) file_hover: NativeFileHover,
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
pub(crate) views: Rc<RefCell<Vec<*mut objc::runtime::Object>>>,
|
||||
@@ -83,14 +89,16 @@ impl DesktopService {
|
||||
shared: Rc<SharedContext>,
|
||||
edit_queue: EditQueue,
|
||||
asset_handlers: AssetHandlerRegistry,
|
||||
file_hover: NativeFileHover,
|
||||
) -> Self {
|
||||
Self {
|
||||
window,
|
||||
webview,
|
||||
shared,
|
||||
edit_queue,
|
||||
mutation_state: Default::default(),
|
||||
asset_handlers,
|
||||
file_hover,
|
||||
mutation_state: Default::default(),
|
||||
query: Default::default(),
|
||||
#[cfg(target_os = "ios")]
|
||||
views: Default::default(),
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
use dioxus_html::{native_bind::NativeFileEngine, FileEngine, HasFileData, HasFormData};
|
||||
use serde::Deserialize;
|
||||
use std::{path::PathBuf, str::FromStr, sync::Arc};
|
||||
use std::{cell::Cell, path::PathBuf, rc::Rc, str::FromStr, sync::Arc};
|
||||
use wry::FileDropEvent;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub(crate) struct FileDialogRequest {
|
||||
@@ -142,3 +143,13 @@ impl HasFormData for DesktopFileUploadForm {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct NativeFileHover {
|
||||
event: Rc<Cell<Option<FileDropEvent>>>,
|
||||
}
|
||||
impl NativeFileHover {
|
||||
pub fn set(&self, event: FileDropEvent) {
|
||||
self.event.set(Some(event));
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,7 @@ pub enum IpcMethod<'a> {
|
||||
Query,
|
||||
BrowserOpen,
|
||||
Initialize,
|
||||
FileDrag,
|
||||
Other(&'a str),
|
||||
}
|
||||
|
||||
@@ -50,6 +51,7 @@ impl IpcMessage {
|
||||
match self.method.as_str() {
|
||||
// todo: this is a misspelling, needs to be fixed
|
||||
"file_dialog" => IpcMethod::FileDialog,
|
||||
"file_drag" => IpcMethod::FileDrag,
|
||||
"user_event" => IpcMethod::UserEvent,
|
||||
"query" => IpcMethod::Query,
|
||||
"browser_open" => IpcMethod::BrowserOpen,
|
||||
|
||||
@@ -34,6 +34,7 @@ pub fn launch_virtual_dom_blocking(virtual_dom: VirtualDom, desktop_config: Conf
|
||||
EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg),
|
||||
EventData::Ipc(msg) => match msg.method() {
|
||||
IpcMethod::FileDialog => app.handle_file_dialog_msg(msg, id),
|
||||
IpcMethod::FileDrag => app.handle_file_drag(msg, id),
|
||||
IpcMethod::UserEvent => app.handle_user_event_msg(msg, id),
|
||||
IpcMethod::Query => app.handle_query_msg(msg, id),
|
||||
IpcMethod::BrowserOpen => app.handle_browser_open(msg),
|
||||
|
||||
@@ -3,8 +3,9 @@ use crate::{
|
||||
assets::AssetHandlerRegistry,
|
||||
edits::EditQueue,
|
||||
eval::DesktopEvalProvider,
|
||||
file_upload::NativeFileHover,
|
||||
ipc::{EventData, UserWindowEvent},
|
||||
protocol::{self},
|
||||
protocol,
|
||||
waker::tao_waker,
|
||||
Config, DesktopContext, DesktopService,
|
||||
};
|
||||
@@ -65,7 +66,6 @@ impl WebviewInstance {
|
||||
|
||||
// Rust :(
|
||||
let window_id = window.id();
|
||||
let file_handler = cfg.file_drop_handler.take();
|
||||
let custom_head = cfg.custom_head.clone();
|
||||
let index_file = cfg.custom_index.clone();
|
||||
let root_name = cfg.root_name.clone();
|
||||
@@ -102,6 +102,8 @@ impl WebviewInstance {
|
||||
}
|
||||
};
|
||||
|
||||
let file_hover = NativeFileHover::default();
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
@@ -128,12 +130,18 @@ impl WebviewInstance {
|
||||
.with_url("dioxus://index.html/")
|
||||
.unwrap()
|
||||
.with_ipc_handler(ipc_handler)
|
||||
.with_navigation_handler(|var| var.contains("dioxus")) // prevent all navigations
|
||||
.with_asynchronous_custom_protocol(String::from("dioxus"), request_handler)
|
||||
.with_web_context(&mut web_context);
|
||||
|
||||
if let Some(handler) = file_handler {
|
||||
webview = webview.with_file_drop_handler(move |evt| handler(window_id, evt))
|
||||
}
|
||||
.with_web_context(&mut web_context)
|
||||
.with_file_drop_handler({
|
||||
let file_hover = file_hover.clone();
|
||||
move |evt| {
|
||||
println!("file drop: {:?}", evt);
|
||||
// Update the most recent file hover status
|
||||
file_hover.set(evt);
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(color) = cfg.background_color {
|
||||
webview = webview.with_background_color(color);
|
||||
@@ -178,6 +186,7 @@ impl WebviewInstance {
|
||||
shared.clone(),
|
||||
edit_queue,
|
||||
asset_handlers,
|
||||
file_hover,
|
||||
));
|
||||
|
||||
let provider: Rc<dyn EvalProvider> =
|
||||
|
||||
Reference in new issue
Block a user