Browse Source

feat: add `DesktopContext`

mrxiaozhuox 3 years ago
parent
commit
169028705d
3 changed files with 71 additions and 91 deletions
  1. 21 0
      examples/borderless.rs
  2. 19 91
      packages/desktop/src/desktop_context.rs
  3. 31 0
      packages/desktop/src/lib.rs

+ 21 - 0
examples/borderless.rs

@@ -0,0 +1,21 @@
+use dioxus::prelude::*;
+use dioxus_desktop::desktop_context::DesktopContext;
+
+fn main() {
+    dioxus::desktop::launch_cfg(app, |cfg| {
+        cfg.with_window(|w| {
+            w.with_title("BorderLess Demo")
+            .with_decorations(false)
+        })
+    });
+}
+
+fn app (cx: Scope) -> Element {
+    let desktop = cx.consume_context::<DesktopContext>().unwrap();
+    cx.render(rsx!(
+        div {
+            style: "background-color: black; height: 20px; width: 100%",
+            onmousedown: move |_| desktop.drag_window(),
+        }
+    ))
+}

+ 19 - 91
packages/desktop/src/desktop_context.rs

@@ -1,100 +1,28 @@
-use std::cell::RefCell;
+use wry::application::event_loop::EventLoopProxy;
 
-use dioxus::prelude::Scope;
-use dioxus_core as dioxus;
-use dioxus_core::{Context, Element, LazyNodes, NodeFactory, Properties};
-use dioxus_core_macro::Props;
+use crate::UserWindowEvent;
 
-/*
-This module provides a set of Dioxus components to easily manage windows, tabs, etc.
+type ProxyType = EventLoopProxy<UserWindowEvent>;
 
-Windows can be created anywhere in the tree, making them very flexible for things like modals, etc.
-
-*/
-pub struct DesktopContext {}
+#[derive(Clone)]
+pub struct DesktopContext {
+    proxy: ProxyType,
+}
 
 impl DesktopContext {
-    fn add_window(&mut self) {
-        //
-    }
-    fn close_window(&mut self) {
-        //
+    pub fn new(proxy: ProxyType) -> Self {
+        Self { proxy }
     }
-}
-
-enum WindowHandlers {
-    Resized(Box<dyn Fn()>),
-    Moved(Box<dyn Fn()>),
-    CloseRequested(Box<dyn Fn()>),
-    Destroyed(Box<dyn Fn()>),
-    DroppedFile(Box<dyn Fn()>),
-    HoveredFile(Box<dyn Fn()>),
-    HoverFileCancelled(Box<dyn Fn()>),
-    ReceivedTimeText(Box<dyn Fn()>),
-    Focused(Box<dyn Fn()>),
-}
-
-#[derive(Props)]
-pub struct WebviewWindowProps<'a> {
-    onclose: &'a dyn FnMut(()),
-
-    onopen: &'a dyn FnMut(()),
-
-    /// focuse me
-    onfocused: &'a dyn FnMut(()),
-
-    children: Element,
-}
-
-/// A handle to a
-///
-///
-///
-///
-///
-///
-///
-///
-///
-pub fn WebviewWindow(cx: Scope<WebviewWindowProps>) -> Element {
-    let dtcx = cx.consume_state::<RefCell<DesktopContext>>()?;
 
-    cx.use_hook(|_| {});
-
-    // render the children directly
-    todo!()
-    // cx.render(LazyNodes::new(move |f: NodeFactory| {
-    //     f.fragment_from_iter(cx.children())
-    // }))
-}
-
-pub struct WindowHandle {}
-
-/// Get a handle to the current window from inside a component
-pub fn use_current_window(cx: Scope) -> Option<WindowHandle> {
-    todo!()
-}
-
-#[test]
-fn syntax_works() {
-    use dioxus_core as dioxus;
-    use dioxus_core::prelude::*;
-    use dioxus_core_macro::*;
-    use dioxus_hooks::*;
-    use dioxus_html as dioxus_elements;
-
-    static App: Component = |cx| {
-        cx.render(rsx! {
-            // left window
-            WebviewWindow {
-                onclose: move |evt| {}
-                onopen: move |evt| {}
-                onfocused: move |evt| {}
+    pub fn drag_window(&self) {
+        let _ = self.proxy.send_event(UserWindowEvent::DragWindow);
+    }
 
-                div {
+    pub fn minimized(&self, minimized: bool) {
+        let _ = self.proxy.send_event(UserWindowEvent::Minimized(minimized));
+    }
 
-                }
-            }
-        })
-    };
-}
+    pub fn maximized(&self, maximized: bool) {
+        let _ = self.proxy.send_event(UserWindowEvent::Maximized(maximized));
+    }
+}

+ 31 - 0
packages/desktop/src/lib.rs

@@ -51,10 +51,12 @@
 //! Make sure to read the [Dioxus Guide](https://dioxuslabs.com/guide) if you already haven't!
 
 pub mod cfg;
+pub mod desktop_context;
 pub mod escape;
 pub mod events;
 
 use cfg::DesktopConfig;
+use desktop_context::DesktopContext;
 use dioxus_core::*;
 use std::{
     collections::{HashMap, VecDeque},
@@ -282,6 +284,27 @@ pub fn launch_with_props<P: 'static + Send>(
                 //
                 match _evt {
                     UserWindowEvent::Update => desktop.try_load_ready_webviews(),
+                    UserWindowEvent::DragWindow => {
+                        // this loop just run once, because dioxus-desktop is unsupport multi-window.
+                        for webview in desktop.webviews.values() {
+                            let window = webview.window();
+                            window.drag_window().unwrap();
+                        }
+                    }
+                    UserWindowEvent::Minimized(state) => {
+                        // this loop just run once, because dioxus-desktop is unsupport multi-window.
+                        for webview in desktop.webviews.values() {
+                            let window = webview.window();
+                            window.set_minimized(state);
+                        }
+                    }
+                    UserWindowEvent::Maximized(state) => {
+                        // this loop just run once, because dioxus-desktop is unsupport multi-window.
+                        for webview in desktop.webviews.values() {
+                            let window = webview.window();
+                            window.set_maximized(state);
+                        }
+                    }
                 }
             }
             Event::MainEventsCleared => {}
@@ -296,6 +319,9 @@ pub fn launch_with_props<P: 'static + Send>(
 
 pub enum UserWindowEvent {
     Update,
+    DragWindow,
+    Minimized(bool),
+    Maximized(bool),
 }
 
 pub struct DesktopController {
@@ -322,6 +348,7 @@ impl DesktopController {
         let return_sender = sender.clone();
         let proxy = evt.clone();
 
+        let desktop_context_proxy = proxy.clone();
         std::thread::spawn(move || {
             // We create the runtime as multithreaded, so you can still "spawn" onto multiple threads
             let runtime = tokio::runtime::Builder::new_multi_thread()
@@ -333,6 +360,10 @@ impl DesktopController {
                 let mut dom =
                     VirtualDom::new_with_props_and_scheduler(root, props, (sender, receiver));
 
+                let window_context = DesktopContext::new(desktop_context_proxy);
+
+                dom.base_scope().provide_context(window_context);
+
                 let edits = dom.rebuild();
 
                 edit_queue