1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-23 14:58:09 +00:00

refactor(core/rust/ui): expose page count to python

[no changelog]
This commit is contained in:
Martin Milata 2022-05-23 19:52:12 +02:00
parent ee1497b87e
commit dd9a7d30e5
9 changed files with 57 additions and 2 deletions

View File

@ -30,6 +30,7 @@ static void _librust_qstrs(void) {
MP_QSTR_paint;
MP_QSTR_trace;
MP_QSTR_bounds;
MP_QSTR_page_count;
MP_QSTR_title;
MP_QSTR_action;

View File

@ -314,6 +314,7 @@ pub struct EventCtx {
place_requested: bool,
paint_requested: bool,
anim_frame_scheduled: bool,
page_count: Option<usize>,
}
impl EventCtx {
@ -338,6 +339,7 @@ impl EventCtx {
paint_requested: false, /* We also need to paint, but this is supplemented by
* `Child::marked_for_paint` being true. */
anim_frame_scheduled: false,
page_count: None,
}
}
@ -376,6 +378,16 @@ impl EventCtx {
}
}
pub fn set_page_count(&mut self, count: usize) {
#[cfg(feature = "ui_debug")]
assert!(self.page_count.is_none());
self.page_count = Some(count);
}
pub fn page_count(&self) -> Option<usize> {
self.page_count
}
pub fn pop_timer(&mut self) -> Option<(TimerToken, Duration)> {
self.timers.pop()
}
@ -384,6 +396,7 @@ impl EventCtx {
self.place_requested = false;
self.paint_requested = false;
self.anim_frame_scheduled = false;
self.page_count = None;
}
fn register_timer(&mut self, token: TimerToken, deadline: Duration) {

View File

@ -112,6 +112,7 @@ struct LayoutObjInner {
root: Gc<dyn ObjComponent>,
event_ctx: EventCtx,
timer_fn: Obj,
page_count: u16,
}
impl LayoutObj {
@ -130,6 +131,7 @@ impl LayoutObj {
root,
event_ctx: EventCtx::new(),
timer_fn: Obj::const_none(),
page_count: 1,
}),
})
}
@ -174,6 +176,10 @@ impl LayoutObj {
}
}
if let Some(count) = inner.event_ctx.page_count() {
inner.page_count = count as u16;
}
Ok(msg)
}
@ -247,6 +253,10 @@ impl LayoutObj {
.trace(&mut CallbackTracer(callback));
}
fn obj_page_count(&self) -> Obj {
self.inner.borrow().page_count.into()
}
#[cfg(feature = "ui_debug")]
fn obj_bounds(&self) {
use crate::ui::display;
@ -275,6 +285,7 @@ impl LayoutObj {
Qstr::MP_QSTR_paint => obj_fn_1!(ui_layout_paint).as_obj(),
Qstr::MP_QSTR_trace => obj_fn_2!(ui_layout_trace).as_obj(),
Qstr::MP_QSTR_bounds => obj_fn_1!(ui_layout_bounds).as_obj(),
Qstr::MP_QSTR_page_count => obj_fn_1!(ui_layout_page_count).as_obj(),
}),
};
&TYPE
@ -411,6 +422,14 @@ extern "C" fn ui_layout_paint(this: Obj) -> Obj {
unsafe { util::try_or_raise(block) }
}
extern "C" fn ui_layout_page_count(this: Obj) -> Obj {
let block = || {
let this: Gc<LayoutObj> = this.try_into()?;
Ok(this.obj_page_count())
};
unsafe { util::try_or_raise(block) }
}
#[cfg(feature = "ui_debug")]
#[no_mangle]
pub extern "C" fn ui_debug_layout_type() -> &'static Type {

View File

@ -67,6 +67,7 @@ where
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
ctx.set_page_count(self.scrollbar.page_count);
if self.scrollbar.has_previous_page() {
if let Some(ButtonMsg::Clicked) = self.prev.event(ctx, event) {
// Scroll up.

View File

@ -67,6 +67,7 @@ where
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
ctx.set_page_count(self.scrollbar.page_count);
if self.scrollbar.has_previous_page() {
if let Some(ButtonMsg::Clicked) = self.prev.event(ctx, event) {
// Scroll up.

View File

@ -99,6 +99,7 @@ where
}
fn event(&mut self, ctx: &mut EventCtx, event: Event) -> Option<Self::Msg> {
ctx.set_page_count(self.scrollbar.page_count);
if let Some(swipe) = self.swipe.event(ctx, event) {
match swipe {
SwipeDirection::Up => {
@ -339,6 +340,7 @@ mod tests {
TouchEvent::TouchMove(p)
};
component.event(&mut ctx, Event::Touch(ev));
ctx.clear();
first = false;
}
}

View File

@ -577,11 +577,19 @@ class spawn(Syscall):
class Timer(Syscall):
def __init__(self) -> None:
self.task: Task | None = None
# Event::Attach is evaluated before task is set. Use this list to
# buffer timers until task is set.
self.before_task: list[tuple[int, Any]] = []
def handle(self, task: Task) -> None:
self.task = task
for deadline, value in self.before_task:
schedule(self.task, value, deadline)
self.before_task.clear()
def schedule(self, deadline: int, value: Any) -> None:
deadline = utime.ticks_add(utime.ticks_ms(), deadline)
if self.task is not None:
schedule(self.task, value, deadline)
else:
self.before_task.append((deadline, value))

View File

@ -16,11 +16,15 @@ async def button_request(
ctx: wire.GenericContext,
br_type: str,
code: ButtonRequestType = ButtonRequestType.Other,
pages: int | None = None,
) -> None:
if __debug__:
log.debug(__name__, "ButtonRequest.type=%s", br_type)
workflow.close_others()
await ctx.call(ButtonRequest(code=code), ButtonAck)
if pages is not None:
await ctx.call(ButtonRequest(code=code, pages=pages), ButtonAck)
else:
await ctx.call(ButtonRequest(code=code), ButtonAck)
async def interact(
@ -34,6 +38,9 @@ async def interact(
assert isinstance(layout, Paginated)
return await layout.interact(ctx, code=br_code)
elif hasattr(layout, "page_count") and layout.page_count() > 1: # type: ignore [Cannot access member "page_count" for type "LayoutType"]
await button_request(ctx, br_type, br_code, pages=layout.page_count()) # type: ignore [Cannot access member "page_count" for type "LayoutType"]
return await ctx.wait(layout)
else:
await button_request(ctx, br_type, br_code)
return await ctx.wait(layout)

View File

@ -19,6 +19,7 @@ class _RustLayout(ui.Layout):
def __init__(self, layout: Any):
self.layout = layout
self.timer = loop.Timer()
self.layout.attach_timer_fn(self.set_timer)
def set_timer(self, token: int, deadline: int) -> None:
self.timer.schedule(deadline, token)
@ -71,7 +72,6 @@ class _RustLayout(ui.Layout):
def handle_input_and_rendering(self) -> loop.Task: # type: ignore [awaitable-is-generator]
touch = loop.wait(io.TOUCH)
self._before_render()
self.layout.attach_timer_fn(self.set_timer)
self.layout.paint()
# self.layout.bounds()
while True:
@ -95,6 +95,9 @@ class _RustLayout(ui.Layout):
if msg is not None:
raise ui.Result(msg)
def page_count(self) -> int:
return self.layout.page_count()
async def confirm_action(
ctx: wire.GenericContext,