mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
feat(core/rust): add support for T1 UI
[no changelog]
This commit is contained in:
parent
3c49ef2f62
commit
4d60c10330
@ -701,7 +701,10 @@ def cargo_build():
|
||||
profile = '--release'
|
||||
else:
|
||||
profile = ''
|
||||
features = []
|
||||
if TREZOR_MODEL == "1":
|
||||
features = ["model_t1"]
|
||||
else:
|
||||
features = ["model_tt"]
|
||||
if BITCOIN_ONLY == "1":
|
||||
features.append("bitcoin_only")
|
||||
if NEW_UI:
|
||||
@ -709,7 +712,7 @@ def cargo_build():
|
||||
if PYOPT == "0":
|
||||
features.append("ui_debug")
|
||||
|
||||
return f'cd embed/rust; cargo build {profile} --target={RUST_TARGET} --target-dir=../../build/firmware/rust --features "{" ".join(features)}"'
|
||||
return f'cd embed/rust; cargo build {profile} --target={RUST_TARGET} --target-dir=../../build/firmware/rust --no-default-features --features "{" ".join(features)}"'
|
||||
|
||||
rust = env.Command(
|
||||
target=RUST_LIBPATH,
|
||||
|
@ -653,7 +653,10 @@ def cargo_build():
|
||||
profile = '--release'
|
||||
else:
|
||||
profile = ''
|
||||
features = []
|
||||
if TREZOR_MODEL == "1":
|
||||
features = ["model_t1"]
|
||||
else:
|
||||
features = ["model_tt"]
|
||||
if BITCOIN_ONLY == "1":
|
||||
features.append("bitcoin_only")
|
||||
if PYOPT == "0":
|
||||
@ -662,7 +665,7 @@ def cargo_build():
|
||||
elif NEW_UI:
|
||||
features.append("ui")
|
||||
|
||||
return f'cd embed/rust; cargo build {profile} --target-dir=../../build/unix/rust --features "{" ".join(features)}"'
|
||||
return f'cd embed/rust; cargo build {profile} --target-dir=../../build/unix/rust --no-default-features --features "{" ".join(features)}"'
|
||||
|
||||
rust = env.Command(
|
||||
target=RUST_LIBPATH,
|
||||
|
@ -7,7 +7,10 @@ resolver = "2"
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
default = ["model_tt"]
|
||||
bitcoin_only = []
|
||||
model_tt = []
|
||||
model_t1 = []
|
||||
ui = []
|
||||
ui_debug = []
|
||||
test = ["cc", "glob"]
|
||||
|
@ -12,9 +12,7 @@ static void _librust_qstrs(void) {
|
||||
// layout
|
||||
MP_QSTR_Layout;
|
||||
MP_QSTR_set_timer_fn;
|
||||
MP_QSTR_touch_start;
|
||||
MP_QSTR_touch_move;
|
||||
MP_QSTR_touch_end;
|
||||
MP_QSTR_hid_event;
|
||||
MP_QSTR_timer;
|
||||
MP_QSTR_paint;
|
||||
MP_QSTR_trace;
|
||||
|
@ -164,3 +164,10 @@ fn buffer_as_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(ptr, len) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ui_debug")]
|
||||
impl crate::trace::Trace for Buffer {
|
||||
fn trace(&self, t: &mut dyn crate::trace::Tracer) {
|
||||
self.as_ref().trace(t)
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ impl Map {
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
pub const EMPTY: Map = Self::from_fixed_static::<0>(&[]);
|
||||
}
|
||||
|
||||
impl Map {
|
||||
|
@ -44,8 +44,7 @@ extern "C" {
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
const WIDTH: i32 = 240;
|
||||
const HEIGHT: i32 = 240;
|
||||
use crate::ui::component::model::constants::{HEIGHT, WIDTH};
|
||||
|
||||
pub struct ToifInfo {
|
||||
pub width: u16,
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod common;
|
||||
#[cfg(feature = "ui")]
|
||||
pub mod display;
|
||||
pub mod random;
|
||||
|
@ -2,7 +2,7 @@ use core::{mem, time::Duration};
|
||||
|
||||
use heapless::Vec;
|
||||
|
||||
use crate::ui::geometry::Point;
|
||||
use crate::ui::{model_t1::event::ButtonEvent, model_tt::event::TouchEvent};
|
||||
|
||||
/// Type used by components that do not return any messages.
|
||||
///
|
||||
@ -81,9 +81,7 @@ where
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Event {
|
||||
TouchStart(Point),
|
||||
TouchMove(Point),
|
||||
TouchEnd(Point),
|
||||
HumanInput(HidEvent),
|
||||
Timer(TimerToken),
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
mod base;
|
||||
pub mod model_t1;
|
||||
pub mod model_tt;
|
||||
pub mod empty;
|
||||
pub mod label;
|
||||
pub mod text;
|
||||
|
||||
pub use base::{Child, Component, Event, EventCtx, Never, TimerToken};
|
||||
pub use empty::Empty;
|
||||
pub use label::{Label, LabelStyle};
|
||||
pub use text::{LineBreaking, PageBreaking, Text, TextLayout};
|
||||
|
@ -1 +1,3 @@
|
||||
pub mod constants;
|
||||
pub mod theme;
|
||||
|
||||
|
@ -12,7 +12,7 @@ use crate::ui::{
|
||||
geometry::{Offset, Point, Rect},
|
||||
};
|
||||
|
||||
use super::theme;
|
||||
use super::model::theme;
|
||||
|
||||
pub const MAX_ARGUMENTS: usize = 6;
|
||||
|
@ -1,6 +1,9 @@
|
||||
use crate::trezorhal::display;
|
||||
|
||||
use super::geometry::{Offset, Point, Rect};
|
||||
use super::{
|
||||
component::model::constants,
|
||||
geometry::{Offset, Point, Rect},
|
||||
};
|
||||
|
||||
pub fn width() -> i32 {
|
||||
display::width()
|
||||
@ -73,13 +76,11 @@ pub fn text_width(text: &[u8], font: Font) -> i32 {
|
||||
}
|
||||
|
||||
pub fn text_height() -> i32 {
|
||||
const TEXT_HEIGHT: i32 = 16;
|
||||
TEXT_HEIGHT
|
||||
constants::TEXT_HEIGHT
|
||||
}
|
||||
|
||||
pub fn line_height() -> i32 {
|
||||
const LINE_HEIGHT: i32 = 26;
|
||||
LINE_HEIGHT
|
||||
constants::LINE_HEIGHT
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
|
@ -1,2 +1 @@
|
||||
mod example;
|
||||
mod obj;
|
||||
pub mod obj;
|
||||
|
@ -13,10 +13,7 @@ use crate::{
|
||||
qstr::Qstr,
|
||||
typ::Type,
|
||||
},
|
||||
ui::{
|
||||
component::{Child, Component, Event, EventCtx, Never, TimerToken},
|
||||
geometry::Point,
|
||||
},
|
||||
ui::component::{model::HidEvent, Child, Component, Event, EventCtx, Never, TimerToken},
|
||||
util,
|
||||
};
|
||||
|
||||
@ -207,9 +204,7 @@ impl LayoutObj {
|
||||
name: Qstr::MP_QSTR_Layout,
|
||||
locals: &obj_dict!(obj_map! {
|
||||
Qstr::MP_QSTR_set_timer_fn => obj_fn_2!(ui_layout_set_timer_fn).as_obj(),
|
||||
Qstr::MP_QSTR_touch_start => obj_fn_3!(ui_layout_touch_start).as_obj(),
|
||||
Qstr::MP_QSTR_touch_move => obj_fn_3!(ui_layout_touch_move).as_obj(),
|
||||
Qstr::MP_QSTR_touch_end => obj_fn_3!(ui_layout_touch_end).as_obj(),
|
||||
Qstr::MP_QSTR_hid_event => obj_fn_var!(4, 4, ui_layout_hid_event).as_obj(),
|
||||
Qstr::MP_QSTR_timer => obj_fn_2!(ui_layout_timer).as_obj(),
|
||||
Qstr::MP_QSTR_paint => obj_fn_1!(ui_layout_paint).as_obj(),
|
||||
Qstr::MP_QSTR_trace => obj_fn_2!(ui_layout_trace).as_obj(),
|
||||
@ -286,34 +281,21 @@ extern "C" fn ui_layout_set_timer_fn(this: Obj, timer_fn: Obj) -> Obj {
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn ui_layout_touch_start(this: Obj, x: Obj, y: Obj) -> Obj {
|
||||
let block = || {
|
||||
let this: Gc<LayoutObj> = this.try_into()?;
|
||||
let event = Event::TouchStart(Point::new(x.try_into()?, y.try_into()?));
|
||||
let msg = this.obj_event(event)?;
|
||||
extern "C" fn ui_layout_hid_event(n_args: usize, args: *const Obj) -> Obj {
|
||||
let block = |args: &[Obj], _kwargs: &Map| {
|
||||
if args.len() != 4 {
|
||||
return Err(Error::TypeError);
|
||||
}
|
||||
let this: Gc<LayoutObj> = args[0].try_into()?;
|
||||
let event = HidEvent::new(
|
||||
args[1].try_into()?,
|
||||
args[2].try_into()?,
|
||||
args[3].try_into()?,
|
||||
)?;
|
||||
let msg = this.obj_event(Event::HumanInput(event))?;
|
||||
Ok(msg)
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn ui_layout_touch_move(this: Obj, x: Obj, y: Obj) -> Obj {
|
||||
let block = || {
|
||||
let this: Gc<LayoutObj> = this.try_into()?;
|
||||
let event = Event::TouchMove(Point::new(x.try_into()?, y.try_into()?));
|
||||
let msg = this.obj_event(event)?;
|
||||
Ok(msg)
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
}
|
||||
|
||||
extern "C" fn ui_layout_touch_end(this: Obj, x: Obj, y: Obj) -> Obj {
|
||||
let block = || {
|
||||
let this: Gc<LayoutObj> = this.try_into()?;
|
||||
let event = Event::TouchEnd(Point::new(x.try_into()?, y.try_into()?));
|
||||
let msg = this.obj_event(event)?;
|
||||
Ok(msg)
|
||||
};
|
||||
unsafe { util::try_or_raise(block) }
|
||||
unsafe { util::try_with_args_and_kwargs(n_args, args, &Map::EMPTY, block) }
|
||||
}
|
||||
|
||||
extern "C" fn ui_layout_timer(this: Obj, token: Obj) -> Obj {
|
||||
|
@ -1,3 +1,4 @@
|
||||
#[allow(unused_macros)] // T1 doesn't use icons (yet)
|
||||
macro_rules! include_res {
|
||||
($filename:expr) => {
|
||||
include_bytes!(concat!(
|
||||
|
@ -5,3 +5,6 @@ pub mod component;
|
||||
pub mod display;
|
||||
pub mod geometry;
|
||||
pub mod layout;
|
||||
|
||||
pub mod model_t1;
|
||||
pub mod model_tt;
|
||||
|
4
core/embed/rust/src/ui/model_t1/constant.rs
Normal file
4
core/embed/rust/src/ui/model_t1/constant.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub const WIDTH: i32 = 128;
|
||||
pub const HEIGHT: i32 = 64;
|
||||
pub const TEXT_HEIGHT: i32 = 8;
|
||||
pub const LINE_HEIGHT: i32 = 9;
|
29
core/embed/rust/src/ui/model_t1/event.rs
Normal file
29
core/embed/rust/src/ui/model_t1/event.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::error;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum T1Button {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ButtonEvent {
|
||||
ButtonPressed(T1Button),
|
||||
ButtonReleased(T1Button),
|
||||
}
|
||||
|
||||
impl ButtonEvent {
|
||||
pub fn new(event: u32, button: u32, _unused: u32) -> Result<Self, error::Error> {
|
||||
let button = match button {
|
||||
0 => T1Button::Left,
|
||||
1 => T1Button::Right,
|
||||
_ => return Err(error::Error::OutOfRange),
|
||||
};
|
||||
let result = match event {
|
||||
1 => Self::ButtonPressed(button),
|
||||
2 => Self::ButtonReleased(button),
|
||||
_ => return Err(error::Error::OutOfRange),
|
||||
};
|
||||
Ok(result)
|
||||
}
|
||||
}
|
3
core/embed/rust/src/ui/model_t1/mod.rs
Normal file
3
core/embed/rust/src/ui/model_t1/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod constant;
|
||||
pub mod event;
|
||||
pub mod theme;
|
61
core/embed/rust/src/ui/model_t1/theme.rs
Normal file
61
core/embed/rust/src/ui/model_t1/theme.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use crate::ui::display::{Color, Font};
|
||||
|
||||
use super::component::{ButtonStyle, ButtonStyleSheet};
|
||||
|
||||
// Font constants.
|
||||
pub const FONT_NORMAL: Font = Font::new(-1);
|
||||
pub const FONT_BOLD: Font = Font::new(-2);
|
||||
pub const FONT_MONO: Font = Font::new(-3);
|
||||
|
||||
// Color palette.
|
||||
pub const WHITE: Color = Color::rgb(255, 255, 255);
|
||||
pub const BLACK: Color = Color::rgb(0, 0, 0);
|
||||
pub const GREY_LIGHT: Color = WHITE; // Word/page break characters.
|
||||
pub const FG: Color = WHITE; // Default foreground (text & icon) color.
|
||||
pub const BG: Color = BLACK; // Default background color.
|
||||
|
||||
pub fn button_default() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
text_color: BG,
|
||||
background_color: FG,
|
||||
border_horiz: true,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
text_color: FG,
|
||||
background_color: BG,
|
||||
border_horiz: true,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
text_color: FG,
|
||||
background_color: BG,
|
||||
border_horiz: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn button_cancel() -> ButtonStyleSheet {
|
||||
ButtonStyleSheet {
|
||||
normal: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
text_color: FG,
|
||||
background_color: BG,
|
||||
border_horiz: false,
|
||||
},
|
||||
active: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
text_color: BG,
|
||||
background_color: FG,
|
||||
border_horiz: false,
|
||||
},
|
||||
disabled: &ButtonStyle {
|
||||
font: FONT_BOLD,
|
||||
text_color: BG,
|
||||
background_color: FG,
|
||||
border_horiz: false,
|
||||
},
|
||||
}
|
||||
}
|
@ -3,8 +3,7 @@ use crate::ui::{
|
||||
display::{self, Color, Font},
|
||||
geometry::{Offset, Rect},
|
||||
};
|
||||
|
||||
use super::theme;
|
||||
use super::event::TouchEvent;
|
||||
|
||||
pub enum ButtonMsg {
|
||||
Clicked,
|
||||
@ -79,7 +78,7 @@ impl Component for Button {
|
||||
|
||||
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
match event {
|
||||
Event::TouchStart(pos) => {
|
||||
Event::Touch(TouchEvent::TouchStart(pos)) => {
|
||||
match self.state {
|
||||
State::Disabled => {
|
||||
// Do nothing.
|
||||
@ -92,7 +91,7 @@ impl Component for Button {
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::TouchMove(pos) => {
|
||||
Event::Touch(TouchEvent::TouchMove(pos)) => {
|
||||
match self.state {
|
||||
State::Released if self.area.contains(pos) => {
|
||||
// Touch entered our area, transform to `Pressed` state.
|
||||
@ -107,7 +106,7 @@ impl Component for Button {
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::TouchEnd(pos) => {
|
||||
Event::Touch(TouchEvent::TouchEnd(pos)) => {
|
||||
match self.state {
|
||||
State::Initial | State::Disabled => {
|
||||
// Do nothing.
|
@ -1,17 +1,13 @@
|
||||
mod button;
|
||||
mod dialog;
|
||||
mod empty;
|
||||
mod label;
|
||||
mod page;
|
||||
mod passphrase;
|
||||
mod pin;
|
||||
mod swipe;
|
||||
pub mod text;
|
||||
pub mod theme;
|
||||
|
||||
pub use button::{Button, ButtonContent, ButtonMsg, ButtonStyle, ButtonStyleSheet};
|
||||
pub use dialog::{Dialog, DialogMsg};
|
||||
pub use empty::Empty;
|
||||
pub use label::{Label, LabelStyle};
|
||||
pub use swipe::{Swipe, SwipeDirection};
|
||||
pub use text::{LineBreaking, PageBreaking, Text, TextLayout};
|
||||
|
||||
use super::event;
|
||||
use super::theme;
|
@ -3,7 +3,10 @@ use heapless::Vec;
|
||||
use crate::{
|
||||
trezorhal::random,
|
||||
ui::{
|
||||
component::{Child, Component, Event, EventCtx, Never},
|
||||
component::{
|
||||
label::{Label, LabelStyle},
|
||||
Child, Component, Event, EventCtx, Never,
|
||||
},
|
||||
display,
|
||||
geometry::{Grid, Offset, Point, Rect},
|
||||
},
|
||||
@ -11,7 +14,6 @@ use crate::{
|
||||
|
||||
use super::{
|
||||
button::{Button, ButtonContent, ButtonMsg::Clicked},
|
||||
label::{Label, LabelStyle},
|
||||
theme,
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ use crate::ui::{
|
||||
geometry::{Point, Rect},
|
||||
};
|
||||
|
||||
use super::theme;
|
||||
use super::{theme, event::TouchEvent};
|
||||
|
||||
pub enum SwipeDirection {
|
||||
Up,
|
||||
@ -86,11 +86,11 @@ impl Component for Swipe {
|
||||
|
||||
fn event(&mut self, _ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
|
||||
match (event, self.origin) {
|
||||
(Event::TouchStart(pos), _) if self.area.contains(pos) => {
|
||||
(Event::Touch(TouchEvent::TouchStart(pos)), _) if self.area.contains(pos) => {
|
||||
// Mark the starting position of this touch.
|
||||
self.origin.replace(pos);
|
||||
}
|
||||
(Event::TouchMove(pos), Some(origin)) => {
|
||||
(Event::Touch(TouchEvent::TouchMove(pos)), Some(origin)) => {
|
||||
// Consider our allowed directions and the touch distance and modify the display
|
||||
// backlight accordingly.
|
||||
let ofs = pos - origin;
|
||||
@ -107,7 +107,7 @@ impl Component for Swipe {
|
||||
}
|
||||
};
|
||||
}
|
||||
(Event::TouchEnd(pos), Some(origin)) => {
|
||||
(Event::Touch(TouchEvent::TouchEnd(pos)), Some(origin)) => {
|
||||
// Touch interaction is over, reset the position.
|
||||
self.origin.take();
|
||||
|
4
core/embed/rust/src/ui/model_tt/constant.rs
Normal file
4
core/embed/rust/src/ui/model_tt/constant.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub const WIDTH: i32 = 240;
|
||||
pub const HEIGHT: i32 = 240;
|
||||
pub const TEXT_HEIGHT: i32 = 16;
|
||||
pub const LINE_HEIGHT: i32 = 26;
|
24
core/embed/rust/src/ui/model_tt/event.rs
Normal file
24
core/embed/rust/src/ui/model_tt/event.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use core::convert::TryInto;
|
||||
|
||||
use crate::{error, ui::geometry::Point};
|
||||
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum TouchEvent {
|
||||
TouchStart(Point),
|
||||
TouchMove(Point),
|
||||
TouchEnd(Point),
|
||||
}
|
||||
|
||||
impl TouchEvent {
|
||||
pub fn new(event: u32, x: u32, y: u32) -> Result<Self, error::Error> {
|
||||
let point = Point::new(x.try_into()?, y.try_into()?);
|
||||
let result = match event {
|
||||
1 => Self::TouchStart(point),
|
||||
2 => Self::TouchMove(point),
|
||||
4 => Self::TouchEnd(point),
|
||||
_ => return Err(error::Error::OutOfRange),
|
||||
};
|
||||
Ok(result)
|
||||
}
|
||||
}
|
@ -4,16 +4,17 @@ use crate::{
|
||||
error::Error,
|
||||
micropython::{buffer::Buffer, obj::Obj},
|
||||
ui::{
|
||||
component::{
|
||||
model_tt::{theme, Button, Dialog, DialogMsg, Text},
|
||||
Child,
|
||||
},
|
||||
component::{Child, Text},
|
||||
display,
|
||||
layout::obj::LayoutObj,
|
||||
},
|
||||
util,
|
||||
};
|
||||
|
||||
use super::obj::LayoutObj;
|
||||
use super::{
|
||||
component::{Button, Dialog, DialogMsg},
|
||||
theme,
|
||||
};
|
||||
|
||||
impl<T> TryFrom<DialogMsg<T>> for Obj
|
||||
where
|
5
core/embed/rust/src/ui/model_tt/mod.rs
Normal file
5
core/embed/rust/src/ui/model_tt/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
pub mod component;
|
||||
pub mod constant;
|
||||
pub mod event;
|
||||
pub mod layout;
|
||||
pub mod theme;
|
@ -1,8 +1,10 @@
|
||||
use crate::ui::{
|
||||
component::model_tt::{ButtonStyle, ButtonStyleSheet, LabelStyle},
|
||||
component::{label::LabelStyle, text::DefaultTextTheme},
|
||||
display::{Color, Font},
|
||||
};
|
||||
|
||||
use super::component::{ButtonStyle, ButtonStyleSheet};
|
||||
|
||||
// Font constants.
|
||||
pub const FONT_NORMAL: Font = Font::new(-1);
|
||||
pub const FONT_BOLD: Font = Font::new(-2);
|
@ -456,11 +456,9 @@ if utils.MODEL == "1":
|
||||
msg = None
|
||||
if event is RENDER:
|
||||
self.layout.paint()
|
||||
elif event is io.TOUCH_START:
|
||||
msg = self.layout.touch_start(x, y)
|
||||
elif event is io.TOUCH_MOVE:
|
||||
msg = self.layout.touch_move(x, y)
|
||||
elif event is io.TOUCH_END:
|
||||
msg = self.layout.touch_end(x, y)
|
||||
elif event in (io.BUTTON_PRESSED, io.BUTTON_RELEASED):
|
||||
msg = self.layout.hid_event(event, x, 0)
|
||||
# elif event in (io.TOUCH_START, io.TOUCH_MOVE, io.TOUCH_END):
|
||||
# self.layout.hid_event(event, x, y)
|
||||
if msg is not None:
|
||||
raise Result(msg)
|
||||
|
Loading…
Reference in New Issue
Block a user