tessera_ui/
window_insets.rs1use crate::{Dp, State, StateOwner};
7
8pub(crate) mod platform;
9
10#[derive(Clone, Copy, Debug, Default, PartialEq)]
12pub struct Insets {
13 pub left: Dp,
15 pub top: Dp,
17 pub right: Dp,
19 pub bottom: Dp,
21}
22
23impl Insets {
24 pub const fn new(left: Dp, top: Dp, right: Dp, bottom: Dp) -> Self {
26 Self {
27 left,
28 top,
29 right,
30 bottom,
31 }
32 }
33
34 pub const fn all(value: Dp) -> Self {
36 Self {
37 left: value,
38 top: value,
39 right: value,
40 bottom: value,
41 }
42 }
43
44 pub const fn symmetric(horizontal: Dp, vertical: Dp) -> Self {
46 Self {
47 left: horizontal,
48 top: vertical,
49 right: horizontal,
50 bottom: vertical,
51 }
52 }
53
54 pub const fn horizontal(value: Dp) -> Self {
56 Self::symmetric(value, Dp(0.0))
57 }
58
59 pub const fn vertical(value: Dp) -> Self {
61 Self::symmetric(Dp(0.0), value)
62 }
63
64 pub const fn left(value: Dp) -> Self {
66 Self {
67 left: value,
68 top: Dp(0.0),
69 right: Dp(0.0),
70 bottom: Dp(0.0),
71 }
72 }
73
74 pub const fn top(value: Dp) -> Self {
76 Self {
77 left: Dp(0.0),
78 top: value,
79 right: Dp(0.0),
80 bottom: Dp(0.0),
81 }
82 }
83
84 pub const fn right(value: Dp) -> Self {
86 Self {
87 left: Dp(0.0),
88 top: Dp(0.0),
89 right: value,
90 bottom: Dp(0.0),
91 }
92 }
93
94 pub const fn bottom(value: Dp) -> Self {
96 Self {
97 left: Dp(0.0),
98 top: Dp(0.0),
99 right: Dp(0.0),
100 bottom: value,
101 }
102 }
103}
104
105impl Insets {
106 pub fn union(self, other: Self) -> Self {
108 Self::new(
109 Dp(self.left.0.max(other.left.0)),
110 Dp(self.top.0.max(other.top.0)),
111 Dp(self.right.0.max(other.right.0)),
112 Dp(self.bottom.0.max(other.bottom.0)),
113 )
114 }
115
116 pub fn exclude(self, consumed: Self) -> Self {
118 Self::new(
119 Dp((self.left.0 - consumed.left.0).max(0.0)),
120 Dp((self.top.0 - consumed.top.0).max(0.0)),
121 Dp((self.right.0 - consumed.right.0).max(0.0)),
122 Dp((self.bottom.0 - consumed.bottom.0).max(0.0)),
123 )
124 }
125}
126
127#[derive(Clone, Copy, Debug, PartialEq)]
129pub enum WindowInsets {
130 SystemBars,
132 Ime,
134 SafeDrawing,
136 Fixed(Insets),
138}
139
140impl WindowInsets {
141 pub fn get(self) -> Insets {
143 if let Self::Fixed(insets) = self {
144 return insets;
145 }
146 let (system, ime) = WindowInsetsController::current().0.get();
147 match self {
148 Self::SystemBars => system,
149 Self::Ime => ime,
150 _ => system.union(ime),
151 }
152 }
153}
154
155#[derive(Clone, Copy, PartialEq)]
157pub struct WindowInsetsController(State<(Insets, Insets)>);
158
159struct WindowInsetsState {
160 _owner: StateOwner,
161 controller: WindowInsetsController,
162}
163
164impl Default for WindowInsetsState {
165 fn default() -> Self {
166 let owner = StateOwner::new();
167 let controller = WindowInsetsController(owner.state_with_key((), Default::default));
168 Self {
169 _owner: owner,
170 controller,
171 }
172 }
173}
174
175impl WindowInsetsController {
176 pub fn current() -> Self {
178 crate::local_runtime_resource::<WindowInsetsState>().controller
179 }
180
181 pub fn set(self, system_bars: Insets, ime: Insets) {
184 self.0.set_if_changed((system_bars, ime));
185 }
186}