From 17d5be118edce5d7d31a985f6bb963ca548d9358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Izzo?= Date: Fri, 29 Sep 2023 11:41:27 +0200 Subject: [PATCH] Enable frequency offset input from radio menu Adapted callsign input to create a frequency input menu, that was used to enable the input of a frequency offset from the Settings->Radio menu. --- openrtx/include/ui/EnglishStrings.h | 9 ++- openrtx/include/ui/ui_default.h | 1 + openrtx/include/ui/ui_strings.h | 1 + openrtx/src/ui/default/ui.c | 113 ++++++++++++++++++++++++---- openrtx/src/ui/default/ui_menu.c | 34 ++++++++- 5 files changed, 136 insertions(+), 22 deletions(-) diff --git a/openrtx/include/ui/EnglishStrings.h b/openrtx/include/ui/EnglishStrings.h index bf76d8b4..245876f2 100644 --- a/openrtx/include/ui/EnglishStrings.h +++ b/openrtx/include/ui/EnglishStrings.h @@ -89,9 +89,10 @@ const stringsTable_t englishStrings = .macroMenu = "Macro Menu", .forEmergencyUse = "For emergency use", .pressAnyButton = "press any button.", - .accessibility = "Accessibility", - .usedHeap = "Used heap", - .broadcast = "ALL", - .radioSettings = "Radio Settings" + .accessibility = "Accessibility", + .usedHeap = "Used heap", + .broadcast = "ALL", + .radioSettings = "Radio Settings", + .frequencyOffset = "Frequency Offset" }; #endif // ENGLISHSTRINGS_H diff --git a/openrtx/include/ui/ui_default.h b/openrtx/include/ui/ui_default.h index 8030adf4..8d38a282 100644 --- a/openrtx/include/ui/ui_default.h +++ b/openrtx/include/ui/ui_default.h @@ -223,6 +223,7 @@ typedef struct ui_state_t char new_time_buf[9]; #endif char new_callsign[10]; + freq_t new_offset; // Which state to return to when we exit menu uint8_t last_main_state; #if defined(UI_NO_KEYBOARD) diff --git a/openrtx/include/ui/ui_strings.h b/openrtx/include/ui/ui_strings.h index a9d06ce6..d173e140 100644 --- a/openrtx/include/ui/ui_strings.h +++ b/openrtx/include/ui/ui_strings.h @@ -97,6 +97,7 @@ typedef struct const char* usedHeap; const char* broadcast; const char* radioSettings; + const char* frequencyOffset; } stringsTable_t; diff --git a/openrtx/src/ui/default/ui.c b/openrtx/src/ui/default/ui.c index a5b3207c..86998d61 100644 --- a/openrtx/src/ui/default/ui.c +++ b/openrtx/src/ui/default/ui.c @@ -1158,7 +1158,41 @@ static void _ui_textInputDel(char *buf) ui_state.input_set = 0; } +static void _ui_numberInputKeypad(uint32_t *num, kbd_msg_t msg) +{ + // Maximum frequency len is uint32_t max value number of decimal digits + if(ui_state.input_position >= 10) + return; + long long now = getTick(); + + // Get currently pressed number key + uint8_t num_key = input_getPressedNumber(msg); + *num *= 10; + *num += num_key; + + // Announce the character + vp_announceInputChar('0' + num_key); + + // Update reference values + ui_state.input_number = num_key; + ui_state.last_keypress = now; +} + +static void _ui_numberInputDel(uint32_t *num) +{ + // announce the digit about to be backspaced. + uint8_t digit = ((*num % (10 * ui_state.input_position)) / (10 * (ui_state.input_position - 1))); + vp_announceInputChar('0' + digit); + + // Move back input cursor + if(ui_state.input_position > 0) + ui_state.input_position--; + else + ui_state.last_keypress = 0; + + ui_state.input_set = 0; +} void ui_init() { @@ -2038,37 +2072,86 @@ void ui_updateFSM(bool *sync_rtx) #endif // Radio Settings case SETTINGS_RADIO: - if(msg.keys & KEY_LEFT || msg.keys & KEY_RIGHT || - (ui_state.edit_mode && - (msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT || - msg.keys & KEY_UP || msg.keys & KNOB_RIGHT))) + // If the entry is selected with enter we are in edit_mode + if (ui_state.edit_mode) { switch(ui_state.menu_selected) { case R_OFFSET: + // Handle offset frequency input + if(msg.keys & KEY_ENTER) + { + // Apply new offset + state.channel.tx_frequency = state.channel.rx_frequency + ui_state.new_offset; + vp_queueStringTableEntry(¤tLanguage->frequencyOffset); + vp_queueFrequency(ui_state.new_offset); + } + else if(msg.keys & KEY_ESC) + { + // Announce old frequency offset + vp_queueStringTableEntry(¤tLanguage->frequencyOffset); + vp_queueFrequency((int32_t)state.channel.tx_frequency - (int32_t)state.channel.rx_frequency); + } + else if(msg.keys & KEY_UP || msg.keys & KEY_DOWN || + msg.keys & KEY_LEFT || msg.keys & KEY_RIGHT) + { + _ui_numberInputDel(&ui_state.new_offset); + } + else if(input_isNumberPressed(msg)) + { + _ui_numberInputKeypad(&ui_state.new_offset, msg); + ui_state.input_position += 1; + } + else if (msg.long_press && (msg.keys & KEY_F1) && (state.settings.vpLevel > vpBeep)) + { + vp_queueFrequency(ui_state.new_offset); + f1Handled=true; + } break; case R_DIRECTION: - // Invert frequency offset direction - if (state.channel.tx_frequency >= state.channel.rx_frequency) - state.channel.tx_frequency -= 2 * ((int32_t)state.channel.tx_frequency - (int32_t)state.channel.rx_frequency); - else // Switch to positive offset - state.channel.tx_frequency -= 2 * ((int32_t)state.channel.tx_frequency - (int32_t)state.channel.rx_frequency); + if(msg.keys & KEY_UP || msg.keys & KEY_DOWN || + msg.keys & KEY_LEFT || msg.keys & KEY_RIGHT) + { + // Invert frequency offset direction + if (state.channel.tx_frequency >= state.channel.rx_frequency) + state.channel.tx_frequency -= 2 * ((int32_t)state.channel.tx_frequency - (int32_t)state.channel.rx_frequency); + else // Switch to positive offset + state.channel.tx_frequency -= 2 * ((int32_t)state.channel.tx_frequency - (int32_t)state.channel.rx_frequency); + } break; case R_STEP: - // Cycle over the available frequency steps - state.step_index++; - state.step_index %= n_freq_steps; + if (msg.keys & KEY_UP || msg.keys & KEY_RIGHT) + { + // Cycle over the available frequency steps + state.step_index++; + state.step_index %= n_freq_steps; + } + else if(msg.keys & KEY_DOWN || msg.keys & KEY_LEFT) + { + state.step_index += n_freq_steps; + state.step_index--; + state.step_index %= n_freq_steps; + } break; default: - state.ui_screen = SETTINGS_GPS; + state.ui_screen = SETTINGS_RADIO; } + // If ENTER or ESC are pressed, exit edit mode + if(msg.keys & KEY_ENTER || msg.keys & KEY_ESC) + ui_state.edit_mode = false; } else if(msg.keys & KEY_UP || msg.keys & KNOB_LEFT) _ui_menuUp(settings_radio_num); else if(msg.keys & KEY_DOWN || msg.keys & KNOB_RIGHT) _ui_menuDown(settings_radio_num); - else if(msg.keys & KEY_ENTER) - ui_state.edit_mode = !ui_state.edit_mode; + else if(msg.keys & KEY_ENTER) { + ui_state.edit_mode = true; + // If we are entering R_OFFSET clear temp offset + if (ui_state.menu_selected == R_OFFSET) + ui_state.new_offset = 0; + // Reset input position + ui_state.input_position = 0; + } else if(msg.keys & KEY_ESC) _ui_menuBack(MENU_SETTINGS); break; diff --git a/openrtx/src/ui/default/ui_menu.c b/openrtx/src/ui/default/ui_menu.c index da228dd7..10340b57 100644 --- a/openrtx/src/ui/default/ui_menu.c +++ b/openrtx/src/ui/default/ui_menu.c @@ -938,12 +938,40 @@ void _ui_drawSettingsReset2Defaults(ui_state_t* ui_state) void _ui_drawSettingsRadio(ui_state_t* ui_state) { gfx_clearScreen(); + // Print "Radio Settings" on top bar gfx_print(layout.top_pos, layout.top_font, TEXT_ALIGN_CENTER, color_white, currentLanguage->radioSettings); - // Print radio settings entries - _ui_drawMenuListValue(ui_state, ui_state->menu_selected, _ui_getRadioEntryName, - _ui_getRadioValueName); + + // Handle the special case where a frequency is being input + if ((ui_state->menu_selected == R_OFFSET) && (ui_state->edit_mode)) + { + char buf[17] = { 0 }; + uint16_t rect_width = SCREEN_WIDTH - (layout.horizontal_pad * 2); + uint16_t rect_height = (SCREEN_HEIGHT - (layout.top_h + layout.bottom_h))/2; + point_t rect_origin = {(SCREEN_WIDTH - rect_width) / 2, + (SCREEN_HEIGHT - rect_height) / 2}; + + gfx_drawRect(rect_origin, rect_width, rect_height, color_white, false); + + // Print frequency with the most sensible unit + if (ui_state->new_offset < 1000) + snprintf(buf, 17, "%dHz", ui_state->new_offset); + else if (ui_state->new_offset < 1000000) + snprintf(buf, 17, "%gkHz", (float) ui_state->new_offset / 1000.0f); + else + snprintf(buf, 17, "%gMHz", (float) ui_state->new_offset / 1000000.0f); + + gfx_printLine(1, 1, layout.top_h, SCREEN_HEIGHT - layout.bottom_h, + layout.horizontal_pad, layout.input_font, + TEXT_ALIGN_CENTER, color_white, buf); + } + else + { + // Print radio settings entries + _ui_drawMenuListValue(ui_state, ui_state->menu_selected, _ui_getRadioEntryName, + _ui_getRadioValueName); + } } void _ui_drawMacroTop()