display_screen_ui_settings.c
1 #include "display_screen_ui.h" 2 3 #include "global/global_strings.h" 4 5 #define UI_NAME settings 6 7 static struct { 8 lv_obj_t* screen; 9 lv_obj_t* window; 10 lv_obj_t* window_done_button; 11 lv_obj_t* general; 12 lv_obj_t* brightness_label; 13 lv_obj_t* brightness; 14 lv_obj_t* nfc; 15 lv_obj_t* nfc_nyi; 16 lv_obj_t* cryptography; 17 lv_obj_t* cryptography_key_status_label; 18 lv_obj_t* cryptography_select_keys_button; 19 lv_obj_t* cryptography_clear_keys_button; 20 lv_obj_t* bootloader; 21 lv_obj_t* bootloader_text; 22 lv_obj_t* bootloader_button; 23 lv_group_t* active_group; 24 } ui; 25 26 static lv_style_t style_box; 27 28 static ui_common_simple_cb done_cb = NULL; 29 static ui_common_float_cb brightness_cb = NULL; 30 static ui_common_simple_cb select_crypto_keys_cb = NULL; 31 static ui_common_simple_cb clear_crypto_keys_cb = NULL; 32 static ui_common_simple_cb enter_dfu_cb = NULL; 33 34 static void settings_done_pressed(lv_obj_t* obj, lv_event_t e); 35 static void brightness_slider_event_cb(lv_obj_t* slider, lv_event_t e); 36 static void settings_focus_cb(lv_group_t* group); 37 38 UI_DEFINE_SIMPLE_BUTTON_PRESS_CALLBACK_HANDLER(settings_select_cryptography_keys_pressed, select_crypto_keys_cb) 39 UI_DEFINE_SIMPLE_BUTTON_PRESS_CALLBACK_HANDLER(settings_clear_cryptography_keys_pressed, select_crypto_keys_cb) 40 UI_DEFINE_SIMPLE_BUTTON_PRESS_CALLBACK_HANDLER(settings_enter_dfu_pressed, enter_dfu_cb) 41 42 static const char* cryptography_key_status_prefix = "Key status: "; 43 44 UI_DECLARE_CREATE(UI_NAME) 45 { 46 if (ui.screen != NULL) 47 { 48 done_cb = NULL; 49 brightness_cb = NULL; 50 return ui.screen; 51 } 52 53 lv_style_init(&style_box); 54 lv_style_set_value_align(&style_box, LV_STATE_DEFAULT, LV_ALIGN_OUT_TOP_LEFT); 55 lv_style_set_value_ofs_y(&style_box, LV_STATE_DEFAULT, -LV_DPX(10)); 56 lv_style_set_margin_top(&style_box, LV_STATE_DEFAULT, LV_DPX(30)); 57 58 ui.screen = lv_obj_create(NULL, NULL); 59 60 // window 61 ui.window = lv_win_create(ui.screen, NULL); 62 63 // 'done' (back) button 64 ui.window_done_button = lv_win_add_btn_left(ui.window, LV_SYMBOL_LEFT); 65 lv_obj_set_event_cb(ui.window_done_button, settings_done_pressed); 66 ui_common_set_window_button_style(ui.window_done_button); 67 68 // header 69 lv_win_set_title(ui.window, "Settings"); 70 71 // the page content 72 lv_obj_t* content = lv_win_get_content(ui.window); 73 lv_page_set_scrl_layout(content, LV_LAYOUT_PRETTY_TOP); 74 //lv_cont_set_fit2(content, LV_FIT_NONE, LV_FIT_TIGHT); 75 76 // general container 77 ui.general = lv_cont_create(content, NULL); 78 lv_cont_set_layout(ui.general, LV_LAYOUT_COLUMN_LEFT); 79 lv_obj_add_style(ui.general, LV_CONT_PART_MAIN, &style_box); 80 lv_obj_set_drag_parent(ui.general, true); 81 lv_cont_set_fit2(ui.general, LV_FIT_NONE, LV_FIT_TIGHT); 82 lv_obj_set_width_fit(ui.general, lv_obj_get_width(content)); 83 lv_obj_set_style_local_value_str(ui.general, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, "General"); 84 85 lv_coord_t fit_w = lv_obj_get_width_fit(ui.general); 86 87 // brightness setting label 88 ui.brightness_label = lv_label_create(ui.general, NULL); 89 ui_common_set_label_font_theme_small(ui.brightness_label); 90 lv_label_set_align(ui.brightness_label, LV_LABEL_ALIGN_LEFT); 91 lv_obj_set_width_margin(ui.brightness_label, fit_w); 92 lv_label_set_text(ui.brightness_label, "Backlight"); 93 94 // brightness slider 95 ui.brightness = lv_slider_create(ui.general, NULL); 96 lv_slider_set_range(ui.brightness, 0, 100); 97 lv_slider_set_value(ui.brightness, 100, LV_ANIM_OFF); 98 lv_obj_set_event_cb(ui.brightness, brightness_slider_event_cb); 99 lv_obj_set_width_margin(ui.brightness, fit_w); 100 101 // make the slider fancy 102 lv_obj_set_style_local_margin_top(ui.brightness, LV_SLIDER_PART_BG, LV_STATE_DEFAULT, LV_DPX(25)); 103 lv_obj_set_style_local_value_font(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_DEFAULT, lv_theme_get_font_small()); 104 lv_obj_set_style_local_value_ofs_y(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_FOCUSED, -LV_DPX(25)); 105 lv_obj_set_style_local_value_opa(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_DEFAULT, LV_OPA_TRANSP); 106 lv_obj_set_style_local_value_opa(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_FOCUSED, LV_OPA_COVER); 107 lv_obj_set_style_local_transition_time(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_DEFAULT, 300); 108 lv_obj_set_style_local_transition_prop_5(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_DEFAULT, LV_STYLE_VALUE_OFS_Y); 109 lv_obj_set_style_local_transition_prop_6(ui.brightness, LV_SLIDER_PART_KNOB, LV_STATE_DEFAULT, LV_STYLE_VALUE_OPA); 110 111 // nfc container 112 ui.nfc = lv_cont_create(content, ui.general); 113 lv_obj_set_style_local_value_str(ui.nfc, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, "NFC"); 114 lv_obj_set_event_cb(ui.nfc, ui_common_up_down_focus_cb); 115 116 // nfc coming soon 117 ui.nfc_nyi = lv_label_create(ui.nfc, ui.brightness_label); 118 lv_label_set_text(ui.nfc_nyi, "NFC settings are not yet implemented.\n" 119 "They will come in a future update."); 120 121 // cryptography container 122 ui.cryptography = lv_cont_create(content, ui.general); 123 lv_obj_set_style_local_value_str(ui.cryptography, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, "Cryptography"); 124 lv_obj_set_event_cb(ui.cryptography, ui_common_up_down_focus_cb); 125 126 // aes key status label 127 ui.cryptography_key_status_label = lv_label_create(ui.cryptography, ui.brightness_label); 128 lv_label_set_text(ui.cryptography_key_status_label, cryptography_key_status_prefix); 129 130 // select aes key(s) button 131 ui.cryptography_select_keys_button = lv_btn_create(ui.cryptography, NULL); 132 lv_obj_set_event_cb(ui.cryptography_select_keys_button, settings_select_cryptography_keys_pressed); 133 lv_obj_set_width_fit(ui.cryptography_select_keys_button, fit_w / 2); 134 lv_obj_set_style_local_border_color(ui.cryptography_select_keys_button, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_PURPLE); 135 lv_obj_set_style_local_outline_color(ui.cryptography_select_keys_button, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_RED); 136 lv_obj_t* cryptography_select_keys_button_label = lv_label_create(ui.cryptography_select_keys_button, NULL); 137 lv_label_set_text(cryptography_select_keys_button_label, "Select Key(s)"); 138 139 // clear aes key(s) button 140 ui.cryptography_clear_keys_button = lv_btn_create(ui.cryptography, NULL); 141 lv_obj_set_event_cb(ui.cryptography_clear_keys_button, settings_clear_cryptography_keys_pressed); 142 lv_obj_set_width_fit(ui.cryptography_clear_keys_button, fit_w / 2); 143 lv_obj_set_style_local_border_color(ui.cryptography_clear_keys_button, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_PURPLE); 144 lv_obj_set_style_local_outline_color(ui.cryptography_clear_keys_button, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_RED); 145 lv_obj_t* cryptography_clear_keys_button_label = lv_label_create(ui.cryptography_clear_keys_button, NULL); 146 lv_label_set_text(cryptography_clear_keys_button_label, "Clear Key(s)"); 147 148 // bootloader container 149 ui.bootloader = lv_cont_create(content, ui.general); 150 lv_obj_set_style_local_value_str(ui.bootloader, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, "Firmware Update"); 151 lv_obj_set_event_cb(ui.bootloader, ui_common_up_down_focus_cb); 152 153 // bootloader help text 154 ui.bootloader_text = lv_label_create(ui.bootloader, ui.brightness_label); 155 lv_label_set_text(ui.bootloader_text, 156 "Press the button below to restart " PRODUCT_NAME_SHORT "\n" 157 "in firmware (DFU) update mode. After the screen\n" 158 "goes off, attach " PRODUCT_NAME_SHORT " to your PC, and look\n" 159 "for a USB Disk named " PRODUCT_NAME_SHORT "BOOT. Drag the\n" 160 "UF2 file to it to flash new firmware. If\n" 161 "this process isn't completed in 5 minutes, \n" 162 PRODUCT_NAME_SHORT " will reboot.\n" 163 "\n" 164 "Current version:\n" 165 PRODUCT_NAME_FULL_BUILD); 166 167 ui.bootloader_button = lv_btn_create(ui.bootloader, NULL); 168 lv_obj_set_event_cb(ui.bootloader_button, settings_enter_dfu_pressed); 169 lv_obj_set_width_fit(ui.bootloader_button, fit_w); 170 lv_obj_set_style_local_border_color(ui.bootloader_button, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_PURPLE); 171 lv_obj_set_style_local_outline_color(ui.bootloader_button, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_COLOR_RED); 172 lv_obj_t* bootloader_button_label = lv_label_create(ui.bootloader_button, NULL); 173 lv_label_set_text(bootloader_button_label, "Reboot to DFU Mode"); 174 175 return ui.screen; 176 } 177 178 UI_DECLARE_ACTIVATE(UI_NAME) 179 { 180 lv_scr_load(ui.screen); 181 lv_group_set_focus_cb(group, settings_focus_cb); 182 lv_group_remove_all_objs(group); 183 184 lv_group_add_obj(group, ui.window_done_button); 185 186 lv_group_add_obj(group, ui.brightness); 187 188 lv_group_add_obj(group, ui.cryptography); 189 lv_group_add_obj(group, ui.cryptography_select_keys_button); 190 lv_group_add_obj(group, ui.cryptography_clear_keys_button); 191 192 lv_group_add_obj(group, ui.nfc); 193 194 lv_group_add_obj(group, ui.bootloader); 195 lv_group_add_obj(group, ui.bootloader_button); 196 197 lv_group_focus_obj(ui.brightness); 198 199 ui_common_cb_set_active_group(group); 200 201 ui.active_group = group; 202 203 // add status widget 204 ui_status_widget_get(ui.screen); 205 } 206 207 void UI_DECLARE_FUNCTION(UI_NAME, set_done_callback)(ui_common_simple_cb cb) 208 { 209 done_cb = cb; 210 } 211 212 void UI_DECLARE_FUNCTION(UI_NAME, set_brightness_callback)(ui_common_float_cb cb) 213 { 214 brightness_cb = cb; 215 } 216 217 void UI_DECLARE_FUNCTION(UI_NAME, set_select_crypto_keys_callback)(ui_common_simple_cb cb) 218 { 219 select_crypto_keys_cb = cb; 220 } 221 222 void UI_DECLARE_FUNCTION(UI_NAME, set_clear_crypto_keys_callback)(ui_common_simple_cb cb) 223 { 224 clear_crypto_keys_cb = cb; 225 } 226 227 void UI_DECLARE_FUNCTION(UI_NAME, set_enter_dfu_callback)(ui_common_simple_cb cb) 228 { 229 enter_dfu_cb = cb; 230 } 231 232 static void settings_done_pressed(lv_obj_t* obj, lv_event_t e) 233 { 234 if (e == LV_EVENT_CLICKED) 235 { 236 if (done_cb != NULL) 237 { 238 done_cb(); 239 } 240 else 241 { 242 // they aren't handling cancel, 243 // we will delete our window 244 // so we can be created again in the future. 245 lv_win_close_event_cb(obj, e); 246 lv_obj_del(ui.screen); 247 ui.screen = NULL; 248 } 249 } 250 else 251 { 252 ui_common_up_down_focus_cb(obj, e); 253 } 254 } 255 256 static void brightness_slider_event_cb(lv_obj_t* slider, lv_event_t e) 257 { 258 if (e == LV_EVENT_VALUE_CHANGED && lv_obj_is_focused(slider)) 259 { 260 uint16_t level_int = lv_slider_get_value(slider); 261 float level = level_int / 100.0f; 262 263 // tell someone it's changed! 264 if (brightness_cb != NULL) 265 { 266 brightness_cb(level); 267 } 268 269 static char buf[16]; 270 lv_snprintf(buf, sizeof(buf), "%d", lv_slider_get_value(slider)); 271 lv_obj_set_style_local_value_str(slider, LV_SLIDER_PART_KNOB, LV_STATE_DEFAULT, buf); 272 } 273 else 274 { 275 ui_common_up_down_focus_cb(slider, e); 276 } 277 } 278 279 static void settings_focus_cb(lv_group_t* group) 280 { 281 lv_win_focus(ui.window, *group->obj_focus, LV_ANIM_ON); 282 }