1+ use crate :: error:: { Error , Result } ;
12use alloc:: { format, string:: String } ;
2- use xila:: graphics:: { self , lvgl, theme} ;
3+ use core:: ptr:: null_mut;
4+ use xila:: graphics:: { self , EventKind , lvgl, theme} ;
35use xila:: shared:: unix_to_human_time;
4- use xila:: time;
5-
6- use crate :: error:: { Error , Result } ;
6+ use xila:: { log, time} ;
77
88pub struct Layout {
99 window : * mut lvgl:: lv_obj_t ,
@@ -21,6 +21,85 @@ impl Drop for Layout {
2121 }
2222}
2323
24+ /// Keyboard event handler.
25+ ///
26+ /// # Safety
27+ ///
28+ /// This function is unsafe because it dereferences raw pointers.
29+ pub unsafe extern "C" fn keyboard_event_handler ( event : * mut lvgl:: lv_event_t ) {
30+ unsafe {
31+ let code = lvgl:: lv_event_get_code ( event) ;
32+ let code = EventKind :: from_lvgl_code ( code) ;
33+ let keyboard = lvgl:: lv_event_get_user_data ( event) as * mut lvgl:: lv_obj_t ;
34+
35+ if keyboard. is_null ( ) {
36+ return ;
37+ }
38+
39+ match code {
40+ EventKind :: Ready => {
41+ let focused_input = lvgl:: lv_keyboard_get_textarea ( keyboard) ;
42+
43+ if focused_input. is_null ( ) {
44+ return ;
45+ }
46+
47+ lvgl:: lv_obj_send_event (
48+ focused_input,
49+ EventKind :: Ready . into_lvgl_code ( ) ,
50+ null_mut ( ) ,
51+ ) ;
52+
53+ lvgl:: lv_keyboard_set_textarea ( keyboard, null_mut ( ) ) ;
54+ lvgl:: lv_obj_add_flag ( keyboard, lvgl:: lv_obj_flag_t_LV_OBJ_FLAG_HIDDEN) ;
55+ }
56+ EventKind :: Cancel => {
57+ lvgl:: lv_keyboard_set_textarea ( keyboard, null_mut ( ) ) ;
58+ lvgl:: lv_obj_add_flag ( keyboard, lvgl:: lv_obj_flag_t_LV_OBJ_FLAG_HIDDEN) ;
59+ }
60+
61+ _ => { }
62+ }
63+ }
64+ }
65+
66+ /// Screen event handler.
67+ ///
68+ /// # Safety
69+ ///
70+ /// This function is unsafe because it dereferences raw pointers.
71+ pub unsafe extern "C" fn screen_event_handler ( event : * mut lvgl:: lv_event_t ) {
72+ unsafe {
73+ let code = lvgl:: lv_event_get_code ( event) ;
74+ let code = EventKind :: from_lvgl_code ( code) ;
75+ let target = lvgl:: lv_event_get_target_obj ( event) ;
76+ let keyboard = lvgl:: lv_event_get_user_data ( event) as * mut lvgl:: lv_obj_t ;
77+
78+ if target. is_null ( ) || keyboard. is_null ( ) {
79+ return ;
80+ }
81+
82+ log:: information!( "event screen : {code:?}" ) ;
83+
84+ match code {
85+ EventKind :: Focused => {
86+ if lvgl:: lv_obj_has_class ( target, & lvgl:: lv_textarea_class) {
87+ lvgl:: lv_keyboard_set_textarea ( keyboard, target) ;
88+ lvgl:: lv_obj_remove_flag ( keyboard, lvgl:: lv_obj_flag_t_LV_OBJ_FLAG_HIDDEN) ;
89+ lvgl:: lv_obj_move_foreground ( keyboard) ;
90+ }
91+ }
92+ EventKind :: Defocused => {
93+ if lvgl:: lv_obj_has_class ( target, & lvgl:: lv_textarea_class) {
94+ lvgl:: lv_keyboard_set_textarea ( keyboard, null_mut ( ) ) ;
95+ lvgl:: lv_obj_add_flag ( keyboard, lvgl:: lv_obj_flag_t_LV_OBJ_FLAG_HIDDEN) ;
96+ }
97+ }
98+ _ => { }
99+ }
100+ }
101+ }
102+
24103impl Layout {
25104 pub async fn r#loop ( & mut self ) {
26105 self . update_clock ( ) . await ;
@@ -47,7 +126,7 @@ impl Layout {
47126 self . window
48127 }
49128
50- pub async fn new ( ) -> Result < Self > {
129+ pub async fn new ( show_keyboard : bool ) -> Result < Self > {
51130 let _lock = graphics:: get_instance ( ) . lock ( ) . await ; // Lock the graphics
52131
53132 // - Create a window
@@ -147,7 +226,7 @@ impl Layout {
147226 if body. is_null ( ) {
148227 return Err ( Error :: FailedToCreateObject ) ;
149228 }
150-
229+ lvgl :: lv_obj_add_flag ( body , lvgl :: lv_obj_flag_t_LV_OBJ_FLAG_EVENT_BUBBLE ) ;
151230 lvgl:: lv_obj_set_width ( body, lvgl:: lv_pct ( 100 ) ) ;
152231 lvgl:: lv_obj_set_flex_grow ( body, 1 ) ;
153232 lvgl:: lv_obj_set_style_pad_all ( body, 0 , lvgl:: LV_STATE_DEFAULT ) ;
@@ -156,6 +235,44 @@ impl Layout {
156235 body
157236 } ;
158237
238+ // - Create a keyboard
239+ unsafe {
240+ let keyboard = lvgl:: lv_keyboard_create ( window) ;
241+
242+ if keyboard. is_null ( ) {
243+ return Err ( Error :: FailedToCreateObject ) ;
244+ }
245+
246+ lvgl:: lv_obj_add_flag ( keyboard, lvgl:: lv_obj_flag_t_LV_OBJ_FLAG_HIDDEN) ;
247+
248+ if show_keyboard {
249+ lvgl:: lv_obj_add_event_cb (
250+ window,
251+ Some ( screen_event_handler) ,
252+ EventKind :: Focused . into_lvgl_code ( ) ,
253+ keyboard as * mut _ ,
254+ ) ;
255+ lvgl:: lv_obj_add_event_cb (
256+ window,
257+ Some ( screen_event_handler) ,
258+ EventKind :: Defocused . into_lvgl_code ( ) ,
259+ keyboard as * mut _ ,
260+ ) ;
261+ lvgl:: lv_obj_add_event_cb (
262+ keyboard,
263+ Some ( keyboard_event_handler) ,
264+ EventKind :: Ready . into_lvgl_code ( ) ,
265+ keyboard as * mut _ ,
266+ ) ;
267+ lvgl:: lv_obj_add_event_cb (
268+ window,
269+ Some ( keyboard_event_handler) ,
270+ EventKind :: Cancel . into_lvgl_code ( ) ,
271+ keyboard as * mut _ ,
272+ ) ;
273+ }
274+ } ;
275+
159276 drop ( _lock) ; // Unlock the graphics
160277
161278 graphics:: get_instance ( ) . set_window_parent ( body) . await ?;
0 commit comments