nyx: add no box and 5 entries per line support

Icons that have `_nobox.bmp` in their name will make the grey background disappear.

Additionally a new option was added in Nyx Options called `Extended Boot Entries` that allows user to have a total of 10 entries showing up in Launch and More configs menus.
This commit is contained in:
CTCaer 2022-05-13 03:49:32 +03:00
parent b9cdf5d697
commit c2ff5dbd1c
9 changed files with 151 additions and 47 deletions

View File

@ -167,9 +167,11 @@ If the main .ini is not found, it is created on the first hekate boot and only h
| Config option | Description |
| ------------------ | ---------------------------------------------------------- |
| themecolor=167 | Sets Nyx color of text highlights. |
| entries5col=0 | 1: Sets Launch entry columns from 4 to 5 per line. For a total of 10 entries. |
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
| ------------------ | ------- The following options can only be edited in nyx.ini ------- |
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
| jcdisable=0 | 1: Disables Joycon driver completely. |
| jcforceright=0 | 1: Forces right joycon to be used as main mouse control. |

View File

@ -4,14 +4,16 @@ The bootlogo can be any size with a maximum of 720 x 1280.
When it's smaller than 720 x 1280, it is automatically centered and the background takes the color of the first pixel.
When saving a landscape bootlogo, it should be rotated 90 degrees counterclockwise.
The process is to create a landscape bootlogo and then rotate it 90 degrees counterclockwise.
Lastly, the supported format is 32-bit (ARGB) BMP. Classic 24-bit (RGB) BMPs are not supported for performance reasons.
## How to configure
If a boot entry specifies a custom logo path (`logopath=`), this is one will be loaded.
If a boot entry specifies a custom logo path (`logopath=`), this one will be loaded.
If the above is not found or the format is not correct, it will try to load `bootloader/bootlogo.bmp`.
If this is not found, the default hekate logo will be used.
(`bootloader/bootlogo.bmp` is basically like a global bootlogo.)

View File

@ -2,10 +2,12 @@
The background for Nyx, must be a 1280 x 720 32-bit BMP. Alpha blending is taken into account. For that reason, if a solid background is required, that value must be 0xFF. There are sites that can produce the correct bmp.
The icons supported are 192 x 192 32-bit BMP. You can utilize transparency at will and make nice mixes with the button background.
The icons supported are 192 x 192 32-bit BMP. You can utilize transparency at will and make nice mixes with the button background.
Additionally, using the `icon={sd path}`, the icon will get colorized if the name ends in `_hue.bmp`. That only works nicely if the icon is a white layout with transparency.
If `_nobox.bmp` is used then the button background is removed. Useful for icon themes that aim for a specific style.
The default system icons (`icon_switch.bmp` and `icon_payload.bmp`) can be replaced with white layouts that have transparency. They can also be replaced with normal icons if the following exist: `icon_switch_custom.bmp` or/and `icon_payload_custom.bmp`
@ -13,4 +15,4 @@ The default system icons (`icon_switch.bmp` and `icon_payload.bmp`) can be repla
The background must go to /bootloader/res/background.bmp
The icons can be utilized either via `[boot entries names]` -> `boot entries names.bmp` or by using `icon={sd path}`, which should point at a bmp.
The icons can be utilized either via `[boot entries names]` -> `boot entries names.bmp` or by using `icon={sd path}` (preferred method), which should point at a bmp.

View File

