Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/nyx/nyx_gui/frontend/gui_options.c
3711 views
1
/*
2
* Copyright (c) 2018-2026 CTCaer
3
*
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms and conditions of the GNU General Public License,
6
* version 2, as published by the Free Software Foundation.
7
*
8
* This program is distributed in the hope it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
* more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15
*/
16
17
#include <stdlib.h>
18
19
#include <bdk.h>
20
21
#include "gui.h"
22
#include "gui_info.h"
23
#include "../config.h"
24
#include <libs/lvgl/lv_themes/lv_theme_hekate.h>
25
#include <libs/lvgl/lvgl.h>
26
27
#define CLOCK_MIN_YEAR 2025
28
#define CLOCK_MAX_YEAR (CLOCK_MIN_YEAR + 10)
29
#define CLOCK_YEARLIST "2025\n2026\n2027\n2028\n2029\n2030\n2031\n2032\n2033\n2034\n2035"
30
31
static lv_obj_t *autoboot_btn;
32
static bool autoboot_first_time = true;
33
34
static bool ini_changes_made = false;
35
static bool nyx_changes_made = false;
36
37
void nyx_options_clear_ini_changes_made()
38
{
39
ini_changes_made = false;
40
}
41
42
bool nyx_options_get_ini_changes_made()
43
{
44
return ini_changes_made;
45
}
46
47
static lv_res_t auto_hos_poweroff_toggle(lv_obj_t *btn)
48
{
49
h_cfg.autohosoff = !h_cfg.autohosoff;
50
ini_changes_made = true;
51
52
if (!h_cfg.autohosoff)
53
lv_btn_set_state(btn, LV_BTN_STATE_REL);
54
else
55
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
56
57
nyx_generic_onoff_toggle(btn);
58
59
return LV_RES_OK;
60
}
61
62
static lv_res_t auto_nogc_toggle(lv_obj_t *btn)
63
{
64
h_cfg.autonogc = !h_cfg.autonogc;
65
ini_changes_made = true;
66
67
if (!h_cfg.autonogc)
68
lv_btn_set_state(btn, LV_BTN_STATE_REL);
69
else
70
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
71
72
nyx_generic_onoff_toggle(btn);
73
74
return LV_RES_OK;
75
}
76
77
static lv_res_t _update_r2p_action(lv_obj_t *btn)
78
{
79
h_cfg.updater2p = !h_cfg.updater2p;
80
ini_changes_made = true;
81
82
if (!h_cfg.updater2p)
83
lv_btn_set_state(btn, LV_BTN_STATE_REL);
84
else
85
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
86
87
nyx_generic_onoff_toggle(btn);
88
89
return LV_RES_OK;
90
}
91
92
static lv_res_t _win_autoboot_close_action(lv_obj_t * btn)
93
{
94
if (!h_cfg.autoboot)
95
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_REL);
96
else
97
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_TGL_REL);
98
99
nyx_generic_onoff_toggle(autoboot_btn);
100
101
lv_obj_t * win = lv_win_get_from_btn(btn);
102
103
lv_obj_del(win);
104
105
close_btn = NULL;
106
107
return LV_RES_INV;
108
}
109
110
lv_obj_t *create_window_autoboot(const char *win_title)
111
{
112
static lv_style_t win_bg_style;
113
114
lv_style_copy(&win_bg_style, &lv_style_plain);
115
win_bg_style.body.main_color = LV_COLOR_HEX(theme_bg_color);
116
win_bg_style.body.grad_color = win_bg_style.body.main_color;
117
118
lv_obj_t *win = lv_win_create(lv_scr_act(), NULL);
119
lv_win_set_title(win, win_title);
120
lv_win_set_style(win, LV_WIN_STYLE_BG, &win_bg_style);
121
lv_obj_set_size(win, LV_HOR_RES, LV_VER_RES);
122
123
close_btn = lv_win_add_btn(win, NULL, SYMBOL_CLOSE" Close", _win_autoboot_close_action);
124
125
return win;
126
}
127
128
static lv_res_t _autoboot_disable_action(lv_obj_t *btn)
129
{
130
h_cfg.autoboot = 0;
131
h_cfg.autoboot_list = 0;
132
ini_changes_made = true;
133
134
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_REL);
135
nyx_generic_onoff_toggle(autoboot_btn);
136
137
lv_obj_t * win = lv_win_get_from_btn(btn);
138
139
lv_obj_del(win);
140
141
close_btn = NULL;
142
143
return LV_RES_OK;
144
}
145
146
lv_obj_t *auto_main_list;
147
lv_obj_t *auto_more_list;
148
static lv_res_t _autoboot_enable_main_action(lv_obj_t *btn)
149
{
150
h_cfg.autoboot = lv_list_get_btn_index(auto_main_list, btn) + 1;
151
h_cfg.autoboot_list = 0;
152
ini_changes_made = true;
153
154
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_TGL_REL);
155
nyx_generic_onoff_toggle(autoboot_btn);
156
157
lv_obj_t *obj = lv_obj_get_parent(btn);
158
for (int i = 0; i < 5; i++)
159
obj = lv_obj_get_parent(obj);
160
lv_obj_del(obj);
161
162
close_btn = NULL;
163
164
return LV_RES_INV;
165
}
166
167
static lv_res_t _autoboot_enable_more_action(lv_obj_t *btn)
168
{
169
h_cfg.autoboot = lv_list_get_btn_index(auto_more_list, btn) + 1;
170
h_cfg.autoboot_list = 1;
171
ini_changes_made = true;
172
173
lv_btn_set_state(autoboot_btn, LV_BTN_STATE_TGL_REL);
174
nyx_generic_onoff_toggle(autoboot_btn);
175
176
lv_obj_t *obj = lv_obj_get_parent(btn);
177
for (int i = 0; i < 5; i++)
178
obj = lv_obj_get_parent(obj);
179
lv_obj_del(obj);
180
181
close_btn = NULL;
182
183
return LV_RES_INV;
184
}
185
186
static void _create_autoboot_window()
187
{
188
lv_obj_t *win = create_window_autoboot(SYMBOL_GPS" Auto Boot");
189
lv_win_add_btn(win, NULL, SYMBOL_POWER" Disable", _autoboot_disable_action);
190
191
static lv_style_t h_style;
192
lv_style_copy(&h_style, &lv_style_transp);
193
h_style.body.padding.inner = 0;
194
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
195
h_style.body.padding.ver = LV_DPI / 6;
196
197
// Main configurations container.
198
lv_obj_t *h1 = lv_cont_create(win, NULL);
199
lv_cont_set_style(h1, &h_style);
200
lv_cont_set_fit(h1, false, true);
201
lv_obj_set_width(h1, (LV_HOR_RES / 9) * 4);
202
lv_obj_set_click(h1, false);
203
lv_cont_set_layout(h1, LV_LAYOUT_OFF);
204
205
lv_obj_t *label_sep = lv_label_create(h1, NULL);
206
lv_label_set_static_text(label_sep, "");
207
208
lv_obj_t *label_txt = lv_label_create(h1, NULL);
209
lv_label_set_static_text(label_txt, "Main configurations");
210
lv_obj_set_style(label_txt, lv_theme_get_current()->label.prim);
211
lv_obj_align(label_txt, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -(LV_DPI / 4));
212
213
lv_obj_t *line_sep = lv_line_create(h1, NULL);
214
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
215
lv_line_set_points(line_sep, line_pp, 2);
216
lv_line_set_style(line_sep, lv_theme_get_current()->line.decor);
217
lv_obj_align(line_sep, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 8);
218
219
// Create list and populate it with Main boot entries.
220
lv_obj_t *list_main = lv_list_create(h1, NULL);
221
auto_main_list = list_main;
222
lv_obj_align(list_main, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
223
224
lv_obj_set_size(list_main, LV_HOR_RES * 4 / 10, LV_VER_RES * 4 / 7);
225
lv_list_set_single_mode(list_main, true);
226
227
sd_mount();
228
229
// Parse hekate main configuration.
230
LIST_INIT(ini_sections);
231
if (!ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
232
{
233
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
234
{
235
if (!strcmp(ini_sec->name, "config") || (ini_sec->type != INI_CHOICE))
236
continue;
237
238
lv_list_add(list_main, NULL, ini_sec->name, _autoboot_enable_main_action);
239
}
240
241
ini_free(&ini_sections);
242
}
243
244
// More configuration container.
245
lv_obj_t *h2 = lv_cont_create(win, NULL);
246
lv_cont_set_style(h2, &h_style);
247
lv_cont_set_fit(h2, false, true);
248
lv_obj_set_width(h2, (LV_HOR_RES / 9) * 4);
249
lv_obj_set_click(h2, false);
250
lv_cont_set_layout(h2, LV_LAYOUT_OFF);
251
lv_obj_align(h2, h1, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI * 17 / 29, 0);
252
253
label_sep = lv_label_create(h2, NULL);
254
lv_label_set_static_text(label_sep, "");
255
256
lv_obj_t *label_txt3 = lv_label_create(h2, NULL);
257
lv_label_set_static_text(label_txt3, "Ini folder configurations");
258
lv_obj_set_style(label_txt3, lv_theme_get_current()->label.prim);
259
lv_obj_align(label_txt3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI / 11);
260
261
line_sep = lv_line_create(h2, line_sep);
262
lv_obj_align(line_sep, label_txt3, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 2), LV_DPI / 8);
263
lv_line_set_style(line_sep, lv_theme_get_current()->line.decor);
264
265
// Create list and populate it with more cfg boot entries.
266
lv_obj_t *list_more_cfg = lv_list_create(h2, NULL);
267
auto_more_list = list_more_cfg;
268
lv_obj_align(list_more_cfg, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 2, LV_DPI / 4);
269
270
lv_obj_set_size(list_more_cfg, LV_HOR_RES * 4 / 10, LV_VER_RES * 4 / 7);
271
lv_list_set_single_mode(list_more_cfg, true);
272
273
// Parse all .ini files in ini folder.
274
LIST_INIT(ini_list_sections);
275
if (!ini_parse(&ini_list_sections, "bootloader/ini", true))
276
{
277
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_list_sections, link)
278
{
279
if (!strcmp(ini_sec->name, "config") || (ini_sec->type != INI_CHOICE))
280
continue;
281
282
lv_list_add(list_more_cfg, NULL, ini_sec->name, _autoboot_enable_more_action);
283
}
284
285
ini_free(&ini_list_sections);
286
}
287
288
sd_unmount();
289
}
290
291
static lv_res_t _autoboot_hide_delay_action(lv_obj_t *btn)
292
{
293
if (!autoboot_first_time)
294
_create_autoboot_window();
295
296
if (!h_cfg.autoboot && autoboot_first_time)
297
lv_btn_set_state(btn, LV_BTN_STATE_REL);
298
else
299
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
300
autoboot_first_time = false;
301
302
nyx_generic_onoff_toggle(btn);
303
304
return LV_RES_INV;
305
}
306
307
static lv_res_t _autoboot_delay_action(lv_obj_t *ddlist)
308
{
309
u32 new_selection = lv_ddlist_get_selected(ddlist);
310
if (h_cfg.bootwait != new_selection)
311
{
312
h_cfg.bootwait = new_selection;
313
ini_changes_made = true;
314
}
315
316
return LV_RES_OK;
317
}
318
319
static lv_res_t _slider_brightness_action(lv_obj_t * slider)
320
{
321
display_backlight_brightness(lv_slider_get_value(slider) - 20, 0);
322
h_cfg.backlight = lv_slider_get_value(slider);
323
ini_changes_made = true;
324
325
return LV_RES_OK;
326
}
327
328
static lv_res_t _data_verification_action(lv_obj_t *ddlist)
329
{
330
u32 new_selection = lv_ddlist_get_selected(ddlist);
331
if (n_cfg.verification != new_selection)
332
{
333
n_cfg.verification = new_selection;
334
nyx_changes_made = true;
335
}
336
337
return LV_RES_OK;
338
}
339
340
static lv_res_t _entries_columns_action(lv_obj_t *btn)
341
{
342
n_cfg.entries_5_col = !n_cfg.entries_5_col;
343
nyx_changes_made = true;
344
345
if (!n_cfg.entries_5_col)
346
lv_btn_set_state(btn, LV_BTN_STATE_REL);
347
else
348
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
349
350
nyx_generic_onoff_toggle(btn);
351
352
return LV_RES_OK;
353
}
354
355
static lv_res_t _save_nyx_options_action(lv_obj_t *btn)
356
{
357
static const char * mbox_btn_map[] = {"\251", "\222OK!", "\251", ""};
358
lv_obj_t * mbox = lv_mbox_create(lv_scr_act(), NULL);
359
lv_mbox_set_recolor_text(mbox, true);
360
361
int res = !create_nyx_config_entry(true);
362
363
nyx_changes_made = false;
364
365
if (res)
366
lv_mbox_set_text(mbox, "#FF8000 Nyx Configuration#\n\n#96FF00 The configuration was saved to sd card!#");
367
else
368
lv_mbox_set_text(mbox, "#FF8000 Nyx Configuration#\n\n#FFDD00 Failed to save the configuration#\n#FFDD00 to sd card!#");
369
lv_mbox_add_btns(mbox, mbox_btn_map, NULL);
370
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
371
lv_obj_set_top(mbox, true);
372
373
return LV_RES_OK;
374
}
375
376
void create_flat_button(lv_obj_t *btn, int color_idx, lv_action_t action)
377
{
378
lv_color_t color = color_idx ? lv_color_hsv_to_rgb(color_idx, 100, 100) : lv_color_hsv_to_rgb(53, 8, 90);
379
lv_style_t *btn_onoff_rel_hos_style = malloc(sizeof(lv_style_t));
380
lv_style_t *btn_onoff_pr_hos_style = malloc(sizeof(lv_style_t));
381
lv_style_copy(btn_onoff_rel_hos_style, lv_theme_get_current()->btn.rel);
382
btn_onoff_rel_hos_style->body.main_color = color;
383
btn_onoff_rel_hos_style->body.grad_color = btn_onoff_rel_hos_style->body.main_color;
384
btn_onoff_rel_hos_style->body.padding.hor = 0;
385
btn_onoff_rel_hos_style->body.radius = 0;
386
387
if (color_idx == 167)
388
{
389
btn_onoff_rel_hos_style->body.border.color = LV_COLOR_HEX(0x000000);
390
btn_onoff_rel_hos_style->body.border.opa = LV_OPA_20;
391
btn_onoff_rel_hos_style->body.border.width = 3;
392
}
393
394
lv_style_copy(btn_onoff_pr_hos_style, lv_theme_get_current()->btn.pr);
395
btn_onoff_pr_hos_style->body.main_color = color;
396
btn_onoff_pr_hos_style->body.grad_color = btn_onoff_pr_hos_style->body.main_color;
397
btn_onoff_pr_hos_style->body.padding.hor = 0;
398
btn_onoff_pr_hos_style->body.border.color = LV_COLOR_HEX(0xFFFFFF);
399
btn_onoff_pr_hos_style->body.border.opa = LV_OPA_50;
400
btn_onoff_pr_hos_style->body.border.width = 4;
401
btn_onoff_pr_hos_style->body.radius = 0;
402
403
lv_btn_set_style(btn, LV_BTN_STYLE_REL, btn_onoff_rel_hos_style);
404
lv_btn_set_style(btn, LV_BTN_STYLE_PR, btn_onoff_pr_hos_style);
405
lv_btn_set_style(btn, LV_BTN_STYLE_TGL_REL, btn_onoff_rel_hos_style);
406
lv_btn_set_style(btn, LV_BTN_STYLE_TGL_PR, btn_onoff_pr_hos_style);
407
408
lv_btn_set_fit(btn, false, false);
409
lv_obj_set_size(btn, LV_DPI * 7 / 11, LV_DPI * 7 / 11);
410
lv_btn_set_toggle(btn, true);
411
412
if (action)
413
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, action);
414
}
415
416
typedef struct _color_test_ctxt
417
{
418
u32 bg;
419
u16 hue;
420
u8 r;
421
u8 g;
422
u8 b;
423
424
lv_obj_t *window;
425
lv_obj_t *header1;
426
lv_obj_t *header2;
427
lv_obj_t *label;
428
lv_obj_t *icons;
429
lv_obj_t *slider;
430
lv_obj_t *button;
431
lv_obj_t *hue_slider;
432
lv_obj_t *hue_label;
433
434
lv_obj_t *r_slider;
435
lv_obj_t *r_label;
436
lv_obj_t *g_slider;
437
lv_obj_t *g_label;
438
lv_obj_t *b_slider;
439
lv_obj_t *b_label;
440
441
lv_style_t box_style;
442
lv_obj_t *box;
443
444
lv_obj_t *btn_reset;
445
lv_obj_t *btn_apply;
446
lv_obj_t *btn_black;
447
} color_test_ctxt;
448
449
color_test_ctxt color_test;
450
451
static lv_res_t _action_win_nyx_colors_save(lv_obj_t *btn)
452
{
453
n_cfg.theme_bg = color_test.bg;
454
n_cfg.theme_color = color_test.hue;
455
456
// Save nyx config.
457
create_nyx_config_entry(true);
458
459
reload_nyx(NULL, false);
460
461
return LV_RES_OK;
462
}
463
464
static void _show_new_nyx_color(bool update_bg)
465
{
466
u32 bg = color_test.bg;
467
u16 hue = color_test.hue;
468
469
lv_color_t bgc = LV_COLOR_HEX(bg); // COLOR_HOS_BG.
470
lv_color_t bgc_light = LV_COLOR_HEX(bg ? (bg + 0x101010) : 0x2D2D2D); // COLOR_HOS_BG_LIGHT.
471
lv_color_t bgc_press = LV_COLOR_HEX(bg ? (bg + 0x232323) : 0x404040); // 0x505050.
472
lv_color_t bg_border = LV_COLOR_HEX(bg ? (bg + 0x202020) : 0x3D3D3D); // COLOR_HOS_BG_LIGHTER.
473
lv_color_t color = hue ? lv_color_hsv_to_rgb(hue, 100, 100) : lv_color_hsv_to_rgb(53, 8, 90);
474
475
static lv_style_t btn_tgl_pr_test;
476
lv_style_copy(&btn_tgl_pr_test, lv_btn_get_style(color_test.button, LV_BTN_STATE_TGL_PR));
477
btn_tgl_pr_test.body.main_color = bgc_press;
478
btn_tgl_pr_test.body.grad_color = btn_tgl_pr_test.body.main_color;
479
btn_tgl_pr_test.body.border.color = color;
480
btn_tgl_pr_test.text.color = color;
481
482
if (update_bg)
483
{
484
static lv_style_t win_bg_test;
485
lv_style_copy(&win_bg_test, lv_win_get_style(color_test.window, LV_WIN_STYLE_BG));
486
win_bg_test.body.main_color = bgc;
487
win_bg_test.body.grad_color = win_bg_test.body.main_color;
488
lv_win_set_style(color_test.window, LV_WIN_STYLE_BG, &win_bg_test);
489
490
static lv_style_t win_hdr_test;
491
lv_style_copy(&win_hdr_test, lv_win_get_style(color_test.window, LV_WIN_STYLE_HEADER));
492
win_hdr_test.body.main_color = bgc;
493
win_hdr_test.body.grad_color = win_hdr_test.body.main_color;
494
lv_win_set_style(color_test.window, LV_WIN_STYLE_HEADER, &win_hdr_test);
495
496
static lv_style_t hdr1_bg_test;
497
lv_style_copy(&hdr1_bg_test, lv_cont_get_style(color_test.header1));
498
hdr1_bg_test.body.main_color = bgc;
499
hdr1_bg_test.body.grad_color = hdr1_bg_test.body.main_color;
500
lv_cont_set_style(color_test.header1, &hdr1_bg_test);
501
502
static lv_style_t hdr2_bg_test;
503
lv_style_copy(&hdr2_bg_test, lv_cont_get_style(color_test.header2));
504
hdr2_bg_test.body.main_color = bgc;
505
hdr2_bg_test.body.grad_color = hdr2_bg_test.body.main_color;
506
lv_cont_set_style(color_test.header2, &hdr2_bg_test);
507
508
static lv_style_t btn_tgl_rel_test;
509
lv_style_copy(&btn_tgl_rel_test, lv_btn_get_style(color_test.btn_reset, LV_BTN_STATE_REL));
510
btn_tgl_rel_test.body.main_color = bgc_light;
511
btn_tgl_rel_test.body.grad_color = btn_tgl_rel_test.body.main_color;
512
lv_btn_set_style(color_test.btn_reset, LV_BTN_STATE_REL, &btn_tgl_rel_test);
513
lv_btn_set_style(color_test.btn_reset, LV_BTN_STATE_PR, &btn_tgl_pr_test);
514
lv_btn_set_style(color_test.btn_apply, LV_BTN_STATE_REL, &btn_tgl_rel_test);
515
lv_btn_set_style(color_test.btn_apply, LV_BTN_STATE_PR, &btn_tgl_pr_test);
516
lv_btn_set_style(color_test.btn_black, LV_BTN_STATE_REL, &btn_tgl_rel_test);
517
lv_btn_set_style(color_test.btn_black, LV_BTN_STATE_PR, &btn_tgl_pr_test);
518
519
static lv_style_t slider_bg;
520
lv_style_copy(&slider_bg, lv_slider_get_style(color_test.slider, LV_SLIDER_STYLE_BG));
521
slider_bg.body.main_color = bg_border;
522
slider_bg.body.grad_color = slider_bg.body.main_color;
523
lv_slider_set_style(color_test.hue_slider, LV_SLIDER_STYLE_BG, &slider_bg);
524
lv_slider_set_style(color_test.slider, LV_SLIDER_STYLE_BG, &slider_bg);
525
lv_slider_set_style(color_test.r_slider, LV_SLIDER_STYLE_BG, &slider_bg);
526
lv_slider_set_style(color_test.g_slider, LV_SLIDER_STYLE_BG, &slider_bg);
527
lv_slider_set_style(color_test.b_slider, LV_SLIDER_STYLE_BG, &slider_bg);
528
}
529
else
530
{
531
static lv_style_t txt_test;
532
lv_style_copy(&txt_test, lv_label_get_style(color_test.label));
533
txt_test.text.color = color;
534
lv_obj_set_style(color_test.label, &txt_test);
535
lv_obj_set_style(color_test.icons, &txt_test);
536
537
static lv_style_t slider_knb;
538
lv_style_copy(&slider_knb, lv_slider_get_style(color_test.slider, LV_SLIDER_STYLE_KNOB));
539
slider_knb.body.main_color = color;
540
slider_knb.body.grad_color = slider_knb.body.main_color;
541
lv_slider_set_style(color_test.hue_slider, LV_SLIDER_STYLE_KNOB, &slider_knb);
542
lv_slider_set_style(color_test.slider, LV_SLIDER_STYLE_KNOB, &slider_knb);
543
lv_slider_set_style(color_test.r_slider, LV_SLIDER_STYLE_KNOB, &slider_knb);
544
lv_slider_set_style(color_test.g_slider, LV_SLIDER_STYLE_KNOB, &slider_knb);
545
lv_slider_set_style(color_test.b_slider, LV_SLIDER_STYLE_KNOB, &slider_knb);
546
547
static lv_style_t slider_ind;
548
lv_style_copy(&slider_ind, lv_slider_get_style(color_test.slider, LV_SLIDER_STYLE_INDIC));
549
slider_ind.body.main_color = hue ? lv_color_hsv_to_rgb(hue, 100, 72) : lv_color_hsv_to_rgb(53, 8, 65);
550
slider_ind.body.grad_color = slider_ind.body.main_color;
551
lv_slider_set_style(color_test.hue_slider, LV_SLIDER_STYLE_INDIC, &slider_ind);
552
lv_slider_set_style(color_test.slider, LV_SLIDER_STYLE_INDIC, &slider_ind);
553
lv_slider_set_style(color_test.r_slider, LV_SLIDER_STYLE_INDIC, &slider_ind);
554
lv_slider_set_style(color_test.g_slider, LV_SLIDER_STYLE_INDIC, &slider_ind);
555
lv_slider_set_style(color_test.b_slider, LV_SLIDER_STYLE_INDIC, &slider_ind);
556
}
557
558
lv_btn_set_style(color_test.button, LV_BTN_STATE_TGL_PR, &btn_tgl_pr_test);
559
}
560
561
static lv_res_t _slider_hue_action(lv_obj_t *slider)
562
{
563
if (color_test.hue != lv_slider_get_value(slider))
564
{
565
color_test.hue = lv_slider_get_value(slider);
566
567
_show_new_nyx_color(false);
568
569
char hue[8];
570
s_printf(hue, "%03d", color_test.hue);
571
lv_label_set_text(color_test.hue_label, hue);
572
}
573
574
return LV_RES_OK;
575
}
576
577
static lv_res_t _slider_r_action(lv_obj_t *slider)
578
{
579
if (color_test.r != lv_slider_get_value(slider))
580
{
581
color_test.r = lv_slider_get_value(slider);
582
color_test.box_style.body.main_color = LV_COLOR_HEX((color_test.r << 16) | (color_test.g << 8) | color_test.b);
583
color_test.box_style.body.grad_color = color_test.box_style.body.main_color;
584
lv_obj_set_style(color_test.box, &color_test.box_style);
585
586
char shade[8];
587
s_printf(shade, "%03d", color_test.r);
588
lv_label_set_text(color_test.r_label, shade);
589
}
590
591
return LV_RES_OK;
592
}
593
594
static lv_res_t _slider_g_action(lv_obj_t *slider)
595
{
596
if (color_test.g != lv_slider_get_value(slider))
597
{
598
color_test.g = lv_slider_get_value(slider);
599
color_test.box_style.body.main_color = LV_COLOR_HEX((color_test.r << 16) | (color_test.g << 8) | color_test.b);
600
color_test.box_style.body.grad_color = color_test.box_style.body.main_color;
601
lv_obj_set_style(color_test.box, &color_test.box_style);
602
603
char shade[8];
604
s_printf(shade, "%03d", color_test.g);
605
lv_label_set_text(color_test.g_label, shade);
606
}
607
608
return LV_RES_OK;
609
}
610
611
static lv_res_t _slider_b_action(lv_obj_t *slider)
612
{
613
if (color_test.b != lv_slider_get_value(slider))
614
{
615
color_test.b = lv_slider_get_value(slider);
616
color_test.box_style.body.main_color = LV_COLOR_HEX((color_test.r << 16) | (color_test.g << 8) | color_test.b);
617
color_test.box_style.body.grad_color = color_test.box_style.body.main_color;
618
lv_obj_set_style(color_test.box, &color_test.box_style);
619
620
char shade[8];
621
s_printf(shade, "%03d", color_test.b);
622
lv_label_set_text(color_test.b_label, shade);
623
}
624
625
return LV_RES_OK;
626
}
627
628
static lv_res_t _preset_bg_apply(lv_obj_t *btn)
629
{
630
color_test.bg = (color_test.r << 16) | (color_test.g << 8) | color_test.b;
631
632
_show_new_nyx_color(true);
633
634
return LV_RES_OK;
635
}
636
637
static lv_res_t _preset_bg_black(lv_obj_t *btn)
638
{
639
color_test.bg = 0;
640
641
_show_new_nyx_color(true);
642
643
return LV_RES_OK;
644
}
645
646
static lv_res_t _preset_bg_reset(lv_obj_t *btn)
647
{
648
color_test.r = 0x2D;
649
color_test.g = 0x2D;
650
color_test.b = 0x2D;
651
color_test.bg = 0x2D2D2D;
652
653
color_test.box_style.body.main_color = LV_COLOR_HEX(color_test.bg);
654
color_test.box_style.body.grad_color = color_test.box_style.body.main_color;
655
lv_obj_set_style(color_test.box, &color_test.box_style);
656
657
lv_bar_set_value(color_test.r_slider, color_test.r);
658
lv_bar_set_value(color_test.g_slider, color_test.g);
659
lv_bar_set_value(color_test.b_slider, color_test.b);
660
661
char shade[8];
662
s_printf(shade, "%03d", color_test.r);
663
lv_label_set_text(color_test.r_label, shade);
664
lv_label_set_text(color_test.g_label, shade);
665
lv_label_set_text(color_test.b_label, shade);
666
667
_show_new_nyx_color(true);
668
669
return LV_RES_OK;
670
}
671
672
static lv_res_t _preset_hue_action(lv_obj_t *btn)
673
{
674
lv_btn_ext_t *ext = lv_obj_get_ext_attr(btn);
675
676
if (color_test.hue != ext->idx)
677
{
678
color_test.hue = ext->idx;
679
680
char hue[8];
681
s_printf(hue, "%03d", color_test.hue);
682
lv_label_set_text(color_test.hue_label, hue);
683
lv_bar_set_value(color_test.hue_slider, color_test.hue);
684
685
_show_new_nyx_color(false);
686
}
687
688
return LV_RES_OK;
689
}
690
691
static const u16 theme_colors[18] = {
692
0, 4, 13, 23, 33, 43, 54, 66, 89, 124, 167, 187, 200, 208, 231, 261, 291, 341
693
};
694
695
lv_res_t _action_win_nyx_colors_close(lv_obj_t * btn)
696
{
697
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_COVER);
698
lv_obj_set_click(status_bar.mid, true);
699
700
return nyx_win_close_action(btn);
701
}
702
703
static lv_res_t _create_window_nyx_colors(lv_obj_t *btn)
704
{
705
lv_obj_t *win = nyx_create_standard_window(SYMBOL_COPY" Nyx Color Theme", _action_win_nyx_colors_close);
706
lv_win_add_btn(win, NULL, SYMBOL_SAVE" Save & Reload", _action_win_nyx_colors_save);
707
color_test.window = win;
708
709
// Set current theme colors.
710
color_test.bg = n_cfg.theme_bg;
711
color_test.hue = n_cfg.theme_color;
712
u32 bg = n_cfg.theme_bg ? n_cfg.theme_bg : 0x2D2D2D;
713
color_test.r = (bg >> 16) & 0xFF;
714
color_test.g = (bg >> 8) & 0xFF;
715
color_test.b = (bg >> 0) & 0xFF;
716
717
lv_style_copy(&color_test.box_style, &lv_style_plain_color);
718
color_test.box_style.body.main_color = LV_COLOR_HEX(color_test.bg);
719
color_test.box_style.body.grad_color = color_test.box_style.body.main_color;
720
color_test.box_style.body.border.color = LV_COLOR_HEX(0xFFFFFF);
721
color_test.box_style.body.border.opa = LV_OPA_20;
722
color_test.box_style.body.border.width = 2;
723
724
// Create container to keep content inside.
725
lv_obj_t *h1 = lv_cont_create(win, NULL);
726
lv_obj_set_size(h1, LV_DPI * 299 / 25, LV_DPI * 27 / 26);
727
color_test.header1 = h1;
728
729
lv_obj_t *acc_label = lv_label_create(h1, NULL);
730
lv_label_set_static_text(acc_label, "Accent color:");
731
732
// Create color preset buttons.
733
lv_obj_t *color_btn = lv_btn_create(h1, NULL);
734
lv_btn_ext_t *ext = lv_obj_get_ext_attr(color_btn);
735
ext->idx = theme_colors[0];
736
create_flat_button(color_btn, ext->idx, _preset_hue_action);
737
lv_obj_align(color_btn, acc_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 10);
738
lv_obj_t *color_btn2;
739
740
for (u32 i = 1; i < ARRAY_SIZE(theme_colors); i++)
741
{
742
color_btn2 = lv_btn_create(h1, NULL);
743
ext = lv_obj_get_ext_attr(color_btn2);
744
ext->idx = theme_colors[i];
745
create_flat_button(color_btn2, ext->idx, _preset_hue_action);
746
lv_obj_align(color_btn2, color_btn, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
747
color_btn = color_btn2;
748
}
749
750
lv_obj_align(h1, NULL, LV_ALIGN_IN_TOP_MID, 0, LV_DPI / 5);
751
752
// Create hue slider.
753
lv_obj_t *h_slider = lv_slider_create(win, NULL);
754
lv_obj_set_width(h_slider, LV_DPI * 213 / 20);
755
lv_obj_set_height(h_slider, LV_DPI * 4 / 10);
756
lv_bar_set_range(h_slider, 0, 359);
757
lv_bar_set_value(h_slider, color_test.hue);
758
lv_slider_set_action(h_slider, _slider_hue_action);
759
lv_obj_align(h_slider, h1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 5);
760
color_test.hue_slider = h_slider;
761
762
// Create hue label.
763
lv_obj_t *hue_text_label = lv_label_create(win, NULL);
764
lv_obj_align(hue_text_label, h_slider, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 24 / 100, 0);
765
char txt[8];
766
s_printf(txt, "%03d", color_test.hue);
767
lv_label_set_text(hue_text_label, txt);
768
color_test.hue_label = hue_text_label;
769
770
lv_obj_t *bg_label = lv_label_create(win, NULL);
771
lv_label_set_static_text(bg_label, "Theme color:");
772
lv_obj_align(bg_label, h_slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 6 / 25);
773
774
// Create red slider.
775
lv_obj_t *r_slider = lv_slider_create(win, NULL);
776
lv_obj_set_width(r_slider, LV_DPI * 85 / 16);
777
lv_obj_set_height(r_slider, LV_DPI * 4 / 10);
778
lv_bar_set_range(r_slider, 11, 100);
779
lv_bar_set_value(r_slider, color_test.r);
780
lv_slider_set_action(r_slider, _slider_r_action);
781
lv_obj_align(r_slider, bg_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 21);
782
color_test.r_slider = r_slider;
783
784
// Create red label.
785
lv_obj_t *r_text_label = lv_label_create(win, NULL);
786
lv_obj_align(r_text_label, r_slider, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 24 / 100, 0);
787
s_printf(txt, "%03d", color_test.r);
788
lv_label_set_text(r_text_label, txt);
789
color_test.r_label = r_text_label;
790
791
// Create green slider.
792
lv_obj_t *g_slider = lv_slider_create(win, r_slider);
793
lv_bar_set_value(g_slider, color_test.g);
794
lv_slider_set_action(g_slider, _slider_g_action);
795
lv_obj_align(g_slider, r_slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 7);
796
color_test.g_slider = g_slider;
797
798
// Create green label.
799
lv_obj_t *g_text_label = lv_label_create(win, NULL);
800
lv_obj_align(g_text_label, g_slider, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 24 / 100, 0);
801
s_printf(txt, "%03d", color_test.g);
802
lv_label_set_text(g_text_label, txt);
803
color_test.g_label = g_text_label;
804
805
// Create blue slider.
806
lv_obj_t *b_slider = lv_slider_create(win, r_slider);
807
lv_bar_set_value(b_slider, color_test.b);
808
lv_slider_set_action(b_slider, _slider_b_action);
809
lv_obj_align(b_slider, g_slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 7);
810
color_test.b_slider = b_slider;
811
812
// Create blue label.
813
lv_obj_t *b_text_label = lv_label_create(win, NULL);
814
lv_obj_align(b_text_label, b_slider, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 24 / 100, 0);
815
s_printf(txt, "%03d", color_test.b);
816
lv_label_set_text(b_text_label, txt);
817
color_test.b_label = b_text_label;
818
819
// Create theme color box.
820
lv_obj_t * bg_box = lv_obj_create(win, NULL);
821
lv_obj_set_size(bg_box, LV_DPI * 10 / 7, LV_DPI * 18 / 13);
822
lv_obj_align(bg_box, r_text_label, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI / 4, 0);
823
lv_obj_set_style(bg_box, &color_test.box_style);
824
color_test.box = bg_box;
825
826
// Create theme color buttons.
827
lv_obj_t *btn_reset = lv_btn_create(win, NULL);
828
lv_obj_t *label_btn = lv_label_create(btn_reset, NULL);
829
lv_label_set_static_text(label_btn, SYMBOL_REFRESH" Grey");
830
lv_btn_set_fit(btn_reset, false, true);
831
lv_obj_set_width(btn_reset, LV_DPI * 5 / 3);
832
lv_btn_set_action(btn_reset, LV_BTN_ACTION_CLICK, _preset_bg_reset);
833
lv_obj_align(btn_reset, bg_box, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI / 5, 0);
834
color_test.btn_reset = btn_reset;
835
836
lv_obj_t *btn_black = lv_btn_create(win, btn_reset);
837
label_btn = lv_label_create(btn_black, NULL);
838
lv_label_set_static_text(label_btn, SYMBOL_BRIGHTNESS" Black");
839
lv_btn_set_action(btn_black, LV_BTN_ACTION_CLICK, _preset_bg_black);
840
lv_obj_align(btn_black, btn_reset, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI / 5, 0);
841
color_test.btn_black = btn_black;
842
843
lv_obj_t *btn_apply = lv_btn_create(win, btn_reset);
844
label_btn = lv_label_create(btn_apply, NULL);
845
lv_label_set_static_text(label_btn, SYMBOL_LIST" Custom Color");
846
lv_obj_set_width(btn_apply, LV_DPI * 10 / 3 + LV_DPI / 5);
847
lv_btn_set_action(btn_apply, LV_BTN_ACTION_CLICK, _preset_bg_apply);
848
lv_obj_align(btn_apply, btn_reset, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 7);
849
color_test.btn_apply = btn_apply;
850
851
// Create sample text.
852
lv_obj_t *h2 = lv_cont_create(win, NULL);
853
lv_obj_set_size(h2, LV_DPI * 12, LV_DPI * 18 / 10);
854
lv_obj_align(h2, b_slider, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI * 6 / 25);
855
color_test.header2 = h2;
856
857
lv_obj_t *lbl_sample = lv_label_create(h2, NULL);
858
lv_label_set_static_text(lbl_sample, "Accent sample:");
859
860
lv_obj_t *lbl_test = lv_label_create(h2, NULL);
861
lv_label_set_long_mode(lbl_test, LV_LABEL_LONG_BREAK);
862
lv_label_set_static_text(lbl_test,
863
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
864
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
865
lv_obj_set_width(lbl_test, LV_DPI * 261 / 23);
866
lv_obj_align(lbl_test, lbl_sample, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 34);
867
color_test.label = lbl_test;
868
869
// Create sample icons.
870
lv_obj_t *lbl_icons = lv_label_create(h2, NULL);
871
lv_label_set_static_text(lbl_icons,
872
SYMBOL_BRIGHTNESS SYMBOL_CHARGE SYMBOL_FILE SYMBOL_DRIVE SYMBOL_FILE_CODE
873
SYMBOL_EDIT SYMBOL_HINT SYMBOL_DRIVE SYMBOL_KEYBOARD SYMBOL_POWER);
874
lv_obj_align(lbl_icons, lbl_test, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 5);
875
color_test.icons = lbl_icons;
876
877
// Create sample slider.
878
lv_obj_t *slider_test = lv_slider_create(h2, NULL);
879
lv_obj_align(slider_test, lbl_test, LV_ALIGN_OUT_BOTTOM_MID, 0, LV_DPI / 5);
880
lv_obj_set_click(slider_test, false);
881
lv_bar_set_value(slider_test, 60);
882
color_test.slider = slider_test;
883
884
// Create sample button.
885
lv_obj_t *btn_test = lv_btn_create(h2, NULL);
886
lv_btn_set_state(btn_test, LV_BTN_STATE_TGL_PR);
887
lv_label_create(btn_test, NULL);
888
lv_btn_set_fit(btn_test, false, true);
889
lv_obj_set_width(btn_test, LV_DPI * 5 / 3);
890
lv_obj_align(btn_test, lbl_test, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, LV_DPI / 20);
891
lv_obj_set_click(btn_test, false);
892
color_test.button = btn_test;
893
894
_show_new_nyx_color(false);
895
896
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_0);
897
lv_obj_set_click(status_bar.mid, false);
898
899
return LV_RES_OK;
900
}
901
902
typedef struct _time_edit_obj_t
903
{
904
lv_obj_t *year;
905
lv_obj_t *month;
906
lv_obj_t *day;
907
lv_obj_t *hour;
908
lv_obj_t *min;
909
} time_edit_obj_t;
910
911
time_edit_obj_t clock_ctxt;
912
913
static lv_res_t _action_clock_edit(lv_obj_t *btns, const char * txt)
914
{
915
int btn_idx = lv_btnm_get_pressed(btns);
916
917
if (btn_idx == 1)
918
{
919
rtc_time_t time;
920
max77620_rtc_get_time(&time);
921
u32 epoch = max77620_rtc_date_to_epoch(&time);
922
923
u32 year = lv_roller_get_selected(clock_ctxt.year) + CLOCK_MIN_YEAR;
924
u32 month = lv_roller_get_selected(clock_ctxt.month) + 1;
925
u32 day = lv_roller_get_selected(clock_ctxt.day) + 1;
926
u32 hour = lv_roller_get_selected(clock_ctxt.hour);
927
u32 min = lv_roller_get_selected(clock_ctxt.min);
928
929
switch (month)
930
{
931
case 2:
932
if (!(year % 4) && day > 29)
933
day = 29;
934
else if (day > 28)
935
day = 28;
936
break;
937
case 4:
938
case 6:
939
case 9:
940
case 11:
941
if (day > 30)
942
day = 30;
943
break;
944
}
945
946
time.year = year;
947
time.month = month;
948
time.day = day;
949
time.hour = hour;
950
time.min = min;
951
952
u32 new_epoch = max77620_rtc_date_to_epoch(&time);
953
954
// Stored in u32 and allow overflow for integer offset casting.
955
n_cfg.timeoffset = new_epoch - epoch;
956
957
// If canceled set 1 for invalidating first boot clock edit.
958
if (!n_cfg.timeoffset)
959
n_cfg.timeoffset = 1;
960
else
961
{
962
// Adjust for DST between 28 march and 28 october.
963
// Good enough to cover all years as week info is not valid.
964
u16 md = (time.month << 8) | time.day;
965
if (n_cfg.timedst && md >= 0x31C && md < 0xA1C)
966
n_cfg.timeoffset -= 3600; // Store time in non DST.
967
max77620_rtc_set_epoch_offset((int)n_cfg.timeoffset);
968
}
969
970
nyx_changes_made = true;
971
}
972
973
nyx_mbox_action(btns, txt);
974
975
return LV_RES_INV;
976
}
977
978
static lv_res_t _action_clock_edit_save(lv_obj_t *btns, const char * txt)
979
{
980
_action_clock_edit(btns, txt);
981
982
// Save if changes were made.
983
if (nyx_changes_made)
984
_save_nyx_options_action(NULL);
985
986
return LV_RES_INV;
987
}
988
989
static lv_res_t _action_auto_dst_toggle(lv_obj_t *btn)
990
{
991
n_cfg.timedst = !n_cfg.timedst;
992
max77620_rtc_set_auto_dst(n_cfg.timedst);
993
994
if (!n_cfg.timedst)
995
lv_btn_set_state(btn, LV_BTN_STATE_REL);
996
else
997
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
998
999
nyx_generic_onoff_toggle(btn);
1000
1001
return LV_RES_OK;
1002
}
1003
1004
static const u32 month_days[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
1005
1006
static lv_res_t _action_date_validation(lv_obj_t *roller)
1007
{
1008
u32 year = lv_roller_get_selected(clock_ctxt.year) + CLOCK_MIN_YEAR;
1009
u32 month = lv_roller_get_selected(clock_ctxt.month) + 1;
1010
u32 day = lv_roller_get_selected(clock_ctxt.day) + 1;
1011
1012
// Adjust max day based on year and month.
1013
u32 max_mon_day = month_days[month - 1];
1014
u32 max_feb_day = !(year % 4) ? 29 : 28;
1015
if (month == 2 && day > max_feb_day)
1016
lv_roller_set_selected(clock_ctxt.day, max_feb_day - 1, false);
1017
else if (day > max_mon_day)
1018
lv_roller_set_selected(clock_ctxt.day, max_mon_day - 1, false);
1019
1020
return LV_RES_OK;
1021
}
1022
1023
static lv_res_t _create_mbox_clock_edit(lv_obj_t *btn)
1024
{
1025
static lv_style_t mbox_style;
1026
lv_theme_t *th = lv_theme_get_current();
1027
lv_style_copy(&mbox_style, th->mbox.bg);
1028
mbox_style.body.padding.inner = LV_DPI / 10;
1029
1030
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
1031
lv_obj_set_style(dark_bg, &mbox_darken);
1032
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
1033
1034
static const char *mbox_btn_map[] = { "\251", "\222Done", "\222Cancel", "\251", "" };
1035
lv_obj_t *mbox = lv_mbox_create(dark_bg, NULL);
1036
lv_mbox_set_style(mbox, LV_MBOX_STYLE_BG, &mbox_style);
1037
lv_mbox_set_recolor_text(mbox, true);
1038
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 6);
1039
1040
lv_mbox_set_text(mbox, "Enter #C7EA46 Date# and #C7EA46 Time# for Nyx\n"
1041
"Used in all file operations and menu.\n"
1042
"This doesn't alter the actual HW clock!");
1043
1044
lv_obj_t *padding = lv_cont_create(mbox, NULL);
1045
lv_cont_set_fit(padding, true, false);
1046
lv_cont_set_style(padding, &lv_style_transp);
1047
lv_obj_set_height(padding, LV_DPI / 10);
1048
1049
// Get current time.
1050
rtc_time_t time;
1051
max77620_rtc_get_time_adjusted(&time);
1052
1053
// Normalize year if out of range.
1054
if (time.year < CLOCK_MIN_YEAR)
1055
time.year = CLOCK_MIN_YEAR;
1056
else if (time.year > CLOCK_MAX_YEAR)
1057
time.year = CLOCK_MAX_YEAR;
1058
1059
time.year -= CLOCK_MIN_YEAR;
1060
1061
lv_obj_t *h1 = lv_cont_create(mbox, NULL);
1062
lv_cont_set_fit(h1, true, true);
1063
1064
// Create year roller.
1065
lv_obj_t *roller_year = lv_roller_create(h1, NULL);
1066
lv_roller_set_options(roller_year, CLOCK_YEARLIST);
1067
lv_roller_set_selected(roller_year, time.year, false);
1068
lv_roller_set_visible_row_count(roller_year, 3);
1069
lv_roller_set_action(roller_year, _action_date_validation);
1070
clock_ctxt.year = roller_year;
1071
1072
// Create month roller.
1073
lv_obj_t *roller_month = lv_roller_create(h1, roller_year);
1074
lv_roller_set_options(roller_month,
1075
"January\n"
1076
"February\n"
1077
"March\n"
1078
"April\n"
1079
"May\n"
1080
"June\n"
1081
"July\n"
1082
"August\n"
1083
"September\n"
1084
"October\n"
1085
"November\n"
1086
"December");
1087
lv_roller_set_selected(roller_month, time.month - 1, false);
1088
lv_obj_align(roller_month, roller_year, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
1089
lv_roller_set_action(roller_month, _action_date_validation);
1090
clock_ctxt.month = roller_month;
1091
1092
// Create day roller.
1093
static char days[256];
1094
days[0] = 0;
1095
for (u32 i = 1; i < 32; i++)
1096
s_printf(days + strlen(days), " %d \n", i);
1097
days[strlen(days) - 1] = 0;
1098
lv_obj_t *roller_day = lv_roller_create(h1, roller_year);
1099
lv_roller_set_options(roller_day, days);
1100
lv_roller_set_selected(roller_day, time.day - 1, false);
1101
lv_roller_set_action(roller_day, _action_date_validation);
1102
lv_obj_align(roller_day, roller_month, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
1103
clock_ctxt.day = roller_day;
1104
1105
// Create hours roller.
1106
static char hours[256];
1107
hours[0] = 0;
1108
for (u32 i = 0; i < 24; i++)
1109
s_printf(hours + strlen(hours), " %d \n", i);
1110
hours[strlen(hours) - 1] = 0;
1111
lv_obj_t *roller_hour = lv_roller_create(h1, roller_year);
1112
lv_roller_set_options(roller_hour, hours);
1113
lv_roller_set_selected(roller_hour, time.hour, false);
1114
lv_obj_align(roller_hour, roller_day, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 2, 0);
1115
clock_ctxt.hour = roller_hour;
1116
1117
// Create minutes roller.
1118
static char minutes[512];
1119
minutes[0] = 0;
1120
for (u32 i = 0; i < 60; i++)
1121
s_printf(minutes + strlen(minutes), " %02d \n", i);
1122
minutes[strlen(minutes) - 1] = 0;
1123
lv_obj_t *roller_minute = lv_roller_create(h1, roller_year);
1124
lv_roller_set_options(roller_minute, minutes);
1125
lv_roller_set_selected(roller_minute, time.min, false);
1126
lv_obj_align(roller_minute, roller_hour, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
1127
clock_ctxt.min = roller_minute;
1128
1129
// Add DST option.
1130
lv_obj_t *btn_dst = lv_btn_create(mbox, NULL);
1131
nyx_create_onoff_button(th, h1, btn_dst, SYMBOL_BRIGHTNESS" Auto Daylight Saving Time", _action_auto_dst_toggle, true);
1132
if (n_cfg.timedst)
1133
lv_btn_set_state(btn_dst, LV_BTN_STATE_TGL_REL);
1134
nyx_generic_onoff_toggle(btn_dst);
1135
1136
// If btn is empty, save options also because it was launched from boot.
1137
lv_mbox_add_btns(mbox, mbox_btn_map, btn ? _action_clock_edit : _action_clock_edit_save);
1138
1139
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
1140
lv_obj_set_top(mbox, true);
1141
1142
return LV_RES_OK;
1143
}
1144
1145
void first_time_clock_edit(void *param)
1146
{
1147
_create_mbox_clock_edit(NULL);
1148
}
1149
1150
static lv_res_t _joycon_info_dump_action(lv_obj_t * btn)
1151
{
1152
FIL fp;
1153
int error = 0;
1154
int cal_error = 0;
1155
bool is_l_hos = false;
1156
bool is_r_hos = false;
1157
u32 joycon_found = 0;
1158
bool nx_hoag = fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG;
1159
jc_gamepad_rpt_t *jc_pad = jc_get_bt_pairing_info(&is_l_hos, &is_r_hos);
1160
1161
char *data = (char *)malloc(SZ_16K);
1162
char *txt_buf = (char *)malloc(SZ_4K);
1163
1164
if (!nx_hoag && !jc_pad)
1165
error = 255;
1166
1167
// Try 2 times to get factory calibration data.
1168
for (u32 i = 0; i < 2; i++)
1169
{
1170
if (!error)
1171
cal_error = hos_dump_cal0();
1172
if (!cal_error)
1173
break;
1174
}
1175
1176
if (cal_error && nx_hoag)
1177
error = cal_error;
1178
1179
if (error)
1180
goto disabled_or_cal0_issue;
1181
1182
if (nx_hoag)
1183
goto save_data;
1184
1185
// Count valid joycon.
1186
joycon_found = jc_pad->bt_conn_l.type ? 1 : 0;
1187
if (jc_pad->bt_conn_r.type)
1188
joycon_found++;
1189
1190
// Reset PC based for dumping.
1191
jc_pad->bt_conn_l.type = is_l_hos ? jc_pad->bt_conn_l.type : 0;
1192
jc_pad->bt_conn_r.type = is_r_hos ? jc_pad->bt_conn_r.type : 0;
1193
1194
save_data:
1195
error = sd_mount() ? 5 : 0;
1196
1197
if (!error)
1198
{
1199
nx_emmc_cal0_t *cal0 = (nx_emmc_cal0_t *)cal0_buf;
1200
1201
f_mkdir("switchroot");
1202
1203
if (!nx_hoag)
1204
{
1205
// Save binary dump.
1206
memcpy(data, &jc_pad->bt_conn_l, sizeof(jc_bt_conn_t));
1207
memcpy(data + sizeof(jc_bt_conn_t), &jc_pad->bt_conn_r, sizeof(jc_bt_conn_t));
1208
1209
error = sd_save_to_file((u8 *)data, sizeof(jc_bt_conn_t) * 2, "switchroot/joycon_mac.bin") ? 4 : 0;
1210
1211
// Save readable dump.
1212
data[0] = 0;
1213
for (u32 i = 0; i < 2; i++)
1214
{
1215
jc_bt_conn_t *bt = !i ? &jc_pad->bt_conn_l : &jc_pad->bt_conn_r;
1216
s_printf(data + strlen(data),
1217
"[joycon_0%d]\ntype=%d\nmac=%02X:%02X:%02X:%02X:%02X:%02X\n"
1218
"host=%02X:%02X:%02X:%02X:%02X:%02X\n"
1219
"ltk=%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n\n",
1220
i, bt->type, bt->mac[0], bt->mac[1], bt->mac[2], bt->mac[3], bt->mac[4], bt->mac[5],
1221
bt->host_mac[0], bt->host_mac[1], bt->host_mac[2], bt->host_mac[3], bt->host_mac[4], bt->host_mac[5],
1222
bt->ltk[0], bt->ltk[1], bt->ltk[2], bt->ltk[3], bt->ltk[4], bt->ltk[5], bt->ltk[6], bt->ltk[7],
1223
bt->ltk[8], bt->ltk[9], bt->ltk[10], bt->ltk[11], bt->ltk[12], bt->ltk[13], bt->ltk[14], bt->ltk[15]);
1224
}
1225
1226
if (!error)
1227
error = f_open(&fp, "switchroot/joycon_mac.ini", FA_WRITE | FA_CREATE_ALWAYS) ? 4 : 0;
1228
if (!error)
1229
{
1230
f_puts(data, &fp);
1231
f_close(&fp);
1232
}
1233
1234
// Save IMU Calibration data.
1235
if (!error && !cal_error)
1236
{
1237
s_printf(data,
1238
"imu_type=%d\n\n"
1239
"acc_cal_off_x=0x%X\n"
1240
"acc_cal_off_y=0x%X\n"
1241
"acc_cal_off_z=0x%X\n"
1242
"acc_cal_scl_x=0x%X\n"
1243
"acc_cal_scl_y=0x%X\n"
1244
"acc_cal_scl_z=0x%X\n\n"
1245
1246
"gyr_cal_off_x=0x%X\n"
1247
"gyr_cal_off_y=0x%X\n"
1248
"gyr_cal_off_z=0x%X\n"
1249
"gyr_cal_scl_x=0x%X\n"
1250
"gyr_cal_scl_y=0x%X\n"
1251
"gyr_cal_scl_z=0x%X\n\n"
1252
1253
"device_bt_mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
1254
cal0->console_6axis_sensor_type,
1255
cal0->acc_offset[0], cal0->acc_offset[1], cal0->acc_offset[2],
1256
cal0->acc_scale[0], cal0->acc_scale[1], cal0->acc_scale[2],
1257
cal0->gyro_offset[0], cal0->gyro_offset[1], cal0->gyro_offset[2],
1258
cal0->gyro_scale[0], cal0->gyro_scale[1], cal0->gyro_scale[2],
1259
cal0->bd_mac[0], cal0->bd_mac[1], cal0->bd_mac[2], cal0->bd_mac[3], cal0->bd_mac[4], cal0->bd_mac[5]);
1260
1261
error = f_open(&fp, "switchroot/switch.cal", FA_WRITE | FA_CREATE_ALWAYS) ? 4 : 0;
1262
if (!error)
1263
{
1264
f_puts(data, &fp);
1265
f_close(&fp);
1266
}
1267
}
1268
}
1269
else
1270
{
1271
jc_calib_t *stick_cal_l = (jc_calib_t *)cal0->analog_stick_cal_l;
1272
jc_calib_t *stick_cal_r = (jc_calib_t *)cal0->analog_stick_cal_r;
1273
1274
// Save Lite Gamepad and IMU Calibration data.
1275
// Actual max/min are right/left and up/down offsets.
1276
// Sticks: 0x23: H1 (Hosiden), 0x25: H5 (Hosiden), 0x41: F1 (FIT), ?add missing?
1277
s_printf(data,
1278
"lite_cal_l_type=0x%X\n"
1279
"lite_cal_lx_lof=0x%X\n"
1280
"lite_cal_lx_cnt=0x%X\n"
1281
"lite_cal_lx_rof=0x%X\n"
1282
"lite_cal_ly_dof=0x%X\n"
1283
"lite_cal_ly_cnt=0x%X\n"
1284
"lite_cal_ly_uof=0x%X\n\n"
1285
1286
"lite_cal_r_type=0x%X\n"
1287
"lite_cal_rx_lof=0x%X\n"
1288
"lite_cal_rx_cnt=0x%X\n"
1289
"lite_cal_rx_rof=0x%X\n"
1290
"lite_cal_ry_dof=0x%X\n"
1291
"lite_cal_ry_cnt=0x%X\n"
1292
"lite_cal_ry_uof=0x%X\n\n"
1293
1294
"imu_type=%d\n\n"
1295
"acc_cal_off_x=0x%X\n"
1296
"acc_cal_off_y=0x%X\n"
1297
"acc_cal_off_z=0x%X\n"
1298
"acc_cal_scl_x=0x%X\n"
1299
"acc_cal_scl_y=0x%X\n"
1300
"acc_cal_scl_z=0x%X\n\n"
1301
1302
"gyr_cal_off_x=0x%X\n"
1303
"gyr_cal_off_y=0x%X\n"
1304
"gyr_cal_off_z=0x%X\n"
1305
"gyr_cal_scl_x=0x%X\n"
1306
"gyr_cal_scl_y=0x%X\n"
1307
"gyr_cal_scl_z=0x%X\n\n"
1308
1309
"device_bt_mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
1310
cal0->analog_stick_type_l,
1311
stick_cal_l->x_min, stick_cal_l->x_center, stick_cal_l->x_max,
1312
stick_cal_l->y_min, stick_cal_l->y_center, stick_cal_l->y_max,
1313
cal0->analog_stick_type_r,
1314
stick_cal_r->x_min, stick_cal_r->x_center, stick_cal_r->x_max,
1315
stick_cal_r->y_min, stick_cal_r->y_center, stick_cal_r->y_max,
1316
cal0->console_6axis_sensor_type,
1317
cal0->acc_offset[0], cal0->acc_offset[1], cal0->acc_offset[2],
1318
cal0->acc_scale[0], cal0->acc_scale[1], cal0->acc_scale[2],
1319
cal0->gyro_offset[0], cal0->gyro_offset[1], cal0->gyro_offset[2],
1320
cal0->gyro_scale[0], cal0->gyro_scale[1], cal0->gyro_scale[2],
1321
cal0->bd_mac[0], cal0->bd_mac[1], cal0->bd_mac[2], cal0->bd_mac[3], cal0->bd_mac[4], cal0->bd_mac[5]);
1322
if (!error)
1323
error = f_open(&fp, "switchroot/switch.cal", FA_WRITE | FA_CREATE_ALWAYS) ? 4 : 0;
1324
if (!error)
1325
{
1326
f_puts(data, &fp);
1327
f_close(&fp);
1328
}
1329
}
1330
1331
sd_unmount();
1332
}
1333
1334
disabled_or_cal0_issue:;
1335
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
1336
lv_obj_set_style(dark_bg, &mbox_darken);
1337
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
1338
1339
static const char *mbox_btn_map[] = { "\251", "\222OK", "\251", "" };
1340
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
1341
lv_mbox_set_recolor_text(mbox, true);
1342
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
1343
1344
if (!error)
1345
{
1346
if (!nx_hoag)
1347
{
1348
s_printf(txt_buf,
1349
"Dumping to SD card finished!\n"
1350
"Saved to: #C7EA46 switchroot/joycon_mac.[bin/ini]#\n\n");
1351
1352
bool success = true;
1353
1354
// Check if pairing info was found.
1355
if (joycon_found == 2)
1356
strcat(txt_buf, "#C7EA46 Success!#\n#C7EA46 Found 2 out of 2 Joy-Con pairing data!#\n");
1357
else
1358
{
1359
s_printf(txt_buf + strlen(txt_buf), "#FF8000 Failed!#\n#FF8000 Warning:# Found #FFDD00 %d out of 2# pairing data!\n", joycon_found);
1360
success = false;
1361
}
1362
1363
// Check if pairing was done in HOS.
1364
if (is_l_hos && is_r_hos)
1365
strcat(txt_buf, "#C7EA46 Both pairing data are HOS based!#");
1366
else if (!is_l_hos && is_r_hos)
1367
{
1368
strcat(txt_buf, "#FF8000 Warning:# #FFDD00 Left# pairing data is not HOS based!");
1369
success = false;
1370
}
1371
else if (is_l_hos && !is_r_hos)
1372
{
1373
strcat(txt_buf, "#FF8000 Warning:# #FFDD00 Right# pairing data is not HOS based!");
1374
success = false;
1375
}
1376
else
1377
{
1378
strcat(txt_buf, "#FF8000 Warning:# #FFDD00 No# pairing data is HOS based!");
1379
success = false;
1380
}
1381
1382
if (!success)
1383
strcat(txt_buf,
1384
"\n\n#FFDD00 Make sure that both Joy-Con are connected,#\n"
1385
"#FFDD00 and that you paired them in HOS!#");
1386
1387
if (cal_error)
1388
s_printf(txt_buf + strlen(txt_buf), "\n\n#FF8000 Warning: Failed (%d) to get IMU calibration!#", cal_error);
1389
}
1390
else
1391
{
1392
s_printf(txt_buf,
1393
"Dumping to SD card finished!\n"
1394
"Saved to: #C7EA46 switchroot/switch.cal#\n\n");
1395
strcat(txt_buf, "#C7EA46 Success!#\n#C7EA46 Found Lite Gamepad data!#\n");
1396
}
1397
}
1398
else
1399
{
1400
if (!nx_hoag)
1401
s_printf(txt_buf, "#FFDD00 Failed to dump Joy-Con pairing info!#\n#FFDD00 Error: %d#", error);
1402
else
1403
s_printf(txt_buf, "#FFDD00 Failed to get Lite Gamepad info!#\n#FFDD00 Error: %d#", error);
1404
}
1405
1406
lv_mbox_set_text(mbox, txt_buf);
1407
1408
lv_mbox_add_btns(mbox, mbox_btn_map, nyx_mbox_action); // Important. After set_text.
1409
1410
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
1411
lv_obj_set_top(mbox, true);
1412
1413
free(txt_buf);
1414
free(data);
1415
1416
return LV_RES_OK;
1417
}
1418
1419
static lv_res_t _home_screen_action(lv_obj_t *ddlist)
1420
{
1421
u32 new_selection = lv_ddlist_get_selected(ddlist);
1422
if (n_cfg.home_screen != new_selection)
1423
{
1424
n_cfg.home_screen = new_selection;
1425
nyx_changes_made = true;
1426
}
1427
1428
return LV_RES_OK;
1429
}
1430
1431
static lv_res_t _action_nyx_options_save(lv_obj_t *btns, const char * txt)
1432
{
1433
int btn_idx = lv_btnm_get_pressed(btns);
1434
1435
nyx_mbox_action(btns, txt);
1436
1437
if (!btn_idx)
1438
_save_nyx_options_action(NULL);
1439
1440
return LV_RES_INV;
1441
}
1442
1443
static void _check_nyx_changes()
1444
{
1445
if (nyx_changes_made)
1446
{
1447
lv_obj_t *dark_bg = lv_obj_create(lv_scr_act(), NULL);
1448
lv_obj_set_style(dark_bg, &mbox_darken);
1449
lv_obj_set_size(dark_bg, LV_HOR_RES, LV_VER_RES);
1450
1451
static const char * mbox_btn_map[] = { "\222Save", "\222Cancel", "" };
1452
lv_obj_t * mbox = lv_mbox_create(dark_bg, NULL);
1453
lv_mbox_set_recolor_text(mbox, true);
1454
1455
lv_mbox_set_text(mbox,
1456
"#FF8000 Nyx configuration#\n\n"
1457
"You changed the configuration!\n\n"
1458
"Do you want to save it?");
1459
1460
lv_mbox_add_btns(mbox, mbox_btn_map, _action_nyx_options_save);
1461
lv_obj_set_width(mbox, LV_HOR_RES / 9 * 5);
1462
lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
1463
lv_obj_set_top(mbox, true);
1464
1465
nyx_changes_made = false;
1466
}
1467
}
1468
1469
static lv_res_t _action_win_nyx_options_close(lv_obj_t *btn)
1470
{
1471
// Hide status bar options save button.
1472
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_0);
1473
lv_obj_set_click(status_bar.mid, false);
1474
1475
lv_res_t res = nyx_win_close_action(btn);
1476
1477
_check_nyx_changes();
1478
1479
return res;
1480
}
1481
1482
lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
1483
{
1484
lv_theme_t *th = lv_theme_get_current();
1485
1486
lv_obj_t *win = nyx_create_standard_window(SYMBOL_HOME" Nyx Settings", _action_win_nyx_options_close);
1487
1488
static lv_style_t h_style;
1489
lv_style_copy(&h_style, &lv_style_transp);
1490
h_style.body.padding.inner = 0;
1491
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
1492
h_style.body.padding.ver = LV_DPI / 6;
1493
1494
// Create containers to keep content inside.
1495
lv_obj_t * sw_h2 = lv_cont_create(win, NULL);
1496
lv_cont_set_style(sw_h2, &h_style);
1497
lv_cont_set_fit(sw_h2, false, true);
1498
lv_obj_set_width(sw_h2, (LV_HOR_RES / 9) * 4);
1499
lv_obj_set_click(sw_h2, false);
1500
lv_cont_set_layout(sw_h2, LV_LAYOUT_OFF);
1501
1502
lv_obj_t * sw_h3 = lv_cont_create(win, NULL);
1503
lv_cont_set_style(sw_h3, &h_style);
1504
lv_cont_set_fit(sw_h3, false, true);
1505
lv_obj_set_width(sw_h3, (LV_HOR_RES / 9) * 4);
1506
lv_obj_set_click(sw_h3, false);
1507
lv_cont_set_layout(sw_h3, LV_LAYOUT_OFF);
1508
lv_obj_align(sw_h3, sw_h2, LV_ALIGN_OUT_RIGHT_TOP, LV_DPI * 11 / 25, 0);
1509
1510
lv_obj_t * l_cont = lv_cont_create(sw_h2, NULL);
1511
lv_cont_set_style(l_cont, &lv_style_transp_tight);
1512
lv_cont_set_fit(l_cont, true, true);
1513
lv_obj_set_click(l_cont, false);
1514
lv_cont_set_layout(l_cont, LV_LAYOUT_OFF);
1515
lv_obj_set_opa_scale(l_cont, LV_OPA_40);
1516
1517
lv_obj_t *label_sep = lv_label_create(sw_h2, NULL);
1518
lv_label_set_static_text(label_sep, "");
1519
1520
// Create theme button.
1521
lv_obj_t *btn = lv_btn_create(sw_h2, NULL);
1522
lv_obj_t *label_btn = lv_label_create(btn, NULL);
1523
lv_btn_set_fit(btn, true, true);
1524
lv_label_set_static_text(label_btn, SYMBOL_COPY" Color Theme");
1525
lv_obj_align(btn, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI / 5 + 3);
1526
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _create_window_nyx_colors);
1527
1528
lv_obj_t *label_txt2 = lv_label_create(sw_h2, NULL);
1529
lv_label_set_recolor(label_txt2, true);
1530
lv_label_set_static_text(label_txt2, "Customize #C7EA46 Theme# and #C7EA46 Accent# colors in Nyx.\n");
1531
lv_obj_set_style(label_txt2, &hint_small_style);
1532
lv_obj_align(label_txt2, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3 - 8);
1533
1534
// Create home screen settings list.
1535
lv_obj_t *line_sep = lv_line_create(sw_h2, NULL);
1536
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
1537
lv_line_set_points(line_sep, line_pp, 2);
1538
lv_line_set_style(line_sep, th->line.decor);
1539
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1540
1541
lv_obj_t *label_txt = lv_label_create(l_cont, NULL);
1542
lv_label_set_static_text(label_txt, SYMBOL_HOME" Home Screen");
1543
lv_obj_set_style(label_txt, th->label.prim);
1544
lv_obj_align(label_txt, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1545
1546
lv_obj_t *ddlist = lv_ddlist_create(l_cont, NULL);
1547
lv_obj_set_top(ddlist, true);
1548
lv_ddlist_set_draw_arrow(ddlist, true);
1549
lv_ddlist_set_options(ddlist,
1550
"Main menu \n"
1551
"All Configs\n"
1552
"Launch\n"
1553
"More Configs");
1554
lv_ddlist_set_selected(ddlist, n_cfg.home_screen);
1555
lv_ddlist_set_action(ddlist, _home_screen_action);
1556
lv_obj_align(ddlist, label_txt, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 2 / 3, 0);
1557
1558
label_txt2 = lv_label_create(l_cont, NULL);
1559
lv_label_set_recolor(label_txt2, true);
1560
lv_label_set_static_text(label_txt2,
1561
"Select what screen to show on Nyx boot.\n"
1562
"#FF8000 All Configs:# #C7EA46 Combines More configs into Launch empty slots.#\n"
1563
"#FF8000 Launch / More Configs:# #C7EA46 Uses the classic divided view.#");
1564
lv_obj_set_style(label_txt2, &hint_small_style);
1565
lv_obj_align(label_txt2, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
1566
1567
line_sep = lv_line_create(sw_h2, line_sep);
1568
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1569
1570
// Create entries per line button.
1571
lv_obj_t *btn2 = lv_btn_create(sw_h2, NULL);
1572
nyx_create_onoff_button(th, sw_h2, btn2, SYMBOL_GPS" Extended Boot Entries", _entries_columns_action, true);
1573
lv_obj_align(btn2, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 10);
1574
if (n_cfg.entries_5_col)
1575
lv_btn_set_state(btn2, LV_BTN_STATE_TGL_REL);
1576
nyx_generic_onoff_toggle(btn2);
1577
1578
label_txt2 = lv_label_create(sw_h2, NULL);
1579
lv_label_set_recolor(label_txt2, true);
1580
lv_label_set_static_text(label_txt2,
1581
"Sets the boot entries per line to 5. (Default is 4)\n"
1582
"#C7EA46 This allows a total of 10 boot entries to be shown in Launch#\n"
1583
"#C7EA46 and More Configs sections.#\n\n\n");
1584
lv_obj_set_style(label_txt2, &hint_small_style);
1585
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 12);
1586
1587
// Create the second column.
1588
label_sep = lv_label_create(sw_h3, NULL);
1589
lv_label_set_static_text(label_sep, "");
1590
1591
// Create Dump Joy-Con BT button.
1592
lv_obj_t *btn3 = lv_btn_create(sw_h3, NULL);
1593
lv_obj_t *label_btn3 = lv_label_create(btn3, NULL);
1594
lv_btn_set_fit(btn3, true, true);
1595
lv_label_set_static_text(label_btn3, SYMBOL_DOWNLOAD" Dump Joy-Con BT");
1596
lv_obj_align(btn3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI / 3);
1597
lv_btn_set_action(btn3, LV_BTN_ACTION_CLICK, _joycon_info_dump_action);
1598
1599
label_txt2 = lv_label_create(sw_h3, NULL);
1600
lv_label_set_recolor(label_txt2, true);
1601
lv_label_set_static_text(label_txt2,
1602
"Allows you to save the Switch and Joy-Con MAC addresses\n"
1603
"and the LTKs associated with them. For #C7EA46 Android# and #C7EA46 Linux#.");
1604
lv_obj_set_style(label_txt2, &hint_small_style);
1605
lv_obj_align(label_txt2, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
1606
1607
line_sep = lv_line_create(sw_h3, line_sep);
1608
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1609
1610
// Create Backup/Restore Verification list.
1611
label_txt = lv_label_create(sw_h3, NULL);
1612
lv_label_set_static_text(label_txt, SYMBOL_MODULES_ALT" Data Verification");
1613
lv_obj_set_style(label_txt, th->label.prim);
1614
lv_obj_align(label_txt, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1615
1616
lv_obj_t *ddlist2 = lv_ddlist_create(sw_h3, NULL);
1617
lv_obj_set_top(ddlist2, true);
1618
lv_ddlist_set_draw_arrow(ddlist2, true);
1619
lv_ddlist_set_options(ddlist2,
1620
"Off (Fastest)\n"
1621
"Sparse (Fast) \n"
1622
"Full (Slow)\n"
1623
"Full (Hashes)");
1624
lv_ddlist_set_selected(ddlist2, n_cfg.verification);
1625
lv_obj_align(ddlist2, label_txt, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 3 / 8, 0);
1626
lv_ddlist_set_action(ddlist2, _data_verification_action);
1627
1628
label_txt2 = lv_label_create(sw_h3, NULL);
1629
lv_label_set_static_text(label_txt2, "Set the type of data verification done for backup and restore.\n"
1630
"Can be canceled without losing the backup/restore.\n");
1631
lv_obj_set_style(label_txt2, &hint_small_style);
1632
lv_obj_align(label_txt2, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
1633
1634
line_sep = lv_line_create(sw_h3, line_sep);
1635
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1636
1637
// Create clock edit button.
1638
lv_obj_t *btn5 = lv_btn_create(sw_h3, NULL);
1639
lv_obj_t *label_btn5 = lv_label_create(btn5, NULL);
1640
lv_btn_set_fit(btn5, true, true);
1641
lv_label_set_static_text(label_btn5, SYMBOL_CLOCK" Clock (Offset)");
1642
lv_obj_align(btn5, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1643
lv_btn_set_action(btn5, LV_BTN_ACTION_CLICK, _create_mbox_clock_edit);
1644
1645
label_txt2 = lv_label_create(sw_h3, NULL);
1646
lv_label_set_recolor(label_txt2, true);
1647
lv_label_set_static_text(label_txt2,
1648
"Change clock offset manually.\n"
1649
"#C7EA46 The entered Date and Time will be converted to an offset#\n"
1650
"#C7EA46 automatically. This will be also used for FatFS operations.#");
1651
lv_obj_set_style(label_txt2, &hint_small_style);
1652
lv_obj_align(label_txt2, btn5, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
1653
1654
// Enable save options button in status bar and set action.
1655
lv_btn_set_action(status_bar.mid, LV_BTN_ACTION_CLICK, _save_nyx_options_action);
1656
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_COVER);
1657
lv_obj_set_click(status_bar.mid, true);
1658
1659
lv_obj_set_top(l_cont, true); // Set the ddlist container at top.
1660
lv_obj_set_parent(ddlist, l_cont); // Reorder ddlist.
1661
lv_obj_set_top(ddlist, true);
1662
lv_obj_set_top(ddlist2, true);
1663
1664
return LV_RES_OK;
1665
}
1666
1667
void create_tab_options(lv_theme_t *th, lv_obj_t *parent)
1668
{
1669
lv_page_set_scrl_layout(parent, LV_LAYOUT_PRETTY);
1670
1671
static lv_style_t h_style;
1672
lv_style_copy(&h_style, &lv_style_transp);
1673
h_style.body.padding.inner = 0;
1674
h_style.body.padding.hor = LV_DPI - (LV_DPI / 4);
1675
h_style.body.padding.ver = LV_DPI / 6;
1676
1677
// Create containers to keep content inside.
1678
lv_obj_t * sw_h2 = lv_cont_create(parent, NULL);
1679
lv_cont_set_style(sw_h2, &h_style);
1680
lv_cont_set_fit(sw_h2, false, true);
1681
lv_obj_set_width(sw_h2, (LV_HOR_RES / 9) * 4);
1682
lv_obj_set_click(sw_h2, false);
1683
lv_cont_set_layout(sw_h2, LV_LAYOUT_OFF);
1684
1685
lv_obj_t * sw_h3 = lv_cont_create(parent, NULL);
1686
lv_cont_set_style(sw_h3, &h_style);
1687
lv_cont_set_fit(sw_h3, false, true);
1688
lv_obj_set_width(sw_h3, (LV_HOR_RES / 9) * 4);
1689
lv_obj_set_click(sw_h3, false);
1690
lv_cont_set_layout(sw_h3, LV_LAYOUT_OFF);
1691
1692
lv_obj_t * l_cont = lv_cont_create(sw_h2, NULL);
1693
lv_cont_set_style(l_cont, &lv_style_transp_tight);
1694
lv_cont_set_fit(l_cont, true, true);
1695
lv_obj_set_click(l_cont, false);
1696
lv_cont_set_layout(l_cont, LV_LAYOUT_OFF);
1697
lv_obj_set_opa_scale(l_cont, LV_OPA_40);
1698
1699
lv_obj_t *label_sep = lv_label_create(sw_h2, NULL);
1700
lv_label_set_static_text(label_sep, "");
1701
1702
// Create Auto Boot button.
1703
lv_obj_t *btn = lv_btn_create(sw_h2, NULL);
1704
if (hekate_bg)
1705
{
1706
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &btn_transp_rel);
1707
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_transp_pr);
1708
lv_btn_set_style(btn, LV_BTN_STYLE_TGL_REL, &btn_transp_tgl_rel);
1709
lv_btn_set_style(btn, LV_BTN_STYLE_TGL_PR, &btn_transp_tgl_pr);
1710
}
1711
lv_btn_set_layout(btn, LV_LAYOUT_OFF);
1712
lv_obj_t *label_btn = lv_label_create(btn, NULL);
1713
lv_label_set_recolor(label_btn, true);
1714
lv_btn_set_fit(btn, true, true);
1715
lv_btn_set_toggle(btn, true);
1716
lv_label_set_static_text(label_btn, SYMBOL_GPS" Auto Boot #00FFC9 ON #");
1717
lv_btn_set_action(btn, LV_BTN_ACTION_CLICK, _autoboot_hide_delay_action);
1718
lv_obj_align(btn, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, -LV_DPI / 18 + 6);
1719
lv_btn_set_fit(btn, false, false);
1720
autoboot_btn = btn;
1721
1722
lv_obj_t *label_txt2 = lv_label_create(sw_h2, NULL);
1723
lv_label_set_static_text(label_txt2, "Choose which boot entry or payload to automatically boot\nwhen injecting.");
1724
lv_obj_set_style(label_txt2, &hint_small_style);
1725
lv_obj_align(label_txt2, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3 - 4);
1726
1727
lv_obj_t *line_sep = lv_line_create(sw_h2, NULL);
1728
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
1729
lv_line_set_points(line_sep, line_pp, 2);
1730
lv_line_set_style(line_sep, th->line.decor);
1731
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1732
1733
// Create Boot time delay list.
1734
lv_obj_t *label_txt = lv_label_create(l_cont, NULL);
1735
lv_label_set_static_text(label_txt, SYMBOL_CLOCK" Boot Time Delay ");
1736
lv_obj_set_style(label_txt, th->label.prim);
1737
lv_obj_align(label_txt, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1738
1739
lv_obj_t *ddlist = lv_ddlist_create(l_cont, NULL);
1740
lv_obj_set_top(ddlist, true);
1741
lv_ddlist_set_draw_arrow(ddlist, true);
1742
lv_ddlist_set_options(ddlist,
1743
"No bootlogo \n"
1744
"1 second\n"
1745
"2 seconds\n"
1746
"3 seconds\n"
1747
"4 seconds\n"
1748
"5 seconds\n"
1749
"6 seconds");
1750
lv_ddlist_set_selected(ddlist, 3);
1751
lv_obj_align(ddlist, label_txt, LV_ALIGN_OUT_RIGHT_MID, LV_DPI / 4, 0);
1752
lv_ddlist_set_action(ddlist, _autoboot_delay_action);
1753
lv_ddlist_set_selected(ddlist, h_cfg.bootwait);
1754
1755
if (hekate_bg)
1756
{
1757
lv_ddlist_set_style(ddlist, LV_DDLIST_STYLE_BG, &ddlist_transp_bg);
1758
lv_ddlist_set_style(ddlist, LV_DDLIST_STYLE_BGO, &ddlist_transp_bg);
1759
lv_ddlist_set_style(ddlist, LV_DDLIST_STYLE_PR, &ddlist_transp_sel);
1760
lv_ddlist_set_style(ddlist, LV_DDLIST_STYLE_SEL, &ddlist_transp_sel);
1761
}
1762
1763
label_txt2 = lv_label_create(l_cont, NULL);
1764
lv_label_set_recolor(label_txt2, true);
1765
lv_label_set_static_text(label_txt2,
1766
"Set how long to show bootlogo when autoboot is enabled.\n"
1767
"#C7EA46 You can press# #FF8000 VOL-# #C7EA46 during that time to enter hekate's menu.#\n");
1768
lv_obj_set_style(label_txt2, &hint_small_style);
1769
lv_obj_align(label_txt2, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
1770
1771
line_sep = lv_line_create(sw_h2, line_sep);
1772
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1773
1774
// Create Auto NoGC button.
1775
lv_obj_t *btn2 = lv_btn_create(sw_h2, NULL);
1776
nyx_create_onoff_button(th, sw_h2, btn2, SYMBOL_CHIP" Auto NoGC", auto_nogc_toggle, true);
1777
lv_obj_align(btn2, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 10);
1778
1779
label_txt2 = lv_label_create(sw_h2, NULL);
1780
lv_label_set_recolor(label_txt2, true);
1781
lv_label_set_static_text(label_txt2,
1782
"It checks fuses and applies the patch automatically\n"
1783
"if higher firmware. It is now a global config and set\n"
1784
"at auto by default. (ON: Auto)\n\n\n");
1785
lv_obj_set_style(label_txt2, &hint_small_style);
1786
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 12);
1787
1788
label_sep = lv_label_create(sw_h3, NULL);
1789
lv_label_set_static_text(label_sep, "");
1790
1791
// Create Auto HOS Power Off button.
1792
lv_obj_t *btn3 = lv_btn_create(sw_h3, NULL);
1793
nyx_create_onoff_button(th, sw_h3, btn3, SYMBOL_POWER" Auto HOS Power Off", auto_hos_poweroff_toggle, true);
1794
lv_obj_align(btn3, label_sep, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
1795
1796
label_txt2 = lv_label_create(sw_h3, NULL);
1797
lv_label_set_static_text(label_txt2,
1798
"When Shutdown is used from HOS, the device wakes up after\n"
1799
"15s. Enable this to automatically power off on the next\npayload injection.");
1800
lv_obj_set_style(label_txt2, &hint_small_style);
1801
lv_obj_align(label_txt2, btn3, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 12);
1802
1803
line_sep = lv_line_create(sw_h3, line_sep);
1804
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1805
1806
// Create Backlight slider.
1807
label_txt = lv_label_create(sw_h3, NULL);
1808
lv_label_set_static_text(label_txt, SYMBOL_BRIGHTNESS" Backlight");
1809
lv_obj_set_style(label_txt, th->label.prim);
1810
lv_obj_align(label_txt, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
1811
1812
lv_obj_t * slider = lv_slider_create(sw_h3, NULL);
1813
lv_obj_set_width(slider, LV_DPI * 80 / 34);
1814
//lv_obj_set_height(slider, LV_DPI * 4 / 10);
1815
lv_bar_set_range(slider, 30, 220);
1816
lv_bar_set_value(slider, h_cfg.backlight);
1817
lv_slider_set_action(slider, _slider_brightness_action);
1818
lv_obj_align(slider, label_txt, LV_ALIGN_OUT_RIGHT_MID, LV_DPI * 20 / 15, 0);
1819
1820
label_txt2 = lv_label_create(sw_h3, NULL);
1821
lv_label_set_static_text(label_txt2, "Set backlight brightness.\n\n");
1822
lv_obj_set_style(label_txt2, &hint_small_style);
1823
lv_obj_align(label_txt2, label_txt, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
1824
1825
line_sep = lv_line_create(sw_h3, line_sep);
1826
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
1827
1828
// Create Update r2p button.
1829
lv_obj_t *btn4 = lv_btn_create(sw_h3, NULL);
1830
nyx_create_onoff_button(th, sw_h3, btn4, SYMBOL_REFRESH" Update Reboot 2 Payload", _update_r2p_action, true);
1831
lv_obj_align(btn4, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 10);
1832
1833
label_txt2 = lv_label_create(sw_h3, NULL);
1834
lv_label_set_recolor(label_txt2, true);
1835
lv_label_set_static_text(label_txt2,
1836
"If #FF8000 FSS0# is used in the selected boot entry, the reboot 2 payload\n"
1837
"binary will be checked and forced to be updated to hekate.\n\n\n\n");
1838
lv_obj_set_style(label_txt2, &hint_small_style);
1839
lv_obj_align(label_txt2, btn4, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 12);
1840
1841
// Set default loaded states.
1842
if (h_cfg.autohosoff)
1843
lv_btn_set_state(btn3, LV_BTN_STATE_TGL_REL);
1844
if (h_cfg.autonogc)
1845
lv_btn_set_state(btn2, LV_BTN_STATE_TGL_REL);
1846
if (h_cfg.updater2p)
1847
lv_btn_set_state(btn4, LV_BTN_STATE_TGL_REL);
1848
1849
nyx_generic_onoff_toggle(btn2);
1850
nyx_generic_onoff_toggle(btn3);
1851
nyx_generic_onoff_toggle(btn4);
1852
_autoboot_hide_delay_action(btn);
1853
1854
lv_obj_set_top(l_cont, true); // Set the ddlist container at top.
1855
lv_obj_set_parent(ddlist, l_cont); // Reorder ddlist.
1856
lv_obj_set_top(ddlist, true);
1857
}
1858
1859