blob: 83a1d5a0c0a97db115dca71bb49a357e0cd02e66 [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use fidl_fuchsia_ui_pointerinjector as pointerinjector;
use fuchsia_zircon::Time;
/// State tracking for touch events. Touch events follow a cycle of states:
/// Add -> Change -> Remove -> Add -> ...
///
/// This struct generates these states repeatedly, at random coordinates on the display.
/// Note that when a touch event hits an object on the scene graph, a pointer event is sent to the
/// corresponding scenic client.
pub struct PointerState {
phase: pointerinjector::EventPhase,
pointer_id: u32,
x: u16,
y: u16,
display_width: u16,
display_height: u16,
}
impl PointerState {
pub fn new(display_width: u16, display_height: u16) -> Self {
Self {
// Initial phase is "Remove", so that the first call to next_event() yields "Add".
phase: pointerinjector::EventPhase::Remove,
pointer_id: 1,
x: 0,
y: 0,
display_width,
display_height,
}
}
/// Transition from one phase to the next.
fn next_phase(&mut self) {
self.phase = match self.phase {
pointerinjector::EventPhase::Add => pointerinjector::EventPhase::Change,
pointerinjector::EventPhase::Change => pointerinjector::EventPhase::Remove,
pointerinjector::EventPhase::Remove => pointerinjector::EventPhase::Add,
_ => unreachable!("Unsupported event phase"),
}
}
/// Generate a pointer event for the current state.
/// The pointer coordinates move in a diagonal pattern across the display.
pub fn next_event(&mut self) -> pointerinjector::Event {
self.next_phase();
let pointer_sample = pointerinjector::PointerSample {
pointer_id: Some(self.pointer_id),
phase: Some(self.phase),
position_in_viewport: Some([self.x as f32, self.y as f32]),
..Default::default()
};
// Update coordinates.
self.y = (self.y + (self.x == self.display_width) as u16) % (self.display_height + 1);
self.x = (self.x + 1) % (self.display_width + 1);
pointerinjector::Event {
timestamp: Some(Time::get_monotonic().into_nanos()),
data: Some(pointerinjector::Data::PointerSample(pointer_sample)),
..Default::default()
}
}
}