Skip to main content

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. Physical pixels; the presenter
181    /// applies no extra scaling.
182    fn present(&self, picture: &crate::Picture);
183
184    /// Flutter `TextInput.attach` / `TextInputConnection.show`: start an IME
185    /// session for this view. The default drops it.
186    fn start_text_input(&self, configuration: &TextInputConfiguration) {
187        let _ = configuration;
188    }
189
190    /// Flutter `TextInputConnection.close`: end the IME session. The default
191    /// drops it.
192    fn stop_text_input(&self) {}
193
194    /// Flutter `TextInputConnection.setEditingState`. The default drops it.
195    fn set_text_input_editing_state(&self, value: &TextEditingValue) {
196        let _ = value;
197    }
198
199    /// Flutter `TextInput.setComposingRect`. The default drops it.
200    fn set_text_input_composing_rect(&self, rect: Rect) {
201        let _ = rect;
202    }
203
204    /// Flutter `TextInput.setCaretRect`. The default drops it.
205    fn set_text_input_caret_rect(&self, rect: Rect) {
206        let _ = rect;
207    }
208
209    /// Flutter `TextInput.setEditableSizeAndTransform`. The default drops it.
210    fn set_text_input_client_geometry(&self, size: Size, transform: &Matrix4) {
211        let _ = (size, transform);
212    }
213}