66# and the performance impact of converting RGB565 to grayscale is probably minimal anyway.
77
88import lvgl as lv
9+ from mpos .ui .keyboard import MposKeyboard
910
1011try :
1112 import webcam
@@ -626,6 +627,9 @@ class CameraSettingsActivity(Activity):
626627 ("1920x1080" , "1920x1080" ),
627628 ]
628629
630+ # Widgets:
631+ button_cont = None
632+
629633 def __init__ (self ):
630634 super ().__init__ ()
631635 self .ui_controls = {}
@@ -674,30 +678,30 @@ def onCreate(self):
674678 self .create_raw_tab (raw_tab , prefs )
675679
676680 # Save/Cancel buttons at bottom
677- button_cont = lv .obj (screen )
678- button_cont .set_size (lv .pct (100 ), mpos .ui .pct_of_display_height (20 ))
679- button_cont .remove_flag (lv .obj .FLAG .SCROLLABLE )
680- button_cont .align (lv .ALIGN .BOTTOM_MID , 0 , 0 )
681- button_cont .set_style_border_width (0 , 0 )
682- button_cont .set_style_bg_opa (0 , 0 )
683-
684- save_button = lv .button (button_cont )
681+ self . button_cont = lv .obj (screen )
682+ self . button_cont .set_size (lv .pct (100 ), mpos .ui .pct_of_display_height (20 ))
683+ self . button_cont .remove_flag (lv .obj .FLAG .SCROLLABLE )
684+ self . button_cont .align (lv .ALIGN .BOTTOM_MID , 0 , 0 )
685+ self . button_cont .set_style_border_width (0 , 0 )
686+ self . button_cont .set_style_bg_opa (0 , 0 )
687+
688+ save_button = lv .button (self . button_cont )
685689 save_button .set_size (mpos .ui .pct_of_display_width (25 ), lv .SIZE_CONTENT )
686690 save_button .align (lv .ALIGN .BOTTOM_LEFT , 0 , 0 )
687691 save_button .add_event_cb (lambda e : self .save_and_close (), lv .EVENT .CLICKED , None )
688692 save_label = lv .label (save_button )
689693 save_label .set_text ("Save" )
690694 save_label .center ()
691695
692- cancel_button = lv .button (button_cont )
696+ cancel_button = lv .button (self . button_cont )
693697 cancel_button .set_size (mpos .ui .pct_of_display_width (25 ), lv .SIZE_CONTENT )
694698 cancel_button .align (lv .ALIGN .BOTTOM_MID , 0 , 0 )
695699 cancel_button .add_event_cb (lambda e : self .finish (), lv .EVENT .CLICKED , None )
696700 cancel_label = lv .label (cancel_button )
697701 cancel_label .set_text ("Cancel" )
698702 cancel_label .center ()
699703
700- erase_button = lv .button (button_cont )
704+ erase_button = lv .button (self . button_cont )
701705 erase_button .set_size (mpos .ui .pct_of_display_width (25 ), lv .SIZE_CONTENT )
702706 erase_button .align (lv .ALIGN .BOTTOM_RIGHT , 0 , 0 )
703707 erase_button .add_event_cb (lambda e : self .erase_and_close (), lv .EVENT .CLICKED , None )
@@ -729,9 +733,6 @@ def slider_changed(e):
729733
730734 slider .add_event_cb (slider_changed , lv .EVENT .VALUE_CHANGED , None )
731735
732- # Store metadata separately
733- self .control_metadata [id (slider )] = {"pref_key" : pref_key , "type" : "slider" }
734-
735736 return slider , label , cont
736737
737738 def create_checkbox (self , parent , label_text , default_val , pref_key ):
@@ -746,9 +747,6 @@ def create_checkbox(self, parent, label_text, default_val, pref_key):
746747 checkbox .add_state (lv .STATE .CHECKED )
747748 checkbox .align (lv .ALIGN .LEFT_MID , 0 , 0 )
748749
749- # Store metadata separately
750- self .control_metadata [id (checkbox )] = {"pref_key" : pref_key , "type" : "checkbox" }
751-
752750 return checkbox , cont
753751
754752 def create_dropdown (self , parent , label_text , options , default_idx , pref_key ):
@@ -779,6 +777,46 @@ def create_dropdown(self, parent, label_text, options, default_idx, pref_key):
779777
780778 return dropdown , cont
781779
780+ def create_textarea (self , parent , label_text , min_val , max_val , default_val , pref_key ):
781+ cont = lv .obj (parent )
782+ cont .set_size (lv .pct (100 ), 60 )
783+ cont .set_style_pad_all (3 , 0 )
784+
785+ label = lv .label (cont )
786+ label .set_text (f"{ label_text } : { default_val } " )
787+ label .align (lv .ALIGN .TOP_LEFT , 0 , 0 )
788+
789+ textarea = lv .textarea (parent )
790+ textarea .set_width (lv .pct (90 ))
791+ textarea .set_one_line (True ) # might not be good for all settings but it's good for most
792+ textarea .set_text (str (default_val ))
793+
794+ # Initialize keyboard (hidden initially)
795+ keyboard = MposKeyboard (parent )
796+ keyboard .align (lv .ALIGN .BOTTOM_MID , 0 , 0 )
797+ keyboard .add_flag (lv .obj .FLAG .HIDDEN )
798+ keyboard .set_textarea (textarea )
799+ keyboard .add_event_cb (lambda e , kbd = keyboard : self .hide_keyboard (kbd ), lv .EVENT .READY , None )
800+ keyboard .add_event_cb (lambda e , kbd = keyboard : self .hide_keyboard (kbd ), lv .EVENT .CANCEL , None )
801+ textarea .add_event_cb (lambda e , kbd = keyboard : self .show_keyboard (kbd ), lv .EVENT .CLICKED , None )
802+
803+ return textarea , cont
804+
805+ def show_keyboard (self , kbd ):
806+ self .button_cont .add_flag (lv .obj .FLAG .HIDDEN )
807+ mpos .ui .anim .smooth_show (kbd )
808+ focusgroup = lv .group_get_default ()
809+ if focusgroup :
810+ # move the focus to the keyboard to save the user a "next" button press (optional but nice)
811+ # this is focusing on the right thing (keyboard) but the focus is not "active" (shown or used) somehow
812+ #print(f"current focus object: {lv.group_get_default().get_focused()}")
813+ focusgroup .focus_next ()
814+ #print(f"current focus object: {lv.group_get_default().get_focused()}")
815+
816+ def hide_keyboard (self , kbd ):
817+ mpos .ui .anim .smooth_hide (kbd )
818+ self .button_cont .remove_flag (lv .obj .FLAG .HIDDEN )
819+
782820 def create_basic_tab (self , tab , prefs ):
783821 """Create Basic settings tab."""
784822 tab .set_flex_flow (lv .FLEX_FLOW .COLUMN )
@@ -1014,10 +1052,10 @@ def create_expert_tab(self, tab, prefs):
10141052 self .ui_controls ["lenc" ] = checkbox
10151053
10161054 def create_raw_tab (self , tab , prefs ):
1017- startX = prefs .get_bool ("startX" , 0 )
1018- #startX, cont = self.create_checkbox (tab, "Lens Correction ", lenc, "lenc ")
1019- startX , label , cont = self .create_slider (tab , "startX" , 0 , 2844 , startX , "startX" )
1020- self .ui_controls ["statX " ] = startX
1055+ startX = prefs .get_int ("startX" , 0 )
1056+ #startX, label, cont = self.create_slider (tab, "startX ", 0, 2844, startX, "startX ")
1057+ textarea , cont = self .create_textarea (tab , "startX" , 0 , 2844 , startX , "startX" )
1058+ self .ui_controls ["startX " ] = startX
10211059
10221060 def erase_and_close (self ):
10231061 SharedPreferences ("com.micropythonos.camera" ).edit ().remove_all ().commit ()
@@ -1040,6 +1078,9 @@ def save_and_close(self):
10401078 elif isinstance (control , lv .checkbox ):
10411079 is_checked = control .get_state () & lv .STATE .CHECKED
10421080 editor .put_bool (pref_key , bool (is_checked ))
1081+ elif isinstance (control , lv .textarea ):
1082+ value = int (control .get_value ())
1083+ editor .put_int (pref_key , value )
10431084 elif isinstance (control , lv .dropdown ):
10441085 selected_idx = control .get_selected ()
10451086 option_values = metadata .get ("option_values" , [])
0 commit comments