From 7f745e76aee567fb8a88932d0d2fe420fbf35803 Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Mon, 17 Apr 2023 21:44:31 +0200 Subject: [PATCH 1/7] Add new setting page for goggle OSD move osd mode from image settings to osd settings --- src/core/app_state.h | 7 + src/core/input_device.c | 6 +- src/core/settings.c | 40 ++- src/core/settings.h | 8 +- src/ui/page_common.c | 7 + src/ui/page_common.h | 2 + src/ui/page_imagesettings.c | 17 +- src/ui/page_osd.c | 549 ++++++++++++++++++++++++++++++++++++ src/ui/page_osd.h | 8 + src/ui/ui_image_setting.c | 42 +-- src/ui/ui_image_setting.h | 15 +- src/ui/ui_main_menu.c | 18 ++ src/ui/ui_main_menu.h | 1 + src/util/math.c | 11 + src/util/math.h | 1 + 15 files changed, 673 insertions(+), 59 deletions(-) create mode 100644 src/ui/page_osd.c create mode 100644 src/ui/page_osd.h diff --git a/src/core/app_state.h b/src/core/app_state.h index b9514852..2bcbd0f6 100644 --- a/src/core/app_state.h +++ b/src/core/app_state.h @@ -6,11 +6,18 @@ typedef enum { APP_STATE_MAINMENU = 0, APP_STATE_SUBMENU = 1, APP_STATE_PLAYBACK = 2, + + // in this state, the menu pages' on_roller is called, + // but the selected submenu item selection (e.g. pp_osd.p_arr.cur) + // is not automatically changed. + APP_STATE_SUBMENU_ITEM_FOCUSED = 3, APP_STATE_VIDEO = 10, APP_STATE_IMS = 11, APP_STATE_USER_INPUT_DISABLED = 20, + // TODO pages should set the on_roller callback and handle the input themselves + // instead of creating an app state. (use APP_STATE_SUBMENU_ITEM_FOCUSED) PAGE_FAN_SLIDE = 100, PAGE_ANGLE_SLIDE = 101, PAGE_POWER_SLIDE_CELL_COUNT = 102, diff --git a/src/core/input_device.c b/src/core/input_device.c index 2b218021..3389c683 100644 --- a/src/core/input_device.c +++ b/src/core/input_device.c @@ -222,7 +222,7 @@ static void btn_click(void) // short press enter key LOGI("level = 1"); app_state_push(APP_STATE_SUBMENU); submenu_enter(); - } else if ((g_app_state == APP_STATE_SUBMENU) || (g_app_state == APP_STATE_PLAYBACK)) { + } else if ((g_app_state == APP_STATE_SUBMENU) || (g_app_state == APP_STATE_SUBMENU_ITEM_FOCUSED) || (g_app_state == APP_STATE_PLAYBACK)) { submenu_click(); } else if (g_app_state == PAGE_FAN_SLIDE) { submenu_click(); @@ -283,6 +283,8 @@ static void roller_up(void) { menu_nav(DIAL_KEY_UP); } else if ((g_app_state == APP_STATE_SUBMENU) || (g_app_state == APP_STATE_PLAYBACK)) { submenu_roller(DIAL_KEY_UP); + } else if ((g_app_state == APP_STATE_SUBMENU_ITEM_FOCUSED)) { + submenu_roller_no_selection_change(DIAL_KEY_UP); } else if (g_app_state == APP_STATE_VIDEO) { if (g_source_info.source == SOURCE_HDZERO) tune_channel(DIAL_KEY_UP); @@ -318,6 +320,8 @@ static void roller_down(void) { menu_nav(DIAL_KEY_DOWN); } else if ((g_app_state == APP_STATE_SUBMENU) || (g_app_state == APP_STATE_PLAYBACK)) { submenu_roller(DIAL_KEY_DOWN); + } else if ((g_app_state == APP_STATE_SUBMENU_ITEM_FOCUSED)) { + submenu_roller_no_selection_change(DIAL_KEY_DOWN); } else if (g_app_state == APP_STATE_VIDEO) { if (g_source_info.source == SOURCE_HDZERO) tune_channel(DIAL_KEY_DOWN); diff --git a/src/core/settings.c b/src/core/settings.c index ce1ecb21..bcc923f0 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -41,7 +41,7 @@ const setting_t g_setting_defaults = { .power_ana = false, }, .source = { - .analog_format = SETTING_SOURCES_ANALOG_FORMAT_PAL + .analog_format = SETTING_SOURCES_ANALOG_FORMAT_PAL, }, .record = { .mode_manual = false, @@ -166,6 +166,44 @@ const setting_t g_setting_defaults = { .format = 0, }}; +int settings_put_osd_element_shown(bool show, char *config_name) { + char setting_key[128]; + + sprintf(setting_key, "element_%s_show", config_name); + return settings_put_bool("osd", setting_key, show); +} + +int settings_put_osd_element_pos_x(setting_osd_goggle_element_positions_t *pos, char *config_name) { + char setting_key[128]; + int ret = 0; + + sprintf(setting_key, "element_%s_pos_4_3_x", config_name); + ret = ini_putl("osd", setting_key, pos->mode_4_3.x, SETTING_INI); + sprintf(setting_key, "element_%s_pos_16_9_x", config_name); + ret &= ini_putl("osd", setting_key, pos->mode_16_9.x, SETTING_INI); + return ret; +} + +int settings_put_osd_element_pos_y(setting_osd_goggle_element_positions_t *pos, char *config_name) { + char setting_key[128]; + int ret = 0; + + sprintf(setting_key, "element_%s_pos_4_3_y", config_name); + ret = ini_putl("osd", setting_key, pos->mode_4_3.y, SETTING_INI); + sprintf(setting_key, "element_%s_pos_16_9_y", config_name); + ret &= ini_putl("osd", setting_key, pos->mode_16_9.y, SETTING_INI); + return ret; +} + +int settings_put_osd_element(setting_osd_goggle_element_t *element, char *config_name) { + int ret = 0; + + ret = settings_put_osd_element_shown(element->show, config_name); + ret &= settings_put_osd_element_pos_x(&element->position, config_name); + ret &= settings_put_osd_element_pos_y(&element->position, config_name); + return ret; +} + static void settings_load_osd_element(setting_osd_goggle_element_t *element, char *config_name, const setting_osd_goggle_element_t *defaults) { char buf[128]; diff --git a/src/core/settings.h b/src/core/settings.h index eb1d71a9..fbc628c9 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -193,5 +193,9 @@ extern const setting_t g_setting_defaults; void settings_reset(void); void settings_init(void); void settings_load(void); -bool settings_get_bool(char* section, char* key, bool default_val); -int settings_put_bool(char* section, char* key, bool value); +bool settings_get_bool(char *section, char *key, bool default_val); +int settings_put_bool(char *section, char *key, bool value); +int settings_put_osd_element(setting_osd_goggle_element_t *element, char *config_name); +int settings_put_osd_element_pos_y(setting_osd_goggle_element_positions_t *pos, char *config_name); +int settings_put_osd_element_pos_x(setting_osd_goggle_element_positions_t *pos, char *config_name); +int settings_put_osd_element_shown(bool show, char *config_name); \ No newline at end of file diff --git a/src/ui/page_common.c b/src/ui/page_common.c index 1fd52893..8507c4de 100644 --- a/src/ui/page_common.c +++ b/src/ui/page_common.c @@ -161,6 +161,13 @@ void create_slider_item(slider_group_t *slider_group, lv_obj_t *parent, const ch LV_GRID_ALIGN_CENTER, row, 1); } +void update_slider_item_with_value(slider_group_t *slider_group, int value) { + char str[20]; + sprintf(str, "%d", value); + lv_slider_set_value(slider_group->slider, value, LV_ANIM_OFF); + lv_label_set_text(slider_group->label, str); +} + void create_btn_item(lv_obj_t *parent, const char *name, int col, int row) { lv_obj_t *btn = lv_btn_create(parent); diff --git a/src/ui/page_common.h b/src/ui/page_common.h index 3b0a1262..54a82203 100644 --- a/src/ui/page_common.h +++ b/src/ui/page_common.h @@ -128,6 +128,8 @@ int create_text(struct menu_obj_s *s, lv_obj_t *parent, bool is_icon, const char void create_slider_item(slider_group_t *slider_group, lv_obj_t *parent, const char *name, int range, int default_value, int row); +void update_slider_item_with_value(slider_group_t *slider_group, int value); + void create_btn_item(lv_obj_t *parent, const char *name, int col, int row); lv_obj_t *create_dropdown_item(lv_obj_t *parent, const char *options, int col, int row); diff --git a/src/ui/page_imagesettings.c b/src/ui/page_imagesettings.c index 462c353f..168a3fef 100644 --- a/src/ui/page_imagesettings.c +++ b/src/ui/page_imagesettings.c @@ -55,9 +55,8 @@ static lv_obj_t *page_imagesettings_create(lv_obj_t *parent, panel_arr_t *arr) { create_slider_item(&slider_group2, cont, "Saturation", 47, g_setting.image.saturation, 2); create_slider_item(&slider_group3, cont, "Contrast", 47, g_setting.image.contrast, 3); create_slider_item(&slider_group4, cont, "OLED Auto off", 3, g_setting.image.auto_off, 4); - create_slider_item(&slider_group5, cont, "Embedded OSD Mode", 1, g_setting.osd.embedded_mode, 5); - create_label_item(cont, "< Back", 1, 6, 1); + create_label_item(cont, "< Back", 1, 5, 1); lv_obj_t *label2 = lv_label_create(cont); lv_label_set_text(label2, "To change image settings, click the Enter button to enter video mode. \nMake sure a HDZero VTX or analog VTX is powered on for live video."); @@ -67,7 +66,7 @@ static lv_obj_t *page_imagesettings_create(lv_obj_t *parent, panel_arr_t *arr) { lv_obj_set_style_pad_top(label2, 12, 0); lv_label_set_long_mode(label2, LV_LABEL_LONG_WRAP); lv_obj_set_grid_cell(label2, LV_GRID_ALIGN_START, 1, 4, - LV_GRID_ALIGN_START, 7, 2); + LV_GRID_ALIGN_START, 6, 2); set_slider_value(); @@ -101,16 +100,6 @@ void set_slider_value() { sprintf(buf, "%d min", g_setting.image.auto_off * 2 + 1); lv_label_set_text(slider_group4.label, buf); lv_slider_set_value(slider_group4.slider, g_setting.image.auto_off, LV_ANIM_OFF); - - switch (g_setting.osd.embedded_mode) { - case EMBEDDED_4x3: - lv_label_set_text(slider_group5.label, "4x3"); - break; - case EMBEDDED_16x9: - lv_label_set_text(slider_group5.label, "16x9"); - break; - } - lv_slider_set_value(slider_group5.slider, g_setting.osd.embedded_mode, LV_ANIM_OFF); } static void page_imagesettings_enter() { @@ -143,7 +132,7 @@ static void page_imagesettings_enter() { page_pack_t pp_imagesettings = { .p_arr = { .cur = 0, - .max = 7, + .max = 6, }, .name = "Image Settings", .create = page_imagesettings_create, diff --git a/src/ui/page_osd.c b/src/ui/page_osd.c new file mode 100644 index 00000000..c8656457 --- /dev/null +++ b/src/ui/page_osd.c @@ -0,0 +1,549 @@ +#include "page_osd.h" + +#include + +#include +#include + +#include "core/app_state.h" +#include "core/common.hh" +#include "core/osd.h" +#include "core/settings.h" +#include "page_common.h" +#include "ui/ui_style.h" +#include "util/math.h" + +#define OSD_ELEMENT_MIN_X_POS 0 +#define OSD_ELEMENT_MAX_X_POS 1280 +#define OSD_ELEMENT_MIN_Y_POS 0 +#define OSD_ELEMENT_MAX_Y_POS 720 + +enum { + ROW_OSD_MODE = 0, + ROW_OSD_ELEMENT, + ROW_OSD_SHOW_ELEMENT, + ROW_OSD_ELEMENT_POS_X, + ROW_OSD_ELEMENT_POS_Y, + ROW_OSD_RESET_ELEMENTS, + ROW_BACK, + + ROW_COUNT, + ROW_USER_HINT = 7 +}; + +typedef enum { + OSD_ELEMENT_TOP_FAN_SPEED = 0, + OSD_ELEMENT_LATENCY_LOCK, + OSD_ELEMENT_VTX_TEMP, + OSD_ELEMENT_VRX_TEMP, + OSD_ELEMENT_BATTERY_LOW, + OSD_ELEMENT_CHANNEL, + OSD_ELEMENT_SD_REC, + OSD_ELEMENT_VLQ, + OSD_ELEMENT_ANT0, + OSD_ELEMENT_ANT1, + OSD_ELEMENT_ANT2, + OSD_ELEMENT_ANT3, + OSD_ELEMENT_GOGGLE_TEMP_TOP, + OSD_ELEMENT_GOGGLE_TEMP_LEFT, + OSD_ELEMENT_GOGGLE_TEMP_RIGHT, + + OSD_ELEMENTS_TOTAL +} osd_elements_t; + +typedef enum { + ALL_ELEMENT_RES_UNCONFIRMED = 0, + ALL_ELEMENT_RES_CONFIRMED, + ALL_ELEMENT_RES_TIMEOUT +} all_element_reset_confirm_t; + +typedef enum { + ELEMENT_POS_SCROLL_DIR_NONE = 0, + ELEMENT_POS_SCROLL_DIR_X_INC, + ELEMENT_POS_SCROLL_DIR_Y_INC, + ELEMENT_POS_SCROLL_DIR_X_DEC, + ELEMENT_POS_SCROLL_DIR_Y_DEC +} element_pos_scroll_dir_t; + +typedef enum { + ELEMENT_POS_SCROLL_SPEED_SLOW = 1, + ELEMENT_POS_SCROLL_SPEED_MED = 5, + ELEMENT_POS_SCROLL_SPEED_FAST = 20 +} element_pos_scroll_speed_t; + +typedef enum { + ELEMENT_POS_SCROLL_SPEED_STEP_MED = 10 * ELEMENT_POS_SCROLL_SPEED_SLOW, + ELEMENT_POS_SCROLL_SPEED_STEP_FAST = ELEMENT_POS_SCROLL_SPEED_STEP_MED + 10 * ELEMENT_POS_SCROLL_SPEED_MED, +} element_pos_scroll_speed_steps_t; + +typedef struct { + char *name; + char *name_settings; +} osd_element_t; + +static lv_coord_t col_dsc[] = {160, 180, 160, 160, 120, 160, LV_GRID_TEMPLATE_LAST}; +static lv_coord_t row_dsc[] = {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, LV_GRID_TEMPLATE_LAST}; + +static btn_group_t btn_group_osd_type; +static lv_obj_t *dropdown_osd_element; +static btn_group_t btn_group_osd_show_element; +static slider_group_t slider_group_osd_element_pos_x; +static slider_group_t slider_group_osd_element_pos_y; +lv_obj_t *label_reset_all_osd_elements; + +static lv_timer_t *reset_all_osd_elements_timer = NULL; + +static bool element_dropdown_focused = false; +static bool element_pos_x_slider_focused = false; +static bool element_pos_y_slider_focused = false; +static int reset_all_elements_confirm = 0; + +static lv_timer_t *element_pos_scroll_speed_timer = NULL; +static int element_pos_cur_scroll_amount = 0; +static int element_pos_cur_scroll_dir = ELEMENT_POS_SCROLL_DIR_NONE; +static int element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_SLOW; + +static char osd_elements_str[512]; + +static osd_element_t osd_element_list[] = { + {"Top Fan Speed", "topfan_speed"}, + {"Latency Lock", "latency_lock"}, + {"VTX Temp", "vtx_temp"}, + {"VRX Temp", "vrx_temp"}, + {"Battery Low", "battery_low"}, + {"Channel", "channel"}, + {"SD Rec", "sd_rec"}, + {"VLQ", "vlq"}, + {"Antenna 1", "ant0"}, + {"Antenna 2", "ant1"}, + {"Antenna 3", "ant2"}, + {"Antenna 4", "ant3"}, + {"Goggle Temp Top", "goggle_temp_top"}, + {"Goggle Temp Left", "goggle_temp_left"}, + {"Goggle Temp Right", "goggle_temp_right"}}; + +static void page_osd_fill_osd_elements_str() { + int max_element = OSD_ELEMENT_ANT3; + + if (g_test_en) { + max_element = OSD_ELEMENT_GOGGLE_TEMP_RIGHT; + } + + osd_elements_str[0] = '\0'; + for (int i = 0; i < max_element; i++) { + strcat(osd_elements_str, osd_element_list[i].name); + strcat(osd_elements_str, "\n"); + } + strcat(osd_elements_str, osd_element_list[max_element].name); +} + +static setting_osd_goggle_element_t *get_osd_element_setting_entry(int element_idx) { + return &g_setting.osd.element[element_idx]; + + // switch (element_idx) { + // case OSD_ELEMENT_TOP_FAN_SPEED: + // return &g_setting.osd.elements.topfan_speed; + + // case OSD_ELEMENT_LATENCY_LOCK: + // return &g_setting.osd.elements.latency_lock; + + // case OSD_ELEMENT_VTX_TEMP: + // return &g_setting.osd.elements.vtx_temp; + + // case OSD_ELEMENT_VRX_TEMP: + // return &g_setting.osd.elements.vrx_temp; + + // case OSD_ELEMENT_BATTERY_LOW: + // return &g_setting.osd.elements.battery_low; + + // case OSD_ELEMENT_CHANNEL: + // return &g_setting.osd.elements.channel; + + // case OSD_ELEMENT_SD_REC: + // return &g_setting.osd.elements.sd_rec; + + // case OSD_ELEMENT_VLQ: + // return &g_setting.osd.elements.vlq; + + // case OSD_ELEMENT_ANT0: + // return &g_setting.osd.elements.ant0; + + // case OSD_ELEMENT_ANT1: + // return &g_setting.osd.elements.ant1; + + // case OSD_ELEMENT_ANT2: + // return &g_setting.osd.elements.ant2; + + // case OSD_ELEMENT_ANT3: + // return &g_setting.osd.elements.ant3; + + // case OSD_ELEMENT_GOGGLE_TEMP_TOP: + // return &g_setting.osd.elements.osd_tempe[0]; + + // case OSD_ELEMENT_GOGGLE_TEMP_LEFT: + // return &g_setting.osd.elements.osd_tempe[1]; + + // case OSD_ELEMENT_GOGGLE_TEMP_RIGHT: + // return &g_setting.osd.elements.osd_tempe[2]; + + // default: + // break; + // } +} + +static setting_osd_goggle_element_t *page_osd_get_selected_osd_element_setting_entry() { + int element_idx = lv_dropdown_get_selected(dropdown_osd_element); + return get_osd_element_setting_entry(element_idx); +} + +static void update_osd_element_ui_items() { + const setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + + btn_group_set_sel(&btn_group_osd_show_element, !element->show); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + update_slider_item_with_value(&slider_group_osd_element_pos_x, element->position.mode_4_3.x); + update_slider_item_with_value(&slider_group_osd_element_pos_y, element->position.mode_4_3.y); + } else { + update_slider_item_with_value(&slider_group_osd_element_pos_x, element->position.mode_16_9.x); + update_slider_item_with_value(&slider_group_osd_element_pos_y, element->position.mode_16_9.y); + } +} + +static void page_osd_reset_all_osd_elements_reset_label() { + lv_label_set_text(label_reset_all_osd_elements, "Reset all elements"); + reset_all_elements_confirm = ALL_ELEMENT_RES_UNCONFIRMED; +} + +static void page_osd_scroll_speed_timer_cb(lv_timer_t *timer) { + lv_timer_pause(element_pos_scroll_speed_timer); + element_pos_cur_scroll_dir = ELEMENT_POS_SCROLL_DIR_NONE; + element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_SLOW; + element_pos_cur_scroll_amount = 0; +} + +static void page_osd_reset_all_osd_elements_timer_cb(struct _lv_timer_t *timer) { + lv_timer_pause(reset_all_osd_elements_timer); + page_osd_reset_all_osd_elements_reset_label(); + reset_all_elements_confirm = ALL_ELEMENT_RES_UNCONFIRMED; +} + +static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { + lv_obj_t *page = lv_menu_page_create(parent, NULL); + lv_obj_clear_flag(page, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_set_size(page, 1053, 900); + lv_obj_add_style(page, &style_subpage, LV_PART_MAIN); + lv_obj_set_style_pad_top(page, 94, 0); + + lv_obj_t *section = lv_menu_section_create(page); + lv_obj_add_style(section, &style_submenu, LV_PART_MAIN); + lv_obj_set_size(section, 1053, 894); + + create_text(NULL, section, false, "Goggle OSD Settings:", LV_MENU_ITEM_BUILDER_VARIANT_2); + + lv_obj_t *cont = lv_obj_create(section); + lv_obj_set_size(cont, 960, 600); + lv_obj_set_pos(cont, 0, 0); + lv_obj_set_layout(cont, LV_LAYOUT_GRID); + lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_style(cont, &style_context, LV_PART_MAIN); + + lv_obj_set_style_grid_column_dsc_array(cont, col_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(cont, row_dsc, 0); + + create_select_item(arr, cont); + + // create menu entries + create_btn_group_item(&btn_group_osd_type, cont, 2, "OSD Mode", "4x3", "16x9", "", "", ROW_OSD_MODE); + + create_label_item(cont, "Element: ", 1, ROW_OSD_ELEMENT, 1); + page_osd_fill_osd_elements_str(); + dropdown_osd_element = create_dropdown_item(cont, osd_elements_str, 2, ROW_OSD_ELEMENT); + lv_obj_set_width(dropdown_osd_element, 320); + + create_btn_group_item(&btn_group_osd_show_element, cont, 2, "Show Element", "Yes", "No", "", "", ROW_OSD_SHOW_ELEMENT); + create_slider_item(&slider_group_osd_element_pos_x, cont, "Element Pos-X", OSD_ELEMENT_MAX_X_POS, 0, ROW_OSD_ELEMENT_POS_X); + create_slider_item(&slider_group_osd_element_pos_y, cont, "Element Pos-Y", OSD_ELEMENT_MAX_Y_POS, 0, ROW_OSD_ELEMENT_POS_Y); + + label_reset_all_osd_elements = create_label_item(cont, "Reset all elements", 1, ROW_OSD_RESET_ELEMENTS, 1); + lv_obj_set_width(label_reset_all_osd_elements, 600); + + lv_obj_t *label_user_hint = lv_label_create(cont); + lv_label_set_text(label_user_hint, "OSD Element positioning is based on a 1280x720 canvas.\nPositions can be set for 4x3 and 16x9 modes separately,\nthe Show Element toggle is shared between both modes."); + lv_obj_set_style_text_font(label_user_hint, &lv_font_montserrat_16, 0); + lv_obj_set_style_text_align(label_user_hint, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_style_text_color(label_user_hint, lv_color_make(255, 255, 255), 0); + lv_obj_set_style_pad_top(label_user_hint, 12, 0); + lv_label_set_long_mode(label_user_hint, LV_LABEL_LONG_WRAP); + lv_obj_set_grid_cell(label_user_hint, LV_GRID_ALIGN_START, 1, 4, + LV_GRID_ALIGN_START, ROW_USER_HINT, 2); + + // Back entry + create_label_item(cont, "< Back", 1, ROW_BACK, 1); + + // set menu selections + btn_group_set_sel(&btn_group_osd_type, g_setting.osd.embedded_mode); + update_osd_element_ui_items(); + + // create timers + element_pos_scroll_speed_timer = lv_timer_create(page_osd_scroll_speed_timer_cb, 1000, NULL); + lv_timer_pause(element_pos_scroll_speed_timer); + reset_all_osd_elements_timer = lv_timer_create(page_osd_reset_all_osd_elements_timer_cb, 3000, NULL); + lv_timer_pause(reset_all_osd_elements_timer); + + return page; +} + +static int page_osd_reset_all_osd_elements() { + int res = 1; + + for (int i = 0; i < OSD_ELEMENTS_TOTAL; i++) { + g_setting.osd.element[i] = g_setting_defaults.osd.element[i]; + res &= settings_put_osd_element(&g_setting.osd.element[i], osd_element_list[i].name_settings); + } + + // res = settings_put_osd_element(&g_setting.osd.elements.topfan_speed, osd_element_list[OSD_ELEMENT_TOP_FAN_SPEED].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.latency_lock, osd_element_list[OSD_ELEMENT_LATENCY_LOCK].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.vtx_temp, osd_element_list[OSD_ELEMENT_VTX_TEMP].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.vrx_temp, osd_element_list[OSD_ELEMENT_VRX_TEMP].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.battery_low, osd_element_list[OSD_ELEMENT_BATTERY_LOW].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.channel, osd_element_list[OSD_ELEMENT_CHANNEL].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.sd_rec, osd_element_list[OSD_ELEMENT_SD_REC].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.vlq, osd_element_list[OSD_ELEMENT_VLQ].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.ant0, osd_element_list[OSD_ELEMENT_ANT0].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.ant1, osd_element_list[OSD_ELEMENT_ANT1].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.ant2, osd_element_list[OSD_ELEMENT_ANT2].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.ant3, osd_element_list[OSD_ELEMENT_ANT3].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.osd_tempe[0], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_TOP].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.osd_tempe[1], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_LEFT].name_settings); + // res &= settings_put_osd_element(&g_setting.osd.elements.osd_tempe[2], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_RIGHT].name_settings); + + return res; +} + +static char *page_osd_get_selected_osd_element_setting_name() { + return osd_element_list[lv_dropdown_get_selected(dropdown_osd_element)].name_settings; +} + +static void page_osd_slider_scroll_acceleration(element_pos_scroll_dir_t direction) { + if (element_pos_cur_scroll_dir != direction) { + element_pos_cur_scroll_dir = direction; + element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_SLOW; + element_pos_cur_scroll_amount = 0; + + lv_timer_reset(element_pos_scroll_speed_timer); + lv_timer_resume(element_pos_scroll_speed_timer); + } else { + lv_timer_reset(element_pos_scroll_speed_timer); + if (element_pos_cur_scroll_amount >= ELEMENT_POS_SCROLL_SPEED_STEP_FAST) { + element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_FAST; + } else if (element_pos_cur_scroll_amount >= ELEMENT_POS_SCROLL_SPEED_STEP_MED) { + element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_MED; + } + } + + element_pos_cur_scroll_amount += element_pos_cur_scroll_speed; +} + +static void page_osd_element_pos_x_dec() { + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + + page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_X_DEC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_4_3.x, + (-element_pos_cur_scroll_speed)); + } else { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_16_9.x, + (-element_pos_cur_scroll_speed)); + } +} + +static void page_osd_element_pos_y_dec() { + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + + page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_Y_DEC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_4_3.y, + (-element_pos_cur_scroll_speed)); + } else { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_16_9.y, + (-element_pos_cur_scroll_speed)); + } +} + +static void page_osd_element_pos_x_inc() { + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + + page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_X_INC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_4_3.x, + element_pos_cur_scroll_speed); + } else { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_16_9.x, + element_pos_cur_scroll_speed); + } +} + +static void page_osd_element_pos_y_inc() { + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + + page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_Y_INC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_4_3.y, + element_pos_cur_scroll_speed); + } else { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_16_9.y, + element_pos_cur_scroll_speed); + } +} + +static void page_osd_on_roller(uint8_t key) { + if (reset_all_elements_confirm == ALL_ELEMENT_RES_CONFIRMED) { + page_osd_reset_all_osd_elements_reset_label(); + return; + } + + if (key == DIAL_KEY_UP) { + + if (element_dropdown_focused) { + uint32_t evt = LV_KEY_DOWN; + lv_event_send(dropdown_osd_element, LV_EVENT_KEY, &evt); + } else if (element_pos_x_slider_focused) { + page_osd_element_pos_x_dec(); + } else if (element_pos_y_slider_focused) { + page_osd_element_pos_y_dec(); + } + + } else if (key == DIAL_KEY_DOWN) { + + if (element_dropdown_focused) { + uint32_t evt = LV_KEY_UP; + lv_event_send(dropdown_osd_element, LV_EVENT_KEY, &evt); + } else if (element_pos_x_slider_focused) { + page_osd_element_pos_x_inc(); + } else if (element_pos_y_slider_focused) { + page_osd_element_pos_y_inc(); + } + } + + update_osd_element_ui_items(); +} + +static void page_osd_on_click(uint8_t key, int sel) { + + switch (sel) { + + case ROW_OSD_MODE: + btn_group_toggle_sel(&btn_group_osd_type); + g_setting.osd.embedded_mode = btn_group_get_sel(&btn_group_osd_type); + ini_putl("osd", "embedded_mode", g_setting.osd.embedded_mode, SETTING_INI); + osd_update_mode(); + break; + + case ROW_OSD_ELEMENT: + if (!element_dropdown_focused) { + app_state_push(APP_STATE_SUBMENU_ITEM_FOCUSED); + lv_obj_t *list = lv_dropdown_get_list(dropdown_osd_element); + lv_dropdown_open(dropdown_osd_element); + lv_obj_add_style(list, &style_dropdown, LV_PART_MAIN); + lv_obj_set_style_text_color(list, lv_color_make(0, 0, 0), LV_PART_SELECTED | LV_STATE_CHECKED); + element_dropdown_focused = true; + } else { + app_state_push(APP_STATE_SUBMENU); + lv_event_send(dropdown_osd_element, LV_EVENT_RELEASED, NULL); + element_dropdown_focused = false; + int option = lv_dropdown_get_selected(dropdown_osd_element); + } + break; + + case ROW_OSD_SHOW_ELEMENT: + btn_group_toggle_sel(&btn_group_osd_show_element); + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + element->show = btn_group_get_sel(&btn_group_osd_show_element) == 0; + settings_put_osd_element_shown(element->show, page_osd_get_selected_osd_element_setting_name()); + osd_update_mode(); + break; + + case ROW_OSD_ELEMENT_POS_X: + if (!element_pos_x_slider_focused) { + app_state_push(APP_STATE_SUBMENU_ITEM_FOCUSED); + lv_obj_add_style(slider_group_osd_element_pos_x.slider, &style_silder_select, LV_PART_MAIN); + element_pos_x_slider_focused = true; + } else { + app_state_push(APP_STATE_SUBMENU); + lv_obj_add_style(slider_group_osd_element_pos_x.slider, &style_silder_main, LV_PART_MAIN); + + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + settings_put_osd_element_pos_x(&element->position, page_osd_get_selected_osd_element_setting_name()); + osd_update_mode(); + + element_pos_x_slider_focused = false; + } + break; + + case ROW_OSD_ELEMENT_POS_Y: + if (!element_pos_y_slider_focused) { + app_state_push(APP_STATE_SUBMENU_ITEM_FOCUSED); + lv_obj_add_style(slider_group_osd_element_pos_y.slider, &style_silder_select, LV_PART_MAIN); + element_pos_y_slider_focused = true; + } else { + app_state_push(APP_STATE_SUBMENU); + lv_obj_add_style(slider_group_osd_element_pos_y.slider, &style_silder_main, LV_PART_MAIN); + + setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); + settings_put_osd_element_pos_y(&element->position, page_osd_get_selected_osd_element_setting_name()); + osd_update_mode(); + + element_pos_y_slider_focused = false; + } + break; + + case ROW_OSD_RESET_ELEMENTS: + if (reset_all_elements_confirm == ALL_ELEMENT_RES_TIMEOUT) + return; + + if (reset_all_elements_confirm) { + page_osd_reset_all_osd_elements(); + osd_update_mode(); + lv_label_set_text(label_reset_all_osd_elements, "#00FF00 Elements reset.#"); + lv_timer_reset(reset_all_osd_elements_timer); + lv_timer_resume(reset_all_osd_elements_timer); + reset_all_elements_confirm = ALL_ELEMENT_RES_TIMEOUT; + } else { + lv_label_set_text(label_reset_all_osd_elements, "#FFFF00 Click to confirm or Scroll to cancel...#"); + reset_all_elements_confirm = ALL_ELEMENT_RES_CONFIRMED; + } + + break; + + default: + break; + } + + update_osd_element_ui_items(); +} + +page_pack_t pp_osd = { + .p_arr = { + .cur = 0, + .max = ROW_COUNT}, + .name = "Goggle OSD", + .create = page_osd_create, + .enter = NULL, + .exit = NULL, + .on_roller = page_osd_on_roller, + .on_click = page_osd_on_click, + .on_right_button = NULL, +}; \ No newline at end of file diff --git a/src/ui/page_osd.h b/src/ui/page_osd.h new file mode 100644 index 00000000..b81606bf --- /dev/null +++ b/src/ui/page_osd.h @@ -0,0 +1,8 @@ +#ifndef _PAGE_OSD_H +#define _PAGE_OSD_H + +#include "ui/ui_main_menu.h" + +extern page_pack_t pp_osd; + +#endif diff --git a/src/ui/ui_image_setting.c b/src/ui/ui_image_setting.c index 1cecef24..cb2f0670 100644 --- a/src/ui/ui_image_setting.c +++ b/src/ui/ui_image_setting.c @@ -77,24 +77,15 @@ static void ims_page_init(uint8_t *val) { ims_page.items[5].x = x; ims_page.items[5].y = y + 125; - ims_page.items[5].type = 1; - strcpy(ims_page.items[5].title, "OSD Mode:"); - ims_page.items[5].range[0] = 0; - ims_page.items[5].range[1] = 1; - ims_page.items[5].value = val[5]; + ims_page.items[5].type = 0; + strcpy(ims_page.items[5].title, "< Back"); ims_page.items[5].state = 0; - ims_page.items[6].x = x; - ims_page.items[6].y = y + 150; + ims_page.items[6].x = x + 200; + ims_page.items[6].y = y + 125; ims_page.items[6].type = 0; - strcpy(ims_page.items[6].title, "< Back"); + strcpy(ims_page.items[6].title, "Reset All"); ims_page.items[6].state = 0; - - ims_page.items[7].x = x + 200; - ims_page.items[7].y = y + 150; - ims_page.items[7].type = 0; - strcpy(ims_page.items[7].title, "Reset All"); - ims_page.items[7].state = 0; } static void show_ims_slider(uint8_t index) { @@ -126,12 +117,6 @@ static void show_ims_slider(uint8_t index) { break; } - case 5: { // osd mode - char *osd_mode[2] = {"4x3", "16x9"}; - strcpy(buf, osd_mode[p_slider->value & 3]); - break; - } - default: sprintf(buf, "%d", p_slider->value); break; @@ -169,14 +154,13 @@ void ims_update() { } void ims_init(void) { - uint8_t defs[6]; + uint8_t defs[5]; defs[0] = g_setting.image.oled; defs[1] = g_setting.image.brightness; defs[2] = g_setting.image.saturation; defs[3] = g_setting.image.contrast; defs[4] = g_setting.image.auto_off; - defs[5] = g_setting.osd.embedded_mode; canvas_ims = lv_canvas_create(lv_scr_act()); lv_obj_clear_flag(canvas_ims, LV_OBJ_FLAG_SCROLLABLE); @@ -216,8 +200,6 @@ void ims_save() { g_setting.image.auto_off = ims_page.items[4].value; ini_putl("image", "auto_off", g_setting.image.auto_off, SETTING_INI); - g_setting.osd.embedded_mode = ims_page.items[5].value; - ini_putl("osd", "embedded_mode", g_setting.osd.embedded_mode, SETTING_INI); osd_update_mode(); } @@ -260,17 +242,17 @@ uint8_t ims_key(uint8_t key) { break; case DIAL_KEY_CLICK: - if (ims_page.selection == 6) { //"p_arr.cur if a selection change is needed +void submenu_roller_no_selection_change(uint8_t key) { + page_pack_t *pp = find_pp(lv_menu_get_cur_main_page(menu)); + if (!pp) { + return; + } + + if (pp->on_roller) { + // if your page as a roller event handler, call it + pp->on_roller(key); + } + + set_select_item(&pp->p_arr, pp->p_arr.cur); +} + void submenu_exit() { LOGI("submenu_exit"); app_state_push(APP_STATE_MAINMENU); diff --git a/src/ui/ui_main_menu.h b/src/ui/ui_main_menu.h index e40e7f7e..8b376156 100644 --- a/src/ui/ui_main_menu.h +++ b/src/ui/ui_main_menu.h @@ -40,6 +40,7 @@ void menu_nav(uint8_t key); void submenu_enter(); void submenu_exit(); void submenu_roller(uint8_t key); +void submenu_roller_no_selection_change(uint8_t key); void submenu_click(void); void submenu_right_button(bool is_short); void progress_bar_update(); diff --git a/src/util/math.c b/src/util/math.c index 0ee6c151..d6a0d9d0 100644 --- a/src/util/math.c +++ b/src/util/math.c @@ -41,3 +41,14 @@ void rotate(float pn[3], const float rot[3]) { memcpy(pn, out, sizeof(out[0]) * 3); } } + +void safe_update_value(int min, int max, int *val, int delta) { + int new_val = *val + delta; + + if (new_val > max) + *val = max; + else if (new_val < min) + *val = min; + else + *val = new_val; +} \ No newline at end of file diff --git a/src/util/math.h b/src/util/math.h index f6c55f87..b2426376 100644 --- a/src/util/math.h +++ b/src/util/math.h @@ -9,5 +9,6 @@ float normalize(float value, float start, float end); void rotate(float pn[3], const float rot[3]); +void safe_update_value(int min, int max, int *val, int delta); #endif // __UTIL_MATH_H__ \ No newline at end of file From 132cb65a55d692269d8301e8b083d58e960d589e Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Thu, 20 Apr 2023 00:43:36 +0200 Subject: [PATCH 2/7] add osd element positioning preview move positioning settings from osd settings page to preview ui --- src/core/app_state.h | 5 + src/core/input_device.c | 11 + src/core/main.c | 3 + src/core/osd.c | 120 +++++++ src/core/settings.c | 6 +- src/core/settings.h | 6 +- src/ui/page_clock.c | 2 +- src/ui/page_common.c | 149 +++++++- src/ui/page_common.h | 9 +- src/ui/page_osd.c | 497 +++------------------------ src/ui/page_osd.h | 1 + src/ui/ui_osd_element_pos.c | 661 ++++++++++++++++++++++++++++++++++++ src/ui/ui_osd_element_pos.h | 14 + 13 files changed, 1018 insertions(+), 466 deletions(-) create mode 100644 src/ui/ui_osd_element_pos.c create mode 100644 src/ui/ui_osd_element_pos.h diff --git a/src/core/app_state.h b/src/core/app_state.h index 2bcbd0f6..dbecb87b 100644 --- a/src/core/app_state.h +++ b/src/core/app_state.h @@ -11,8 +11,13 @@ typedef enum { // but the selected submenu item selection (e.g. pp_osd.p_arr.cur) // is not automatically changed. APP_STATE_SUBMENU_ITEM_FOCUSED = 3, + APP_STATE_VIDEO = 10, + + // the preview for image settings APP_STATE_IMS = 11, + // the preview for osd element positioning settings + APP_STATE_OSD_ELEMENT_PREV = 12, APP_STATE_USER_INPUT_DISABLED = 20, diff --git a/src/core/input_device.c b/src/core/input_device.c index 3389c683..90ef78d6 100644 --- a/src/core/input_device.c +++ b/src/core/input_device.c @@ -42,6 +42,7 @@ #include "ui/page_scannow.h" #include "ui/page_source.h" #include "ui/ui_image_setting.h" +#include "ui/ui_osd_element_pos.h" #include "ui/ui_main_menu.h" #include "ui/ui_porting.h" @@ -207,6 +208,12 @@ static void btn_click(void) // short press enter key app_switch_to_menu(); pthread_mutex_unlock(&lvgl_mutex); return; + } else if (g_app_state == APP_STATE_OSD_ELEMENT_PREV) { + pthread_mutex_lock(&lvgl_mutex); + if (ui_osd_element_pos_handle_input(DIAL_KEY_CLICK)) + app_switch_to_menu(); + pthread_mutex_unlock(&lvgl_mutex); + return; } if (!main_menu_is_shown()) @@ -290,6 +297,8 @@ static void roller_up(void) { tune_channel(DIAL_KEY_UP); } else if (g_app_state == APP_STATE_IMS) { ims_key(DIAL_KEY_UP); + } else if (g_app_state == APP_STATE_OSD_ELEMENT_PREV) { + ui_osd_element_pos_handle_input(DIAL_KEY_UP); } else if (g_app_state == PAGE_FAN_SLIDE) { fans_speed_dec(); } else if (g_app_state == PAGE_ANGLE_SLIDE) { @@ -327,6 +336,8 @@ static void roller_down(void) { tune_channel(DIAL_KEY_DOWN); } else if (g_app_state == APP_STATE_IMS) { ims_key(DIAL_KEY_DOWN); + } else if (g_app_state == APP_STATE_OSD_ELEMENT_PREV) { + ui_osd_element_pos_handle_input(DIAL_KEY_DOWN); } else if (g_app_state == PAGE_FAN_SLIDE) { fans_speed_inc(); } else if (g_app_state == PAGE_ANGLE_SLIDE) { diff --git a/src/core/main.c b/src/core/main.c index 3b57b06a..bcf1a808 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -37,6 +37,7 @@ #include "ui/page_scannow.h" #include "ui/page_source.h" #include "ui/ui_image_setting.h" +#include "ui/ui_osd_element_pos.h" #include "ui/ui_main_menu.h" #include "ui/ui_porting.h" #include "ui/ui_statusbar.h" @@ -169,6 +170,7 @@ int main(int argc, char *argv[]) { OLED_Pattern(0, 0, 0); osd_init(); ims_init(); + ui_osd_element_pos_init(); // 6. Enable functionality if (g_setting.ht.enable) { @@ -191,6 +193,7 @@ int main(int argc, char *argv[]) { statubar_update(); osd_hdzero_update(); ims_update(); + ui_osd_element_pos_update(); ht_detect_motion(); lv_timer_handler(); source_status_timer(); diff --git a/src/core/osd.c b/src/core/osd.c index db6d646e..c9c46373 100644 --- a/src/core/osd.c +++ b/src/core/osd.c @@ -22,6 +22,7 @@ #include "core/elrs.h" #include "core/msp_displayport.h" #include "core/settings.h" +#include "core/app_state.h" #include "driver/dm5680.h" #include "driver/fans.h" #include "driver/fbtools.h" @@ -318,6 +319,116 @@ bool fhd_change() { return false; } +void osd_show_all_elements(){ + + if (g_setting.osd.element[OSD_GOGGLE_TOPFAN_SPEED].show) + lv_obj_clear_flag(g_osd_hdzero.topfan_speed[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.topfan_speed[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_BATTERY_LOW].show) + lv_obj_clear_flag(g_osd_hdzero.battery_low[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.battery_low[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_VTX_TEMP].show) + lv_obj_clear_flag(g_osd_hdzero.vtx_temp[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.vtx_temp[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_VRX_TEMP].show) + lv_obj_clear_flag(g_osd_hdzero.vrx_temp[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.vrx_temp[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_LATENCY_LOCK].show) + lv_obj_clear_flag(g_osd_hdzero.latency_lock[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.latency_lock[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_CHANNEL].show) + lv_obj_clear_flag(g_osd_hdzero.channel[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.channel[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_SD_REC].show) + lv_obj_clear_flag(g_osd_hdzero.sd_rec[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.sd_rec[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_VLQ].show) + lv_obj_clear_flag(g_osd_hdzero.vlq[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.vlq[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_ANT0].show) + lv_obj_clear_flag(g_osd_hdzero.ant0[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.ant0[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_ANT1].show) + lv_obj_clear_flag(g_osd_hdzero.ant1[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.ant1[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_ANT2].show) + lv_obj_clear_flag(g_osd_hdzero.ant2[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.ant2[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_ANT3].show) + lv_obj_clear_flag(g_osd_hdzero.ant3[is_fhd], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.ant3[is_fhd], LV_OBJ_FLAG_HIDDEN); + + if (!g_test_en) + return; + + if (g_setting.osd.element[OSD_GOGGLE_TEMP_TOP].show) + lv_obj_clear_flag(g_osd_hdzero.osd_tempe[is_fhd][0], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.osd_tempe[is_fhd][0], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_TEMP_LEFT].show) + lv_obj_clear_flag(g_osd_hdzero.osd_tempe[is_fhd][1], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.osd_tempe[is_fhd][1], LV_OBJ_FLAG_HIDDEN); + + if (g_setting.osd.element[OSD_GOGGLE_TEMP_RIGHT].show) + lv_obj_clear_flag(g_osd_hdzero.osd_tempe[is_fhd][2], LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(g_osd_hdzero.osd_tempe[is_fhd][2], LV_OBJ_FLAG_HIDDEN); +} + +void osd_elements_set_dummy_sources(){ + char buf[128]; + + osd_resource_path(buf, "%s", is_fhd, VtxTemp1_bmp); + lv_img_set_src(g_osd_hdzero.vtx_temp[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, ant2_bmp); + lv_img_set_src(g_osd_hdzero.ant0[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, ant3_bmp); + lv_img_set_src(g_osd_hdzero.ant1[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, ant4_bmp); + lv_img_set_src(g_osd_hdzero.ant2[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, ant5_bmp); + lv_img_set_src(g_osd_hdzero.ant3[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, recording_bmp); + lv_img_set_src(g_osd_hdzero.sd_rec[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, VLQ9_bmp); + lv_img_set_src(g_osd_hdzero.vlq[is_fhd], buf); + + osd_resource_path(buf, "%s", is_fhd, fan5_bmp); + lv_img_set_src(g_osd_hdzero.topfan_speed[is_fhd], buf); + +} + #define FC_OSD_CHECK_PERIOD 200 // 25ms void osd_hdzero_update(void) { char buf[128], i; @@ -332,6 +443,14 @@ void osd_hdzero_update(void) { if (fhd_change()) return; + // if the user is in the osd element position settings, show all elements + if (g_app_state == APP_STATE_OSD_ELEMENT_PREV){ + // some elements might not be visible, set dummy sources to show them + osd_elements_set_dummy_sources(); + osd_show_all_elements(); + return; + } + bool showRXOSD = g_showRXOSD && (g_source_info.source == SOURCE_HDZERO); osd_rec_show(g_showRXOSD); @@ -487,6 +606,7 @@ void osd_update_mode() { osd_object_set_pos(is_fhd, g_osd_hdzero.latency_lock[is_fhd], &g_setting.osd.element[OSD_GOGGLE_LATENCY_LOCK].position); osd_object_set_pos(is_fhd, g_osd_hdzero.sd_rec[is_fhd], &g_setting.osd.element[OSD_GOGGLE_SD_REC].position); osd_object_set_pos(is_fhd, g_osd_hdzero.vlq[is_fhd], &g_setting.osd.element[OSD_GOGGLE_VLQ].position); + osd_object_set_pos(is_fhd, g_osd_hdzero.channel[is_fhd], &g_setting.osd.element[OSD_GOGGLE_CHANNEL].position); osd_object_set_pos(is_fhd, g_osd_hdzero.ant0[is_fhd], &g_setting.osd.element[OSD_GOGGLE_ANT0].position); osd_object_set_pos(is_fhd, g_osd_hdzero.ant1[is_fhd], &g_setting.osd.element[OSD_GOGGLE_ANT1].position); osd_object_set_pos(is_fhd, g_osd_hdzero.ant2[is_fhd], &g_setting.osd.element[OSD_GOGGLE_ANT2].position); diff --git a/src/core/settings.c b/src/core/settings.c index bcc923f0..3d79ff59 100644 --- a/src/core/settings.c +++ b/src/core/settings.c @@ -173,7 +173,7 @@ int settings_put_osd_element_shown(bool show, char *config_name) { return settings_put_bool("osd", setting_key, show); } -int settings_put_osd_element_pos_x(setting_osd_goggle_element_positions_t *pos, char *config_name) { +int settings_put_osd_element_pos_x(const setting_osd_goggle_element_positions_t *pos, char *config_name) { char setting_key[128]; int ret = 0; @@ -184,7 +184,7 @@ int settings_put_osd_element_pos_x(setting_osd_goggle_element_positions_t *pos, return ret; } -int settings_put_osd_element_pos_y(setting_osd_goggle_element_positions_t *pos, char *config_name) { +int settings_put_osd_element_pos_y(const setting_osd_goggle_element_positions_t *pos, char *config_name) { char setting_key[128]; int ret = 0; @@ -195,7 +195,7 @@ int settings_put_osd_element_pos_y(setting_osd_goggle_element_positions_t *pos, return ret; } -int settings_put_osd_element(setting_osd_goggle_element_t *element, char *config_name) { +int settings_put_osd_element(const setting_osd_goggle_element_t *element, char *config_name) { int ret = 0; ret = settings_put_osd_element_shown(element->show, config_name); diff --git a/src/core/settings.h b/src/core/settings.h index fbc628c9..dbffa5cf 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -195,7 +195,7 @@ void settings_init(void); void settings_load(void); bool settings_get_bool(char *section, char *key, bool default_val); int settings_put_bool(char *section, char *key, bool value); -int settings_put_osd_element(setting_osd_goggle_element_t *element, char *config_name); -int settings_put_osd_element_pos_y(setting_osd_goggle_element_positions_t *pos, char *config_name); -int settings_put_osd_element_pos_x(setting_osd_goggle_element_positions_t *pos, char *config_name); +int settings_put_osd_element(const setting_osd_goggle_element_t *element, char *config_name); +int settings_put_osd_element_pos_y(const setting_osd_goggle_element_positions_t *pos, char *config_name); +int settings_put_osd_element_pos_x(const setting_osd_goggle_element_positions_t *pos, char *config_name); int settings_put_osd_element_shown(bool show, char *config_name); \ No newline at end of file diff --git a/src/ui/page_clock.c b/src/ui/page_clock.c index e06eda43..d9dbd78d 100644 --- a/src/ui/page_clock.c +++ b/src/ui/page_clock.c @@ -147,7 +147,7 @@ static void page_clock_create_dropdown(lv_obj_t *parent, char text[512]; snprintf(text, sizeof(text), "%d", option); - page_clock_items[item].data.obj = create_dropdown_item(parent, page_clock_options[item].list, col, row); + page_clock_items[item].data.obj = create_dropdown_item(parent, page_clock_options[item].list, col, row, 160, 40, 1, 4, LV_GRID_ALIGN_START, &lv_font_montserrat_26); page_clock_items[item].type = ITEM_TYPE_OBJ; int index = page_clock_get_dropdown_index(item, text); diff --git a/src/ui/page_common.c b/src/ui/page_common.c index 8507c4de..d46f5c0e 100644 --- a/src/ui/page_common.c +++ b/src/ui/page_common.c @@ -89,6 +89,22 @@ lv_obj_t *show_msgbox_ok(const char *title, const char *message) { return msgbox; } +lv_obj_t *create_label_item_compact(lv_obj_t *parent, const char *name, int col, int row, int cols, int height, lv_text_align_t text_align, lv_grid_align_t col_align, const lv_font_t *font) { + lv_obj_t *label = lv_label_create(parent); + lv_label_set_text(label, name); + lv_obj_set_style_text_font(label, font, 0); + lv_obj_set_style_text_align(label, text_align, 0); + lv_obj_set_style_pad_top(label, (height - lv_font_get_line_height(font)) >> 1, 0); + lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_size(label, 120 * cols, height); + + lv_label_set_recolor(label, true); + + lv_obj_set_grid_cell(label, col_align, col, cols, + LV_GRID_ALIGN_CENTER, row, 1); + return label; +} + lv_obj_t *create_label_item(lv_obj_t *parent, const char *name, int col, int row, int cols) { lv_obj_t *label = lv_label_create(parent); lv_label_set_text(label, name); @@ -121,6 +137,52 @@ lv_obj_t *create_info_item(lv_obj_t *parent, const char *name, int col, int row, return label; } +void create_slider_item_compact(slider_group_t *slider_group, lv_obj_t *parent, const char *name, int range, int default_value, int row, const lv_font_t *font) { + lv_obj_t *label = lv_label_create(parent); + lv_label_set_text(label, name); + lv_obj_set_style_text_font(label, font, 0); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_style_pad_top(label, lv_font_get_line_height(font) >> 1, 0); + lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_size(label, 200, 40); + lv_obj_set_grid_cell(label, LV_GRID_ALIGN_START, 1, 1, + LV_GRID_ALIGN_CENTER, row, 1); + + slider_group->slider = lv_slider_create(parent); + + //lv_obj_set_style_pad_bottom(slider_group->slider, 50, 0); + + + lv_obj_remove_style_all(slider_group->slider); + lv_obj_add_style(slider_group->slider, &style_silder_main, LV_PART_MAIN); + lv_obj_add_style(slider_group->slider, &style_silder_indicator, LV_PART_INDICATOR); + lv_obj_add_style(slider_group->slider, &style_silder_pressed_color, LV_PART_INDICATOR | LV_STATE_PRESSED); + lv_obj_set_style_bg_opa(slider_group->slider, LV_OPA_COVER, LV_PART_KNOB); + lv_obj_set_style_pad_ver(slider_group->slider, 10, LV_PART_KNOB); + lv_obj_set_style_pad_hor(slider_group->slider, 2, LV_PART_KNOB); + lv_obj_add_style(slider_group->slider, &style_silder_pressed_color, LV_PART_KNOB | LV_STATE_PRESSED); + + + lv_obj_set_size(slider_group->slider, 0, 2); + lv_slider_set_range(slider_group->slider, 0, range); + lv_slider_set_value(slider_group->slider, default_value, LV_ANIM_OFF); + lv_obj_set_grid_cell(slider_group->slider, LV_GRID_ALIGN_STRETCH, 2, 2, + LV_GRID_ALIGN_CENTER, row, 1); + + slider_group->label = lv_label_create(parent); + char buf[25]; + memset(buf, 0, sizeof(buf)); + sprintf(buf, "%d", default_value); + lv_label_set_text(slider_group->label, buf); + lv_obj_set_style_text_font(slider_group->label, font, 0); + lv_obj_set_style_text_align(slider_group->label, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_style_pad_top(slider_group->label, lv_font_get_line_height(font) >> 1, 0); + lv_label_set_long_mode(slider_group->label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_size(slider_group->label, 160, 40); + lv_obj_set_grid_cell(slider_group->label, LV_GRID_ALIGN_START, 4, 1, + LV_GRID_ALIGN_CENTER, row, 1); +} + void create_slider_item(slider_group_t *slider_group, lv_obj_t *parent, const char *name, int range, int default_value, int row) { lv_obj_t *label = lv_label_create(parent); lv_label_set_text(label, name); @@ -187,15 +249,16 @@ void create_btn_item(lv_obj_t *parent, const char *name, int col, int row) { LV_GRID_ALIGN_CENTER, row, 1); } -lv_obj_t *create_dropdown_item(lv_obj_t *parent, const char *options, int col, int row) { +lv_obj_t *create_dropdown_item(lv_obj_t *parent, const char *options, int col, int row, int width, int height, int col_span, int pad_top, lv_grid_align_t column_align, const lv_font_t *font) { lv_obj_t *obj = lv_dropdown_create(parent); lv_dropdown_set_options(obj, options); - lv_obj_set_style_text_font(obj, &lv_font_montserrat_26, 0); + lv_obj_set_style_text_font(obj, font, 0); lv_obj_set_style_shadow_width(obj, 0, 0); - lv_obj_set_style_pad_top(obj, 4, 0); - lv_obj_set_size(obj, 160, 40); - lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_START, col, 1, LV_GRID_ALIGN_CENTER, row, 1); + lv_obj_set_style_pad_top(obj, pad_top, 0); + lv_obj_set_size(obj, width, height); + + lv_obj_set_grid_cell(obj, column_align, col, col_span, LV_GRID_ALIGN_CENTER, row, 1); return obj; } @@ -266,6 +329,82 @@ void btn_group_toggle_sel(btn_group_t *btn_group) { btn_group_set_sel(btn_group, sel); } +static void create_btn_with_arrow_compact(lv_obj_t *parent, btn_with_arr_t *btn_a, const char *name, int row, int col, int height, int arrow_scale_percent, const lv_font_t *font) { + uint16_t zoom_factor = (arrow_scale_percent * 256) / 100; + + btn_a->container = lv_obj_create(parent); + lv_obj_set_size(btn_a->container, 200, height); + lv_obj_set_pos(btn_a->container, 0, 0); + lv_obj_set_layout(btn_a->container, LV_LAYOUT_GRID); + lv_obj_clear_flag(btn_a->container, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_style(btn_a->container, &style_context, LV_PART_MAIN); + lv_obj_set_style_bg_opa(btn_a->container, 0x0, 0); + lv_obj_set_style_grid_column_dsc_array(btn_a->container, col_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(btn_a->container, row_dsc, 0); + lv_obj_set_grid_cell(btn_a->container, LV_GRID_ALIGN_START, col, 1, + LV_GRID_ALIGN_CENTER, row, 1); + + btn_a->arrow = lv_img_create(btn_a->container); + lv_img_set_src(btn_a->arrow, &img_arrow1); + lv_img_set_zoom(btn_a->arrow, zoom_factor); + + lv_obj_set_style_pad_top(btn_a->arrow, 0, 0); + lv_obj_set_style_pad_bottom(btn_a->arrow, height >> 1, 0); + + lv_obj_add_flag(btn_a->arrow, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_grid_cell(btn_a->arrow, LV_GRID_ALIGN_END, 0, 1, + LV_GRID_ALIGN_CENTER, 0, 1); + + btn_a->btn = lv_btn_create(btn_a->container); + btn_a->label = lv_label_create(btn_a->btn); + lv_label_set_text(btn_a->label, name); + lv_obj_set_style_text_align(btn_a->label, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_style_text_font(btn_a->btn, font, 0); + lv_obj_set_style_text_align(btn_a->btn, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_style_bg_color(btn_a->btn, lv_color_make(19, 19, 19), 0); + lv_obj_set_style_bg_opa(btn_a->btn, 0x0, 0); + lv_obj_set_style_shadow_width(btn_a->btn, 0, 0); + + lv_obj_set_style_pad_top(btn_a->btn, 0, 0); + lv_obj_set_style_pad_bottom(btn_a->btn, 0, 0); + + lv_obj_set_size(btn_a->btn, 160, height); + lv_obj_set_grid_cell(btn_a->btn, LV_GRID_ALIGN_START, 1, 1, + LV_GRID_ALIGN_CENTER, 0, 1); + + lv_obj_set_style_pad_column(btn_a->container, 0, 0); +} + +void create_btn_group_item_compact(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, const char *name2, const char *name3, int row, int height, int arrow_scale_percent, const lv_font_t *font) { + if (count > 3) + return; + btn_group->valid = count; + btn_group->current = 0; + + lv_obj_t *label = lv_label_create(parent); + lv_label_set_text(label, name); + lv_obj_set_style_text_font(label, font, 0); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, 0); + lv_obj_set_style_pad_top(label, 10, 0); + lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_size(label, 120, height); + lv_obj_set_grid_cell(label, LV_GRID_ALIGN_START, 1, 1, + LV_GRID_ALIGN_CENTER, row, 1); + + create_btn_with_arrow_compact(parent, &btn_group->btn_a[0], name0, row, 2, height, arrow_scale_percent, font); + if (count >= 2) { + create_btn_with_arrow_compact(parent, &btn_group->btn_a[1], name1, row, 3, height, arrow_scale_percent, font); + } + + if (count >= 3) { + create_btn_with_arrow_compact(parent, &btn_group->btn_a[2], name2, row, 4, height, arrow_scale_percent, font); + } + + btn_group_set_sel(btn_group, 0); +} + + + void create_btn_group_item(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, const char *name2, const char *name3, int row) { if (count > 3) return; diff --git a/src/ui/page_common.h b/src/ui/page_common.h index 54a82203..cf3de373 100644 --- a/src/ui/page_common.h +++ b/src/ui/page_common.h @@ -128,11 +128,15 @@ int create_text(struct menu_obj_s *s, lv_obj_t *parent, bool is_icon, const char void create_slider_item(slider_group_t *slider_group, lv_obj_t *parent, const char *name, int range, int default_value, int row); +void create_slider_item_compact(slider_group_t *slider_group, lv_obj_t *parent, const char *name, int range, int default_value, int row, const lv_font_t *font); + void update_slider_item_with_value(slider_group_t *slider_group, int value); void create_btn_item(lv_obj_t *parent, const char *name, int col, int row); -lv_obj_t *create_dropdown_item(lv_obj_t *parent, const char *options, int col, int row); +lv_obj_t *create_dropdown_item(lv_obj_t *parent, const char *options, int col, int row, int width, int height, int col_span, int pad_top, lv_grid_align_t column_align, const lv_font_t *font); + +lv_obj_t *create_label_item_compact(lv_obj_t *parent, const char *name, int col, int row, int cols, int height, lv_text_align_t text_align, lv_grid_align_t col_align, const lv_font_t *font); lv_obj_t *show_msgbox_ok(const char *title, const char *message); @@ -140,6 +144,9 @@ lv_obj_t *create_label_item(lv_obj_t *parent, const char *name, int col, int row lv_obj_t *create_info_item(lv_obj_t *parent, const char *name, int col, int row, int cols); +void create_btn_group_item_compact(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, + const char *name2, const char *name3, int row, int height, int arrow_scale_percent, const lv_font_t *font); + void create_btn_group_item(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, const char *name2, const char *name3, int row); diff --git a/src/ui/page_osd.c b/src/ui/page_osd.c index c8656457..84872950 100644 --- a/src/ui/page_osd.c +++ b/src/ui/page_osd.c @@ -9,224 +9,25 @@ #include "core/common.hh" #include "core/osd.h" #include "core/settings.h" +#include "driver/hardware.h" #include "page_common.h" #include "ui/ui_style.h" +#include "ui/ui_osd_element_pos.h" #include "util/math.h" -#define OSD_ELEMENT_MIN_X_POS 0 -#define OSD_ELEMENT_MAX_X_POS 1280 -#define OSD_ELEMENT_MIN_Y_POS 0 -#define OSD_ELEMENT_MAX_Y_POS 720 - enum { ROW_OSD_MODE = 0, - ROW_OSD_ELEMENT, - ROW_OSD_SHOW_ELEMENT, - ROW_OSD_ELEMENT_POS_X, - ROW_OSD_ELEMENT_POS_Y, - ROW_OSD_RESET_ELEMENTS, + ROW_ADJUST_OSD_ELEMENTS, ROW_BACK, ROW_COUNT, - ROW_USER_HINT = 7 + ROW_USER_HINT = ROW_COUNT }; -typedef enum { - OSD_ELEMENT_TOP_FAN_SPEED = 0, - OSD_ELEMENT_LATENCY_LOCK, - OSD_ELEMENT_VTX_TEMP, - OSD_ELEMENT_VRX_TEMP, - OSD_ELEMENT_BATTERY_LOW, - OSD_ELEMENT_CHANNEL, - OSD_ELEMENT_SD_REC, - OSD_ELEMENT_VLQ, - OSD_ELEMENT_ANT0, - OSD_ELEMENT_ANT1, - OSD_ELEMENT_ANT2, - OSD_ELEMENT_ANT3, - OSD_ELEMENT_GOGGLE_TEMP_TOP, - OSD_ELEMENT_GOGGLE_TEMP_LEFT, - OSD_ELEMENT_GOGGLE_TEMP_RIGHT, - - OSD_ELEMENTS_TOTAL -} osd_elements_t; - -typedef enum { - ALL_ELEMENT_RES_UNCONFIRMED = 0, - ALL_ELEMENT_RES_CONFIRMED, - ALL_ELEMENT_RES_TIMEOUT -} all_element_reset_confirm_t; - -typedef enum { - ELEMENT_POS_SCROLL_DIR_NONE = 0, - ELEMENT_POS_SCROLL_DIR_X_INC, - ELEMENT_POS_SCROLL_DIR_Y_INC, - ELEMENT_POS_SCROLL_DIR_X_DEC, - ELEMENT_POS_SCROLL_DIR_Y_DEC -} element_pos_scroll_dir_t; - -typedef enum { - ELEMENT_POS_SCROLL_SPEED_SLOW = 1, - ELEMENT_POS_SCROLL_SPEED_MED = 5, - ELEMENT_POS_SCROLL_SPEED_FAST = 20 -} element_pos_scroll_speed_t; - -typedef enum { - ELEMENT_POS_SCROLL_SPEED_STEP_MED = 10 * ELEMENT_POS_SCROLL_SPEED_SLOW, - ELEMENT_POS_SCROLL_SPEED_STEP_FAST = ELEMENT_POS_SCROLL_SPEED_STEP_MED + 10 * ELEMENT_POS_SCROLL_SPEED_MED, -} element_pos_scroll_speed_steps_t; - -typedef struct { - char *name; - char *name_settings; -} osd_element_t; - static lv_coord_t col_dsc[] = {160, 180, 160, 160, 120, 160, LV_GRID_TEMPLATE_LAST}; static lv_coord_t row_dsc[] = {60, 60, 60, 60, 60, 60, 60, 60, 60, 60, LV_GRID_TEMPLATE_LAST}; -static btn_group_t btn_group_osd_type; -static lv_obj_t *dropdown_osd_element; -static btn_group_t btn_group_osd_show_element; -static slider_group_t slider_group_osd_element_pos_x; -static slider_group_t slider_group_osd_element_pos_y; -lv_obj_t *label_reset_all_osd_elements; - -static lv_timer_t *reset_all_osd_elements_timer = NULL; - -static bool element_dropdown_focused = false; -static bool element_pos_x_slider_focused = false; -static bool element_pos_y_slider_focused = false; -static int reset_all_elements_confirm = 0; - -static lv_timer_t *element_pos_scroll_speed_timer = NULL; -static int element_pos_cur_scroll_amount = 0; -static int element_pos_cur_scroll_dir = ELEMENT_POS_SCROLL_DIR_NONE; -static int element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_SLOW; - -static char osd_elements_str[512]; - -static osd_element_t osd_element_list[] = { - {"Top Fan Speed", "topfan_speed"}, - {"Latency Lock", "latency_lock"}, - {"VTX Temp", "vtx_temp"}, - {"VRX Temp", "vrx_temp"}, - {"Battery Low", "battery_low"}, - {"Channel", "channel"}, - {"SD Rec", "sd_rec"}, - {"VLQ", "vlq"}, - {"Antenna 1", "ant0"}, - {"Antenna 2", "ant1"}, - {"Antenna 3", "ant2"}, - {"Antenna 4", "ant3"}, - {"Goggle Temp Top", "goggle_temp_top"}, - {"Goggle Temp Left", "goggle_temp_left"}, - {"Goggle Temp Right", "goggle_temp_right"}}; - -static void page_osd_fill_osd_elements_str() { - int max_element = OSD_ELEMENT_ANT3; - - if (g_test_en) { - max_element = OSD_ELEMENT_GOGGLE_TEMP_RIGHT; - } - - osd_elements_str[0] = '\0'; - for (int i = 0; i < max_element; i++) { - strcat(osd_elements_str, osd_element_list[i].name); - strcat(osd_elements_str, "\n"); - } - strcat(osd_elements_str, osd_element_list[max_element].name); -} - -static setting_osd_goggle_element_t *get_osd_element_setting_entry(int element_idx) { - return &g_setting.osd.element[element_idx]; - - // switch (element_idx) { - // case OSD_ELEMENT_TOP_FAN_SPEED: - // return &g_setting.osd.elements.topfan_speed; - - // case OSD_ELEMENT_LATENCY_LOCK: - // return &g_setting.osd.elements.latency_lock; - - // case OSD_ELEMENT_VTX_TEMP: - // return &g_setting.osd.elements.vtx_temp; - - // case OSD_ELEMENT_VRX_TEMP: - // return &g_setting.osd.elements.vrx_temp; - - // case OSD_ELEMENT_BATTERY_LOW: - // return &g_setting.osd.elements.battery_low; - - // case OSD_ELEMENT_CHANNEL: - // return &g_setting.osd.elements.channel; - - // case OSD_ELEMENT_SD_REC: - // return &g_setting.osd.elements.sd_rec; - - // case OSD_ELEMENT_VLQ: - // return &g_setting.osd.elements.vlq; - - // case OSD_ELEMENT_ANT0: - // return &g_setting.osd.elements.ant0; - - // case OSD_ELEMENT_ANT1: - // return &g_setting.osd.elements.ant1; - - // case OSD_ELEMENT_ANT2: - // return &g_setting.osd.elements.ant2; - - // case OSD_ELEMENT_ANT3: - // return &g_setting.osd.elements.ant3; - - // case OSD_ELEMENT_GOGGLE_TEMP_TOP: - // return &g_setting.osd.elements.osd_tempe[0]; - - // case OSD_ELEMENT_GOGGLE_TEMP_LEFT: - // return &g_setting.osd.elements.osd_tempe[1]; - - // case OSD_ELEMENT_GOGGLE_TEMP_RIGHT: - // return &g_setting.osd.elements.osd_tempe[2]; - - // default: - // break; - // } -} - -static setting_osd_goggle_element_t *page_osd_get_selected_osd_element_setting_entry() { - int element_idx = lv_dropdown_get_selected(dropdown_osd_element); - return get_osd_element_setting_entry(element_idx); -} - -static void update_osd_element_ui_items() { - const setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - - btn_group_set_sel(&btn_group_osd_show_element, !element->show); - - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { - update_slider_item_with_value(&slider_group_osd_element_pos_x, element->position.mode_4_3.x); - update_slider_item_with_value(&slider_group_osd_element_pos_y, element->position.mode_4_3.y); - } else { - update_slider_item_with_value(&slider_group_osd_element_pos_x, element->position.mode_16_9.x); - update_slider_item_with_value(&slider_group_osd_element_pos_y, element->position.mode_16_9.y); - } -} - -static void page_osd_reset_all_osd_elements_reset_label() { - lv_label_set_text(label_reset_all_osd_elements, "Reset all elements"); - reset_all_elements_confirm = ALL_ELEMENT_RES_UNCONFIRMED; -} - -static void page_osd_scroll_speed_timer_cb(lv_timer_t *timer) { - lv_timer_pause(element_pos_scroll_speed_timer); - element_pos_cur_scroll_dir = ELEMENT_POS_SCROLL_DIR_NONE; - element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_SLOW; - element_pos_cur_scroll_amount = 0; -} - -static void page_osd_reset_all_osd_elements_timer_cb(struct _lv_timer_t *timer) { - lv_timer_pause(reset_all_osd_elements_timer); - page_osd_reset_all_osd_elements_reset_label(); - reset_all_elements_confirm = ALL_ELEMENT_RES_UNCONFIRMED; -} +static btn_group_t btn_group_osd_mode; static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { lv_obj_t *page = lv_menu_page_create(parent, NULL); @@ -239,7 +40,7 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { lv_obj_add_style(section, &style_submenu, LV_PART_MAIN); lv_obj_set_size(section, 1053, 894); - create_text(NULL, section, false, "Goggle OSD Settings:", LV_MENU_ITEM_BUILDER_VARIANT_2); + create_text(NULL, section, false, "OSD Settings:", LV_MENU_ITEM_BUILDER_VARIANT_2); lv_obj_t *cont = lv_obj_create(section); lv_obj_set_size(cont, 960, 600); @@ -254,19 +55,9 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { create_select_item(arr, cont); // create menu entries - create_btn_group_item(&btn_group_osd_type, cont, 2, "OSD Mode", "4x3", "16x9", "", "", ROW_OSD_MODE); - - create_label_item(cont, "Element: ", 1, ROW_OSD_ELEMENT, 1); - page_osd_fill_osd_elements_str(); - dropdown_osd_element = create_dropdown_item(cont, osd_elements_str, 2, ROW_OSD_ELEMENT); - lv_obj_set_width(dropdown_osd_element, 320); - - create_btn_group_item(&btn_group_osd_show_element, cont, 2, "Show Element", "Yes", "No", "", "", ROW_OSD_SHOW_ELEMENT); - create_slider_item(&slider_group_osd_element_pos_x, cont, "Element Pos-X", OSD_ELEMENT_MAX_X_POS, 0, ROW_OSD_ELEMENT_POS_X); - create_slider_item(&slider_group_osd_element_pos_y, cont, "Element Pos-Y", OSD_ELEMENT_MAX_Y_POS, 0, ROW_OSD_ELEMENT_POS_Y); - - label_reset_all_osd_elements = create_label_item(cont, "Reset all elements", 1, ROW_OSD_RESET_ELEMENTS, 1); - lv_obj_set_width(label_reset_all_osd_elements, 600); + create_label_item(cont, "Adjust OSD Elements", 1, ROW_ADJUST_OSD_ELEMENTS, 1); + create_btn_group_item(&btn_group_osd_mode, cont, 2, "OSD Mode", "4x3", "16x9", "", "", ROW_OSD_MODE); + create_label_item(cont, "< Back", 1, ROW_BACK, 1); lv_obj_t *label_user_hint = lv_label_create(cont); lv_label_set_text(label_user_hint, "OSD Element positioning is based on a 1280x720 canvas.\nPositions can be set for 4x3 and 16x9 modes separately,\nthe Show Element toggle is shared between both modes."); @@ -278,272 +69,72 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { lv_obj_set_grid_cell(label_user_hint, LV_GRID_ALIGN_START, 1, 4, LV_GRID_ALIGN_START, ROW_USER_HINT, 2); - // Back entry - create_label_item(cont, "< Back", 1, ROW_BACK, 1); - - // set menu selections - btn_group_set_sel(&btn_group_osd_type, g_setting.osd.embedded_mode); - update_osd_element_ui_items(); - - // create timers - element_pos_scroll_speed_timer = lv_timer_create(page_osd_scroll_speed_timer_cb, 1000, NULL); - lv_timer_pause(element_pos_scroll_speed_timer); - reset_all_osd_elements_timer = lv_timer_create(page_osd_reset_all_osd_elements_timer_cb, 3000, NULL); - lv_timer_pause(reset_all_osd_elements_timer); + // set ui values from settings + btn_group_set_sel(&btn_group_osd_mode, g_setting.osd.embedded_mode); return page; } -static int page_osd_reset_all_osd_elements() { - int res = 1; - - for (int i = 0; i < OSD_ELEMENTS_TOTAL; i++) { - g_setting.osd.element[i] = g_setting_defaults.osd.element[i]; - res &= settings_put_osd_element(&g_setting.osd.element[i], osd_element_list[i].name_settings); - } - - // res = settings_put_osd_element(&g_setting.osd.elements.topfan_speed, osd_element_list[OSD_ELEMENT_TOP_FAN_SPEED].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.latency_lock, osd_element_list[OSD_ELEMENT_LATENCY_LOCK].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.vtx_temp, osd_element_list[OSD_ELEMENT_VTX_TEMP].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.vrx_temp, osd_element_list[OSD_ELEMENT_VRX_TEMP].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.battery_low, osd_element_list[OSD_ELEMENT_BATTERY_LOW].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.channel, osd_element_list[OSD_ELEMENT_CHANNEL].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.sd_rec, osd_element_list[OSD_ELEMENT_SD_REC].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.vlq, osd_element_list[OSD_ELEMENT_VLQ].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.ant0, osd_element_list[OSD_ELEMENT_ANT0].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.ant1, osd_element_list[OSD_ELEMENT_ANT1].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.ant2, osd_element_list[OSD_ELEMENT_ANT2].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.ant3, osd_element_list[OSD_ELEMENT_ANT3].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.osd_tempe[0], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_TOP].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.osd_tempe[1], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_LEFT].name_settings); - // res &= settings_put_osd_element(&g_setting.osd.elements.osd_tempe[2], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_RIGHT].name_settings); - - return res; -} - -static char *page_osd_get_selected_osd_element_setting_name() { - return osd_element_list[lv_dropdown_get_selected(dropdown_osd_element)].name_settings; -} - -static void page_osd_slider_scroll_acceleration(element_pos_scroll_dir_t direction) { - if (element_pos_cur_scroll_dir != direction) { - element_pos_cur_scroll_dir = direction; - element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_SLOW; - element_pos_cur_scroll_amount = 0; - - lv_timer_reset(element_pos_scroll_speed_timer); - lv_timer_resume(element_pos_scroll_speed_timer); - } else { - lv_timer_reset(element_pos_scroll_speed_timer); - if (element_pos_cur_scroll_amount >= ELEMENT_POS_SCROLL_SPEED_STEP_FAST) { - element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_FAST; - } else if (element_pos_cur_scroll_amount >= ELEMENT_POS_SCROLL_SPEED_STEP_MED) { - element_pos_cur_scroll_speed = ELEMENT_POS_SCROLL_SPEED_MED; - } - } - - element_pos_cur_scroll_amount += element_pos_cur_scroll_speed; -} - -static void page_osd_element_pos_x_dec() { - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - - page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_X_DEC); - - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { - safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, - &element->position.mode_4_3.x, - (-element_pos_cur_scroll_speed)); - } else { - safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, - &element->position.mode_16_9.x, - (-element_pos_cur_scroll_speed)); - } +// when changing settings in the element position preview, +// this is used to reflect the changes on this settings page, +// in case the changed setting is visible here +void page_osd_update_ui_elements(){ + btn_group_set_sel(&btn_group_osd_mode, g_setting.osd.embedded_mode); } -static void page_osd_element_pos_y_dec() { - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - - page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_Y_DEC); - - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { - safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, - &element->position.mode_4_3.y, - (-element_pos_cur_scroll_speed)); - } else { - safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, - &element->position.mode_16_9.y, - (-element_pos_cur_scroll_speed)); - } -} - -static void page_osd_element_pos_x_inc() { - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - - page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_X_INC); - - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { - safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, - &element->position.mode_4_3.x, - element_pos_cur_scroll_speed); - } else { - safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, - &element->position.mode_16_9.x, - element_pos_cur_scroll_speed); - } -} - -static void page_osd_element_pos_y_inc() { - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - - page_osd_slider_scroll_acceleration(ELEMENT_POS_SCROLL_DIR_Y_INC); - - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { - safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, - &element->position.mode_4_3.y, - element_pos_cur_scroll_speed); - } else { - safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, - &element->position.mode_16_9.y, - element_pos_cur_scroll_speed); - } -} - -static void page_osd_on_roller(uint8_t key) { - if (reset_all_elements_confirm == ALL_ELEMENT_RES_CONFIRMED) { - page_osd_reset_all_osd_elements_reset_label(); - return; - } - - if (key == DIAL_KEY_UP) { - - if (element_dropdown_focused) { - uint32_t evt = LV_KEY_DOWN; - lv_event_send(dropdown_osd_element, LV_EVENT_KEY, &evt); - } else if (element_pos_x_slider_focused) { - page_osd_element_pos_x_dec(); - } else if (element_pos_y_slider_focused) { - page_osd_element_pos_y_dec(); - } - - } else if (key == DIAL_KEY_DOWN) { - - if (element_dropdown_focused) { - uint32_t evt = LV_KEY_UP; - lv_event_send(dropdown_osd_element, LV_EVENT_KEY, &evt); - } else if (element_pos_x_slider_focused) { - page_osd_element_pos_x_inc(); - } else if (element_pos_y_slider_focused) { - page_osd_element_pos_y_inc(); - } - } - - update_osd_element_ui_items(); -} - -static void page_osd_on_click(uint8_t key, int sel) { - - switch (sel) { - - case ROW_OSD_MODE: - btn_group_toggle_sel(&btn_group_osd_type); - g_setting.osd.embedded_mode = btn_group_get_sel(&btn_group_osd_type); - ini_putl("osd", "embedded_mode", g_setting.osd.embedded_mode, SETTING_INI); - osd_update_mode(); +static void open_element_pos_preview() { + switch (g_source_info.source) { + case SOURCE_HDZERO: + progress_bar.start = 1; + HDZero_open(g_hw_stat.hdz_bw); + app_switch_to_hdzero(true); break; - case ROW_OSD_ELEMENT: - if (!element_dropdown_focused) { - app_state_push(APP_STATE_SUBMENU_ITEM_FOCUSED); - lv_obj_t *list = lv_dropdown_get_list(dropdown_osd_element); - lv_dropdown_open(dropdown_osd_element); - lv_obj_add_style(list, &style_dropdown, LV_PART_MAIN); - lv_obj_set_style_text_color(list, lv_color_make(0, 0, 0), LV_PART_SELECTED | LV_STATE_CHECKED); - element_dropdown_focused = true; - } else { - app_state_push(APP_STATE_SUBMENU); - lv_event_send(dropdown_osd_element, LV_EVENT_RELEASED, NULL); - element_dropdown_focused = false; - int option = lv_dropdown_get_selected(dropdown_osd_element); - } + case SOURCE_HDMI_IN: + app_switch_to_hdmi_in(); break; - case ROW_OSD_SHOW_ELEMENT: - btn_group_toggle_sel(&btn_group_osd_show_element); - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - element->show = btn_group_get_sel(&btn_group_osd_show_element) == 0; - settings_put_osd_element_shown(element->show, page_osd_get_selected_osd_element_setting_name()); - osd_update_mode(); + case SOURCE_AV_IN: + app_switch_to_analog(0); break; - case ROW_OSD_ELEMENT_POS_X: - if (!element_pos_x_slider_focused) { - app_state_push(APP_STATE_SUBMENU_ITEM_FOCUSED); - lv_obj_add_style(slider_group_osd_element_pos_x.slider, &style_silder_select, LV_PART_MAIN); - element_pos_x_slider_focused = true; - } else { - app_state_push(APP_STATE_SUBMENU); - lv_obj_add_style(slider_group_osd_element_pos_x.slider, &style_silder_main, LV_PART_MAIN); - - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - settings_put_osd_element_pos_x(&element->position, page_osd_get_selected_osd_element_setting_name()); - osd_update_mode(); - - element_pos_x_slider_focused = false; - } + case SOURCE_EXPANSION: + app_switch_to_analog(1); break; + } - case ROW_OSD_ELEMENT_POS_Y: - if (!element_pos_y_slider_focused) { - app_state_push(APP_STATE_SUBMENU_ITEM_FOCUSED); - lv_obj_add_style(slider_group_osd_element_pos_y.slider, &style_silder_select, LV_PART_MAIN); - element_pos_y_slider_focused = true; - } else { - app_state_push(APP_STATE_SUBMENU); - lv_obj_add_style(slider_group_osd_element_pos_y.slider, &style_silder_main, LV_PART_MAIN); + ui_osd_element_pos_on_enter(); + app_state_push(APP_STATE_OSD_ELEMENT_PREV); +} - setting_osd_goggle_element_t *element = page_osd_get_selected_osd_element_setting_entry(); - settings_put_osd_element_pos_y(&element->position, page_osd_get_selected_osd_element_setting_name()); - osd_update_mode(); +static void on_click(uint8_t key, int sel) { + switch (sel) { - element_pos_y_slider_focused = false; - } + case ROW_ADJUST_OSD_ELEMENTS: + open_element_pos_preview(); break; - case ROW_OSD_RESET_ELEMENTS: - if (reset_all_elements_confirm == ALL_ELEMENT_RES_TIMEOUT) - return; - - if (reset_all_elements_confirm) { - page_osd_reset_all_osd_elements(); - osd_update_mode(); - lv_label_set_text(label_reset_all_osd_elements, "#00FF00 Elements reset.#"); - lv_timer_reset(reset_all_osd_elements_timer); - lv_timer_resume(reset_all_osd_elements_timer); - reset_all_elements_confirm = ALL_ELEMENT_RES_TIMEOUT; - } else { - lv_label_set_text(label_reset_all_osd_elements, "#FFFF00 Click to confirm or Scroll to cancel...#"); - reset_all_elements_confirm = ALL_ELEMENT_RES_CONFIRMED; - } - + case ROW_OSD_MODE: + btn_group_toggle_sel(&btn_group_osd_mode); + g_setting.osd.embedded_mode = btn_group_get_sel(&btn_group_osd_mode); + ini_putl("osd", "embedded_mode", g_setting.osd.embedded_mode, SETTING_INI); + osd_update_mode(); break; default: break; } - - update_osd_element_ui_items(); } page_pack_t pp_osd = { .p_arr = { .cur = 0, .max = ROW_COUNT}, - .name = "Goggle OSD", + .name = "OSD", .create = page_osd_create, .enter = NULL, .exit = NULL, - .on_roller = page_osd_on_roller, - .on_click = page_osd_on_click, + .on_roller = NULL, + .on_click = on_click, .on_right_button = NULL, }; \ No newline at end of file diff --git a/src/ui/page_osd.h b/src/ui/page_osd.h index b81606bf..76c886cd 100644 --- a/src/ui/page_osd.h +++ b/src/ui/page_osd.h @@ -4,5 +4,6 @@ #include "ui/ui_main_menu.h" extern page_pack_t pp_osd; +void page_osd_update_ui_elements(); #endif diff --git a/src/ui/ui_osd_element_pos.c b/src/ui/ui_osd_element_pos.c new file mode 100644 index 00000000..84d016de --- /dev/null +++ b/src/ui/ui_osd_element_pos.c @@ -0,0 +1,661 @@ +#include "ui/ui_osd_element_pos.h" + +#include + +#include +#include +#include + +#include "core/common.hh" +#include "core/osd.h" +#include "driver/hardware.h" +#include "driver/oled.h" +#include "log/log.h" +#include "ui/page_common.h" +#include "ui/page_osd.h" +#include "util/math.h" + +#define CANVAS_WIDTH 445 +#define CANVAS_HEIGHT 365 + +#define OSD_ELEMENT_MIN_X_POS 0 +#define OSD_ELEMENT_MAX_X_POS 1280 +#define OSD_ELEMENT_MIN_Y_POS 0 +#define OSD_ELEMENT_MAX_Y_POS 720 + +enum { + ROW_OSD_MODE = 0, + ROW_OSD_ELEMENT, + ROW_OSD_SHOW_ELEMENT, + ROW_OSD_ELEMENT_POS_X, + ROW_OSD_ELEMENT_POS_Y, + ROW_SAVE, + ROW_CANCEL, + ROW_RESET_ELEMENTS, + + ROW_COUNT +}; + +typedef enum { + UI_STATE_SCROLL = 0, + UI_STATE_FOCUSED +} ui_state_t; + +typedef enum { + CONFIRMATION_UNCONFIRMED = 0, + CONFIRMATION_CONFIRMED, + CONFIRMATION_TIMEOUT +} ui_confirmation_t; + +typedef enum { + SLIDER_SCROLL_DIR_NONE = 0, + SLIDER_SCROLL_DIR_X_INC, + SLIDER_SCROLL_DIR_Y_INC, + SLIDER_SCROLL_DIR_X_DEC, + SLIDER_SCROLL_DIR_Y_DEC +} slider_scroll_dir_t; + +typedef enum { + SLIDER_SCROLL_SPEED_SLOW = 1, + SLIDER_SCROLL_SPEED_MED = 5, + SLIDER_SCROLL_SPEED_FAST = 20 +} slider_scroll_speed_t; + +typedef enum { + SLIDER_SCROLL_SPEED_STEP_MED = 10 * SLIDER_SCROLL_SPEED_SLOW, + SLIDER_SCROLL_SPEED_STEP_FAST = SLIDER_SCROLL_SPEED_STEP_MED + 10 * SLIDER_SCROLL_SPEED_MED, +} slider_scroll_speed_step_t; + +// a list of all osd elements +// must contain the same elements, in the same order, as osd_element_list[] +typedef enum { + OSD_ELEMENT_TOP_FAN_SPEED = 0, + OSD_ELEMENT_LATENCY_LOCK, + OSD_ELEMENT_VTX_TEMP, + OSD_ELEMENT_VRX_TEMP, + OSD_ELEMENT_BATTERY_LOW, + OSD_ELEMENT_CHANNEL, + OSD_ELEMENT_SD_REC, + OSD_ELEMENT_VLQ, + OSD_ELEMENT_ANT0, + OSD_ELEMENT_ANT1, + OSD_ELEMENT_ANT2, + OSD_ELEMENT_ANT3, + OSD_ELEMENT_GOGGLE_TEMP_TOP, + OSD_ELEMENT_GOGGLE_TEMP_LEFT, + OSD_ELEMENT_GOGGLE_TEMP_RIGHT, + + OSD_ELEMENTS_TOTAL +} osd_elements_t; + +typedef struct { + char *name; + char *name_settings; +} osd_element_t; + +// ########################################################################### +// ########################## local variables start ########################## +// ########################################################################### + +// sets if the ui is shown during the next ui update (ui_osd_element_pos_update()) +static bool show_osd_element_pos_ui = false; + +// elements making up the ui +static lv_coord_t col_dsc[] = {10, 95, 120, 120, 60, 30, LV_GRID_TEMPLATE_LAST}; +static lv_coord_t row_dsc[] = {40, 40, 40, 40, 40, 30, 30, 30, 30, LV_GRID_TEMPLATE_LAST}; +static panel_arr_t ui_selection_panel = {.cur = 0, .max = ROW_COUNT}; +static lv_obj_t *ui_root_container; +static btn_group_t btn_group_osd_mode; +static lv_obj_t *dropdown_osd_element; +static btn_group_t btn_group_osd_show_element; +static slider_group_t slider_group_osd_element_pos_x; +static slider_group_t slider_group_osd_element_pos_y; +static lv_obj_t *label_save_osd_elements; +static lv_obj_t *label_cancel_osd_elements; +static lv_obj_t *label_reset_all_osd_elements; + +// to keep track of the current state of the ui +static int ui_state; +static int ui_cur_row; + +// used for action confirmations +static lv_timer_t *reset_all_osd_elements_timer = NULL; +static int reset_all_elements_confirm = CONFIRMATION_UNCONFIRMED; +static int save_changes_confirm = CONFIRMATION_UNCONFIRMED; +static int cancel_changes_confirm = CONFIRMATION_UNCONFIRMED; + +// used for slider scroll acceleration +static lv_timer_t *slider_scroll_accel_timer = NULL; +static int slider_cur_scroll_amount = 0; +static int slider_cur_scroll_dir = SLIDER_SCROLL_DIR_NONE; +static int slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_SLOW; + +// keeps track of the unchanged element settings in case user clicks cancel +static setting_osd_t ui_osd_el_pos_unchanged_settings; + +// all elements with a display string and the corresponding setting name +// this and osd_elements_t must contain the same elements, in the same order +static osd_element_t osd_element_list[] = { + {"Top Fan Speed", "topfan_speed"}, + {"Latency Lock", "latency_lock"}, + {"VTX Temp", "vtx_temp"}, + {"VRX Temp", "vrx_temp"}, + {"Battery Low", "battery_low"}, + {"Channel", "channel"}, + {"DVR", "sd_rec"}, + {"VLQ", "vlq"}, + {"Antenna 1", "ant0"}, + {"Antenna 2", "ant1"}, + {"Antenna 3", "ant2"}, + {"Antenna 4", "ant3"}, + {"Goggle Temp Top", "goggle_temp_top"}, + {"Goggle Temp Left", "goggle_temp_left"}, + {"Goggle Temp Right", "goggle_temp_right"}}; + +// string used for the dropdown menu +static char osd_elements_str[512]; + +// ########################################################################### +// ########################### local variables end ########################### +// ########################################################################### + +// ########################################################################## +// #################### local functions prototypes start #################### +// ########################################################################## + +// utility functions +static setting_osd_goggle_element_t *get_osd_element_setting_entry(int element_idx); +static void fill_osd_elements_str(); +static setting_osd_goggle_element_t *get_selected_osd_element_setting_entry(); +static int persist_all_osd_element_settings(const setting_osd_t *settings_to_persist); + +// ui utility functions +static void update_ui(); +static void ui_set_selection(int row); + +// used for user action confirmations like save/cancel/reset +static void reset_all_osd_elements_reset_label_text(); +static void save_osd_elements_reset_label_text(); +static void cancel_osd_elements_reset_label_text(); +static void reset_all_osd_elements_timer_cb(struct _lv_timer_t *timer); + +// handle slider acceleration when positioning elements +static void slider_scroll_speed_timer_cb(lv_timer_t *timer); +static void slider_scroll_accel_apply(slider_scroll_dir_t direction); + +// user input handling +static void osd_element_pos_x_dec(); +static void osd_element_pos_y_dec(); +static void osd_element_pos_x_inc(); +static void osd_element_pos_y_inc(); +static void ui_handle_roll_up(); +static void ui_handle_roll_down(); +static int ui_handle_click(); + +// ########################################################################## +// ##################### local functions prototypes end ##################### +// ########################################################################## + +static setting_osd_goggle_element_t *get_osd_element_setting_entry(int element_idx) { + return &g_setting.osd.element[element_idx]; +} + +// creates the string used for the dropdown menu +static void fill_osd_elements_str() { + int max_element = OSD_ELEMENT_ANT3; + + if (g_test_en) { + max_element = OSD_ELEMENT_GOGGLE_TEMP_RIGHT; + } + + osd_elements_str[0] = '\0'; + for (int idx = 0; idx < max_element; idx++) { + strcat(osd_elements_str, osd_element_list[idx].name); + strcat(osd_elements_str, "\n"); + } + strcat(osd_elements_str, osd_element_list[max_element].name); +} + +static setting_osd_goggle_element_t *get_selected_osd_element_setting_entry() { + int element_idx = lv_dropdown_get_selected(dropdown_osd_element); + return get_osd_element_setting_entry(element_idx); +} + +static int persist_all_osd_element_settings(const setting_osd_t *settings_to_persist) { + int res = 1; + + res = ini_putl("osd", "embedded_mode", settings_to_persist->embedded_mode, SETTING_INI); + + for (int i = 0; i < OSD_ELEMENTS_TOTAL; i++) { + res &= settings_put_osd_element(&settings_to_persist->element[i], osd_element_list[i].name_settings); + } + + // res &= settings_put_osd_element(&settings_to_persist->elements.topfan_speed, osd_element_list[OSD_ELEMENT_TOP_FAN_SPEED].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.latency_lock, osd_element_list[OSD_ELEMENT_LATENCY_LOCK].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.vtx_temp, osd_element_list[OSD_ELEMENT_VTX_TEMP].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.vrx_temp, osd_element_list[OSD_ELEMENT_VRX_TEMP].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.battery_low, osd_element_list[OSD_ELEMENT_BATTERY_LOW].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.channel, osd_element_list[OSD_ELEMENT_CHANNEL].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.sd_rec, osd_element_list[OSD_ELEMENT_SD_REC].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.vlq, osd_element_list[OSD_ELEMENT_VLQ].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.ant0, osd_element_list[OSD_ELEMENT_ANT0].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.ant1, osd_element_list[OSD_ELEMENT_ANT1].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.ant2, osd_element_list[OSD_ELEMENT_ANT2].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.ant3, osd_element_list[OSD_ELEMENT_ANT3].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.osd_tempe[0], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_TOP].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.osd_tempe[1], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_LEFT].name_settings); + // res &= settings_put_osd_element(&settings_to_persist->elements.osd_tempe[2], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_RIGHT].name_settings); + + return res; +} + +static void update_ui() { + const setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); + + btn_group_set_sel(&btn_group_osd_mode, g_setting.osd.embedded_mode); + + btn_group_set_sel(&btn_group_osd_show_element, !element->show); + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + update_slider_item_with_value(&slider_group_osd_element_pos_x, element->position.mode_4_3.x); + update_slider_item_with_value(&slider_group_osd_element_pos_y, element->position.mode_4_3.y); + } else { + update_slider_item_with_value(&slider_group_osd_element_pos_x, element->position.mode_16_9.x); + update_slider_item_with_value(&slider_group_osd_element_pos_y, element->position.mode_16_9.y); + } +} + +static void ui_set_selection(int row) { + set_select_item(&ui_selection_panel, row); +} + +static void reset_all_osd_elements_reset_label_text() { + lv_label_set_text(label_reset_all_osd_elements, "Reset all elements (both modes)"); + reset_all_elements_confirm = CONFIRMATION_UNCONFIRMED; +} + +static void save_osd_elements_reset_label_text() { + lv_label_set_text(label_save_osd_elements, "Save changes"); + lv_obj_set_style_text_font(label_save_osd_elements, &lv_font_montserrat_20, 0); + save_changes_confirm = CONFIRMATION_UNCONFIRMED; +} + +static void cancel_osd_elements_reset_label_text() { + lv_label_set_text(label_cancel_osd_elements, "Cancel"); + lv_obj_set_style_text_font(label_cancel_osd_elements, &lv_font_montserrat_20, 0); + cancel_changes_confirm = CONFIRMATION_UNCONFIRMED; +} + +static void reset_all_osd_elements_timer_cb(struct _lv_timer_t *timer) { + lv_timer_pause(reset_all_osd_elements_timer); + reset_all_osd_elements_reset_label_text(); + reset_all_elements_confirm = CONFIRMATION_UNCONFIRMED; +} + +static void slider_scroll_speed_timer_cb(lv_timer_t *timer) { + lv_timer_pause(slider_scroll_accel_timer); + slider_cur_scroll_dir = SLIDER_SCROLL_DIR_NONE; + slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_SLOW; + slider_cur_scroll_amount = 0; +} + +static void slider_scroll_accel_apply(slider_scroll_dir_t direction) { + if (slider_cur_scroll_dir != direction) { + slider_cur_scroll_dir = direction; + slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_SLOW; + slider_cur_scroll_amount = 0; + + lv_timer_reset(slider_scroll_accel_timer); + lv_timer_resume(slider_scroll_accel_timer); + } else { + lv_timer_reset(slider_scroll_accel_timer); + if (slider_cur_scroll_amount >= SLIDER_SCROLL_SPEED_STEP_FAST) { + slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_FAST; + } else if (slider_cur_scroll_amount >= SLIDER_SCROLL_SPEED_STEP_MED) { + slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_MED; + } + } + + slider_cur_scroll_amount += slider_cur_scroll_speed; +} + +static void osd_element_pos_x_dec() { + setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); + + slider_scroll_accel_apply(SLIDER_SCROLL_DIR_X_DEC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_4_3.x, + (-slider_cur_scroll_speed)); + } else { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_16_9.x, + (-slider_cur_scroll_speed)); + } +} + +static void osd_element_pos_y_dec() { + setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); + + slider_scroll_accel_apply(SLIDER_SCROLL_DIR_Y_DEC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_4_3.y, + (-slider_cur_scroll_speed)); + } else { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_16_9.y, + (-slider_cur_scroll_speed)); + } +} + +static void osd_element_pos_x_inc() { + setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); + + slider_scroll_accel_apply(SLIDER_SCROLL_DIR_X_INC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_4_3.x, + slider_cur_scroll_speed); + } else { + safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, + &element->position.mode_16_9.x, + slider_cur_scroll_speed); + } +} + +static void osd_element_pos_y_inc() { + setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); + + slider_scroll_accel_apply(SLIDER_SCROLL_DIR_Y_INC); + + if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_4_3.y, + slider_cur_scroll_speed); + } else { + safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, + &element->position.mode_16_9.y, + slider_cur_scroll_speed); + } +} + +static void ui_handle_roll_up() { + // if a confirmation is pending, cancel it + if (reset_all_elements_confirm == CONFIRMATION_CONFIRMED) + reset_all_osd_elements_reset_label_text(); + else if (save_changes_confirm == CONFIRMATION_CONFIRMED) + save_osd_elements_reset_label_text(); + else if (cancel_changes_confirm == CONFIRMATION_CONFIRMED) + cancel_osd_elements_reset_label_text(); + + // if no item is focused, scroll through the rows + if (ui_state == UI_STATE_SCROLL) { + ui_cur_row++; + if (ui_cur_row >= ROW_COUNT) + ui_cur_row = 0; + + ui_set_selection(ui_cur_row); + return; + } + + // if an item is focused, user input is directed at that item + switch (ui_cur_row) { + case ROW_OSD_ELEMENT: { + uint32_t evt = LV_KEY_DOWN; + lv_event_send(dropdown_osd_element, LV_EVENT_KEY, &evt); + update_ui(); + } break; + + case ROW_OSD_ELEMENT_POS_X: + osd_element_pos_x_dec(); + update_ui(); + osd_update_mode(); + break; + + case ROW_OSD_ELEMENT_POS_Y: + osd_element_pos_y_dec(); + update_ui(); + osd_update_mode(); + break; + + default: + break; + } +} + +static void ui_handle_roll_down() { + // if a confirmation is pending, cancel it + if (reset_all_elements_confirm == CONFIRMATION_CONFIRMED) + reset_all_osd_elements_reset_label_text(); + else if (save_changes_confirm == CONFIRMATION_CONFIRMED) + save_osd_elements_reset_label_text(); + else if (cancel_changes_confirm == CONFIRMATION_CONFIRMED) + cancel_osd_elements_reset_label_text(); + + // if no item is focused, scroll through the rows + if (ui_state == UI_STATE_SCROLL) { + ui_cur_row--; + if (ui_cur_row < 0) + ui_cur_row = ROW_COUNT - 1; + + ui_set_selection(ui_cur_row); + return; + } + + // if an item is focused, user input is directed at that item + switch (ui_cur_row) { + case ROW_OSD_ELEMENT: { + uint32_t evt = LV_KEY_UP; + lv_event_send(dropdown_osd_element, LV_EVENT_KEY, &evt); + update_ui(); + } break; + + case ROW_OSD_ELEMENT_POS_X: + osd_element_pos_x_inc(); + update_ui(); + osd_update_mode(); + break; + + case ROW_OSD_ELEMENT_POS_Y: + osd_element_pos_y_inc(); + update_ui(); + osd_update_mode(); + break; + + default: + break; + } +} + +static int ui_handle_click() { + // handle click depending on the current row + switch (ui_cur_row) { + case ROW_OSD_MODE: + btn_group_toggle_sel(&btn_group_osd_mode); + g_setting.osd.embedded_mode = btn_group_get_sel(&btn_group_osd_mode); + update_ui(); + osd_update_mode(); + break; + + case ROW_OSD_ELEMENT: + if (ui_state != UI_STATE_FOCUSED) { + ui_state = UI_STATE_FOCUSED; + lv_obj_t *list = lv_dropdown_get_list(dropdown_osd_element); + lv_dropdown_open(dropdown_osd_element); + lv_obj_add_style(list, &style_dropdown, LV_PART_MAIN); + lv_obj_set_style_text_color(list, lv_color_make(0, 0, 0), LV_PART_SELECTED | LV_STATE_CHECKED); + } else { + ui_state = UI_STATE_SCROLL; + lv_event_send(dropdown_osd_element, LV_EVENT_RELEASED, NULL); + } + + break; + + case ROW_OSD_SHOW_ELEMENT: + btn_group_toggle_sel(&btn_group_osd_show_element); + setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); + element->show = btn_group_get_sel(&btn_group_osd_show_element) == 0; + break; + + case ROW_OSD_ELEMENT_POS_X: + if (ui_state != UI_STATE_FOCUSED) { + ui_state = UI_STATE_FOCUSED; + lv_obj_add_style(slider_group_osd_element_pos_x.slider, &style_silder_select, LV_PART_MAIN); + } else { + ui_state = UI_STATE_SCROLL; + lv_obj_add_style(slider_group_osd_element_pos_x.slider, &style_silder_main, LV_PART_MAIN); + } + break; + + case ROW_OSD_ELEMENT_POS_Y: + if (ui_state != UI_STATE_FOCUSED) { + ui_state = UI_STATE_FOCUSED; + lv_obj_add_style(slider_group_osd_element_pos_y.slider, &style_silder_select, LV_PART_MAIN); + } else { + ui_state = UI_STATE_SCROLL; + lv_obj_add_style(slider_group_osd_element_pos_y.slider, &style_silder_main, LV_PART_MAIN); + } + break; + + case ROW_CANCEL: + if (cancel_changes_confirm) { + g_setting.osd = ui_osd_el_pos_unchanged_settings; + osd_update_mode(); + show_osd_element_pos_ui = false; + cancel_osd_elements_reset_label_text(); + return 1; + } + + lv_obj_set_style_text_font(label_cancel_osd_elements, &lv_font_montserrat_18, 0); + lv_label_set_text(label_cancel_osd_elements, "#FFFF00 click to confirm/scroll to cancel#"); + cancel_changes_confirm = CONFIRMATION_CONFIRMED; + return 0; + + case ROW_SAVE: + if (save_changes_confirm) { + persist_all_osd_element_settings(&g_setting.osd); + show_osd_element_pos_ui = false; + save_osd_elements_reset_label_text(); + + // some of the changes we made might also be displayed on the osd settings page + // so we need to make sure to update its ui elements + page_osd_update_ui_elements(); + return 1; + } + + lv_obj_set_style_text_font(label_save_osd_elements, &lv_font_montserrat_18, 0); + lv_label_set_text(label_save_osd_elements, "#FFFF00 click to confirm/scroll to cancel#"); + save_changes_confirm = CONFIRMATION_CONFIRMED; + return 0; + + case ROW_RESET_ELEMENTS: + if (reset_all_elements_confirm == CONFIRMATION_TIMEOUT) + return 0; + + if (reset_all_elements_confirm) { + for (int i = 0; i < OSD_GOGGLE_NUM; i++) { + g_setting.osd.element[i] = g_setting_defaults.osd.element[i]; + } + + update_ui(); + osd_update_mode(); + lv_label_set_text(label_reset_all_osd_elements, "#00FF00 Elements reset.#"); + lv_timer_reset(reset_all_osd_elements_timer); + lv_timer_resume(reset_all_osd_elements_timer); + reset_all_elements_confirm = CONFIRMATION_TIMEOUT; + } else { + lv_label_set_text(label_reset_all_osd_elements, "#FFFF00 click to confirm/scroll to cancel#"); + reset_all_elements_confirm = CONFIRMATION_CONFIRMED; + } + return 0; + + default: + break; + } + + return 0; +} + +void ui_osd_element_pos_init(void) { + ui_root_container = lv_obj_create(lv_scr_act()); + lv_obj_add_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_size(ui_root_container, CANVAS_WIDTH, CANVAS_HEIGHT); + lv_obj_align(ui_root_container, LV_ALIGN_BOTTOM_MID, 0, -50); + lv_obj_set_layout(ui_root_container, LV_LAYOUT_GRID); + lv_obj_clear_flag(ui_root_container, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_add_style(ui_root_container, &style_context, LV_PART_MAIN); + lv_obj_set_style_grid_column_dsc_array(ui_root_container, col_dsc, 0); + lv_obj_set_style_grid_row_dsc_array(ui_root_container, row_dsc, 0); + create_select_item(&ui_selection_panel, ui_root_container); + + // create all elements + create_btn_group_item_compact(&btn_group_osd_mode, ui_root_container, 2, "Mode", "4x3", "16x9", "", "", ROW_OSD_MODE, 40, 80, &lv_font_montserrat_20); + + create_label_item_compact(ui_root_container, "Element: ", 1, ROW_OSD_ELEMENT, 1, 40, LV_TEXT_ALIGN_LEFT, LV_GRID_ALIGN_START, &lv_font_montserrat_20); + fill_osd_elements_str(); + dropdown_osd_element = create_dropdown_item(ui_root_container, osd_elements_str, 2, ROW_OSD_ELEMENT, 160, 30, 2, 2, LV_GRID_ALIGN_STRETCH, &lv_font_montserrat_20); + + create_btn_group_item_compact(&btn_group_osd_show_element, ui_root_container, 2, "Show", "Yes", "No", "", "", ROW_OSD_SHOW_ELEMENT, 40, 80, &lv_font_montserrat_20); + create_slider_item_compact(&slider_group_osd_element_pos_x, ui_root_container, "Pos-X", OSD_ELEMENT_MAX_X_POS, 0, ROW_OSD_ELEMENT_POS_X, &lv_font_montserrat_20); + create_slider_item_compact(&slider_group_osd_element_pos_y, ui_root_container, "Pos-Y", OSD_ELEMENT_MAX_Y_POS, 0, ROW_OSD_ELEMENT_POS_Y, &lv_font_montserrat_20); + label_save_osd_elements = create_label_item_compact(ui_root_container, "Save changes", 0, ROW_SAVE, 5, 30, LV_TEXT_ALIGN_CENTER, LV_GRID_ALIGN_CENTER, &lv_font_montserrat_20); + label_cancel_osd_elements = create_label_item_compact(ui_root_container, "Cancel", 0, ROW_CANCEL, 5, 30, LV_TEXT_ALIGN_CENTER, LV_GRID_ALIGN_CENTER, &lv_font_montserrat_20); + label_reset_all_osd_elements = create_label_item_compact(ui_root_container, "Reset all elements (both modes)", 0, ROW_RESET_ELEMENTS, 5, 30, LV_TEXT_ALIGN_CENTER, LV_GRID_ALIGN_CENTER, &lv_font_montserrat_18); + + // make the menu semi-transparent + lv_obj_set_style_bg_opa(ui_root_container, LV_OPA_70, 0); + + // set menu selections + update_ui(); + + // create timers + slider_scroll_accel_timer = lv_timer_create(slider_scroll_speed_timer_cb, 1000, NULL); + lv_timer_pause(slider_scroll_accel_timer); + reset_all_osd_elements_timer = lv_timer_create(reset_all_osd_elements_timer_cb, 3000, NULL); + lv_timer_pause(reset_all_osd_elements_timer); + + ui_cur_row = ROW_OSD_MODE; + ui_state = UI_STATE_SCROLL; + + // set the initial selection + ui_set_selection(ui_cur_row); +} + +void ui_osd_element_pos_on_enter() { + ui_osd_el_pos_unchanged_settings = g_setting.osd; + + ui_cur_row = ROW_OSD_MODE; + ui_set_selection(ui_cur_row); + lv_dropdown_set_selected(dropdown_osd_element, 0); + + update_ui(); + show_osd_element_pos_ui = true; +} + +void ui_osd_element_pos_update() { + if (show_osd_element_pos_ui) + lv_obj_clear_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN); +} + +int ui_osd_element_pos_handle_input(int key) { + switch (key) { + case DIAL_KEY_CLICK: + return ui_handle_click(); + + case DIAL_KEY_UP: + ui_handle_roll_up(); + return 0; + + case DIAL_KEY_DOWN: + ui_handle_roll_down(); + return 0; + + default: + return 0; + } +} diff --git a/src/ui/ui_osd_element_pos.h b/src/ui/ui_osd_element_pos.h new file mode 100644 index 00000000..a84f31aa --- /dev/null +++ b/src/ui/ui_osd_element_pos.h @@ -0,0 +1,14 @@ +#ifndef __OSDELEMENTPOS_H__ +#define __OSDELEMENTPOS_H__ + +#include +#include + +#include "core/settings.h" + +void ui_osd_element_pos_init(void); +void ui_osd_element_pos_update(); +void ui_osd_element_pos_on_enter(); +int ui_osd_element_pos_handle_input(int key); + +#endif \ No newline at end of file From d5830de36993e12fd62e1ad9f8b3685a1c554968 Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Thu, 20 Apr 2023 03:52:44 +0200 Subject: [PATCH 3/7] fix code formatting --- src/core/input_device.c | 2 +- src/core/main.c | 2 +- src/core/osd.c | 12 +++++------- src/ui/page_common.c | 6 ------ src/ui/page_common.h | 2 +- src/ui/page_osd.c | 4 ++-- 6 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/core/input_device.c b/src/core/input_device.c index 90ef78d6..47f5ae05 100644 --- a/src/core/input_device.c +++ b/src/core/input_device.c @@ -42,8 +42,8 @@ #include "ui/page_scannow.h" #include "ui/page_source.h" #include "ui/ui_image_setting.h" -#include "ui/ui_osd_element_pos.h" #include "ui/ui_main_menu.h" +#include "ui/ui_osd_element_pos.h" #include "ui/ui_porting.h" /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/main.c b/src/core/main.c index bcf1a808..f7172af4 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -37,8 +37,8 @@ #include "ui/page_scannow.h" #include "ui/page_source.h" #include "ui/ui_image_setting.h" -#include "ui/ui_osd_element_pos.h" #include "ui/ui_main_menu.h" +#include "ui/ui_osd_element_pos.h" #include "ui/ui_porting.h" #include "ui/ui_statusbar.h" #include "util/file.h" diff --git a/src/core/osd.c b/src/core/osd.c index c9c46373..6b0b109e 100644 --- a/src/core/osd.c +++ b/src/core/osd.c @@ -16,13 +16,13 @@ #include #include +#include "core/app_state.h" #include "core/battery.h" #include "core/common.hh" #include "core/dvr.h" #include "core/elrs.h" #include "core/msp_displayport.h" #include "core/settings.h" -#include "core/app_state.h" #include "driver/dm5680.h" #include "driver/fans.h" #include "driver/fbtools.h" @@ -319,8 +319,7 @@ bool fhd_change() { return false; } -void osd_show_all_elements(){ - +void osd_show_all_elements() { if (g_setting.osd.element[OSD_GOGGLE_TOPFAN_SPEED].show) lv_obj_clear_flag(g_osd_hdzero.topfan_speed[is_fhd], LV_OBJ_FLAG_HIDDEN); else @@ -375,7 +374,7 @@ void osd_show_all_elements(){ lv_obj_clear_flag(g_osd_hdzero.ant2[is_fhd], LV_OBJ_FLAG_HIDDEN); else lv_obj_add_flag(g_osd_hdzero.ant2[is_fhd], LV_OBJ_FLAG_HIDDEN); - + if (g_setting.osd.element[OSD_GOGGLE_ANT3].show) lv_obj_clear_flag(g_osd_hdzero.ant3[is_fhd], LV_OBJ_FLAG_HIDDEN); else @@ -400,7 +399,7 @@ void osd_show_all_elements(){ lv_obj_add_flag(g_osd_hdzero.osd_tempe[is_fhd][2], LV_OBJ_FLAG_HIDDEN); } -void osd_elements_set_dummy_sources(){ +void osd_elements_set_dummy_sources() { char buf[128]; osd_resource_path(buf, "%s", is_fhd, VtxTemp1_bmp); @@ -426,7 +425,6 @@ void osd_elements_set_dummy_sources(){ osd_resource_path(buf, "%s", is_fhd, fan5_bmp); lv_img_set_src(g_osd_hdzero.topfan_speed[is_fhd], buf); - } #define FC_OSD_CHECK_PERIOD 200 // 25ms @@ -444,7 +442,7 @@ void osd_hdzero_update(void) { return; // if the user is in the osd element position settings, show all elements - if (g_app_state == APP_STATE_OSD_ELEMENT_PREV){ + if (g_app_state == APP_STATE_OSD_ELEMENT_PREV) { // some elements might not be visible, set dummy sources to show them osd_elements_set_dummy_sources(); osd_show_all_elements(); diff --git a/src/ui/page_common.c b/src/ui/page_common.c index d46f5c0e..aab0820a 100644 --- a/src/ui/page_common.c +++ b/src/ui/page_common.c @@ -150,9 +150,6 @@ void create_slider_item_compact(slider_group_t *slider_group, lv_obj_t *parent, slider_group->slider = lv_slider_create(parent); - //lv_obj_set_style_pad_bottom(slider_group->slider, 50, 0); - - lv_obj_remove_style_all(slider_group->slider); lv_obj_add_style(slider_group->slider, &style_silder_main, LV_PART_MAIN); lv_obj_add_style(slider_group->slider, &style_silder_indicator, LV_PART_INDICATOR); @@ -161,7 +158,6 @@ void create_slider_item_compact(slider_group_t *slider_group, lv_obj_t *parent, lv_obj_set_style_pad_ver(slider_group->slider, 10, LV_PART_KNOB); lv_obj_set_style_pad_hor(slider_group->slider, 2, LV_PART_KNOB); lv_obj_add_style(slider_group->slider, &style_silder_pressed_color, LV_PART_KNOB | LV_STATE_PRESSED); - lv_obj_set_size(slider_group->slider, 0, 2); lv_slider_set_range(slider_group->slider, 0, range); @@ -403,8 +399,6 @@ void create_btn_group_item_compact(btn_group_t *btn_group, lv_obj_t *parent, int btn_group_set_sel(btn_group, 0); } - - void create_btn_group_item(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, const char *name2, const char *name3, int row) { if (count > 3) return; diff --git a/src/ui/page_common.h b/src/ui/page_common.h index cf3de373..7ab1c125 100644 --- a/src/ui/page_common.h +++ b/src/ui/page_common.h @@ -144,7 +144,7 @@ lv_obj_t *create_label_item(lv_obj_t *parent, const char *name, int col, int row lv_obj_t *create_info_item(lv_obj_t *parent, const char *name, int col, int row, int cols); -void create_btn_group_item_compact(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, +void create_btn_group_item_compact(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, const char *name2, const char *name3, int row, int height, int arrow_scale_percent, const lv_font_t *font); void create_btn_group_item(btn_group_t *btn_group, lv_obj_t *parent, int count, const char *name, const char *name0, const char *name1, diff --git a/src/ui/page_osd.c b/src/ui/page_osd.c index 84872950..6ee1f76f 100644 --- a/src/ui/page_osd.c +++ b/src/ui/page_osd.c @@ -11,8 +11,8 @@ #include "core/settings.h" #include "driver/hardware.h" #include "page_common.h" -#include "ui/ui_style.h" #include "ui/ui_osd_element_pos.h" +#include "ui/ui_style.h" #include "util/math.h" enum { @@ -78,7 +78,7 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { // when changing settings in the element position preview, // this is used to reflect the changes on this settings page, // in case the changed setting is visible here -void page_osd_update_ui_elements(){ +void page_osd_update_ui_elements() { btn_group_set_sel(&btn_group_osd_mode, g_setting.osd.embedded_mode); } From 81785ae95337bb3ddc0dac1e0202c5bcb3e45445 Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Fri, 21 Apr 2023 13:45:22 +0200 Subject: [PATCH 4/7] improve slider scroll acceleration change slider scroll speed to be based on time between inputs --- src/ui/ui_osd_element_pos.c | 98 ++++++++++++------------------------- 1 file changed, 31 insertions(+), 67 deletions(-) diff --git a/src/ui/ui_osd_element_pos.c b/src/ui/ui_osd_element_pos.c index 84d016de..24ad0bbb 100644 --- a/src/ui/ui_osd_element_pos.c +++ b/src/ui/ui_osd_element_pos.c @@ -23,6 +23,12 @@ #define OSD_ELEMENT_MIN_Y_POS 0 #define OSD_ELEMENT_MAX_Y_POS 720 +// used for slider scroll acceleration +#define SLIDER_SCROLL_MIN_INTERVAL 10 // min time interval between scrolls (ms) +#define SLIDER_SCROLL_MAX_INTERVAL 100 // max time interval between scrolls (ms) +#define SLIDER_SCROLL_MIN_STEP_SIZE 1 +#define SLIDER_SCROLL_MAX_STEP_SIZE 10 + enum { ROW_OSD_MODE = 0, ROW_OSD_ELEMENT, @@ -47,25 +53,6 @@ typedef enum { CONFIRMATION_TIMEOUT } ui_confirmation_t; -typedef enum { - SLIDER_SCROLL_DIR_NONE = 0, - SLIDER_SCROLL_DIR_X_INC, - SLIDER_SCROLL_DIR_Y_INC, - SLIDER_SCROLL_DIR_X_DEC, - SLIDER_SCROLL_DIR_Y_DEC -} slider_scroll_dir_t; - -typedef enum { - SLIDER_SCROLL_SPEED_SLOW = 1, - SLIDER_SCROLL_SPEED_MED = 5, - SLIDER_SCROLL_SPEED_FAST = 20 -} slider_scroll_speed_t; - -typedef enum { - SLIDER_SCROLL_SPEED_STEP_MED = 10 * SLIDER_SCROLL_SPEED_SLOW, - SLIDER_SCROLL_SPEED_STEP_FAST = SLIDER_SCROLL_SPEED_STEP_MED + 10 * SLIDER_SCROLL_SPEED_MED, -} slider_scroll_speed_step_t; - // a list of all osd elements // must contain the same elements, in the same order, as osd_element_list[] typedef enum { @@ -125,10 +112,7 @@ static int save_changes_confirm = CONFIRMATION_UNCONFIRMED; static int cancel_changes_confirm = CONFIRMATION_UNCONFIRMED; // used for slider scroll acceleration -static lv_timer_t *slider_scroll_accel_timer = NULL; -static int slider_cur_scroll_amount = 0; -static int slider_cur_scroll_dir = SLIDER_SCROLL_DIR_NONE; -static int slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_SLOW; +static uint32_t slider_scroll_last_tick = 0; // keeps track of the unchanged element settings in case user clicks cancel static setting_osd_t ui_osd_el_pos_unchanged_settings; @@ -180,8 +164,7 @@ static void cancel_osd_elements_reset_label_text(); static void reset_all_osd_elements_timer_cb(struct _lv_timer_t *timer); // handle slider acceleration when positioning elements -static void slider_scroll_speed_timer_cb(lv_timer_t *timer); -static void slider_scroll_accel_apply(slider_scroll_dir_t direction); +static int slider_scroll_speed_get_step(); // user input handling static void osd_element_pos_x_dec(); @@ -291,94 +274,75 @@ static void reset_all_osd_elements_timer_cb(struct _lv_timer_t *timer) { reset_all_elements_confirm = CONFIRMATION_UNCONFIRMED; } -static void slider_scroll_speed_timer_cb(lv_timer_t *timer) { - lv_timer_pause(slider_scroll_accel_timer); - slider_cur_scroll_dir = SLIDER_SCROLL_DIR_NONE; - slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_SLOW; - slider_cur_scroll_amount = 0; -} - -static void slider_scroll_accel_apply(slider_scroll_dir_t direction) { - if (slider_cur_scroll_dir != direction) { - slider_cur_scroll_dir = direction; - slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_SLOW; - slider_cur_scroll_amount = 0; +static int slider_scroll_speed_get_step() { + uint32_t interval = lv_tick_elaps(slider_scroll_last_tick); + slider_scroll_last_tick = lv_tick_get(); - lv_timer_reset(slider_scroll_accel_timer); - lv_timer_resume(slider_scroll_accel_timer); - } else { - lv_timer_reset(slider_scroll_accel_timer); - if (slider_cur_scroll_amount >= SLIDER_SCROLL_SPEED_STEP_FAST) { - slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_FAST; - } else if (slider_cur_scroll_amount >= SLIDER_SCROLL_SPEED_STEP_MED) { - slider_cur_scroll_speed = SLIDER_SCROLL_SPEED_MED; - } + if (interval <= SLIDER_SCROLL_MIN_INTERVAL) { + return SLIDER_SCROLL_MAX_STEP_SIZE; + } else if (interval >= SLIDER_SCROLL_MAX_INTERVAL) { + return SLIDER_SCROLL_MIN_STEP_SIZE; } - slider_cur_scroll_amount += slider_cur_scroll_speed; + float factor = (float)(interval - SLIDER_SCROLL_MIN_INTERVAL) / (SLIDER_SCROLL_MAX_INTERVAL - SLIDER_SCROLL_MIN_INTERVAL); + int step = (int)((1.0 - factor) * (SLIDER_SCROLL_MAX_STEP_SIZE - SLIDER_SCROLL_MIN_STEP_SIZE)); + + return step > 0 ? step : 1; } static void osd_element_pos_x_dec() { setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); - slider_scroll_accel_apply(SLIDER_SCROLL_DIR_X_DEC); - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, &element->position.mode_4_3.x, - (-slider_cur_scroll_speed)); + -(slider_scroll_speed_get_step())); } else { safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, &element->position.mode_16_9.x, - (-slider_cur_scroll_speed)); + -(slider_scroll_speed_get_step())); } } static void osd_element_pos_y_dec() { setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); - slider_scroll_accel_apply(SLIDER_SCROLL_DIR_Y_DEC); - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, &element->position.mode_4_3.y, - (-slider_cur_scroll_speed)); + -(slider_scroll_speed_get_step())); } else { safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, &element->position.mode_16_9.y, - (-slider_cur_scroll_speed)); + -(slider_scroll_speed_get_step())); } } static void osd_element_pos_x_inc() { setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); - slider_scroll_accel_apply(SLIDER_SCROLL_DIR_X_INC); - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, &element->position.mode_4_3.x, - slider_cur_scroll_speed); + (slider_scroll_speed_get_step())); } else { safe_update_value(OSD_ELEMENT_MIN_X_POS, OSD_ELEMENT_MAX_X_POS, &element->position.mode_16_9.x, - slider_cur_scroll_speed); + (slider_scroll_speed_get_step())); } } static void osd_element_pos_y_inc() { setting_osd_goggle_element_t *element = get_selected_osd_element_setting_entry(); - slider_scroll_accel_apply(SLIDER_SCROLL_DIR_Y_INC); - if (g_setting.osd.embedded_mode == EMBEDDED_4x3) { safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, &element->position.mode_4_3.y, - slider_cur_scroll_speed); + (slider_scroll_speed_get_step())); } else { safe_update_value(OSD_ELEMENT_MIN_Y_POS, OSD_ELEMENT_MAX_Y_POS, &element->position.mode_16_9.y, - slider_cur_scroll_speed); + (slider_scroll_speed_get_step())); } } @@ -612,15 +576,15 @@ void ui_osd_element_pos_init(void) { update_ui(); // create timers - slider_scroll_accel_timer = lv_timer_create(slider_scroll_speed_timer_cb, 1000, NULL); - lv_timer_pause(slider_scroll_accel_timer); reset_all_osd_elements_timer = lv_timer_create(reset_all_osd_elements_timer_cb, 3000, NULL); lv_timer_pause(reset_all_osd_elements_timer); + // init slider scroll acceleration vars + slider_scroll_last_tick = lv_tick_get(); + + // set initial ui state ui_cur_row = ROW_OSD_MODE; ui_state = UI_STATE_SCROLL; - - // set the initial selection ui_set_selection(ui_cur_row); } From 3eff5550a34371ea385942e658c0a610db539682 Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Wed, 26 Apr 2023 23:35:18 +0200 Subject: [PATCH 5/7] fix long press handling in osd element pos preview rm superfluous comments --- src/core/input_device.c | 5 ++++- src/ui/ui_osd_element_pos.c | 30 +++++++++++------------------- src/ui/ui_osd_element_pos.h | 1 + 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/core/input_device.c b/src/core/input_device.c index 47f5ae05..4b5a481c 100644 --- a/src/core/input_device.c +++ b/src/core/input_device.c @@ -178,7 +178,10 @@ static void btn_press(void) // long press left key app_state_push(APP_STATE_VIDEO); } else if ((g_app_state == APP_STATE_VIDEO) || (g_app_state == APP_STATE_IMS)) // video -> Main menu app_switch_to_menu(); - else if (g_app_state == APP_STATE_PLAYBACK) + else if (g_app_state == APP_STATE_OSD_ELEMENT_PREV) { + ui_osd_element_pos_cancel_and_hide(); + app_switch_to_menu(); + } else if (g_app_state == APP_STATE_PLAYBACK) pb_key(DIAL_KEY_PRESS); else { // Sub-menu -> Main menu submenu_exit(); diff --git a/src/ui/ui_osd_element_pos.c b/src/ui/ui_osd_element_pos.c index 24ad0bbb..4fa20764 100644 --- a/src/ui/ui_osd_element_pos.c +++ b/src/ui/ui_osd_element_pos.c @@ -80,10 +80,6 @@ typedef struct { char *name_settings; } osd_element_t; -// ########################################################################### -// ########################## local variables start ########################## -// ########################################################################### - // sets if the ui is shown during the next ui update (ui_osd_element_pos_update()) static bool show_osd_element_pos_ui = false; @@ -139,14 +135,6 @@ static osd_element_t osd_element_list[] = { // string used for the dropdown menu static char osd_elements_str[512]; -// ########################################################################### -// ########################### local variables end ########################### -// ########################################################################### - -// ########################################################################## -// #################### local functions prototypes start #################### -// ########################################################################## - // utility functions static setting_osd_goggle_element_t *get_osd_element_setting_entry(int element_idx); static void fill_osd_elements_str(); @@ -175,10 +163,6 @@ static void ui_handle_roll_up(); static void ui_handle_roll_down(); static int ui_handle_click(); -// ########################################################################## -// ##################### local functions prototypes end ##################### -// ########################################################################## - static setting_osd_goggle_element_t *get_osd_element_setting_entry(int element_idx) { return &g_setting.osd.element[element_idx]; } @@ -486,10 +470,8 @@ static int ui_handle_click() { case ROW_CANCEL: if (cancel_changes_confirm) { - g_setting.osd = ui_osd_el_pos_unchanged_settings; - osd_update_mode(); - show_osd_element_pos_ui = false; cancel_osd_elements_reset_label_text(); + ui_osd_element_pos_cancel_and_hide(); return 1; } @@ -596,6 +578,10 @@ void ui_osd_element_pos_on_enter() { lv_dropdown_set_selected(dropdown_osd_element, 0); update_ui(); + save_osd_elements_reset_label_text(); + cancel_osd_elements_reset_label_text(); + reset_all_osd_elements_reset_label_text(); + show_osd_element_pos_ui = true; } @@ -606,6 +592,12 @@ void ui_osd_element_pos_update() { lv_obj_add_flag(ui_root_container, LV_OBJ_FLAG_HIDDEN); } +void ui_osd_element_pos_cancel_and_hide() { + show_osd_element_pos_ui = false; + g_setting.osd = ui_osd_el_pos_unchanged_settings; + osd_update_mode(); +} + int ui_osd_element_pos_handle_input(int key) { switch (key) { case DIAL_KEY_CLICK: diff --git a/src/ui/ui_osd_element_pos.h b/src/ui/ui_osd_element_pos.h index a84f31aa..3a8c22c7 100644 --- a/src/ui/ui_osd_element_pos.h +++ b/src/ui/ui_osd_element_pos.h @@ -9,6 +9,7 @@ void ui_osd_element_pos_init(void); void ui_osd_element_pos_update(); void ui_osd_element_pos_on_enter(); +void ui_osd_element_pos_cancel_and_hide(); int ui_osd_element_pos_handle_input(int key); #endif \ No newline at end of file From 7b1b167cf451fd965528da32bf3873d5de7b89a4 Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Wed, 26 Apr 2023 23:48:37 +0200 Subject: [PATCH 6/7] improve user hint for osd element positioning --- src/ui/page_osd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/page_osd.c b/src/ui/page_osd.c index 6ee1f76f..44cf7f1b 100644 --- a/src/ui/page_osd.c +++ b/src/ui/page_osd.c @@ -60,7 +60,7 @@ static lv_obj_t *page_osd_create(lv_obj_t *parent, panel_arr_t *arr) { create_label_item(cont, "< Back", 1, ROW_BACK, 1); lv_obj_t *label_user_hint = lv_label_create(cont); - lv_label_set_text(label_user_hint, "OSD Element positioning is based on a 1280x720 canvas.\nPositions can be set for 4x3 and 16x9 modes separately,\nthe Show Element toggle is shared between both modes."); + lv_label_set_text(label_user_hint, "Note: The positioning preview will display all OSD elements. Some elements might\nnot show during normal operation, depending on input source and conditions.\nOSD Element positioning is based on a 1280x720 canvas.\nPositions can be set for 4x3 and 16x9 modes separately,\nthe Show Element toggle is shared between both modes."); lv_obj_set_style_text_font(label_user_hint, &lv_font_montserrat_16, 0); lv_obj_set_style_text_align(label_user_hint, LV_TEXT_ALIGN_LEFT, 0); lv_obj_set_style_text_color(label_user_hint, lv_color_make(255, 255, 255), 0); From e99d39667e95607b9c576a715a3807588ab47b86 Mon Sep 17 00:00:00 2001 From: Nikolas Saf Date: Fri, 12 May 2023 21:50:05 +0200 Subject: [PATCH 7/7] remove obsolete comments --- src/ui/ui_osd_element_pos.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/ui/ui_osd_element_pos.c b/src/ui/ui_osd_element_pos.c index 4fa20764..7bfabe6d 100644 --- a/src/ui/ui_osd_element_pos.c +++ b/src/ui/ui_osd_element_pos.c @@ -193,25 +193,8 @@ static int persist_all_osd_element_settings(const setting_osd_t *settings_to_per res = ini_putl("osd", "embedded_mode", settings_to_persist->embedded_mode, SETTING_INI); - for (int i = 0; i < OSD_ELEMENTS_TOTAL; i++) { + for (int i = 0; i < OSD_ELEMENTS_TOTAL; i++) res &= settings_put_osd_element(&settings_to_persist->element[i], osd_element_list[i].name_settings); - } - - // res &= settings_put_osd_element(&settings_to_persist->elements.topfan_speed, osd_element_list[OSD_ELEMENT_TOP_FAN_SPEED].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.latency_lock, osd_element_list[OSD_ELEMENT_LATENCY_LOCK].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.vtx_temp, osd_element_list[OSD_ELEMENT_VTX_TEMP].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.vrx_temp, osd_element_list[OSD_ELEMENT_VRX_TEMP].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.battery_low, osd_element_list[OSD_ELEMENT_BATTERY_LOW].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.channel, osd_element_list[OSD_ELEMENT_CHANNEL].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.sd_rec, osd_element_list[OSD_ELEMENT_SD_REC].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.vlq, osd_element_list[OSD_ELEMENT_VLQ].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.ant0, osd_element_list[OSD_ELEMENT_ANT0].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.ant1, osd_element_list[OSD_ELEMENT_ANT1].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.ant2, osd_element_list[OSD_ELEMENT_ANT2].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.ant3, osd_element_list[OSD_ELEMENT_ANT3].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.osd_tempe[0], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_TOP].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.osd_tempe[1], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_LEFT].name_settings); - // res &= settings_put_osd_element(&settings_to_persist->elements.osd_tempe[2], osd_element_list[OSD_ELEMENT_GOGGLE_TEMP_RIGHT].name_settings); return res; } @@ -505,7 +488,7 @@ static int ui_handle_click() { for (int i = 0; i < OSD_GOGGLE_NUM; i++) { g_setting.osd.element[i] = g_setting_defaults.osd.element[i]; } - + update_ui(); osd_update_mode(); lv_label_set_text(label_reset_all_osd_elements, "#00FF00 Elements reset.#");