1#![no_std]
2#![feature(impl_trait_in_assoc_type)]
3
4use futures::StreamExt as _;
5use heapless::CString;
6use pin_init::stack_pin_init;
7
8use bordstein::{
9 bindings::{GColor8, GPoint, GSize, GTextAlignment, TimeUnits},
10 layers::ScrollLayer,
11 prelude::*,
12 shapes,
13};
14
15bordstein::main!(async_main);
16
17#[embassy_executor::task]
39async fn async_main(services: bordstein::PebbleServices, spawner: embassy_executor::Spawner) {
40 async_main_(services, spawner).await;
41}
42
43async fn async_main_(mut services: bordstein::PebbleServices, _spawner: embassy_executor::Spawner) {
44 bordstein::info!("Async main called!");
45
46 with_window(async |mut h| {
47 let app_messages = services.app_messages.open(1024, 512);
48 stack_pin_init!(let _app_message_listener = app_messages.listen(
49 |_d| {},
50 |_| {},
51 |_| {},
52 |_, _| {},
53 ));
54 stack_pin_init!(let _app_message_listener = app_messages.listen(
55 |_d| {},
56 |_| {},
57 |_| {},
58 |_, _| {},
59 ));
60 stack_pin_init!(let _app_message_listener = app_messages.listen_received(
61 |_d| {},
62 ));
63
64 let _ = app_messages.send(|d| d.u8(10001, 123));
65
66 h.set_background_colour(GColor8::RED);
67
68 let window_bounds = h.root_layer().bounds();
69 bordstein::info!("Window bounds: {:?}", window_bounds);
70
71 stack_pin_init!(let timer_minutes = TickService::listen(TimeUnits::MINUTE_UNIT, |time, _| {
72 bordstein::info!("minute timer tick: {:?}", time);
73 }));
74
75 {
76 stack_pin_init!(let timer_seconds = TickService::listen(TimeUnits::SECOND_UNIT, |time, _| {
77 bordstein::info!("second timer tick: {:?}", time);
78 }));
79
80 let root_layer = h.root_layer();
81 let status_bar = root_layer.new_child::<StatusBarLayer>(()).unwrap();
82
83 let remaining_space =
84 window_bounds.shrink_to_avoid(status_bar.layer().bounds(), shapes::Edge::Top, 0);
85
86 let mut child_layer = root_layer
87 .new_child::<ScrollLayer>(remaining_space)
88 .unwrap();
89
90 child_layer.set_click_config_onto_window(&mut h);
91
92 let mut num_taps: u32 = 0;
93
94 let mut accelerometer_service = services.accelerometer.enable();
95 stack_pin_init!(let tap_events = accelerometer_service.subscribe_to_tap_service(|axis, dir| {
96 num_taps += 1;
97 bordstein::info!("Tap! {}, {:?}, {}", num_taps, axis, dir);
98 }));
99
100 let mut text_layer = child_layer
101 .new_child::<TextLayer>(child_layer.layer().bounds().with_height(100))
102 .unwrap();
103 text_layer.set_text_alignment(GTextAlignment::GTextAlignmentCenter);
104
105 let mut fill_layer = child_layer
106 .new_child::<TextLayer>(child_layer.layer().bounds().translate(0, text_layer.layer().bounds().size.h))
107 .unwrap();
108
109 child_layer.set_content_size(GSize::total_bounds_of_rects([
110 text_layer.layer().frame(),
111 fill_layer.layer().frame(),
112 ]));
113 bordstein::info!("Scroll bounds: {:?}", child_layer.get_content_size());
116
117 let _guard = fill_layer.set_text(cr#"
118foo
119bar
120baz
121hello
122this
123is
124some
125text
126lorem
127ipsum
128dolor
129sit
130amet
131"#);
132
133 let mut text_content: CString<64>;
134 for i in 0..100 {
135 text_content = CString::<64>::new();
136 let _ = ufmt::uwrite!(&mut text_content, "{}", i);
137 let _guard = text_layer.set_text(&text_content);
138
139 embassy_time::Timer::after_secs(1).await;
140
141 child_layer.set_content_offset(GPoint::new(0, i * -10), true);
150
151 bordstein::info!("Scroll offset: {:?}", child_layer.get_content_offset());
152 }
153
154 bordstein::info!("Child bounds: {:?}", child_layer.layer().bounds());
155 }
156
157 stack_pin_init!(let timer_seconds_stream = TickService::stream(TimeUnits::SECOND_UNIT));
158 while let Some(t) = timer_seconds_stream.next().await {
159 bordstein::info!("second tick stream: {}", t.0.secs);
160 }
161
162 core::future::pending::<()>().await;
167 })
168 .await
169 .unwrap();
170}