diff --git a/example/src/lib.rs b/example/src/lib.rs index e675fdc..86a6cb6 100644 --- a/example/src/lib.rs +++ b/example/src/lib.rs @@ -95,28 +95,34 @@ impl Plugin for Gain { .with_developer_mode(true) .with_callback(move |ctx, setter| { for msg in ctx.consume_json() { - // you'll probably want to parse events into structs with Serde in a real scenario - match msg.get("type").unwrap().as_str().unwrap() { - "set_gain" => { - let value = msg.get("value").unwrap().as_f64().unwrap() as f32; - setter.begin_set_parameter(¶ms.gain); - setter.set_parameter_normalized(¶ms.gain, value); - setter.end_set_parameter(¶ms.gain); - }, - "set_size" => { - let width = msg.get("width").unwrap().as_u64().unwrap(); - let height = msg.get("height").unwrap().as_u64().unwrap(); - ctx.resize((width as u32, height as u32)); - }, - "init" => { - let _ = ctx.send_json(json!({ - "type": "set_size", - "width": ctx.width.load(Ordering::Relaxed), - "height": ctx.height.load(Ordering::Relaxed) - })); + match msg { + WebviewMessage::JSON(msg) => { + match msg.get("type").unwrap().as_str().unwrap() { + "set_gain" => { + let value = msg.get("value").unwrap().as_f64().unwrap() as f32; + setter.begin_set_parameter(¶ms.gain); + setter.set_parameter_normalized(¶ms.gain, value); + setter.end_set_parameter(¶ms.gain); + }, + "set_size" => { + let width = msg.get("width").unwrap().as_u64().unwrap(); + let height = msg.get("height").unwrap().as_u64().unwrap(); + ctx.resize((width as u32, height as u32)); + }, + "init" => { + let _ = ctx.send_json(json!({ + "type": "set_size", + "width": ctx.width.load(Ordering::Relaxed), + "height": ctx.height.load(Ordering::Relaxed) + })); + } + _ => {} + } } - _ => {} + WebviewMessage::FileDropped(_) => todo!(), } + // you'll probably want to parse events into structs with Serde in a real scenario + } // sends the param change each frame which is wasteful but good enough for this mvp diff --git a/src/lib.rs b/src/lib.rs index d0f8e00..e782087 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,10 +17,10 @@ use std::{ sync::{ atomic::{AtomicU32, Ordering}, Arc, Mutex, - }, + }, path::PathBuf, }; use wry::{ - webview::{WebView, WebViewBuilder, Window}, + webview::{WebView, WebViewBuilder, Window, FileDropEvent}, }; struct Instance { @@ -39,10 +39,16 @@ impl Drop for Instance { } } +#[derive(Clone)] +pub enum WebviewMessage { + JSON(Value), + FileDropped(Vec) +} + pub struct Context { webview: Option, pub gui_context: Option>, - messages: Vec, + messages: Vec, pub width: Arc, pub height: Arc, } @@ -71,7 +77,7 @@ impl Context { Err(None) } - pub fn consume_json(&mut self) -> Vec { + pub fn consume_json(&mut self) -> Vec { // TODO: there has to be a better way let msgs = self.messages.clone(); self.messages.clear(); @@ -179,7 +185,8 @@ impl Editor for WebViewEditor { { let mut context = self.context.lock().unwrap(); context.gui_context = Some(gui_context.clone()); - let inner_context = self.context.clone(); + let file_drop_context = self.context.clone(); + let ipc_context = self.context.clone(); let mut webview_builder = match parent.handle { #[cfg(target_os = "macos")] @@ -193,10 +200,18 @@ impl Editor for WebViewEditor { .with_accept_first_mouse(true) .with_devtools(self.developer_mode) .with_initialization_script(include_str!("script.js")) + .with_file_drop_handler(move |_: &Window, msg: FileDropEvent| { + if let FileDropEvent::Dropped(path) = msg { + if let Ok(mut context) = file_drop_context.lock() { + context.messages.push(WebviewMessage::FileDropped(path)); + } + } + false + }) .with_ipc_handler(move |_: &Window, msg: String| { - if let Ok(mut context) = inner_context.lock() { + if let Ok(mut context) = ipc_context.lock() { if let Ok(json_value) = serde_json::from_str(&msg) { - context.messages.push(json_value); + context.messages.push(WebviewMessage::JSON(json_value)); } } else { panic!("Invalid JSON from web view: {}.", msg);