Skip to main content

TouchEvent

Struct TouchEvent 

Source
pub struct TouchEvent {
    pub point: Point,
    pub phase: TouchPhase,
    pub timestamp_ms: u32,
}
Expand description

One touch sample routed through the UI framework.

Fields§

§point: Point

Absolute point in display coordinates.

§phase: TouchPhase

Gesture phase for this sample.

§timestamp_ms: u32

Monotonic timestamp in milliseconds.

Implementations§

Source§

impl TouchEvent

Source

pub const fn new(point: Point, phase: TouchPhase, timestamp_ms: u32) -> Self

Creates a new touch event.

Examples found in repository?
examples/runtime_shell.rs (lines 78-82)
77    fn poll_touch(&mut self, _now_ms: u32) -> Result<Option<TouchEvent>, Self::Error> {
78        Ok(Some(TouchEvent::new(
79            Point::new(12, 12),
80            TouchPhase::End,
81            1,
82        )))
83    }
More examples
Hide additional examples
examples/uikit_root.rs (line 217)
206fn main() {
207    let bounds = Rectangle::new(Point::zero(), Size::new(320, 240));
208    let mut system = UiSystem::new(
209        NullDisplay::new(bounds),
210        RootView::new(),
211        FsTheme::default(),
212        I18n::new("en", "en", &[]),
213    );
214
215    let redraw = system.update(16).redraw;
216    let _ = system.draw_redraw(redraw);
217    let _ = system.handle_touch(TouchEvent::new(Point::new(24, 24), TouchPhase::Start, 1));
218    let _ = system.handle_touch(TouchEvent::new(Point::new(24, 24), TouchPhase::End, 2));
219    let _ = system.draw();
220    let _ = system.registration();
221    let _ = ViewRedraw::Full;
222}
examples/alerts.rs (line 24)
11fn main() {
12    let bounds = Rectangle::new(Point::zero(), Size::new(320, 240));
13    let theme = support::theme();
14    let i18n = support::i18n();
15    let mut canvas = support::NullCanvas::new(bounds.size);
16
17    let spec = AlertSpec::confirm(
18        Localized::new("alert.title", "Delete item?"),
19        Localized::new("alert.message", "This action cannot be undone."),
20    );
21    let mut alert = AlertView::new(spec);
22    let panel = alert.panel(bounds, &theme, &i18n);
23    alert.draw(&mut canvas, panel, &theme, &i18n);
24    let _ = alert.handle_touch(TouchEvent::new(panel.center(), TouchPhase::Start, 1), panel);
25
26    let mut host = AlertHost::<u8, 2>::new();
27    let _ = host.present(7, spec);
28    let _ = host.layer(bounds, &theme, &i18n);
29    host.draw(&mut canvas, bounds, &theme, &i18n);
30    let _ = host.handle_touch(
31        TouchEvent::new(Point::new(160, 160), TouchPhase::End, 2),
32        bounds,
33        &theme,
34        &i18n,
35    );
36
37    let mut modal = ModalHost::new();
38    modal.show(3_u8);
39    let _ = modal.current(bounds, &theme);
40    let _ = Rgb565::BLACK;
41}
examples/scroll_and_list.rs (line 65)
60fn main() {
61    let mut canvas = support::NullCanvas::new(Size::new(320, 240));
62    let viewport = Rectangle::new(Point::new(16, 16), Size::new(180, 160));
63
64    let mut scroll = ScrollView::new();
65    scroll.begin_drag(TouchEvent::new(Point::new(8, 8), TouchPhase::Start, 1));
66    let _ = scroll.drag(
67        TouchEvent::new(Point::new(8, 32), TouchPhase::Move, 2),
68        420,
69        160,
70    );
71    let _ = scroll.end_drag(
72        TouchEvent::new(Point::new(8, 32), TouchPhase::End, 3),
73        420,
74        160,
75    );
76    let _ = scroll.tick(16, 420, 160);
77    let _ = scroll.scroll_bar(viewport, 420);
78
79    let mut list = ListView::new(DemoDataSource, DemoDelegate);
80    let _ = list.handle_touch(
81        TouchEvent::new(Point::new(24, 24), TouchPhase::Start, 10),
82        viewport,
83    );
84    let _ = list.handle_touch(
85        TouchEvent::new(Point::new(24, 60), TouchPhase::Move, 11),
86        viewport,
87    );
88    let _ = list.handle_touch(
89        TouchEvent::new(Point::new(24, 60), TouchPhase::End, 12),
90        viewport,
91    );
92    list.draw(
93        &mut canvas,
94        viewport,
95        &ViewEnvironment {
96            theme: &support::theme(),
97            i18n: &support::i18n(),
98        },
99    );
100}
examples/containers.rs (line 37)
25fn main() {
26    let bounds = Rectangle::new(Point::zero(), Size::new(320, 240));
27    let split = SplitView::new(SplitAxis::Horizontal, 620, 12);
28    let _layout = split.layout(bounds);
29
30    let mut stack = StackView::<Screen, _, 4>::new(Screen::Devices, |screen| match screen {
31        Screen::Devices => Localized::new("screen.devices", "Devices"),
32        Screen::DeviceDetail => Localized::new("screen.detail", "Device"),
33    });
34    let _ = stack.push_view(Screen::DeviceDetail);
35    let _ = stack.motion(bounds);
36    let _ = stack.handle_touch(
37        TouchEvent::new(Point::new(12, 12), TouchPhase::Start, 1),
38        bounds,
39    );
40
41    let tabs = [
42        TabSpec {
43            key: TabId::Home,
44            icon: "H",
45            title: Localized::new("tab.home", "Home"),
46        },
47        TabSpec {
48            key: TabId::Logs,
49            icon: "L",
50            title: Localized::new("tab.logs", "Logs"),
51        },
52        TabSpec {
53            key: TabId::Settings,
54            icon: "S",
55            title: Localized::new("tab.settings", "Settings"),
56        },
57    ];
58    let mut tab_view = TabView::new(tabs, 0);
59    let _ = tab_view.content_frame(bounds, &support::theme());
60    let _ = tab_view.handle_touch(
61        TouchEvent::new(Point::new(200, 220), TouchPhase::End, 2),
62        bounds,
63        &support::theme(),
64    );
65}
examples/buttons.rs (line 48)
11fn main() {
12    let mut canvas = support::NullCanvas::new(Size::new(320, 240));
13    let theme = support::theme();
14    let i18n = support::i18n();
15
16    let mut primary = Button::new(
17        Rectangle::new(Point::new(16, 16), Size::new(132, 56)),
18        ButtonSpec {
19            key: 1_u8,
20            icon: Some("+"),
21            label: Localized::new("button.add", "Add device"),
22            kind: ButtonKind::Primary,
23        },
24    );
25    let secondary = Button::new(
26        Rectangle::new(Point::new(16, 84), Size::new(132, 48)),
27        ButtonSpec {
28            key: 2_u8,
29            icon: None,
30            label: Localized::new("button.more", "More"),
31            kind: ButtonKind::Secondary,
32        },
33    );
34    let destructive = Button::new(
35        Rectangle::new(Point::new(16, 144), Size::new(132, 48)),
36        ButtonSpec {
37            key: 3_u8,
38            icon: None,
39            label: Localized::new("button.delete", "Delete"),
40            kind: ButtonKind::Destructive,
41        },
42    );
43
44    primary.draw(&mut canvas, &theme, &i18n);
45    secondary.draw(&mut canvas, &theme, &i18n);
46    destructive.draw(&mut canvas, &theme, &i18n);
47
48    let _ = primary.handle_touch(TouchEvent::new(Point::new(24, 24), TouchPhase::Start, 1));
49    let response = primary.handle_touch(TouchEvent::new(Point::new(24, 24), TouchPhase::End, 2));
50    let _pressed = response.action == Some(1);
51
52    let _ = Rgb565::BLACK;
53}
Source

