inset_embedder/views.rs
1//! Flutter counterpart: dart:ui `FlutterView`. The host owns the native
2//! window; this stable handle exposes its identity and current configuration.
3
4use crate::{Matrix4, Rect, Size, TextEditingValue, TextInputConfiguration};
5
6/// Opaque id for one [`View`] (`FlutterView.viewId`).
7#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
8pub struct ViewId(pub u64);
9
10/// An event for the engine to communicate view focus changes to the app.
11/// Flutter counterpart: `ViewFocusEvent` in `dart:ui/platform_dispatcher.dart`.
12#[derive(Clone, Copy, Debug)]
13pub struct ViewFocusEvent {
14 /// The ID of the view that experienced a focus change.
15 pub view_id: ViewId,
16 /// The state focus changed to.
17 pub state: ViewFocusState,
18 /// The direction focus changed to.
19 pub direction: ViewFocusDirection,
20}
21
22/// Represents the focus state of a given view.
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum ViewFocusState {
25 /// The view does not have platform focus.
26 Unfocused,
27 /// The view has platform focus.
28 Focused,
29}
30
31/// Represents the direction in which focus transitioned across views.
32#[derive(Clone, Copy, Debug, PartialEq, Eq)]
33pub enum ViewFocusDirection {
34 /// The transition did not have a direction, such as a programmatic request or focus loss.
35 Undefined,
36 /// The transition was forward, typically from pressing Tab.
37 Forward,
38 /// The transition was backward, typically from pressing Shift+Tab.
39 Backward,
40}
41
42/// Physical padding on each side of a view (`dart:ui` `ViewPadding`).
43#[derive(Clone, Copy, Debug, PartialEq)]
44pub struct ViewPadding {
45 pub left: f64,
46 pub top: f64,
47 pub right: f64,
48 pub bottom: f64,
49}
50
51impl ViewPadding {
52 /// A view padding that has zeros for each edge.
53 pub const ZERO: ViewPadding = ViewPadding {
54 left: 0.0,
55 top: 0.0,
56 right: 0.0,
57 bottom: 0.0,
58 };
59}
60
61/// Immutable layout constraints for a view (`dart:ui` `ViewConstraints`).
62#[derive(Clone, Copy, Debug, PartialEq)]
63pub struct ViewConstraints {
64 pub min_width: f64,
65 pub max_width: f64,
66 pub min_height: f64,
67 pub max_height: f64,
68}
69
70impl ViewConstraints {
71 pub const fn new(
72 min_width: f64,
73 max_width: f64,
74 min_height: f64,
75 max_height: f64,
76 ) -> ViewConstraints {
77 ViewConstraints {
78 min_width,
79 max_width,
80 min_height,
81 max_height,
82 }
83 }
84
85 /// Constraints respected only by the given size.
86 pub const fn tight(width: f64, height: f64) -> ViewConstraints {
87 ViewConstraints {
88 min_width: width,
89 max_width: width,
90 min_height: height,
91 max_height: height,
92 }
93 }
94}
95
96impl Default for ViewConstraints {
97 fn default() -> ViewConstraints {
98 ViewConstraints {
99 min_width: 0.0,
100 max_width: f64::INFINITY,
101 min_height: 0.0,
102 max_height: f64::INFINITY,
103 }
104 }
105}
106
107/// Per-view geometry the host reports (`_ViewConfiguration` fields we use).
108#[derive(Clone, Copy, Debug, PartialEq)]
109pub struct ViewMetrics {
110 pub physical_size: [f64; 2],
111 pub physical_constraints: ViewConstraints,
112 pub device_pixel_ratio: f64,
113 pub padding: ViewPadding,
114 pub view_padding: ViewPadding,
115 pub view_insets: ViewPadding,
116}
117
118impl Default for ViewMetrics {
119 fn default() -> ViewMetrics {
120 ViewMetrics {
121 physical_size: [0.0, 0.0],
122 physical_constraints: ViewConstraints::tight(0.0, 0.0),
123 device_pixel_ratio: 1.0,
124 padding: ViewPadding::ZERO,
125 view_padding: ViewPadding::ZERO,
126 view_insets: ViewPadding::ZERO,
127 }
128 }
129}
130
131/// A `null` field indicates that the platform or view does not have a preference
132/// and the fallback constants should be used instead.
133///
134/// Flutter counterpart: `GestureSettings` (`dart:ui` `window.dart`).
135#[derive(Clone, Copy, Debug, Default, PartialEq)]
136pub struct GestureSettings {
137 /// The number of physical pixels a pointer is allowed to drift before it is
138 /// considered an intentional movement.
139 ///
140 /// If `None`, the framework's default touch slop configuration should be used
141 /// instead.
142 pub physical_touch_slop: Option<f64>,
143
144 /// The number of physical pixels that the first and second tap of a double tap
145 /// can drift apart to still be recognized as a double tap.
146 ///
147 /// If `None`, the framework's default double tap slop configuration should be used
148 /// instead.
149 pub physical_double_tap_slop: Option<f64>,
150}
151
152impl GestureSettings {
153 /// Create a new [`GestureSettings`] object from an existing value, overwriting
154 /// all of the provided fields.
155 pub fn copy_with(
156 self,
157 physical_touch_slop: Option<f64>,
158 physical_double_tap_slop: Option<f64>,
159 ) -> GestureSettings {
160 GestureSettings {
161 physical_touch_slop: physical_touch_slop.or(self.physical_touch_slop),
162 physical_double_tap_slop: physical_double_tap_slop.or(self.physical_double_tap_slop),
163 }
164 }
165}
166
167/// A stable handle to one host-provided view.
168///
169/// [`present`](View::present) is Flutter `FlutterView.render`. The host owns
170/// the surface; the framework records a [`crate::Picture`] and hands it over.
171pub trait View: 'static {
172 fn id(&self) -> ViewId;
173 fn metrics(&self) -> ViewMetrics;
174
175 /// Flutter `FlutterView.gestureSettings`.
176 fn gesture_settings(&self) -> GestureSettings {
177 GestureSettings::default()
178 }
179
180 /// Renders and presents one picture, shared so the host may keep it: to present it
181 /// again when the window is seen again, and to tell a picture equal to the last from
182 /// one worth drawing. Physical pixels; the presenter applies no extra scaling.
183 fn present(&self, picture: std::sync::Arc<crate::Picture>);
184
185 /// Flutter `TextInput.attach` / `TextInputConnection.show`: start an IME
186 /// session for this view. The default drops it.
187 fn start_text_input(&self, configuration: &TextInputConfiguration) {
188 let _ = configuration;
189 }
190
191 /// Flutter `TextInputConnection.close`: end the IME session. The default
192 /// drops it.
193 fn stop_text_input(&self) {}
194
195 /// Flutter `TextInputConnection.setEditingState`. The default drops it.
196 fn set_text_input_editing_state(&self, value: &TextEditingValue) {
197 let _ = value;
198 }
199
200 /// Flutter `TextInput.setComposingRect`. The default drops it.
201 fn set_text_input_composing_rect(&self, rect: Rect) {
202 let _ = rect;
203 }
204
205 /// Flutter `TextInput.setCaretRect`. The default drops it.
206 fn set_text_input_caret_rect(&self, rect: Rect) {
207 let _ = rect;
208 }
209
210 /// Flutter `TextInput.setEditableSizeAndTransform`. The default drops it.
211 fn set_text_input_client_geometry(&self, size: Size, transform: &Matrix4) {
212 let _ = (size, transform);
213 }
214}