Skip to main content

ravenrs_widgets/
full_screen.rs

1//! Full screen, as a service the platform layer provides.
2
3use std::cell::Cell;
4use std::fmt;
5use std::rc::Rc;
6
7/// Puts the app in full screen and takes it out. Platform layers install one with
8/// [`crate::Ui::set_full_screen`]: the browser asks for the page's full screen, the
9/// desktop turns the window into a borderless full screen.
10pub trait FullScreenProvider {
11    /// Whether the app fills the screen now.
12    fn is_on(&self) -> bool;
13
14    /// Asks for full screen, or to leave it. The answer may come later, as a resize.
15    fn set(&self, on: bool);
16
17    /// Whether this place can show the app in full screen at all; a page inside a
18    /// frame that does not allow it cannot.
19    fn available(&self) -> bool {
20        true
21    }
22}
23
24/// Only remembers the request, for tests and headless use.
25#[derive(Debug, Default)]
26struct Remembered(Cell<bool>);
27
28impl FullScreenProvider for Remembered {
29    fn is_on(&self) -> bool {
30        self.0.get()
31    }
32
33    fn set(&self, on: bool) {
34        self.0.set(on);
35    }
36}
37
38/// A shared handle to the full screen service, from [`crate::BuildCx::full_screen`] or
39/// [`crate::Ui::full_screen`].
40///
41/// ```
42/// use ravenrs_widgets::FullScreen;
43///
44/// let screen = FullScreen::default();
45/// screen.toggle();
46/// assert!(screen.is_on());
47/// ```
48#[derive(Clone)]
49#[cfg_attr(feature = "live", ravenrs_live::expose(part = "fields"))]
50pub struct FullScreen {
51    provider: Rc<dyn FullScreenProvider>,
52}
53
54#[cfg_attr(feature = "live", ravenrs_live::expose)]
55impl FullScreen {
56    /// The service backed by `provider`.
57    pub fn new(provider: impl FullScreenProvider + 'static) -> Self {
58        Self { provider: Rc::new(provider) }
59    }
60
61    /// Whether the app fills the screen now.
62    pub fn is_on(&self) -> bool {
63        self.provider.is_on()
64    }
65
66    /// Asks for full screen, or to leave it.
67    pub fn set(&self, on: bool) {
68        self.provider.set(on);
69    }
70
71    /// Enters full screen when out of it, and leaves it when in.
72    pub fn toggle(&self) {
73        self.set(!self.is_on());
74    }
75
76    /// Whether full screen can be asked for here.
77    pub fn available(&self) -> bool {
78        self.provider.available()
79    }
80}
81
82impl Default for FullScreen {
83    fn default() -> Self {
84        Self::new(Remembered::default())
85    }
86}
87
88impl fmt::Debug for FullScreen {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        f.debug_struct("FullScreen").field("on", &self.is_on()).finish_non_exhaustive()
91    }
92}