pub fn is_release(self) -> bool

Returns true for touch release events.

Source

pub fn is_active(self) -> bool

Returns true while the touch is active.

Source

pub fn within(self, frame: Rectangle) -> bool

Returns true when the point lies within frame.

Examples found in repository?
src/tabs.rs (line 101)
100    fn hit_test(&self, touch: TouchEvent, bounds: Rectangle, theme: &FsTheme) -> Option<usize> {
101        if !touch.within(tab_bar_frame(bounds, theme)) {
102            return None;
103        }
104
105        let width = bounds.size.width as i32 / N as i32;
106        let relative_x = touch.point.x - bounds.top_left.x;
107        let index = (relative_x / width.max(1)) as usize;
108        Some(index.min(N.saturating_sub(1)))
109    }
More examples
Hide additional examples
src/button/mod.rs (line 158)
156    fn start_touch(&mut self, touch: TouchEvent) -> ButtonTouchResponse<K> {
157        let was_highlighted = self.highlighted;
158        if touch.within(self.frame) {
159            self.touch_active = true;
160            self.highlighted = true;
161            return ButtonTouchResponse {
162                action: None,
163                captured: true,
164                redraw: !was_highlighted,
165            };
166        }
167
168        self.clear_touch_state();
169        ButtonTouchResponse {
170            action: None,
171            captured: false,
172            redraw: was_highlighted,
173        }
174    }
175
176    fn move_touch(&mut self, touch: TouchEvent) -> ButtonTouchResponse<K> {
177        if !self.touch_active {
178            return ButtonTouchResponse {
179                action: None,
180                captured: false,
181                redraw: false,
182            };
183        }
184
185        let highlighted = touch.within(self.frame);
186        let redraw = highlighted != self.highlighted;
187        self.highlighted = highlighted;
188        ButtonTouchResponse {
189            action: None,
190            captured: true,
191            redraw,
192        }
193    }
194
195    fn finish_touch(&mut self, touch: TouchEvent) -> ButtonTouchResponse<K> {
196        if !self.touch_active {
197            return ButtonTouchResponse {
198                action: None,
199                captured: false,
200                redraw: false,
201            };
202        }
203
204        let action = (self.highlighted && touch.within(self.frame)).then_some(self.spec.key);
205        let redraw = self.highlighted;
206        self.clear_touch_state();
207        ButtonTouchResponse {
208            action,
209            captured: true,
210            redraw,
211        }
212    }
src/button_touch.rs (line 61)
52    pub fn handle_touch<'a>(
53        &mut self,
54        touch: TouchEvent,
55        buttons: &[Button<'a, K>],
56    ) -> ButtonTouchResponse<K> {
57        let was_active = self.active;
58        match touch.phase {
59            TouchPhase::Start => {
60                self.active = buttons.iter().find_map(|button| {
61                    touch.within(button.frame).then_some(ActiveButton {
62                        key: button.spec.key,
63                        frame: button.frame,
64                        highlighted: true,
65                    })
66                });
67                ButtonTouchResponse {
68                    action: None,
69                    captured: self.active.is_some(),
70                    redraw: was_active != self.active,
71                }
72            }
73            TouchPhase::Move => self.move_touch(touch),
74            TouchPhase::End => self.finish_touch(touch),
75            TouchPhase::Cancel => self.cancel_touch(),
76        }
77    }
78
79    fn move_touch(&mut self, touch: TouchEvent) -> ButtonTouchResponse<K> {
80        let Some(mut active) = self.active else {
81            return ButtonTouchResponse {
82                action: None,
83                captured: false,
84                redraw: false,
85            };
86        };
87        let highlighted = touch.within(active.frame);
88        let redraw = highlighted != active.highlighted;
89        active.highlighted = highlighted;
90        self.active = Some(active);
91        ButtonTouchResponse {
92            action: None,
93            captured: true,
94            redraw,
95        }
96    }
97
98    fn finish_touch(&mut self, touch: TouchEvent) -> ButtonTouchResponse<K> {
99        let Some(active) = self.active.take() else {
100            return ButtonTouchResponse {
101                action: None,
102                captured: false,
103                redraw: false,
104            };
105        };
106        ButtonTouchResponse {
107            action: (active.highlighted && touch.within(active.frame)).then_some(active.key),
108            captured: true,
109            redraw: active.highlighted,
110        }
111    }
src/list_view/interaction.rs (line 20)
12    pub fn handle_touch<'text>(
13        &mut self,
14        touch: TouchEvent,
15        viewport: Rectangle,
16    ) -> ListEvent<Delegate::Message>
17    where
18        Delegate: ListDelegate<'text, DataSource::ItemId>,
19    {
20        if !touch.within(viewport) && !self.scroll_view.is_dragging() {
21            return ListEvent::none();
22        }
23
24        let local_touch = offset_touch(touch, viewport.top_left);
25        let touched_index = self.item_index_at_point(touch.point, viewport);
26        let was_dragging = self.scroll_view.is_dragging();
27        let previous_highlight = self.highlighted_index;
28        let previous_selection = self.selected_index;
29        let mut activity = ListActivity::None;
30        let mut message = None;
31
32        let scrolled = match touch.phase {
33            TouchPhase::Start => {
34                self.touch_started_inside = touch.within(viewport);
35                self.tap_candidate = self.touch_started_inside;
36                self.scroll_view.begin_drag(local_touch);
37                message = message.or(
38                    self.set_highlighted_index(touched_index.filter(|_| self.touch_started_inside))
39                );
40                false
41            }
42            TouchPhase::Move => {
43                let changed =
44                    self.scroll_view
45                        .drag(local_touch, self.content_height(), viewport.size.height);
46                if changed || self.scroll_view.is_scrolling() {
47                    self.tap_candidate = false;
48                    message = message.or(self.set_highlighted_index(None));
49                } else {
50                    let next_highlight = if self.touch_started_inside && touch.within(viewport) {
51                        touched_index
52                    } else {
53                        None
54                    };
55                    message = message.or(self.set_highlighted_index(next_highlight));
56                }
57                changed
58            }
59            TouchPhase::End | TouchPhase::Cancel => {
60                let changed = self.scroll_view.end_drag(
61                    local_touch,
62                    self.content_height(),
63                    viewport.size.height,
64                );
65
66                if matches!(touch.phase, TouchPhase::End)
67                    && self.touch_started_inside
68                    && self.tap_candidate
69                    && touch.within(viewport)
70                {
71                    if let Some(index) = touched_index {
72                        if self.allows_selection {
73                            self.selected_index = Some(index);
74                        }
75                        if let Some(selection) = self.selection_for_index(index) {
76                            message = message.or(self.delegate.did_select_item(selection));
77                        }
78                    }
79                }
80
81                message = message.or(self.set_highlighted_index(None));
82                self.touch_started_inside = false;
83                self.tap_candidate = false;
84                changed
85            }
86        };
87
88        let visual_state_changed = previous_highlight != self.highlighted_index
89            || previous_selection != self.selected_index;
90        let motion_active = scrolled || self.scroll_view.is_scrolling();
91
92        if motion_active {
93            activity = ListActivity::Motion;
94        } else if visual_state_changed {
95            activity = ListActivity::Interactive;
96        }
97
98        ListEvent {
99            redraw: match activity {
100                ListActivity::None => ViewRedraw::None,
101                ListActivity::Interactive | ListActivity::Motion => ViewRedraw::Dirty(viewport),
102            },
103            captured: was_dragging || touch.within(viewport) || self.touch_started_inside,
104            message,
105            activity,
106        }
107    }

Trait Implementations§

Source§

impl Clone for TouchEvent

Source§

fn clone(&self) -> TouchEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TouchEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for TouchEvent

Source§

fn eq(&self, other: &TouchEvent) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for TouchEvent

Source§

impl Eq for TouchEvent

Source§

impl StructuralPartialEq for TouchEvent

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.