From 39cbfbe66f54cad5822515a584c0d5af88bcdd53 Mon Sep 17 00:00:00 2001 From: vk7js <58905135+vk7js@users.noreply.github.com> Date: Thu, 12 May 2022 21:41:43 +1000 Subject: [PATCH] Added a function which will look up a string in our string table and, if found, returns its offset and use it in order to locate the equivalent voice prompt. Added logic to see if the current menu index has changed. Added a function to speak the current menu item and its value if the menu index changes. --- openrtx/include/core/voicePromptUtils.h | 8 ++++++ openrtx/include/ui/UIStrings.h | 2 ++ openrtx/src/core/voicePromptUtils.c | 17 +++++++++++++ openrtx/src/ui/UIStrings.c | 29 ++++++++++++++++++++- openrtx/src/ui/ui_menu.c | 34 ++++++++++++++++++++++++- 5 files changed, 88 insertions(+), 2 deletions(-) diff --git a/openrtx/include/core/voicePromptUtils.h b/openrtx/include/core/voicePromptUtils.h index 249b3c35..b5caf2f4 100644 --- a/openrtx/include/core/voicePromptUtils.h +++ b/openrtx/include/core/voicePromptUtils.h @@ -35,4 +35,12 @@ void AnnounceInputChar(char ch); void announceInputReceiveOrTransmit(bool tx, VoicePromptQueueFlags_T flags); void ReplayLastPrompt(); void announceError(VoicePromptQueueFlags_T flags); + +/* +This function first tries to see if we have a prompt for the text +passed in and if so, queues it, but if not, just spells the text +character by character. +*/ +void announceText( char* text, VoicePromptQueueFlags_T flags); + #endif //VOICE_PROMPT_UTILS_H_INCLUDED \ No newline at end of file diff --git a/openrtx/include/ui/UIStrings.h b/openrtx/include/ui/UIStrings.h index 4af9af45..e9b78501 100644 --- a/openrtx/include/ui/UIStrings.h +++ b/openrtx/include/ui/UIStrings.h @@ -92,4 +92,6 @@ typedef struct extern const stringsTable_t languages[]; extern const stringsTable_t* currentLanguage; +int GetEnglishStringTableOffset( char* text); + #endif \ No newline at end of file diff --git a/openrtx/src/core/voicePromptUtils.c b/openrtx/src/core/voicePromptUtils.c index df94e036..27994688 100644 --- a/openrtx/src/core/voicePromptUtils.c +++ b/openrtx/src/core/voicePromptUtils.c @@ -193,3 +193,20 @@ void announceError(VoicePromptQueueFlags_T flags) vpPlayIfNeeded(flags); } + +void announceText( char* text, VoicePromptQueueFlags_T flags) +{ + if (!text || !*text) + return; + + vpInitIfNeeded(flags); + // see if we have a prompt for this string. + int offset = GetEnglishStringTableOffset(text); + + if (offset != -1) + vpQueueStringTableEntry((const char* const *)(¤tLanguage->languageName + offset)); + else // just spel it out + vpQueueString(text, (flags&~(vpqInit|vpqPlayImmediately))); + + vpPlayIfNeeded(flags); +} diff --git a/openrtx/src/ui/UIStrings.c b/openrtx/src/ui/UIStrings.c index f0037743..e91a5fb9 100644 --- a/openrtx/src/ui/UIStrings.c +++ b/openrtx/src/ui/UIStrings.c @@ -22,9 +22,36 @@ This string table's order must not be altered as voice prompts will be indexed i */ #include "ui/UIStrings.h" #include "ui/EnglishStrings.h" - + #include + // add more languages here. const stringsTable_t languages[NUM_LANGUAGES]={ englishStrings }; // default to English. const stringsTable_t* currentLanguage=&languages[0]; + +/* +Given an english string such as a menu item or value, +search the english string table and return the offset if found. +This can then be used to look up the localized string in the currentLanguages +struct, or to announce an indexed voice prompt. +*/ +int GetEnglishStringTableOffset( char* text) +{ + if (!text || !*text) + return -1; // error. + + uint8_t stringCount =sizeof(stringsTable_t)/sizeof(char*); + + for (uint8_t i = 0; i < stringCount; ++i) + { + const char* strPtr = ((const char **)&englishStrings)[i]; + + if (strcmp(text, strPtr) == 0) + { + return (i * sizeof(char *)); + } + } + + return -1; +} diff --git a/openrtx/src/ui/ui_menu.c b/openrtx/src/ui/ui_menu.c index f9443c45..c9cb84d4 100644 --- a/openrtx/src/ui/ui_menu.c +++ b/openrtx/src/ui/ui_menu.c @@ -29,10 +29,11 @@ #include #include #include +#include /* UI main screen helper functions, their implementation is in "ui_main.c" */ extern void _ui_drawMainBottom(); - +static int priorMenuIndex = -1; const char *display_timer_values[] = { "Off", @@ -53,6 +54,31 @@ const char *display_timer_values[] = "1 hour" }; +bool DidSelectedMenuItemChange(uint8_t index) +{ + if (priorMenuIndex == -1) + return true; + bool result = index != priorMenuIndex; + priorMenuIndex = index; + return result; +} + +static void announceMenuItemIfNeeded(uint8_t index, char* name, char* value) +{ + if (!name || !*name) + return; + + if (!DidSelectedMenuItemChange(index)) + return; + + announceText(name, vpqInit); + + if (value && *value) + announceText(name, vpqDefault); + + vpPlay(); +} + void _ui_drawMenuList(uint8_t selected, int (*getCurrentEntry)(char *buf, uint8_t max_len, uint8_t index)) { point_t pos = layout.line1_pos; @@ -77,6 +103,7 @@ void _ui_drawMenuList(uint8_t selected, int (*getCurrentEntry)(char *buf, uint8_ // Draw rectangle under selected item, compensating for text height point_t rect_pos = {0, pos.y - layout.menu_h + 3}; gfx_drawRect(rect_pos, SCREEN_WIDTH, layout.menu_h, color_white, true); + announceMenuItemIfNeeded(item+scroll, entry_buf, NULL); } gfx_print(pos, layout.menu_font, TEXT_ALIGN_LEFT, text_color, entry_buf); pos.y += layout.menu_h; @@ -120,6 +147,11 @@ void _ui_drawMenuListValue(ui_state_t* ui_state, uint8_t selected, } point_t rect_pos = {0, pos.y - layout.menu_h + 3}; gfx_drawRect(rect_pos, SCREEN_WIDTH, layout.menu_h, color_white, full_rect); + if (!ui_state->edit_mode) + {// If in edit mode, only want to speak the char being entered,, + //not repeat the entire display. + announceMenuItemIfNeeded(item+scroll, entry_buf, value_buf); + } } gfx_print(pos, layout.menu_font, TEXT_ALIGN_LEFT, text_color, entry_buf); gfx_print(pos, layout.menu_font, TEXT_ALIGN_RIGHT, text_color, value_buf);