Skip to main content

runtime_shell/
runtime_shell.rs

1#[path = "support/mod.rs"]
2mod support;
3
4use core::convert::Infallible;
5
6use embedded_graphics::{
7    Drawable,
8    draw_target::DrawTarget,
9    pixelcolor::Rgb565,
10    prelude::{Point, Primitive},
11    primitives::PrimitiveStyle,
12};
13use faststep::{
14    ChildView, FsTheme, I18n, TouchEvent, TouchPhase, UiRuntimeDriver, UiRuntimePresenter,
15    UiSystem, UiView, ViewEnvironment, ViewEvent, ViewKind, ViewRedraw, ViewRegistration,
16    run_ui_system,
17};
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20enum RootId {
21    Surface,
22}
23
24struct RootView;
25
26impl UiView<'static, RootId, (), 1> for RootView {
27    fn configure(&mut self, registration: &mut ViewRegistration<'static, RootId, 1>) {
28        let _ = registration.add_child(
29            ChildView::new(RootId::Surface, registration.frame()).with_kind(ViewKind::Custom),
30        );
31    }
32
33    fn handle_touch(
34        &mut self,
35        _touch: TouchEvent,
36        _registration: &ViewRegistration<'static, RootId, 1>,
37        _env: &ViewEnvironment<'_, 'static>,
38    ) -> ViewEvent<()> {
39        ViewEvent::redraw(ViewRedraw::Full)
40    }
41
42    fn draw<D>(
43        &self,
44        display: &mut D,
45        registration: &ViewRegistration<'static, RootId, 1>,
46        _env: &ViewEnvironment<'_, 'static>,
47    ) where
48        D: DrawTarget<Color = Rgb565>,
49    {
50        registration
51            .frame()
52            .into_styled(PrimitiveStyle::with_fill(Rgb565::new(31, 63, 31)))
53            .draw(display)
54            .ok();
55    }
56}
57
58struct NoopDriver;
59
60impl UiRuntimeDriver for NoopDriver {
61    type Error = Infallible;
62
63    fn idle_poll_ms(&self) -> u32 {
64        16
65    }
66    fn active_poll_ms(&self) -> u32 {
67        8
68    }
69    fn needs_active_poll(&self) -> bool {
70        false
71    }
72    fn delay_ms(&mut self, _delay_ms: u32) {}
73    fn now_ms(&self) -> u32 {
74        0
75    }
76
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    }
84}
85
86struct ImmediatePresenter;
87
88impl UiRuntimePresenter<'static, support::NullDisplay, RootView, RootId, (), 1>
89    for ImmediatePresenter
90{
91    type Pending = ViewRedraw;
92    type Error = Infallible;
93
94    fn idle_pending(&self) -> Self::Pending {
95        ViewRedraw::None
96    }
97
98    fn merge_pending(&self, current: Self::Pending, next: Self::Pending) -> Self::Pending {
99        current.merge(next)
100    }
101
102    fn pending_for_event(&mut self, event: ViewEvent<()>) -> Self::Pending {
103        event.redraw
104    }
105
106    fn should_present(
107        &mut self,
108        pending: Self::Pending,
109        _since_present_ms: u32,
110        _system: &UiSystem<'static, support::NullDisplay, RootView, RootId, (), 1>,
111    ) -> bool {
112        !matches!(pending, ViewRedraw::None)
113    }
114
115    fn present(
116        &mut self,
117        pending: Self::Pending,
118        system: &mut UiSystem<'static, support::NullDisplay, RootView, RootId, (), 1>,
119    ) -> Result<(), Self::Error> {
120        let _ = system.draw_redraw(pending);
121        Ok(())
122    }
123}
124
125fn main() {
126    let display = support::NullDisplay::new(support::bounds(320, 240));
127    let root = RootView;
128    let theme: FsTheme = support::theme();
129    let i18n: I18n<'static> = support::i18n();
130    let driver = NoopDriver;
131    let presenter = ImmediatePresenter;
132
133    if false {
134        let _ = run_ui_system(display, root, theme, i18n, driver, presenter);
135    }
136}