docs: document all of desktop crate

This commit is contained in:
Jonathan Kelley committed 2022-02-20 23:52:36 -05:00
1 parent e71069883d
commit b2a4d387c7
7 files changed
+138 -108

No files matched your search

+1 -2
View File
@@ -1,5 +1,4 @@
use crate::desktop_context::DesktopContext; use crate::desktop_context::{DesktopContext, UserWindowEvent};
use crate::user_window_events::UserWindowEvent;
use dioxus_core::*; use dioxus_core::*;
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},
+86 -12
View File
@@ -3,14 +3,23 @@ use std::rc::Rc;
use dioxus_core::ScopeState; use dioxus_core::ScopeState;
use wry::application::event_loop::EventLoopProxy; use wry::application::event_loop::EventLoopProxy;
use crate::user_window_events::UserWindowEvent;
use UserWindowEvent::*; use UserWindowEvent::*;
type ProxyType = EventLoopProxy<UserWindowEvent>; pub type ProxyType = EventLoopProxy<UserWindowEvent>;
/// Desktop-Window handle api context /// Get an imperative handle to the current window
pub fn use_window(cx: &ScopeState) -> &Rc<DesktopContext> {
cx.use_hook(|_| cx.consume_context::<DesktopContext>())
.as_ref()
.unwrap()
}
/// An imperative interface to the current window.
/// ///
/// you can use this context control some window event /// To get a handle to the current window, use the [`use_window`] hook.
///
///
/// # Example
/// ///
/// you can use `cx.consume_context::<DesktopContext>` to get this context /// you can use `cx.consume_context::<DesktopContext>` to get this context
/// ///
@@ -19,7 +28,8 @@ type ProxyType = EventLoopProxy<UserWindowEvent>;
/// ``` /// ```
#[derive(Clone)] #[derive(Clone)]
pub struct DesktopContext { pub struct DesktopContext {
proxy: ProxyType, /// The wry/tao proxy to the current window
pub proxy: ProxyType,
} }
impl DesktopContext { impl DesktopContext {
@@ -84,12 +94,12 @@ impl DesktopContext {
let _ = self.proxy.send_event(AlwaysOnTop(top)); let _ = self.proxy.send_event(AlwaysOnTop(top));
} }
// set cursor visible or not /// set cursor visible or not
pub fn set_cursor_visible(&self, visible: bool) { pub fn set_cursor_visible(&self, visible: bool) {
let _ = self.proxy.send_event(CursorVisible(visible)); let _ = self.proxy.send_event(CursorVisible(visible));
} }
// set cursor grab /// set cursor grab
pub fn set_cursor_grab(&self, grab: bool) { pub fn set_cursor_grab(&self, grab: bool) {
let _ = self.proxy.send_event(CursorGrab(grab)); let _ = self.proxy.send_event(CursorGrab(grab));
} }
@@ -110,9 +120,73 @@ impl DesktopContext {
} }
} }
/// use this function can get the `DesktopContext` context. use wry::application::event_loop::ControlFlow;
pub fn use_window(cx: &ScopeState) -> &Rc<DesktopContext> { use wry::application::window::Fullscreen as WryFullscreen;
cx.use_hook(|_| cx.consume_context::<DesktopContext>())
.as_ref() use crate::controller::DesktopController;
.unwrap()
pub enum UserWindowEvent {
Update,
CloseWindow,
DragWindow,
FocusWindow,
Visible(bool),
Minimize(bool),
Maximize(bool),
MaximizeToggle,
Resizable(bool),
AlwaysOnTop(bool),
Fullscreen(bool),
CursorVisible(bool),
CursorGrab(bool),
SetTitle(String),
SetDecorations(bool),
DevTool,
}
pub(super) fn handler(
user_event: UserWindowEvent,
desktop: &mut DesktopController,
control_flow: &mut ControlFlow,
) {
// currently dioxus-desktop supports a single window only,
// so we can grab the only webview from the map;
let webview = desktop.webviews.values().next().unwrap();
let window = webview.window();
match user_event {
Update => desktop.try_load_ready_webviews(),
CloseWindow => *control_flow = ControlFlow::Exit,
DragWindow => {
// if the drag_window has any errors, we don't do anything
window.fullscreen().is_none().then(|| window.drag_window());
}
Visible(state) => window.set_visible(state),
Minimize(state) => window.set_minimized(state),
Maximize(state) => window.set_maximized(state),
MaximizeToggle => window.set_maximized(!window.is_maximized()),
Fullscreen(state) => {
if let Some(handle) = window.current_monitor() {
window.set_fullscreen(state.then(|| WryFullscreen::Borderless(Some(handle))));
}
}
FocusWindow => window.set_focus(),
Resizable(state) => window.set_resizable(state),
AlwaysOnTop(state) => window.set_always_on_top(state),
CursorVisible(state) => window.set_cursor_visible(state),
CursorGrab(state) => {
let _ = window.set_cursor_grab(state);
}
SetTitle(content) => window.set_title(&content),
SetDecorations(state) => window.set_decorations(state),
DevTool => webview.devtool(),
}
} }
+13 -13
View File
@@ -1,18 +1,23 @@
#![doc = include_str!("readme.md")] #![doc = include_str!("readme.md")]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")] #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")] #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
#![deny(missing_docs)]
pub mod cfg; mod cfg;
mod controller; mod controller;
pub mod desktop_context; mod desktop_context;
pub mod escape; mod escape;
pub mod events; mod events;
mod protocol; mod protocol;
mod user_window_events;
use desktop_context::UserWindowEvent;
pub use desktop_context::{use_window, DesktopContext};
pub use wry;
pub use wry::application as tao;
use crate::events::trigger_from_serialized;
use cfg::DesktopConfig; use cfg::DesktopConfig;
use controller::DesktopController; use controller::DesktopController;
pub use desktop_context::use_window;
use dioxus_core::*; use dioxus_core::*;
use events::parse_ipc_message; use events::parse_ipc_message;
use tao::{ use tao::{
@@ -20,12 +25,8 @@ use tao::{
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},
window::Window, window::Window,
}; };
pub use wry;
pub use wry::application as tao;
use wry::webview::WebViewBuilder; use wry::webview::WebViewBuilder;
use crate::events::trigger_from_serialized;
/// Launch the WebView and run the event loop. /// Launch the WebView and run the event loop.
/// ///
/// This function will start a multithreaded Tokio runtime as well the WebView event loop. /// This function will start a multithreaded Tokio runtime as well the WebView event loop.
@@ -139,8 +140,7 @@ pub fn launch_with_props<P: 'static + Send>(
} }
"initialize" => { "initialize" => {
is_ready.store(true, std::sync::atomic::Ordering::Relaxed); is_ready.store(true, std::sync::atomic::Ordering::Relaxed);
let _ = proxy let _ = proxy.send_event(UserWindowEvent::Update);
.send_event(user_window_events::UserWindowEvent::Update);
} }
"browser_open" => { "browser_open" => {
println!("browser_open"); println!("browser_open");
@@ -214,7 +214,7 @@ pub fn launch_with_props<P: 'static + Send>(
}, },
Event::UserEvent(user_event) => { Event::UserEvent(user_event) => {
user_window_events::handler(user_event, &mut desktop, control_flow) desktop_context::handler(user_event, &mut desktop, control_flow)
} }
Event::MainEventsCleared => {} Event::MainEventsCleared => {}
Event::Resumed => {} Event::Resumed => {}
@@ -1,72 +0,0 @@
use wry::application::event_loop::ControlFlow;
use wry::application::window::Fullscreen as WryFullscreen;
use crate::controller::DesktopController;
pub(crate) enum UserWindowEvent {
Update,
CloseWindow,
DragWindow,
FocusWindow,
Visible(bool),
Minimize(bool),
Maximize(bool),
MaximizeToggle,
Resizable(bool),
AlwaysOnTop(bool),
Fullscreen(bool),
CursorVisible(bool),
CursorGrab(bool),
SetTitle(String),
SetDecorations(bool),
DevTool,
}
use UserWindowEvent::*;
pub(super) fn handler(
user_event: UserWindowEvent,
desktop: &mut DesktopController,
control_flow: &mut ControlFlow,
) {
// currently dioxus-desktop supports a single window only,
// so we can grab the only webview from the map;
let webview = desktop.webviews.values().next().unwrap();
let window = webview.window();
match user_event {
Update => desktop.try_load_ready_webviews(),
CloseWindow => *control_flow = ControlFlow::Exit,
DragWindow => {
// if the drag_window has any errors, we don't do anything
window.fullscreen().is_none().then(|| window.drag_window());
}
Visible(state) => window.set_visible(state),
Minimize(state) => window.set_minimized(state),
Maximize(state) => window.set_maximized(state),
MaximizeToggle => window.set_maximized(!window.is_maximized()),
Fullscreen(state) => {
if let Some(handle) = window.current_monitor() {
window.set_fullscreen(state.then(|| WryFullscreen::Borderless(Some(handle))));
}
}
FocusWindow => window.set_focus(),
Resizable(state) => window.set_resizable(state),
AlwaysOnTop(state) => window.set_always_on_top(state),
CursorVisible(state) => window.set_cursor_visible(state),
CursorGrab(state) => {
let _ = window.set_cursor_grab(state);
}
SetTitle(content) => window.set_title(&content),
SetDecorations(state) => window.set_decorations(state),
DevTool => webview.devtool(),
}
}
+3
View File
@@ -1,3 +1,6 @@
#![deny(missing_docs)]
//! Useful foundational hooks for Dioxus
mod usestate; mod usestate;
pub use usestate::{use_state, UseState}; pub use usestate::{use_state, UseState};
+33 -9
View File
@@ -1,19 +1,30 @@
#![allow(missing_docs)]
use dioxus_core::{ScopeState, TaskId}; use dioxus_core::{ScopeState, TaskId};
use std::{cell::Cell, future::Future, rc::Rc}; use std::{cell::Cell, future::Future, rc::Rc};
/// A future that resolves to a value.
///
/// This runs the future only once - though the future may be regenerated
/// through the [`UseFuture::restart`] method.
///
/// This is commonly used for components that cannot be rendered until some
/// asynchronous operation has completed.
///
///
///
///
///
pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>( pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
cx: &'a ScopeState, cx: &'a ScopeState,
new_fut: impl FnOnce() -> F, new_fut: impl FnOnce() -> F,
) -> &'a UseFuture<T> { ) -> &'a UseFuture<T> {
let state = cx.use_hook(move |_| { let state = cx.use_hook(move |_| UseFuture {
// update: cx.schedule_update(),
UseFuture { needs_regen: Cell::new(true),
update: cx.schedule_update(), slot: Rc::new(Cell::new(None)),
needs_regen: Cell::new(true), value: None,
slot: Rc::new(Cell::new(None)), task: None,
value: None, pending: true,
task: None,
}
}); });
if let Some(value) = state.slot.take() { if let Some(value) = state.slot.take() {
@@ -24,6 +35,7 @@ pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
if state.needs_regen.get() { if state.needs_regen.get() {
// We don't need regen anymore // We don't need regen anymore
state.needs_regen.set(false); state.needs_regen.set(false);
state.pending = false;
// Create the new future // Create the new future
let fut = new_fut(); let fut = new_fut();
@@ -42,10 +54,17 @@ pub fn use_future<'a, T: 'static, F: Future<Output = T> + 'static>(
state state
} }
pub enum FutureState<'a, T> {
Pending,
Complete(&'a T),
Regenerating(&'a T), // the old value
}
pub struct UseFuture<T> { pub struct UseFuture<T> {
update: Rc<dyn Fn()>, update: Rc<dyn Fn()>,
needs_regen: Cell<bool>, needs_regen: Cell<bool>,
value: Option<T>, value: Option<T>,
pending: bool,
slot: Rc<Cell<Option<T>>>, slot: Rc<Cell<Option<T>>>,
task: Option<TaskId>, task: Option<TaskId>,
} }
@@ -72,4 +91,9 @@ impl<T> UseFuture<T> {
pub fn value(&self) -> Option<&T> { pub fn value(&self) -> Option<&T> {
self.value.as_ref() self.value.as_ref()
} }
pub fn state(&self) -> FutureState<T> {
// self.value.as_ref()
FutureState::Pending
}
} }
+2
View File
@@ -1,3 +1,5 @@
#![deny(missing_docs)]
//! Dioxus WebSys //! Dioxus WebSys
//! //!
//! ## Overview //! ## Overview