@ -46,7 +46,8 @@ void set_default_configuration()
void set_nyx_default_configuration()
{
n_cfg.themecolor = 167;
n_cfg.theme_color = 167;
n_cfg.entries_5_columns = 0;
n_cfg.timeoff = 0;
n_cfg.home_screen = 0;
n_cfg.verification = 1;
@ -194,7 +195,10 @@ int create_nyx_config_entry(bool force_unmount)
// Add config entry.
f_puts("[config]\nthemecolor=", &fp);
itoa(n_cfg.themecolor, lbuf, 10);
itoa(n_cfg.theme_color, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\nentries5col=", &fp);
itoa(n_cfg.entries_5_columns, lbuf, 10);
f_puts(lbuf, &fp);
f_puts("\ntimeoff=", &fp);
itoa(n_cfg.timeoff, lbuf, 16);

View File

@ -42,7 +42,8 @@ typedef struct _hekate_config
typedef struct _nyx_config
{
u32 themecolor;
u32 theme_color;
u32 entries_5_columns;
u32 timeoff;
u32 home_screen;
u32 verification;

View File

@ -62,16 +62,6 @@ lv_style_t mbox_darken;
char *text_color;
typedef struct _gui_status_bar_ctx
{
lv_obj_t *mid;
lv_obj_t *time_temp;
lv_obj_t *temp_symbol;
lv_obj_t *temp_degrees;
lv_obj_t *battery;
lv_obj_t *battery_more;
} gui_status_bar_ctx;
typedef struct _jc_lv_driver_t
{
lv_indev_t *indev;
@ -92,7 +82,7 @@ typedef struct _jc_lv_driver_t
static jc_lv_driver_t jc_drv_ctx;
static gui_status_bar_ctx status_bar;
gui_status_bar_ctx status_bar;
static void _nyx_disp_init()
{
@ -1411,8 +1401,8 @@ out_end:
}
typedef struct _launch_menu_entries_t
{
lv_obj_t *btn[16];
lv_obj_t *label[16];
lv_obj_t *btn[20];
lv_obj_t *label[20];
} launch_menu_entries_t;
static launch_menu_entries_t launch_ctxt;
@ -1543,24 +1533,49 @@ typedef struct _launch_button_pos_t
u16 btn_y;
u16 lbl_x;
u16 lbl_y;
} launch_button_pos_t;
static const launch_button_pos_t launch_button_pos[8] = {
static const launch_button_pos_t launch_button_pos8[8] = {
// First row.
{ 19, 36, 0, 245 },
{ 340, 36, 321, 245 },
{ 661, 36, 642, 245 },
{ 982, 36, 963, 245 },
// Second row.
{ 19, 313, 0, 522 },
{ 340, 313, 321, 522 },
{ 661, 313, 642, 522 },
{ 982, 313, 963, 522 }
};
static const launch_button_pos_t launch_button_pos10[10] = {
// First row.
{ 19, 36, 0, 245},
{260, 36, 241, 245},
{501, 36, 482, 245},
{742, 36, 723, 245},
{983, 36, 964, 245},
// Second row.
{ 19, 313, 0, 522},
{260, 313, 241, 522},
{501, 313, 482, 522},
{742, 313, 723, 522},
{983, 313, 964, 522}
};
static lv_res_t _create_window_home_launch(lv_obj_t *btn)
{
const u32 max_entries = n_cfg.entries_5_columns ? 10 : 8;
const launch_button_pos_t *launch_button_pos = n_cfg.entries_5_columns ? launch_button_pos10 : launch_button_pos8;
char *icon_path;
static lv_style_t btn_home_noborder_rel;
lv_style_copy(&btn_home_noborder_rel, lv_theme_get_current()->btn.rel);
btn_home_noborder_rel.body.opa = LV_OPA_0;
btn_home_noborder_rel.body.border.width = 4;
btn_home_noborder_rel.body.border.opa = LV_OPA_0;
static lv_style_t btn_home_transp_rel;
lv_style_copy(&btn_home_transp_rel, lv_theme_get_current()->btn.rel);
btn_home_transp_rel.body.opa = LV_OPA_0;
@ -1611,14 +1626,12 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
lv_cont_set_fit(lv_page_get_scrl(lv_win_get_content(win)), false, false);
lv_page_set_scrl_height(lv_win_get_content(win), 572);
lv_btn_ext_t * ext;
lv_obj_t *btn_boot_entry;
lv_obj_t *boot_entry_lbl_cont;
lv_obj_t *boot_entry_label;
bool no_boot_entries = false;
u32 max_entries = 8;
lv_btn_ext_t * ext;
// Create CFW buttons.
// Buttons are 200 x 200 with 4 pixel borders.
// Icons must be <= 192 x 192.
@ -1644,7 +1657,7 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
lv_obj_set_style(boot_entry_lbl_cont, &btn_label_home_transp);
// Create the rest of the buttons.
for (u32 btn_idx = 1; btn_idx < 8; btn_idx++)
for (u32 btn_idx = 1; btn_idx < (n_cfg.entries_5_columns ? 10 : 8); btn_idx++)
{
btn_boot_entry = lv_btn_create(win, btn_boot_entry);
launch_ctxt.btn[btn_idx] = btn_boot_entry;
@ -1659,7 +1672,7 @@ static lv_res_t _create_window_home_launch(lv_obj_t *btn)
// Create colorized icon style based on its parrent style.
static lv_style_t img_style;
lv_style_copy(&img_style, &lv_style_plain);
img_style.image.color = lv_color_hsv_to_rgb(n_cfg.themecolor, 100, 100);
img_style.image.color = lv_color_hsv_to_rgb(n_cfg.theme_color, 100, 100);
img_style.image.intense = LV_OPA_COVER;
// Parse ini boot entries and set buttons/icons.
@ -1704,6 +1717,7 @@ ini_parsing:
icon_path = NULL;
bool payload = false;
bool img_colorize = false;
bool img_noborder = false;
lv_img_dsc_t *bmp = NULL;
lv_obj_t *img = NULL;
@ -1728,6 +1742,10 @@ ini_parsing:
bmp = bmp_to_lvimg_obj(tmp_path);
if (bmp)
img_colorize = true;
s_printf(tmp_path, "bootloader/res/%s_nobox.bmp", ini_sec->name);
bmp = bmp_to_lvimg_obj(tmp_path);
if (bmp)
img_noborder = true;
}
if (!bmp && payload)
@ -1745,6 +1763,10 @@ ini_parsing:
// Check if colorization is enabled.
if (bmp && strlen(icon_path) > 8 && !memcmp(icon_path + strlen(icon_path) - 8, "_hue", 4))
img_colorize = true;
// Check if no border is enabled.
if (bmp && strlen(icon_path) > 8 && !memcmp(icon_path + strlen(icon_path) - 10, "_nobox", 4))
img_noborder = true;
}
// Enable button.
@ -1772,11 +1794,28 @@ ini_parsing:
// Add button mask/radius and align icon.
lv_obj_t *btn = lv_btn_create(launch_ctxt.btn[curr_btn_idx], NULL);
lv_obj_set_size(btn, 200, 200);
lv_btn_set_style(btn, LV_BTN_STYLE_REL, &btn_home_transp_rel);
u32 btn_width = 200;
u32 btn_height = 200;
if (img_noborder)
{
btn_width = bmp->header.w + 4;
btn_height = bmp->header.h + 4;
if (btn_width > 200)
btn_width = 200;
if (btn_height > 200)
btn_height = 200;
lv_btn_set_style(launch_ctxt.btn[curr_btn_idx], LV_BTN_STYLE_REL, &btn_home_noborder_rel);
lv_btn_set_style(launch_ctxt.btn[curr_btn_idx], LV_BTN_STYLE_PR, &btn_home_noborder_rel);
}
lv_obj_set_size(btn, btn_width, btn_height);
lv_btn_set_style(btn, LV_BTN_STYLE_REL, img_noborder ? &btn_home_noborder_rel : &btn_home_transp_rel);
lv_btn_set_style(btn, LV_BTN_STYLE_PR, &btn_home_transp_pr);
if (img)
lv_obj_align(img, NULL, LV_ALIGN_CENTER, 0, 0);
if (img_noborder)
lv_obj_align(btn, NULL, LV_ALIGN_CENTER, 0, 0);
// Set autoboot index.
ext = lv_obj_get_ext_attr(btn);
@ -1808,7 +1847,7 @@ ini_parsing:
ini_parse_failed:
// Reiterate the loop with more cfgs if combined.
if (combined_cfg && (curr_btn_idx < 8) && !more_cfg)
if (combined_cfg && (curr_btn_idx < (n_cfg.entries_5_columns ? 10 : 8)) && !more_cfg)
goto ini_parsing;
failed_sd_mount:
@ -2094,6 +2133,7 @@ static lv_res_t _show_hide_save_button(lv_obj_t *tv, uint16_t tab_idx)
{
if (tab_idx == 4) // Options.
{
lv_btn_set_action(status_bar.mid, LV_BTN_ACTION_CLICK, _save_options_action);
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_COVER);
lv_obj_set_click(status_bar.mid, true);
}
@ -2174,7 +2214,7 @@ static void _nyx_set_default_styles(lv_theme_t * th)
tabview_btn_tgl_pr.body.grad_color = tabview_btn_tgl_pr.body.main_color;
tabview_btn_tgl_pr.body.opa = 35;
lv_color_t tmp_color = lv_color_hsv_to_rgb(n_cfg.themecolor, 100, 100);
lv_color_t tmp_color = lv_color_hsv_to_rgb(n_cfg.theme_color, 100, 100);
text_color = malloc(32);
s_printf(text_color, "#%06X", (u32)(tmp_color.full & 0xFFFFFF));
}
@ -2351,7 +2391,7 @@ void nyx_load_and_run()
tmp451_init();
// Set hekate theme based on chosen hue.
lv_theme_t *th = lv_theme_hekate_init(n_cfg.themecolor, NULL);
lv_theme_t *th = lv_theme_hekate_init(n_cfg.theme_color, NULL);
lv_theme_set_current(th);
// Create main menu

View File

@ -34,6 +34,17 @@ typedef struct _emmc_tool_gui_t
bool raw_emummc;
} emmc_tool_gui_t;
typedef struct _gui_status_bar_ctx
{
lv_obj_t *mid;
lv_obj_t *time_temp;
lv_obj_t *temp_symbol;
lv_obj_t *temp_degrees;
lv_obj_t *battery;
lv_obj_t *battery_more;
lv_obj_t *monitor;
} gui_status_bar_ctx;
extern lv_style_t hint_small_style;
extern lv_style_t hint_small_style_white;
extern lv_style_t monospace_text;
@ -56,6 +67,8 @@ extern lv_style_t mbox_darken;
extern char *text_color;
extern gui_status_bar_ctx status_bar;
void reload_nyx();
lv_img_dsc_t *bmp_to_lvimg_obj(const char *path);
lv_res_t mbox_action(lv_obj_t * btns, const char * txt);

View File

@ -328,6 +328,21 @@ static lv_res_t _data_verification_action(lv_obj_t *ddlist)
return LV_RES_OK;
}
static lv_res_t _entries_columns_action(lv_obj_t *btn)
{
n_cfg.entries_5_columns = !n_cfg.entries_5_columns;
nyx_changes_made = true;
if (!n_cfg.entries_5_columns)
lv_btn_set_state(btn, LV_BTN_STATE_REL);
else
lv_btn_set_state(btn, LV_BTN_STATE_TGL_REL);
nyx_generic_onoff_toggle(btn);
return LV_RES_OK;
}
static lv_res_t _save_nyx_options_action(lv_obj_t *btn)
{
static const char * mbox_btn_map[] = {"\211", "\222OK!", "\211", ""};
@ -395,7 +410,7 @@ color_test_ctxt color_test;
static lv_res_t _save_theme_color_action(lv_obj_t *btn)
{
n_cfg.themecolor = color_test.hue;
n_cfg.theme_color = color_test.hue;
// Save nyx config.
create_nyx_config_entry(true);
@ -472,7 +487,7 @@ static lv_res_t _create_window_nyx_colors(lv_obj_t *btn)
lv_win_add_btn(win, NULL, SYMBOL_SAVE" Save & Reload", _save_theme_color_action);
// Set current color.
color_test.hue = n_cfg.themecolor;
color_test.hue = n_cfg.theme_color;
lv_obj_t *sep = lv_label_create(win, NULL);
lv_label_set_static_text(sep, "");
@ -940,6 +955,10 @@ static void _check_nyx_changes()
static lv_res_t _action_win_nyx_options_close(lv_obj_t *btn)
{
// Hide status bar options save button.
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_0);
lv_obj_set_click(status_bar.mid, false);
lv_win_close_action(btn);
close_btn = NULL;
@ -987,6 +1006,7 @@ lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
lv_obj_t *label_sep = lv_label_create(sw_h2, NULL);
lv_label_set_static_text(label_sep, "");
// Create theme button.
lv_obj_t *btn = lv_btn_create(sw_h2, NULL);
lv_obj_t *label_btn = lv_label_create(btn, NULL);
lv_btn_set_fit(btn, true, true);
@ -1000,6 +1020,7 @@ lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
lv_obj_set_style(label_txt2, &hint_small_style);
lv_obj_align(label_txt2, btn, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 3 - 8);
// Create home screen settings list.
lv_obj_t *line_sep = lv_line_create(sw_h2, NULL);
static const lv_point_t line_pp[] = { {0, 0}, { LV_HOR_RES - (LV_DPI - (LV_DPI / 4)) * 2, 0} };
lv_line_set_points(line_sep, line_pp, 2);
@ -1035,22 +1056,24 @@ lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
line_sep = lv_line_create(sw_h2, line_sep);
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
// Create entries per line button.
lv_obj_t *btn2 = lv_btn_create(sw_h2, NULL);
lv_obj_t *label_btn2 = lv_label_create(btn2, NULL);
lv_btn_set_fit(btn2, true, true);
lv_label_set_static_text(label_btn2, SYMBOL_CLOCK" Clock (Offset)");
lv_obj_align(btn2, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, _create_mbox_clock_edit);
nyx_create_onoff_button(th, sw_h2, btn2, SYMBOL_GPS" Extended Boot Entries", _entries_columns_action, true);
lv_obj_align(btn2, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 10);
if (n_cfg.entries_5_columns)
lv_btn_set_state(btn2, LV_BTN_STATE_TGL_REL);
nyx_generic_onoff_toggle(btn2);
label_txt2 = lv_label_create(sw_h2, NULL);
lv_label_set_recolor(label_txt2, true);
lv_label_set_static_text(label_txt2,
"Change clock offset manually.\n"
"#C7EA46 The entered Date and Time will be converted to an offset#\n"
"#C7EA46 automatically. This will be also used for FatFS operations.#");
"Sets the boot entries per line to 5. (Default is 4)\n"
"#C7EA46 This allows a total of 10 boot entries to be shown in Launch#\n"
"#C7EA46 and More Configs sections.#\n\n\n");
lv_obj_set_style(label_txt2, &hint_small_style);
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
lv_obj_align(label_txt2, btn2, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 12);
// Create the second column.
label_sep = lv_label_create(sw_h3, NULL);
lv_label_set_static_text(label_sep, "");
@ -1100,12 +1123,27 @@ lv_res_t create_win_nyx_options(lv_obj_t *parrent_btn)
line_sep = lv_line_create(sw_h3, line_sep);
lv_obj_align(line_sep, label_txt2, LV_ALIGN_OUT_BOTTOM_LEFT, -(LV_DPI / 4), LV_DPI / 4);
// Create clock edit button.
lv_obj_t *btn5 = lv_btn_create(sw_h3, NULL);
lv_obj_t *label_btn5 = lv_label_create(btn5, NULL);
lv_btn_set_fit(btn5, true, true);
lv_label_set_static_text(label_btn5, SYMBOL_EDIT" Save Options");
lv_obj_align(btn5, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI * 31 / 21, LV_DPI * 6 / 8);
lv_btn_set_action(btn5, LV_BTN_ACTION_CLICK, _save_nyx_options_action);
lv_label_set_static_text(label_btn5, SYMBOL_CLOCK" Clock (Offset)");
lv_obj_align(btn5, line_sep, LV_ALIGN_OUT_BOTTOM_LEFT, LV_DPI / 4, LV_DPI / 4);
lv_btn_set_action(btn5, LV_BTN_ACTION_CLICK, _create_mbox_clock_edit);
label_txt2 = lv_label_create(sw_h3, NULL);
lv_label_set_recolor(label_txt2, true);
lv_label_set_static_text(label_txt2,
"Change clock offset manually.\n"
"#C7EA46 The entered Date and Time will be converted to an offset#\n"
"#C7EA46 automatically. This will be also used for FatFS operations.#");
lv_obj_set_style(label_txt2, &hint_small_style);
lv_obj_align(label_txt2, btn5, LV_ALIGN_OUT_BOTTOM_LEFT, 0, LV_DPI / 4);
// Enable save options button in status bar and set action.
lv_btn_set_action(status_bar.mid, LV_BTN_ACTION_CLICK, _save_nyx_options_action);
lv_obj_set_opa_scale(status_bar.mid, LV_OPA_COVER);
lv_obj_set_click(status_bar.mid, true);
lv_obj_set_top(l_cont, true); // Set the ddlist container at top.
lv_obj_set_parent(ddlist, l_cont); // Reorder ddlist.

View File

@ -260,7 +260,9 @@ skip_main_cfg_parse:
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp("themecolor", kv->key))
n_cfg.themecolor = atoi(kv->val);
n_cfg.theme_color = atoi(kv->val);
else if (!strcmp("entries5col", kv->key))
n_cfg.entries_5_columns = atoi(kv->val) == 1;
else if (!strcmp("timeoff", kv->key))
n_cfg.timeoff = strtol(kv->val, NULL, 16);
else if (!strcmp("homescreen", kv->key))