Diff
checker
文本
文本
圖像
文檔
Excel
文件夾
Legal
Enterprise
桌面版
定價
登入
下載 Diffchecker 桌面版
比較文本
尋找兩個文字檔案之間的差異
工具
歷史
即時編輯器
摺疊未變更行
關閉換行
檢視
拆分
統一
比對精度
智能
單詞
字符
語法突出顯示
選擇語法
忽略
文字轉換
前往第一個差異
編輯輸入
Diffchecker Desktop
執行Diffchecker最安全的方式。取得Diffchecker桌面應用程式:您的差異永遠不會離開您的電腦!
取得桌面版
opengd77
建立於
5 個月前
差異永不過期
清除
匯出
分享
解釋
57 刪除
行
總計
刪除
字符
總計
刪除
要繼續使用此功能,請升級到
Diff
checker
Pro
查看價格
732 行
全部複製
78 新增
行
總計
新增
字符
總計
新增
要繼續使用此功能,請升級到
Diff
checker
Pro
查看價格
754 行
全部複製
/*
/*
複製
已複製
複製
已複製
* Copyright (C) 2019-202
4
Roger Clark, VK3KYY / G4KYF
* Copyright (C) 2019-202
5
Roger Clark, VK3KYY / G4KYF
* Daniel Caujolle-Bert, F1RMB
* Daniel Caujolle-Bert, F1RMB
*
*
*
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions
* are met:
* are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the distribution.
* in the documentation and/or other materials provided with the distribution.
*
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* from this software without specific prior written permission.
*
*
* 4. Use of this source code or binary releases for commercial purposes is strictly forbidden. This includes, without limitation,
* 4. Use of this source code or binary releases for commercial purposes is strictly forbidden. This includes, without limitation,
* incorporation in a commercial product or incorporation into a product or project which allows commercial use.
* incorporation in a commercial product or incorporation into a product or project which allows commercial use.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
*/
#if defined(PLATFORM_MD9600)
#if defined(PLATFORM_MD9600)
#include "hardware/ST7567.h"
#include "hardware/ST7567.h"
#elif (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#elif (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#include "hardware/HX8353E.h"
#include "hardware/HX8353E.h"
#else
#else
#include "hardware/UC1701.h"
#include "hardware/UC1701.h"
#endif
#endif
#include "user_interface/uiGlobals.h"
#include "user_interface/uiGlobals.h"
#include "user_interface/menuSystem.h"
#include "user_interface/menuSystem.h"
#include "user_interface/uiLocalisation.h"
#include "user_interface/uiLocalisation.h"
#include "user_interface/uiUtilities.h"
#include "user_interface/uiUtilities.h"
static void updateScreen(bool isFirstRun);
static void updateScreen(bool isFirstRun);
static void handleEvent(uiEvent_t *ev);
static void handleEvent(uiEvent_t *ev);
static void updateBacklightMode(uint8_t mode);
static void updateBacklightMode(uint8_t mode);
static void setDisplayInvert(bool invert);
static void setDisplayInvert(bool invert);
static void checkMinBacklightValue(void);
static void checkMinBacklightValue(void);
static void buildTimeZoneBufferText(char * buffer);
static void buildTimeZoneBufferText(char * buffer);
static void applySettings(void);
static void applySettings(void);
static void exitCallback(void *data);
static void exitCallback(void *data);
static menuStatus_t menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS;
static menuStatus_t menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS;
static const int BACKLIGHT_MAX_TIMEOUT = 30;
static const int BACKLIGHT_MAX_TIMEOUT = 30;
#if defined(PLATFORM_RD5R)
#if defined(PLATFORM_RD5R)
static const int CONTRAST_MAX_VALUE = 10;// Maximum value which still seems to be readable
static const int CONTRAST_MAX_VALUE = 10;// Maximum value which still seems to be readable
static const int CONTRAST_MIN_VALUE = 0;// Minimum value which still seems to be readable
static const int CONTRAST_MIN_VALUE = 0;// Minimum value which still seems to be readable
#elif ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#elif ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
static const int CONTRAST_MAX_VALUE = 30;// Maximum value which still seems to be readable
static const int CONTRAST_MAX_VALUE = 30;// Maximum value which still seems to be readable
static const int CONTRAST_MIN_VALUE = 5;// Minimum value which still seems to be readable
static const int CONTRAST_MIN_VALUE = 5;// Minimum value which still seems to be readable
#endif
#endif
static const int BACKLIGHT_TIMEOUT_STEP = 5;
static const int BACKLIGHT_TIMEOUT_STEP = 5;
static const int BACKLIGHT_MAX_PERCENTAGE = 100;
static const int BACKLIGHT_MAX_PERCENTAGE = 100;
static const int BACKLIGHT_PERCENTAGE_STEP = 10;
static const int BACKLIGHT_PERCENTAGE_STEP = 10;
static const int BACKLIGHT_PERCENTAGE_STEP_SMALL = 1;
static const int BACKLIGHT_PERCENTAGE_STEP_SMALL = 1;
static const char *contactOrders[] = { "Ct/DB/TA", "DB/Ct/TA", "TA/Ct/DB", "TA/DB/Ct" };
static const char *contactOrders[] = { "Ct/DB/TA", "DB/Ct/TA", "TA/Ct/DB", "TA/DB/Ct" };
enum
enum
{
{
複製
已複製
複製
已複製
DISPLAY_MENU_BRIGHTNESS
= 0
,
#if defined(HAS_COLOURS)
DISPLAY_TYPE_STYLE,
#endif
DISPLAY_MENU_BRIGHTNESS
,
#if ! defined(PLATFORM_GD77S)
#if ! defined(PLATFORM_GD77S)
DISPLAY_MENU_BRIGHTNESS_NIGHT,
DISPLAY_MENU_BRIGHTNESS_NIGHT,
#endif
#endif
DISPLAY_MENU_BRIGHTNESS_OFF,
DISPLAY_MENU_BRIGHTNESS_OFF,
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
DISPLAY_MENU_CONTRAST,
DISPLAY_MENU_CONTRAST,
#endif
#endif
DISPLAY_MENU_BACKLIGHT_MODE,
DISPLAY_MENU_BACKLIGHT_MODE,
DISPLAY_MENU_TIMEOUT,
DISPLAY_MENU_TIMEOUT,
DISPLAY_MENU_SCREEN_INVERT,
DISPLAY_MENU_SCREEN_INVERT,
#if ! defined(PLATFORM_GD77S)
#if ! defined(PLATFORM_GD77S)
DISPLAY_AUTO_NIGHT,
DISPLAY_AUTO_NIGHT,
#endif
#endif
DISPLAY_MENU_CONTACT_DISPLAY_ORDER,
DISPLAY_MENU_CONTACT_DISPLAY_ORDER,
DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT,
DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT,
複製
已複製
複製
已複製
#if defined(HAS_COLOURS) || defined(PLATFORM_MD9600)
DISPLAY_TIME_IN_HEADER,
#endif
#if ! defined(PLATFORM_MD9600)
#if ! defined(PLATFORM_MD9600)
DISPLAY_BATTERY_UNIT_IN_HEADER,
DISPLAY_BATTERY_UNIT_IN_HEADER,
#endif
#endif
DISPLAY_EXTENDED_INFOS,
DISPLAY_EXTENDED_INFOS,
#if defined(HAS_SOFT_VOLUME)
#if defined(HAS_SOFT_VOLUME)
DISPLAY_VISUAL_VOLUME,
DISPLAY_VISUAL_VOLUME,
#endif
#endif
#if ! defined(PLATFORM_MD9600)
#if ! defined(PLATFORM_MD9600)
DISPLAY_ALL_LEDS_ENABLED,
DISPLAY_ALL_LEDS_ENABLED,
#endif
#endif
DISPLAY_TIMEZONE_VALUE,
DISPLAY_TIMEZONE_VALUE,
DISPLAY_TIME_UTC_OR_LOCAL,
DISPLAY_TIME_UTC_OR_LOCAL,
DISPLAY_SHOW_DISTANCE,
DISPLAY_SHOW_DISTANCE,
複製
已複製
複製
已複製
DISPLAY_DMR_LAST_TALKER_ON_SCREEN,
NUM_DISPLAY_MENU_ITEMS
NUM_DISPLAY_MENU_ITEMS
};
};
menuStatus_t menuDisplayOptions(uiEvent_t *ev, bool isFirstRun)
menuStatus_t menuDisplayOptions(uiEvent_t *ev, bool isFirstRun)
{
{
if (isFirstRun)
if (isFirstRun)
{
{
menuDataGlobal.menuOptionsSetQuickkey = 0;
menuDataGlobal.menuOptionsSetQuickkey = 0;
menuDataGlobal.menuOptionsTimeout = 0;
menuDataGlobal.menuOptionsTimeout = 0;
menuDataGlobal.newOptionSelected = true;
menuDataGlobal.newOptionSelected = true;
menuDataGlobal.numItems = NUM_DISPLAY_MENU_ITEMS;
menuDataGlobal.numItems = NUM_DISPLAY_MENU_ITEMS;
if (originalNonVolatileSettings.magicNumber == 0xDEADBEEF)
if (originalNonVolatileSettings.magicNumber == 0xDEADBEEF)
{
{
// Store original settings, used on cancel event.
// Store original settings, used on cancel event.
memcpy(&originalNonVolatileSettings, &nonVolatileSettings, sizeof(settingsStruct_t));
memcpy(&originalNonVolatileSettings, &nonVolatileSettings, sizeof(settingsStruct_t));
}
}
voicePromptsInit();
voicePromptsInit();
voicePromptsAppendPrompt(PROMPT_SILENCE);
voicePromptsAppendPrompt(PROMPT_SILENCE);
voicePromptsAppendLanguageString(currentLanguage->display_options);
voicePromptsAppendLanguageString(currentLanguage->display_options);
voicePromptsAppendLanguageString(currentLanguage->menu);
voicePromptsAppendLanguageString(currentLanguage->menu);
voicePromptsAppendPrompt(PROMPT_SILENCE);
voicePromptsAppendPrompt(PROMPT_SILENCE);
menuSystemRegisterExitCallback(exitCallback, NULL);
menuSystemRegisterExitCallback(exitCallback, NULL);
updateScreen(true);
updateScreen(true);
return (MENU_STATUS_LIST_TYPE | MENU_STATUS_SUCCESS);
return (MENU_STATUS_LIST_TYPE | MENU_STATUS_SUCCESS);
}
}
else
else
{
{
menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS;
menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS;
if (ev->hasEvent || (menuDataGlobal.menuOptionsTimeout > 0))
if (ev->hasEvent || (menuDataGlobal.menuOptionsTimeout > 0))
{
{
handleEvent(ev);
handleEvent(ev);
}
}
}
}
return menuDisplayOptionsExitCode;
return menuDisplayOptionsExitCode;
}
}
static void updateScreen(bool isFirstRun)
static void updateScreen(bool isFirstRun)
{
{
int mNum = 0;
int mNum = 0;
char buf[SCREEN_LINE_BUFFER_SIZE];
char buf[SCREEN_LINE_BUFFER_SIZE];
const char *leftSide = NULL;// initialize to please the compiler
const char *leftSide = NULL;// initialize to please the compiler
const char *rightSideConst = NULL;// initialize to please the compiler
const char *rightSideConst = NULL;// initialize to please the compiler
char rightSideVar[SCREEN_LINE_BUFFER_SIZE];
char rightSideVar[SCREEN_LINE_BUFFER_SIZE];
voicePrompt_t rightSideUnitsPrompt;
voicePrompt_t rightSideUnitsPrompt;
const char *rightSideUnitsStr;
const char *rightSideUnitsStr;
displayClearBuf();
displayClearBuf();
bool settingOption = uiQuickKeysShowChoices(buf, SCREEN_LINE_BUFFER_SIZE, currentLanguage->display_options);
bool settingOption = uiQuickKeysShowChoices(buf, SCREEN_LINE_BUFFER_SIZE, currentLanguage->display_options);
for (int i = MENU_START_ITERATION_VALUE; i <= MENU_END_ITERATION_VALUE; i++)
for (int i = MENU_START_ITERATION_VALUE; i <= MENU_END_ITERATION_VALUE; i++)
{
{
if ((settingOption == false) || (i == 0))
if ((settingOption == false) || (i == 0))
{
{
mNum = menuGetMenuOffset(NUM_DISPLAY_MENU_ITEMS, i);
mNum = menuGetMenuOffset(NUM_DISPLAY_MENU_ITEMS, i);
if (mNum == MENU_OFFSET_BEFORE_FIRST_ENTRY)
if (mNum == MENU_OFFSET_BEFORE_FIRST_ENTRY)
{
{
continue;
continue;
}
}
else if (mNum == MENU_OFFSET_AFTER_LAST_ENTRY)
else if (mNum == MENU_OFFSET_AFTER_LAST_ENTRY)
{
{
break;
break;
}
}
buf[0] = 0;
buf[0] = 0;
leftSide = NULL;
leftSide = NULL;
rightSideConst = NULL;
rightSideConst = NULL;
rightSideVar[0] = 0;
rightSideVar[0] = 0;
rightSideUnitsPrompt = PROMPT_SILENCE;// use PROMPT_SILENCE as flag that the unit has not been set
rightSideUnitsPrompt = PROMPT_SILENCE;// use PROMPT_SILENCE as flag that the unit has not been set
rightSideUnitsStr = NULL;
rightSideUnitsStr = NULL;
switch(mNum)
switch(mNum)
{
{
複製
已複製
複製
已複製
#if defined(HAS_COLOURS)
case DISPLAY_TYPE_STYLE:
leftSide = currentLanguage->text_size;
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", settingsIsOptionBitSet(BIT_UI_USES_DOUBLE_HEIGHT) ? 2 : 1);
break;
#endif
case DISPLAY_MENU_BRIGHTNESS:
case DISPLAY_MENU_BRIGHTNESS:
leftSide = currentLanguage->brightness;
leftSide = currentLanguage->brightness;
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[DAY]);
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[DAY]);
break;
break;
#if ! defined(PLATFORM_GD77S)
#if ! defined(PLATFORM_GD77S)
case DISPLAY_MENU_BRIGHTNESS_NIGHT:
case DISPLAY_MENU_BRIGHTNESS_NIGHT:
leftSide = currentLanguage->brightness_night;
leftSide = currentLanguage->brightness_night;
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[NIGHT]);
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[NIGHT]);
break;
break;
#endif
#endif
case DISPLAY_MENU_BRIGHTNESS_OFF:
case DISPLAY_MENU_BRIGHTNESS_OFF:
leftSide = currentLanguage->brightness_off;
leftSide = currentLanguage->brightness_off;
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentageOff);
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentageOff);
break;
break;
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
case DISPLAY_MENU_CONTRAST:
case DISPLAY_MENU_CONTRAST:
leftSide = currentLanguage->contrast;
leftSide = currentLanguage->contrast;
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.displayContrast);
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.displayContrast);
break;
break;
#endif
#endif
case DISPLAY_MENU_BACKLIGHT_MODE:
case DISPLAY_MENU_BACKLIGHT_MODE:
{
{
const char *backlightModes[] = { currentLanguage->Auto, currentLanguage->squelch, currentLanguage->manual, currentLanguage->buttons, currentLanguage->none };
const char *backlightModes[] = { currentLanguage->Auto, currentLanguage->squelch, currentLanguage->manual, currentLanguage->buttons, currentLanguage->none };
leftSide = currentLanguage->mode;
leftSide = currentLanguage->mode;
rightSideConst = backlightModes[nonVolatileSettings.backlightMode];
rightSideConst = backlightModes[nonVolatileSettings.backlightMode];
}
}
break;
break;
case DISPLAY_MENU_TIMEOUT:
case DISPLAY_MENU_TIMEOUT:
leftSide = currentLanguage->backlight_timeout;
leftSide = currentLanguage->backlight_timeout;
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) ||
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) ||
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) ||
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) ||
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS))
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS))
{
{
if (nonVolatileSettings.backLightTimeout == 0)
if (nonVolatileSettings.backLightTimeout == 0)
{
{
rightSideConst = currentLanguage->no;
rightSideConst = currentLanguage->no;
}
}
else
else
{
{
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.backLightTimeout);
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.backLightTimeout);
rightSideUnitsPrompt = PROMPT_SECONDS;
rightSideUnitsPrompt = PROMPT_SECONDS;
rightSideUnitsStr = "s";
rightSideUnitsStr = "s";
}
}
}
}
else
else
{
{
rightSideConst = currentLanguage->n_a;
rightSideConst = currentLanguage->n_a;
}
}
break;
break;
case DISPLAY_MENU_SCREEN_INVERT:
case DISPLAY_MENU_SCREEN_INVERT:
leftSide = currentLanguage->display_screen_invert;
leftSide = currentLanguage->display_screen_invert;
rightSideConst = settingsIsOptionBitSet(BIT_INVERSE_VIDEO) ? currentLanguage->screen_invert : currentLanguage->screen_normal;
rightSideConst = settingsIsOptionBitSet(BIT_INVERSE_VIDEO) ? currentLanguage->screen_invert : currentLanguage->screen_normal;
break;
break;
#if ! defined(PLATFORM_GD77S)
#if ! defined(PLATFORM_GD77S)
case DISPLAY_AUTO_NIGHT:
case DISPLAY_AUTO_NIGHT:
leftSide = currentLanguage->auto_night;
leftSide = currentLanguage->auto_night;
rightSideConst = settingsIsOptionBitSet(BIT_AUTO_NIGHT) ? currentLanguage->on : currentLanguage->off;
rightSideConst = settingsIsOptionBitSet(BIT_AUTO_NIGHT) ? currentLanguage->on : currentLanguage->off;
break;
break;
#endif
#endif
複製
已複製
複製
已複製
case DISPLAY_MENU_CONTACT_DISPLAY_ORDER:
case DISPLAY_MENU_CONTACT_DISPLAY_ORDER:
leftSide = currentLanguage->priority_order;
leftSide = currentLanguage->priority_order;
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", contactOrders[nonVolatileSettings.contactDisplayPriority]);
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", contactOrders[nonVolatileSettings.contactDisplayPriority]);
break;
break;
case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT:
case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT:
{
{
const char *splitContact[] = { currentLanguage->one_line, currentLanguage->two_lines, currentLanguage->Auto };
const char *splitContact[] = { currentLanguage->one_line, currentLanguage->two_lines, currentLanguage->Auto };
leftSide = currentLanguage->contact;
leftSide = currentLanguage->contact;
rightSideConst = splitContact[nonVolatileSettings.splitContact];
rightSideConst = splitContact[nonVolatileSettings.splitContact];
}
}
break;
break;
複製
已複製
複製
已複製
#if defined(HAS_COLOURS) || defined(PLATFORM_MD9600)
case DISPLAY_TIME_IN_HEADER:
leftSide = currentLanguage->time;
rightSideConst = settingsIsOptionBitSet(BIT_DISPLAY_TIME_IN_HEADER) ? currentLanguage->on : currentLanguage->off;
break;
#endif
#if ! defined(PLATFORM_MD9600)
#if ! defined(PLATFORM_MD9600)
case DISPLAY_BATTERY_UNIT_IN_HEADER:
case DISPLAY_BATTERY_UNIT_IN_HEADER:
leftSide = currentLanguage->battery;
leftSide = currentLanguage->battery;
if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER))
if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER))
{
{
rightSideUnitsPrompt = PROMPT_VOLTS;
rightSideUnitsPrompt = PROMPT_VOLTS;
rightSideUnitsStr = "V";
rightSideUnitsStr = "V";
}
}
else
else
{
{
rightSideUnitsPrompt = PROMPT_PERCENT;
rightSideUnitsPrompt = PROMPT_PERCENT;
rightSideUnitsStr = "%";
rightSideUnitsStr = "%";
}
}
break;
break;
#endif
#endif
case DISPLAY_EXTENDED_INFOS:
case DISPLAY_EXTENDED_INFOS:
{
{
const char *extendedInfos[] = { currentLanguage->off, currentLanguage->ts, currentLanguage->pwr, currentLanguage->both };
const char *extendedInfos[] = { currentLanguage->off, currentLanguage->ts, currentLanguage->pwr, currentLanguage->both };
leftSide = currentLanguage->info;
leftSide = currentLanguage->info;
rightSideConst = extendedInfos[nonVolatileSettings.extendedInfosOnScreen];
rightSideConst = extendedInfos[nonVolatileSettings.extendedInfosOnScreen];
}
}
break;
break;
#if defined(HAS_SOFT_VOLUME)
#if defined(HAS_SOFT_VOLUME)
case DISPLAY_VISUAL_VOLUME:
case DISPLAY_VISUAL_VOLUME:
leftSide = currentLanguage->volume;
leftSide = currentLanguage->volume;
rightSideConst = settingsIsOptionBitSet(BIT_VISUAL_VOLUME) ? currentLanguage->on : currentLanguage->off;
rightSideConst = settingsIsOptionBitSet(BIT_VISUAL_VOLUME) ? currentLanguage->on : currentLanguage->off;
break;
break;
#endif
#endif
#if ! defined(PLATFORM_MD9600)
#if ! defined(PLATFORM_MD9600)
case DISPLAY_ALL_LEDS_ENABLED:
case DISPLAY_ALL_LEDS_ENABLED:
leftSide = currentLanguage->leds;
leftSide = currentLanguage->leds;
rightSideConst = settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) ? currentLanguage->off : currentLanguage->on;
rightSideConst = settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) ? currentLanguage->off : currentLanguage->on;
break;
break;
#endif
#endif
case DISPLAY_TIMEZONE_VALUE:
case DISPLAY_TIMEZONE_VALUE:
leftSide = currentLanguage->timeZone;
leftSide = currentLanguage->timeZone;
buildTimeZoneBufferText(rightSideVar);
buildTimeZoneBufferText(rightSideVar);
break;
break;
case DISPLAY_TIME_UTC_OR_LOCAL:
case DISPLAY_TIME_UTC_OR_LOCAL:
複製
已複製
複製
已複製
leftSide = currentLanguage->
time
;
leftSide = currentLanguage->
UTC
;
rightSideConst = (nonVolatileSettings.timezone & 0x80) ? currentLanguage->
local
: currentLanguage->
UTC
;
rightSideConst = (nonVolatileSettings.timezone & 0x80) ? currentLanguage->
no
: currentLanguage->
yes
;
break;
break;
case DISPLAY_SHOW_DISTANCE:
case DISPLAY_SHOW_DISTANCE:
leftSide = currentLanguage->show_distance;
leftSide = currentLanguage->show_distance;
rightSideConst = settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) ? currentLanguage->on : currentLanguage->off;
rightSideConst = settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) ? currentLanguage->on : currentLanguage->off;
break;
break;
複製
已複製
複製
已複製
case DISPLAY_DMR_LAST_TALKER_ON_SCREEN:
leftSide = currentLanguage->last_talker;
if (nonVolatileSettings.lastTalkerOnScreenTimer > 0)
{
snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%u", nonVolatileSettings.lastTalkerOnScreenTimer);
rightSideUnitsPrompt = PROMPT_SECONDS;
rightSideUnitsStr = "s";
}
else
{
rightSideConst = currentLanguage->off;
}
break;
}
}
// workaround for non standard format of line for colour display
// workaround for non standard format of line for colour display
snprintf(buf, SCREEN_LINE_BUFFER_SIZE, "%s:%s", leftSide, (rightSideVar[0] ? rightSideVar : (rightSideConst ? rightSideConst : "")));
snprintf(buf, SCREEN_LINE_BUFFER_SIZE, "%s:%s", leftSide, (rightSideVar[0] ? rightSideVar : (rightSideConst ? rightSideConst : "")));
if (i == 0)
if (i == 0)
{
{
bool wasPlaying = voicePromptsIsPlaying();
bool wasPlaying = voicePromptsIsPlaying();
if (!isFirstRun && (menuDataGlobal.menuOptionsSetQuickkey == 0))
if (!isFirstRun && (menuDataGlobal.menuOptionsSetQuickkey == 0))
{
{
voicePromptsInit();
voicePromptsInit();
}
}
if (!wasPlaying || (menuDataGlobal.newOptionSelected || (menuDataGlobal.menuOptionsTimeout > 0)))
if (!wasPlaying || (menuDataGlobal.newOptionSelected || (menuDataGlobal.menuOptionsTimeout > 0)))
{
{
voicePromptsAppendLanguageString(leftSide);
voicePromptsAppendLanguageString(leftSide);
}
}
if ((rightSideVar[0] != 0) || ((rightSideVar[0] == 0) && (rightSideConst == NULL)))
if ((rightSideVar[0] != 0) || ((rightSideVar[0] == 0) && (rightSideConst == NULL)))
{
{
voicePromptsAppendString(rightSideVar);
voicePromptsAppendString(rightSideVar);
}
}
else
else
{
{
voicePromptsAppendLanguageString(rightSideConst);
voicePromptsAppendLanguageString(rightSideConst);
}
}
if (rightSideUnitsPrompt != PROMPT_SILENCE)
if (rightSideUnitsPrompt != PROMPT_SILENCE)
{
{
voicePromptsAppendPrompt(rightSideUnitsPrompt);
voicePromptsAppendPrompt(rightSideUnitsPrompt);
}
}
if (rightSideUnitsStr != NULL)
if (rightSideUnitsStr != NULL)
{
{
strncat(rightSideVar, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE);
strncat(rightSideVar, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE);
}
}
if (menuDataGlobal.menuOptionsTimeout != -1)
if (menuDataGlobal.menuOptionsTimeout != -1)
{
{
promptsPlayNotAfterTx();
promptsPlayNotAfterTx();
}
}
else
else
{
{
menuDataGlobal.menuOptionsTimeout = 0;// clear flag indicating that a QuickKey has just been set
menuDataGlobal.menuOptionsTimeout = 0;// clear flag indicating that a QuickKey has just been set
}
}
}
}
// QuickKeys
// QuickKeys
if (menuDataGlobal.menuOptionsTimeout > 0)
if (menuDataGlobal.menuOptionsTimeout > 0)
{
{
menuDisplaySettingOption(leftSide, (rightSideVar[0] ? rightSideVar : rightSideConst));
menuDisplaySettingOption(leftSide, (rightSideVar[0] ? rightSideVar : rightSideConst));
}
}
else
else
{
{
if (rightSideUnitsStr != NULL)
if (rightSideUnitsStr != NULL)
{
{
strncat(buf, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE);
strncat(buf, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE);
}
}
menuDisplayEntry(i, mNum, buf, (strlen(leftSide) + 1), THEME_ITEM_FG_MENU_ITEM, THEME_ITEM_FG_OPTIONS_VALUE, THEME_ITEM_BG);
menuDisplayEntry(i, mNum, buf, (strlen(leftSide) + 1), THEME_ITEM_FG_MENU_ITEM, THEME_ITEM_FG_OPTIONS_VALUE, THEME_ITEM_BG);
}
}
}
}
}
}
displayRender();
displayRender();
}
}
static void handleEvent(uiEvent_t *ev)
static void handleEvent(uiEvent_t *ev)
{
{
bool isDirty = false;
bool isDirty = false;
if ((menuDataGlobal.menuOptionsTimeout > 0) && (!BUTTONCHECK_DOWN(ev, BUTTON_SK2)))
if ((menuDataGlobal.menuOptionsTimeout > 0) && (!BUTTONCHECK_DOWN(ev, BUTTON_SK2)))
{
{
if (voicePromptsIsPlaying() == false)
if (voicePromptsIsPlaying() == false)
{
{
menuDataGlobal.menuOptionsTimeout--;
menuDataGlobal.menuOptionsTimeout--;
if (menuDataGlobal.menuOptionsTimeout == 0)
if (menuDataGlobal.menuOptionsTimeout == 0)
{
{
applySettings();
applySettings();
menuSystemPopPreviousMenu();
menuSystemPopPreviousMenu();
return;
return;
}
}
}
}
}
}
if (ev->events & FUNCTION_EVENT)
if (ev->events & FUNCTION_EVENT)
{
{
isDirty = true;
isDirty = true;
if (ev->function == FUNC_REDRAW)
if (ev->function == FUNC_REDRAW)
{
{
updateScreen(false);
updateScreen(false);
return;
return;
}
}
else if ((QUICKKEY_TYPE(ev->function) == QUICKKEY_MENU) && (QUICKKEY_ENTRYID(ev->function) < NUM_DISPLAY_MENU_ITEMS))
else if ((QUICKKEY_TYPE(ev->function) == QUICKKEY_MENU) && (QUICKKEY_ENTRYID(ev->function) < NUM_DISPLAY_MENU_ITEMS))
{
{
menuDataGlobal.currentItemIndex = QUICKKEY_ENTRYID(ev->function);
menuDataGlobal.currentItemIndex = QUICKKEY_ENTRYID(ev->function);
#if ! defined(PLATFORM_GD77S)
#if ! defined(PLATFORM_GD77S)
複製
已複製
複製
已複製
// Control the brig
th
ness of the current daytime.
// Control the brig
ht
ness of the current daytime.
if ((menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS) || (menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS_NIGHT))
if ((menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS) || (menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS_NIGHT))
{
{
if (DAYTIME_CURRENT == DAY)
if (DAYTIME_CURRENT == DAY)
{
{
menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS;
menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS;
}
}
else
else
{
{
menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS_NIGHT;
menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS_NIGHT;
}
}
}
}
#endif
#endif
}
}
if ((QUICKKEY_FUNCTIONID(ev->function) != 0))
if ((QUICKKEY_FUNCTIONID(ev->function) != 0))
{
{
menuDataGlobal.menuOptionsTimeout = 1000;
menuDataGlobal.menuOptionsTimeout = 1000;
}
}
}
}
if (ev->events & BUTTON_EVENT)
if (ev->events & BUTTON_EVENT)
{
{
if (repeatVoicePromptOnSK1(ev))
if (repeatVoicePromptOnSK1(ev))
{
{
return;
return;
}
}
}
}
if ((ev->events & KEY_EVENT) && (menuDataGlobal.menuOptionsSetQuickkey == 0) && (menuDataGlobal.menuOptionsTimeout == 0))
if ((ev->events & KEY_EVENT) && (menuDataGlobal.menuOptionsSetQuickkey == 0) && (menuDataGlobal.menuOptionsTimeout == 0))
{
{
if (KEYCHECK_PRESS(ev->keys, KEY_DOWN) && (menuDataGlobal.numItems != 0))
if (KEYCHECK_PRESS(ev->keys, KEY_DOWN) && (menuDataGlobal.numItems != 0))
{
{
isDirty = true;
isDirty = true;
menuSystemMenuIncrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS);
menuSystemMenuIncrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS);
menuDataGlobal.newOptionSelected = true;
menuDataGlobal.newOptionSelected = true;
menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE;
menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE;
}
}
else if (KEYCHECK_PRESS(ev->keys, KEY_UP))
else if (KEYCHECK_PRESS(ev->keys, KEY_UP))
{
{
isDirty = true;
isDirty = true;
menuSystemMenuDecrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS);
menuSystemMenuDecrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS);
menuDataGlobal.newOptionSelected = true;
menuDataGlobal.newOptionSelected = true;
menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE;
menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE;
}
}
else if (KEYCHECK_SHORTUP(ev->keys, KEY_GREEN))
else if (KEYCHECK_SHORTUP(ev->keys, KEY_GREEN))
{
{
applySettings();
applySettings();
menuSystemPopAllAndDisplayRootMenu();
menuSystemPopAllAndDisplayRootMenu();
return;
return;
}
}
else if (KEYCHECK_SHORTUP(ev->keys, KEY_RED))
else if (KEYCHECK_SHORTUP(ev->keys, KEY_RED))
{
{
menuSystemPopPreviousMenu();
menuSystemPopPreviousMenu();
return;
return;
}
}
else if (KEYCHECK_SHORTUP_NUMBER(ev->keys) && BUTTONCHECK_DOWN(ev, BUTTON_SK2))
else if (KEYCHECK_SHORTUP_NUMBER(ev->keys) && BUTTONCHECK_DOWN(ev, BUTTON_SK2))
{
{
menuDataGlobal.menuOptionsSetQuickkey = ev->keys.key;
menuDataGlobal.menuOptionsSetQuickkey = ev->keys.key;
isDirty = true;
isDirty = true;
}
}
}
}
if ((ev->events & (KEY_EVENT | FUNCTION_EVENT)) && (menuDataGlobal.menuOptionsSetQuickkey == 0))
if ((ev->events & (KEY_EVENT | FUNCTION_EVENT)) && (menuDataGlobal.menuOptionsSetQuickkey == 0))
{
{
bool displayIsLit = displayIsBacklightLit();
bool displayIsLit = displayIsBacklightLit();
if (KEYCHECK_PRESS(ev->keys, KEY_RIGHT)
if (KEYCHECK_PRESS(ev->keys, KEY_RIGHT)
#if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
#if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
|| KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_INCREMENT)
|| KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_INCREMENT)
#endif
#endif
|| (QUICKKEY_FUNCTIONID(ev->function) == FUNC_RIGHT))
|| (QUICKKEY_FUNCTIONID(ev->function) == FUNC_RIGHT))
{
{
if (menuDataGlobal.menuOptionsTimeout > 0)
if (menuDataGlobal.menuOptionsTimeout > 0)
{
{
menuDataGlobal.menuOptionsTimeout = 1000;
menuDataGlobal.menuOptionsTimeout = 1000;
}
}
isDirty = true;
isDirty = true;
menuDataGlobal.newOptionSelected = false;
menuDataGlobal.newOptionSelected = false;
switch(menuDataGlobal.currentItemIndex)
switch(menuDataGlobal.currentItemIndex)
{
{
複製
已複製
複製
已複製
#if defined(HAS_COLOURS)
case DISPLAY_TYPE_STYLE:
if (settingsIsOptionBitSet(BIT_UI_USES_DOUBLE_HEIGHT) == false)
{
settingsSetOptionBit(BIT_UI_USES_DOUBLE_HEIGHT, true);
}
break;
#endif
case DISPLAY_MENU_BRIGHTNESS:
case DISPLAY_MENU_BRIGHTNESS:
settingsIncrement(nonVolatileSettings.displayBacklightPercentage[DAY],
settingsIncrement(nonVolatileSettings.displayBacklightPercentage[DAY],
(int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
(int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
if (nonVolatileSettings.displayBacklightPercentage[DAY] > BACKLIGHT_MAX_PERCENTAGE)
if (nonVolatileSettings.displayBacklightPercentage[DAY] > BACKLIGHT_MAX_PERCENTAGE)
{
{
settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) BACKLIGHT_MAX_PERCENTAGE);
settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) BACKLIGHT_MAX_PERCENTAGE);
}
}
#if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
#if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
displayLightTrigger(true);
displayLightTrigger(true);
#endif
#endif
break;
break;
case DISPLAY_MENU_BRIGHTNESS_OFF:
case DISPLAY_MENU_BRIGHTNESS_OFF:
if ((nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[DAY]) &&
if ((nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[DAY]) &&
(nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[NIGHT]))
(nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[NIGHT]))
{
{
settingsIncrement(nonVolatileSettings.displayBacklightPercentageOff,
settingsIncrement(nonVolatileSettings.displayBacklightPercentageOff,
(int8_t) ((nonVolatileSettings.displayBacklightPercentageOff < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
(int8_t) ((nonVolatileSettings.displayBacklightPercentageOff < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
if (nonVolatileSettings.displayBacklightPercentageOff > BACKLIGHT_MAX_PERCENTAGE)
if (nonVolatileSettings.displayBacklightPercentageOff > BACKLIGHT_MAX_PERCENTAGE)
{
{
settingsSet(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) BACKLIGHT_MAX_PERCENTAGE);
settingsSet(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) BACKLIGHT_MAX_PERCENTAGE);
}
}
checkMinBacklightValue();
checkMinBacklightValue();
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit))
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit))
{
{
gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff);
gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff);
}
}
}
}
break;
break;
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
case DISPLAY_MENU_CONTRAST:
case DISPLAY_MENU_CONTRAST:
if (nonVolatileSettings.displayContrast < CONTRAST_MAX_VALUE)
if (nonVolatileSettings.displayContrast < CONTRAST_MAX_VALUE)
{
{
settingsIncrement(nonVolatileSettings.displayContrast, 1);
settingsIncrement(nonVolatileSettings.displayContrast, 1);
}
}
displaySetContrast(nonVolatileSettings.displayContrast);
displaySetContrast(nonVolatileSettings.displayContrast);
break;
break;
#endif
#endif
case DISPLAY_MENU_BACKLIGHT_MODE:
case DISPLAY_MENU_BACKLIGHT_MODE:
#if (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
#if (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_BUTTONS )
if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_BUTTONS )
#else
#else
if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_NONE)
if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_NONE)
#endif
#endif
{
{
settingsIncrement(nonVolatileSettings.backlightMode, 1);
settingsIncrement(nonVolatileSettings.backlightMode, 1);
updateBacklightMode(nonVolatileSettings.backlightMode);
updateBacklightMode(nonVolatileSettings.backlightMode);
}
}
break;
break;
case DISPLAY_MENU_TIMEOUT:
case DISPLAY_MENU_TIMEOUT:
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) ||
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) ||
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) ||
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) ||
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS))
(nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS))
{
{
settingsIncrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP);
settingsIncrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP);
if (nonVolatileSettings.backLightTimeout > BACKLIGHT_MAX_TIMEOUT)
if (nonVolatileSettings.backLightTimeout > BACKLIGHT_MAX_TIMEOUT)
{
{
settingsSet(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_MAX_TIMEOUT);
settingsSet(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_MAX_TIMEOUT);
}
}
}
}
break;
break;
case DISPLAY_MENU_SCREEN_INVERT:
case DISPLAY_MENU_SCREEN_INVERT:
setDisplayInvert(true);
setDisplayInvert(true);
break;
break;
#if ! defined(PLATFORM_GD77S)
#if ! defined(PLATFORM_GD77S)
case DISPLAY_AUTO_NIGHT:
case DISPLAY_AUTO_NIGHT:
if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) == false)
if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) == false)
{
{
settingsSetOptionBit(BIT_AUTO_NIGHT, true);
settingsSetOptionBit(BIT_AUTO_NIGHT, true);
}
}
break;
break;
case DISPLAY_MENU_BRIGHTNESS_NIGHT:
case DISPLAY_MENU_BRIGHTNESS_NIGHT:
settingsIncrement(nonVolatileSettings.displayBacklightPercentage[NIGHT],
settingsIncrement(nonVolatileSettings.displayBacklightPercentage[NIGHT],
(int8_t) ((nonVolatileSettings.displayBacklightPercentage[NIGHT] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
(int8_t) ((nonVolatileSettings.displayBacklightPercentage[NIGHT] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
if (nonVolatileSettings.displayBacklightPercentage[NIGHT] > BACKLIGHT_MAX_PERCENTAGE)
if (nonVolatileSettings.displayBacklightPercentage[NIGHT] > BACKLIGHT_MAX_PERCENTAGE)
{
{
settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) BACKLIGHT_MAX_PERCENTAGE);
settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) BACKLIGHT_MAX_PERCENTAGE);
}
}
#if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
#if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
displayLightTrigger(true);
displayLightTrigger(true);
#endif
#endif
break;
break;
#endif
#endif
case DISPLAY_MENU_CONTACT_DISPLAY_ORDER:
case DISPLAY_MENU_CONTACT_DISPLAY_ORDER:
if (nonVolatileSettings.contactDisplayPriority < CONTACT_DISPLAY_PRIO_TA_DB_CC)
if (nonVolatileSettings.contactDisplayPriority < CONTACT_DISPLAY_PRIO_TA_DB_CC)
{
{
settingsIncrement(nonVolatileSettings.contactDisplayPriority, 1);
settingsIncrement(nonVolatileSettings.contactDisplayPriority, 1);
}
}
break;
break;
case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT:
case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT:
if (nonVolatileSettings.splitContact < SPLIT_CONTACT_AUTO)
if (nonVolatileSettings.splitContact < SPLIT_CONTACT_AUTO)
{
{
settingsIncrement(nonVolatileSettings.splitContact, 1);
settingsIncrement(nonVolatileSettings.splitContact, 1);
}
}
break;
break;
複製
已複製
複製
已複製
#if defined(HAS_COLOURS) || defined(PLATFORM_MD9600)
case DISPLAY_TIME_IN_HEADER:
if (settingsIsOptionBitSet(BIT_DISPLAY_TIME_IN_HEADER) == false)
{
settingsSetOptionBit(BIT_DISPLAY_TIME_IN_HEADER, true);
}
break;
#endif
#if ! defined(PLATFORM_MD9600)
#if ! defined(PLATFORM_MD9600)
case DISPLAY_BATTERY_UNIT_IN_HEADER:
case DISPLAY_BATTERY_UNIT_IN_HEADER:
if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER) == false)
if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER) == false)
{
{
settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, true);
settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, true);
}
}
break;
break;
#endif
#endif
case DISPLAY_EXTENDED_INFOS:
case DISPLAY_EXTENDED_INFOS:
if (nonVolatileSettings.extendedInfosOnScreen < INFO_ON_SCREEN_BOTH)
if (nonVolatileSettings.extendedInfosOnScreen < INFO_ON_SCREEN_BOTH)
{
{
settingsIncrement(nonVolatileSettings.extendedInfosOnScreen, 1);
settingsIncrement(nonVolatileSettings.extendedInfosOnScreen, 1);
}
}
break;
break;
#if defined(HAS_SOFT_VOLUME)
#if defined(HAS_SOFT_VOLUME)
case DISPLAY_VISUAL_VOLUME:
case DISPLAY_VISUAL_VOLUME:
if (settingsIsOptionBitSet(BIT_VISUAL_VOLUME) == false)
if (settingsIsOptionBitSet(BIT_VISUAL_VOLUME) == false)
{
{
settingsSetOptionBit(BIT_VISUAL_VOLUME, true);
settingsSetOptionBit(BIT_VISUAL_VOLUME, true);
}
}
break;
break;
#endif
#endif
#if ! defined(PLATFORM_MD9600)
#if ! defined(PLATFORM_MD9600)
case DISPLAY_ALL_LEDS_ENABLED:
case DISPLAY_ALL_LEDS_ENABLED:
if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED))
if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED))
{
{
uint8_t state = LedRead(LED_GREEN);
uint8_t state = LedRead(LED_GREEN);
settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, false);
settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, false);
LedWriteDirect(LED_GREEN, state);
LedWriteDirect(LED_GREEN, state);
}
}
break;
break;
#endif
#endif
case DISPLAY_TIMEZONE_VALUE:
case DISPLAY_TIMEZONE_VALUE:
{
{
int tz = (nonVolatileSettings.timezone & 0x7F);
int tz = (nonVolatileSettings.timezone & 0x7F);
if (BUTTONCHECK_DOWN(ev, BUTTON_SK2))
if (BUTTONCHECK_DOWN(ev, BUTTON_SK2))
{
{
tz++;
tz++;
}
}
else
else
{
{
tz += 4;
tz += 4;
}
}
if (tz <= ((14 * 4) + SETTINGS_TIMEZONE_UTC))
if (tz <= ((14 * 4) + SETTINGS_TIMEZONE_UTC))
{
{
settingsSet(nonVolatileSettings.timezone, ((nonVolatileSettings.timezone & ~0x7F) + tz));
settingsSet(nonVolatileSettings.timezone, ((nonVolatileSettings.timezone & ~0x7F) + tz));
}
}
}
}
break;
break;
case DISPLAY_TIME_UTC_OR_LOCAL:
case DISPLAY_TIME_UTC_OR_LOCAL:
複製
已複製
複製
已複製
settingsSet(nonVolatileSettings.timezone, (uint8_t) (nonVolatileSettings.timezone
|
0x80));
settingsSet(nonVolatileSettings.timezone, (uint8_t) (nonVolatileSettings.timezone
& ~
0x80));
break;
break;
複製
已複製
複製
已複製
case DISPLAY_SHOW_DISTANCE:
case DISPLAY_SHOW_DISTANCE:
if (settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) == false)
if (settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) == false)
{
{
settingsSetOptionBit(BIT_DISPLAY_CHANNEL_DISTANCE, true);
settingsSetOptionBit(BIT_DISPLAY_CHANNEL_DISTANCE, true);
}
}
break;
break;
複製
已複製
複製
已複製
case DISPLAY_DMR_LAST_TALKER_ON_SCREEN:
if (nonVolatileSettings.lastTalkerOnScreenTimer < 30U)
{
settingsIncrement(nonVolatileSettings.lastTalkerOnScreenTimer, 1U);
}
break;
}
}
}
}
else if (KEYCHECK_PRESS(ev->keys, KEY_LEFT)
else if (KEYCHECK_PRESS(ev->keys, KEY_LEFT)
#if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
#if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)
|| KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_DECREMENT)
|| KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_DECREMENT)
#endif
#endif
|| (QUICKKEY_FUNCTIONID(ev->function) == FUNC_LEFT))
|| (QUICKKEY_FUNCTIONID(ev->function) == FUNC_LEFT))
{
{
if (menuDataGlobal.menuOptionsTimeout > 0)
if (menuDataGlobal.menuOptionsTimeout > 0)
{
{
menuDataGlobal.menuOptionsTimeout = 1000;
menuDataGlobal.menuOptionsTimeout = 1000;
}
}
isDirty = true;
isDirty = true;
menuDataGlobal.newOptionSelected = false;
menuDataGlobal.newOptionSelected = false;
switch(menuDataGlobal.currentItemIndex)
switch(menuDataGlobal.currentItemIndex)
{
{
複製
已複製
複製
已複製
#if defined(HAS_COLOURS)
case DISPLAY_TYPE_STYLE:
if (settingsIsOptionBitSet(BIT_UI_USES_DOUBLE_HEIGHT))
{
settingsSetOptionBit(BIT_UI_USES_DOUBLE_HEIGHT, false);
}
break;
#endif
case DISPLAY_MENU_BRIGHTNESS:
case DISPLAY_MENU_BRIGHTNESS:
settingsDecrement(nonVolatileSettings.displayBacklightPercentage[DAY],
settingsDecrement(nonVolatileSettings.displayBacklightPercentage[DAY],
(int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] <= BACKLIGHT_PERCENTAGE_STEP) ? 1 : BACKLIGHT_PERCENTAGE_STEP));
(int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] <= BACKLIGHT_PERCENTAGE_STEP) ? 1 : BACKLIGHT_PERCENTAGE_STEP));
if (nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_MIN_USABLE_VALUE)
if (nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_MIN_USABLE_VALUE)
{
{
settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], BACKLIGHT_MIN_USABLE_VALUE);
settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], BACKLIGHT_MIN_USABLE_VALUE);
}
}
checkMinBacklightValue();
checkMinBacklightValue();
複製
已複製
複製
已複製
#if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFO
RM_RT84_DM1701) || defined(PLATFORM_MD2017)
#if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFO
displayLightTrigger(true);
#endif
break;
case DISPLAY_MENU_BRIGHTNESS_OFF:
settingsDecrement(nonVolatileSettings.displayBacklightPercentageOff,
(int8_t) ((nonVolatileSettings.displayBacklightPercentageOff <= BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP));
if (nonVolatileSettings.displayBacklightPercentageOff < 0)
{
settingsSet(nonVolatileSettings.displayBacklightPercentageOff, 0);
}
if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit))
{
gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff);
}
break;
#if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017))
case DISPLAY_MENU_CONTRAST:
if (nonVolatileSettings.displayContrast > CONTRAST_MIN_VALUE)
{
settingsDecrement(nonVolatileSettings.displayContrast, 1);
}
displaySetContrast(nonVolatileSettings.displayContrast);
break;
#endif
case DISPLAY_MENU_BACKLIGHT_MODE:
if (nonVolatileSettings.backlightMode > BACKLIGHT_MODE_AUTO)
{
settingsDecrement(nonVolatileSettings.backlightMode, 1);
updateBacklightMode(nonVolatileSettings.backlightMode);
}
break;
case DISPLAY_MENU_TIMEOUT:
if (((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO)
&& (nonVolatileSettings.backLightTimeout >= BACKLIGHT_TIMEOUT_STEP)) ||
(((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS))
&& (nonVolatileSettings.backLightTimeout >= (BACKLIGHT_TIMEOUT_STEP * 2))))
{
settingsDecrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP);
}
break;
case DISPLAY_MENU_SCREEN_INVERT:
setDisplayInvert(false);
break
已保存差異
原始文本
開啟檔案
/* * Copyright (C) 2019-2024 Roger Clark, VK3KYY / G4KYF * Daniel Caujolle-Bert, F1RMB * * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. Use of this source code or binary releases for commercial purposes is strictly forbidden. This includes, without limitation, * incorporation in a commercial product or incorporation into a product or project which allows commercial use. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #if defined(PLATFORM_MD9600) #include "hardware/ST7567.h" #elif (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) #include "hardware/HX8353E.h" #else #include "hardware/UC1701.h" #endif #include "user_interface/uiGlobals.h" #include "user_interface/menuSystem.h" #include "user_interface/uiLocalisation.h" #include "user_interface/uiUtilities.h" static void updateScreen(bool isFirstRun); static void handleEvent(uiEvent_t *ev); static void updateBacklightMode(uint8_t mode); static void setDisplayInvert(bool invert); static void checkMinBacklightValue(void); static void buildTimeZoneBufferText(char * buffer); static void applySettings(void); static void exitCallback(void *data); static menuStatus_t menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS; static const int BACKLIGHT_MAX_TIMEOUT = 30; #if defined(PLATFORM_RD5R) static const int CONTRAST_MAX_VALUE = 10;// Maximum value which still seems to be readable static const int CONTRAST_MIN_VALUE = 0;// Minimum value which still seems to be readable #elif ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) static const int CONTRAST_MAX_VALUE = 30;// Maximum value which still seems to be readable static const int CONTRAST_MIN_VALUE = 5;// Minimum value which still seems to be readable #endif static const int BACKLIGHT_TIMEOUT_STEP = 5; static const int BACKLIGHT_MAX_PERCENTAGE = 100; static const int BACKLIGHT_PERCENTAGE_STEP = 10; static const int BACKLIGHT_PERCENTAGE_STEP_SMALL = 1; static const char *contactOrders[] = { "Ct/DB/TA", "DB/Ct/TA", "TA/Ct/DB", "TA/DB/Ct" }; enum { DISPLAY_MENU_BRIGHTNESS = 0, #if ! defined(PLATFORM_GD77S) DISPLAY_MENU_BRIGHTNESS_NIGHT, #endif DISPLAY_MENU_BRIGHTNESS_OFF, #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) DISPLAY_MENU_CONTRAST, #endif DISPLAY_MENU_BACKLIGHT_MODE, DISPLAY_MENU_TIMEOUT, DISPLAY_MENU_SCREEN_INVERT, #if ! defined(PLATFORM_GD77S) DISPLAY_AUTO_NIGHT, #endif DISPLAY_MENU_CONTACT_DISPLAY_ORDER, DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT, #if ! defined(PLATFORM_MD9600) DISPLAY_BATTERY_UNIT_IN_HEADER, #endif DISPLAY_EXTENDED_INFOS, #if defined(HAS_SOFT_VOLUME) DISPLAY_VISUAL_VOLUME, #endif #if ! defined(PLATFORM_MD9600) DISPLAY_ALL_LEDS_ENABLED, #endif DISPLAY_TIMEZONE_VALUE, DISPLAY_TIME_UTC_OR_LOCAL, DISPLAY_SHOW_DISTANCE, NUM_DISPLAY_MENU_ITEMS }; menuStatus_t menuDisplayOptions(uiEvent_t *ev, bool isFirstRun) { if (isFirstRun) { menuDataGlobal.menuOptionsSetQuickkey = 0; menuDataGlobal.menuOptionsTimeout = 0; menuDataGlobal.newOptionSelected = true; menuDataGlobal.numItems = NUM_DISPLAY_MENU_ITEMS; if (originalNonVolatileSettings.magicNumber == 0xDEADBEEF) { // Store original settings, used on cancel event. memcpy(&originalNonVolatileSettings, &nonVolatileSettings, sizeof(settingsStruct_t)); } voicePromptsInit(); voicePromptsAppendPrompt(PROMPT_SILENCE); voicePromptsAppendLanguageString(currentLanguage->display_options); voicePromptsAppendLanguageString(currentLanguage->menu); voicePromptsAppendPrompt(PROMPT_SILENCE); menuSystemRegisterExitCallback(exitCallback, NULL); updateScreen(true); return (MENU_STATUS_LIST_TYPE | MENU_STATUS_SUCCESS); } else { menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS; if (ev->hasEvent || (menuDataGlobal.menuOptionsTimeout > 0)) { handleEvent(ev); } } return menuDisplayOptionsExitCode; } static void updateScreen(bool isFirstRun) { int mNum = 0; char buf[SCREEN_LINE_BUFFER_SIZE]; const char *leftSide = NULL;// initialize to please the compiler const char *rightSideConst = NULL;// initialize to please the compiler char rightSideVar[SCREEN_LINE_BUFFER_SIZE]; voicePrompt_t rightSideUnitsPrompt; const char *rightSideUnitsStr; displayClearBuf(); bool settingOption = uiQuickKeysShowChoices(buf, SCREEN_LINE_BUFFER_SIZE, currentLanguage->display_options); for (int i = MENU_START_ITERATION_VALUE; i <= MENU_END_ITERATION_VALUE; i++) { if ((settingOption == false) || (i == 0)) { mNum = menuGetMenuOffset(NUM_DISPLAY_MENU_ITEMS, i); if (mNum == MENU_OFFSET_BEFORE_FIRST_ENTRY) { continue; } else if (mNum == MENU_OFFSET_AFTER_LAST_ENTRY) { break; } buf[0] = 0; leftSide = NULL; rightSideConst = NULL; rightSideVar[0] = 0; rightSideUnitsPrompt = PROMPT_SILENCE;// use PROMPT_SILENCE as flag that the unit has not been set rightSideUnitsStr = NULL; switch(mNum) { case DISPLAY_MENU_BRIGHTNESS: leftSide = currentLanguage->brightness; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[DAY]); break; #if ! defined(PLATFORM_GD77S) case DISPLAY_MENU_BRIGHTNESS_NIGHT: leftSide = currentLanguage->brightness_night; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[NIGHT]); break; #endif case DISPLAY_MENU_BRIGHTNESS_OFF: leftSide = currentLanguage->brightness_off; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentageOff); break; #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) case DISPLAY_MENU_CONTRAST: leftSide = currentLanguage->contrast; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.displayContrast); break; #endif case DISPLAY_MENU_BACKLIGHT_MODE: { const char *backlightModes[] = { currentLanguage->Auto, currentLanguage->squelch, currentLanguage->manual, currentLanguage->buttons, currentLanguage->none }; leftSide = currentLanguage->mode; rightSideConst = backlightModes[nonVolatileSettings.backlightMode]; } break; case DISPLAY_MENU_TIMEOUT: leftSide = currentLanguage->backlight_timeout; if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS)) { if (nonVolatileSettings.backLightTimeout == 0) { rightSideConst = currentLanguage->no; } else { snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.backLightTimeout); rightSideUnitsPrompt = PROMPT_SECONDS; rightSideUnitsStr = "s"; } } else { rightSideConst = currentLanguage->n_a; } break; case DISPLAY_MENU_SCREEN_INVERT: leftSide = currentLanguage->display_screen_invert; rightSideConst = settingsIsOptionBitSet(BIT_INVERSE_VIDEO) ? currentLanguage->screen_invert : currentLanguage->screen_normal; break; #if ! defined(PLATFORM_GD77S) case DISPLAY_AUTO_NIGHT: leftSide = currentLanguage->auto_night; rightSideConst = settingsIsOptionBitSet(BIT_AUTO_NIGHT) ? currentLanguage->on : currentLanguage->off; break; #endif case DISPLAY_MENU_CONTACT_DISPLAY_ORDER: leftSide = currentLanguage->priority_order; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", contactOrders[nonVolatileSettings.contactDisplayPriority]); break; case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT: { const char *splitContact[] = { currentLanguage->one_line, currentLanguage->two_lines, currentLanguage->Auto }; leftSide = currentLanguage->contact; rightSideConst = splitContact[nonVolatileSettings.splitContact]; } break; #if ! defined(PLATFORM_MD9600) case DISPLAY_BATTERY_UNIT_IN_HEADER: leftSide = currentLanguage->battery; if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER)) { rightSideUnitsPrompt = PROMPT_VOLTS; rightSideUnitsStr = "V"; } else { rightSideUnitsPrompt = PROMPT_PERCENT; rightSideUnitsStr = "%"; } break; #endif case DISPLAY_EXTENDED_INFOS: { const char *extendedInfos[] = { currentLanguage->off, currentLanguage->ts, currentLanguage->pwr, currentLanguage->both }; leftSide = currentLanguage->info; rightSideConst = extendedInfos[nonVolatileSettings.extendedInfosOnScreen]; } break; #if defined(HAS_SOFT_VOLUME) case DISPLAY_VISUAL_VOLUME: leftSide = currentLanguage->volume; rightSideConst = settingsIsOptionBitSet(BIT_VISUAL_VOLUME) ? currentLanguage->on : currentLanguage->off; break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_ALL_LEDS_ENABLED: leftSide = currentLanguage->leds; rightSideConst = settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) ? currentLanguage->off : currentLanguage->on; break; #endif case DISPLAY_TIMEZONE_VALUE: leftSide = currentLanguage->timeZone; buildTimeZoneBufferText(rightSideVar); break; case DISPLAY_TIME_UTC_OR_LOCAL: leftSide = currentLanguage->time; rightSideConst = (nonVolatileSettings.timezone & 0x80) ? currentLanguage->local : currentLanguage->UTC; break; case DISPLAY_SHOW_DISTANCE: leftSide = currentLanguage->show_distance; rightSideConst = settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) ? currentLanguage->on : currentLanguage->off; break; } // workaround for non standard format of line for colour display snprintf(buf, SCREEN_LINE_BUFFER_SIZE, "%s:%s", leftSide, (rightSideVar[0] ? rightSideVar : (rightSideConst ? rightSideConst : ""))); if (i == 0) { bool wasPlaying = voicePromptsIsPlaying(); if (!isFirstRun && (menuDataGlobal.menuOptionsSetQuickkey == 0)) { voicePromptsInit(); } if (!wasPlaying || (menuDataGlobal.newOptionSelected || (menuDataGlobal.menuOptionsTimeout > 0))) { voicePromptsAppendLanguageString(leftSide); } if ((rightSideVar[0] != 0) || ((rightSideVar[0] == 0) && (rightSideConst == NULL))) { voicePromptsAppendString(rightSideVar); } else { voicePromptsAppendLanguageString(rightSideConst); } if (rightSideUnitsPrompt != PROMPT_SILENCE) { voicePromptsAppendPrompt(rightSideUnitsPrompt); } if (rightSideUnitsStr != NULL) { strncat(rightSideVar, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE); } if (menuDataGlobal.menuOptionsTimeout != -1) { promptsPlayNotAfterTx(); } else { menuDataGlobal.menuOptionsTimeout = 0;// clear flag indicating that a QuickKey has just been set } } // QuickKeys if (menuDataGlobal.menuOptionsTimeout > 0) { menuDisplaySettingOption(leftSide, (rightSideVar[0] ? rightSideVar : rightSideConst)); } else { if (rightSideUnitsStr != NULL) { strncat(buf, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE); } menuDisplayEntry(i, mNum, buf, (strlen(leftSide) + 1), THEME_ITEM_FG_MENU_ITEM, THEME_ITEM_FG_OPTIONS_VALUE, THEME_ITEM_BG); } } } displayRender(); } static void handleEvent(uiEvent_t *ev) { bool isDirty = false; if ((menuDataGlobal.menuOptionsTimeout > 0) && (!BUTTONCHECK_DOWN(ev, BUTTON_SK2))) { if (voicePromptsIsPlaying() == false) { menuDataGlobal.menuOptionsTimeout--; if (menuDataGlobal.menuOptionsTimeout == 0) { applySettings(); menuSystemPopPreviousMenu(); return; } } } if (ev->events & FUNCTION_EVENT) { isDirty = true; if (ev->function == FUNC_REDRAW) { updateScreen(false); return; } else if ((QUICKKEY_TYPE(ev->function) == QUICKKEY_MENU) && (QUICKKEY_ENTRYID(ev->function) < NUM_DISPLAY_MENU_ITEMS)) { menuDataGlobal.currentItemIndex = QUICKKEY_ENTRYID(ev->function); #if ! defined(PLATFORM_GD77S) // Control the brigthness of the current daytime. if ((menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS) || (menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS_NIGHT)) { if (DAYTIME_CURRENT == DAY) { menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS; } else { menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS_NIGHT; } } #endif } if ((QUICKKEY_FUNCTIONID(ev->function) != 0)) { menuDataGlobal.menuOptionsTimeout = 1000; } } if (ev->events & BUTTON_EVENT) { if (repeatVoicePromptOnSK1(ev)) { return; } } if ((ev->events & KEY_EVENT) && (menuDataGlobal.menuOptionsSetQuickkey == 0) && (menuDataGlobal.menuOptionsTimeout == 0)) { if (KEYCHECK_PRESS(ev->keys, KEY_DOWN) && (menuDataGlobal.numItems != 0)) { isDirty = true; menuSystemMenuIncrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS); menuDataGlobal.newOptionSelected = true; menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE; } else if (KEYCHECK_PRESS(ev->keys, KEY_UP)) { isDirty = true; menuSystemMenuDecrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS); menuDataGlobal.newOptionSelected = true; menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE; } else if (KEYCHECK_SHORTUP(ev->keys, KEY_GREEN)) { applySettings(); menuSystemPopAllAndDisplayRootMenu(); return; } else if (KEYCHECK_SHORTUP(ev->keys, KEY_RED)) { menuSystemPopPreviousMenu(); return; } else if (KEYCHECK_SHORTUP_NUMBER(ev->keys) && BUTTONCHECK_DOWN(ev, BUTTON_SK2)) { menuDataGlobal.menuOptionsSetQuickkey = ev->keys.key; isDirty = true; } } if ((ev->events & (KEY_EVENT | FUNCTION_EVENT)) && (menuDataGlobal.menuOptionsSetQuickkey == 0)) { bool displayIsLit = displayIsBacklightLit(); if (KEYCHECK_PRESS(ev->keys, KEY_RIGHT) #if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) || KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_INCREMENT) #endif || (QUICKKEY_FUNCTIONID(ev->function) == FUNC_RIGHT)) { if (menuDataGlobal.menuOptionsTimeout > 0) { menuDataGlobal.menuOptionsTimeout = 1000; } isDirty = true; menuDataGlobal.newOptionSelected = false; switch(menuDataGlobal.currentItemIndex) { case DISPLAY_MENU_BRIGHTNESS: settingsIncrement(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[DAY] > BACKLIGHT_MAX_PERCENTAGE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) BACKLIGHT_MAX_PERCENTAGE); } #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; case DISPLAY_MENU_BRIGHTNESS_OFF: if ((nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[DAY]) && (nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[NIGHT])) { settingsIncrement(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) ((nonVolatileSettings.displayBacklightPercentageOff < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentageOff > BACKLIGHT_MAX_PERCENTAGE) { settingsSet(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) BACKLIGHT_MAX_PERCENTAGE); } checkMinBacklightValue(); if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit)) { gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff); } } break; #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) case DISPLAY_MENU_CONTRAST: if (nonVolatileSettings.displayContrast < CONTRAST_MAX_VALUE) { settingsIncrement(nonVolatileSettings.displayContrast, 1); } displaySetContrast(nonVolatileSettings.displayContrast); break; #endif case DISPLAY_MENU_BACKLIGHT_MODE: #if (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_BUTTONS ) #else if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_NONE) #endif { settingsIncrement(nonVolatileSettings.backlightMode, 1); updateBacklightMode(nonVolatileSettings.backlightMode); } break; case DISPLAY_MENU_TIMEOUT: if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS)) { settingsIncrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP); if (nonVolatileSettings.backLightTimeout > BACKLIGHT_MAX_TIMEOUT) { settingsSet(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_MAX_TIMEOUT); } } break; case DISPLAY_MENU_SCREEN_INVERT: setDisplayInvert(true); break; #if ! defined(PLATFORM_GD77S) case DISPLAY_AUTO_NIGHT: if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) == false) { settingsSetOptionBit(BIT_AUTO_NIGHT, true); } break; case DISPLAY_MENU_BRIGHTNESS_NIGHT: settingsIncrement(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[NIGHT] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[NIGHT] > BACKLIGHT_MAX_PERCENTAGE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) BACKLIGHT_MAX_PERCENTAGE); } #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; #endif case DISPLAY_MENU_CONTACT_DISPLAY_ORDER: if (nonVolatileSettings.contactDisplayPriority < CONTACT_DISPLAY_PRIO_TA_DB_CC) { settingsIncrement(nonVolatileSettings.contactDisplayPriority, 1); } break; case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT: if (nonVolatileSettings.splitContact < SPLIT_CONTACT_AUTO) { settingsIncrement(nonVolatileSettings.splitContact, 1); } break; #if ! defined(PLATFORM_MD9600) case DISPLAY_BATTERY_UNIT_IN_HEADER: if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER) == false) { settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, true); } break; #endif case DISPLAY_EXTENDED_INFOS: if (nonVolatileSettings.extendedInfosOnScreen < INFO_ON_SCREEN_BOTH) { settingsIncrement(nonVolatileSettings.extendedInfosOnScreen, 1); } break; #if defined(HAS_SOFT_VOLUME) case DISPLAY_VISUAL_VOLUME: if (settingsIsOptionBitSet(BIT_VISUAL_VOLUME) == false) { settingsSetOptionBit(BIT_VISUAL_VOLUME, true); } break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_ALL_LEDS_ENABLED: if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED)) { uint8_t state = LedRead(LED_GREEN); settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, false); LedWriteDirect(LED_GREEN, state); } break; #endif case DISPLAY_TIMEZONE_VALUE: { int tz = (nonVolatileSettings.timezone & 0x7F); if (BUTTONCHECK_DOWN(ev, BUTTON_SK2)) { tz++; } else { tz += 4; } if (tz <= ((14 * 4) + SETTINGS_TIMEZONE_UTC)) { settingsSet(nonVolatileSettings.timezone, ((nonVolatileSettings.timezone & ~0x7F) + tz)); } } break; case DISPLAY_TIME_UTC_OR_LOCAL: settingsSet(nonVolatileSettings.timezone, (uint8_t) (nonVolatileSettings.timezone | 0x80)); break; case DISPLAY_SHOW_DISTANCE: if (settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) == false) { settingsSetOptionBit(BIT_DISPLAY_CHANNEL_DISTANCE, true); } break; } } else if (KEYCHECK_PRESS(ev->keys, KEY_LEFT) #if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) || KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_DECREMENT) #endif || (QUICKKEY_FUNCTIONID(ev->function) == FUNC_LEFT)) { if (menuDataGlobal.menuOptionsTimeout > 0) { menuDataGlobal.menuOptionsTimeout = 1000; } isDirty = true; menuDataGlobal.newOptionSelected = false; switch(menuDataGlobal.currentItemIndex) { case DISPLAY_MENU_BRIGHTNESS: settingsDecrement(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] <= BACKLIGHT_PERCENTAGE_STEP) ? 1 : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_MIN_USABLE_VALUE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], BACKLIGHT_MIN_USABLE_VALUE); } checkMinBacklightValue(); #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; case DISPLAY_MENU_BRIGHTNESS_OFF: settingsDecrement(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) ((nonVolatileSettings.displayBacklightPercentageOff <= BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentageOff < 0) { settingsSet(nonVolatileSettings.displayBacklightPercentageOff, 0); } if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit)) { gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff); } break; #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) case DISPLAY_MENU_CONTRAST: if (nonVolatileSettings.displayContrast > CONTRAST_MIN_VALUE) { settingsDecrement(nonVolatileSettings.displayContrast, 1); } displaySetContrast(nonVolatileSettings.displayContrast); break; #endif case DISPLAY_MENU_BACKLIGHT_MODE: if (nonVolatileSettings.backlightMode > BACKLIGHT_MODE_AUTO) { settingsDecrement(nonVolatileSettings.backlightMode, 1); updateBacklightMode(nonVolatileSettings.backlightMode); } break; case DISPLAY_MENU_TIMEOUT: if (((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) && (nonVolatileSettings.backLightTimeout >= BACKLIGHT_TIMEOUT_STEP)) || (((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS)) && (nonVolatileSettings.backLightTimeout >= (BACKLIGHT_TIMEOUT_STEP * 2)))) { settingsDecrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP); } break; case DISPLAY_MENU_SCREEN_INVERT: setDisplayInvert(false); break; #if ! defined(PLATFORM_GD77S) case DISPLAY_AUTO_NIGHT: if (settingsIsOptionBitSet(BIT_AUTO_NIGHT)) { settingsSetOptionBit(BIT_AUTO_NIGHT, false); } break; case DISPLAY_MENU_BRIGHTNESS_NIGHT: settingsDecrement(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[NIGHT] <= BACKLIGHT_PERCENTAGE_STEP) ? 1 : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[NIGHT] < BACKLIGHT_MIN_USABLE_VALUE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], BACKLIGHT_MIN_USABLE_VALUE); } checkMinBacklightValue(); #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; #endif case DISPLAY_MENU_CONTACT_DISPLAY_ORDER: if (nonVolatileSettings.contactDisplayPriority > CONTACT_DISPLAY_PRIO_CC_DB_TA) { settingsDecrement(nonVolatileSettings.contactDisplayPriority, 1); } break; case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT: if (nonVolatileSettings.splitContact > SPLIT_CONTACT_SINGLE_LINE_ONLY) { settingsDecrement(nonVolatileSettings.splitContact, 1); } break; #if ! defined(PLATFORM_MD9600) case DISPLAY_BATTERY_UNIT_IN_HEADER: if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER)) { settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, false); } break; #endif case DISPLAY_EXTENDED_INFOS: if (nonVolatileSettings.extendedInfosOnScreen > INFO_ON_SCREEN_OFF) { settingsDecrement(nonVolatileSettings.extendedInfosOnScreen, 1); } break; #if defined(HAS_SOFT_VOLUME) case DISPLAY_VISUAL_VOLUME: if (settingsIsOptionBitSet(BIT_VISUAL_VOLUME)) { settingsSetOptionBit(BIT_VISUAL_VOLUME, false); } break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_ALL_LEDS_ENABLED: if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) == false) { LedWriteDirect(LED_GREEN, 0); settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, true); } break; #endif case DISPLAY_TIMEZONE_VALUE: { int tz = (nonVolatileSettings.timezone & 0x7F); if (BUTTONCHECK_DOWN(ev, BUTTON_SK2)) { tz--; } else { tz -= 4; } if (tz >= ((-12 * 4) + SETTINGS_TIMEZONE_UTC)) { settingsSet(nonVolatileSettings.timezone, ((nonVolatileSettings.timezone & ~0x7F) + tz)); } } break; case DISPLAY_TIME_UTC_OR_LOCAL: settingsSet(nonVolatileSettings.timezone, (uint8_t) (nonVolatileSettings.timezone & ~0x80)); break; case DISPLAY_SHOW_DISTANCE: if (settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE)) { settingsSetOptionBit(BIT_DISPLAY_CHANNEL_DISTANCE, false); } break; } } else if ((ev->keys.event & KEY_MOD_PRESS) && (menuDataGlobal.menuOptionsTimeout > 0)) { menuDataGlobal.menuOptionsTimeout = 0; resetOriginalSettingsData(); menuSystemPopPreviousMenu(); return; } } if (uiQuickKeysIsStoring(ev)) { uiQuickKeysStore(ev, &menuDisplayOptionsExitCode); isDirty = true; } if (isDirty) { updateScreen(false); } } static void updateBacklightMode(uint8_t mode) { settingsSet(nonVolatileSettings.backlightMode, mode); switch (mode) { case BACKLIGHT_MODE_MANUAL: case BACKLIGHT_MODE_NONE: #if ! (defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) displayEnableBacklight(false, nonVolatileSettings.displayBacklightPercentageOff); // Could be MANUAL previously, but in OFF state, so turn it OFF blindly. #endif break; case BACKLIGHT_MODE_SQUELCH: case BACKLIGHT_MODE_BUTTONS: if (nonVolatileSettings.backLightTimeout < BACKLIGHT_TIMEOUT_STEP) { settingsSet(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP); } case BACKLIGHT_MODE_AUTO: displayLightTrigger(true); break; } } static void setDisplayInvert(bool invert) { if (invert == settingsIsOptionBitSet(BIT_INVERSE_VIDEO)) { return;// Don't update unless the setting is actually changing } settingsSetOptionBit(BIT_INVERSE_VIDEO, invert); // Need to perform a full reset on the display to change back to non-inverted #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displaySetInvertedState(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #else displayInit(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #endif } static void checkMinBacklightValue(void) { if ((nonVolatileSettings.displayBacklightPercentageOff >= nonVolatileSettings.displayBacklightPercentage[DAY]) || (nonVolatileSettings.displayBacklightPercentageOff >= nonVolatileSettings.displayBacklightPercentage[NIGHT])) { int8_t minBCL = SAFE_MIN(nonVolatileSettings.displayBacklightPercentage[DAY], nonVolatileSettings.displayBacklightPercentage[NIGHT]); settingsSet(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) (minBCL ? (minBCL - ((nonVolatileSettings.displayBacklightPercentageOff <= BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)) : 0)); } } static void buildTimeZoneBufferText(char *buffer) { int tz = (nonVolatileSettings.timezone & 0x7F); int hoursPart = abs((tz - SETTINGS_TIMEZONE_UTC) / 4); int minutesPart = 15 * abs(tz % 4);// optimisation . No need to subtract the SETTINGS_TIMEZONE_UTC as we just extra act the modulus 4 part. snprintf(buffer, SCREEN_LINE_BUFFER_SIZE, "%c%2u:%02u", (tz >= SETTINGS_TIMEZONE_UTC) ? '+' : '-', abs(hoursPart), minutesPart); } static void applySettings(void) { // Reset last heard list, otherwise entries won't get updated, accordingly to the new setting value if (nonVolatileSettings.contactDisplayPriority != originalNonVolatileSettings.contactDisplayPriority) { lastHeardInitList(); } // if auto night is enabled, disable override if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) && settingsIsOptionBitSet(BIT_AUTO_NIGHT_OVERRIDE)) { settingsSetOptionBit(BIT_AUTO_NIGHT_OVERRIDE, false); uiDataGlobal.daytimeOverridden = UNDEFINED; } else if ((settingsIsOptionBitSet(BIT_AUTO_NIGHT) == false) && (uiDataGlobal.daytimeOverridden != UNDEFINED)) { settingsSetOptionBit(BIT_AUTO_NIGHT_OVERRIDE, true); settingsSetOptionBit(BIT_AUTO_NIGHT_DAYTIME, (uiDataGlobal.daytimeOverridden == NIGHT)); } #if ! defined(PLATFORM_GD77S) daytimeThemeApply(DAYTIME_CURRENT); daytimeThemeChangeUpdate(true); #endif // All parameters has already been applied settingsSaveIfNeeded(true); resetOriginalSettingsData(); } static void exitCallback(void *data) { if (originalNonVolatileSettings.magicNumber != 0xDEADBEEF) { bool displayIsLit = displayIsBacklightLit(); if (nonVolatileSettings.displayContrast != originalNonVolatileSettings.displayContrast) { settingsSet(nonVolatileSettings.displayContrast, originalNonVolatileSettings.displayContrast); displaySetContrast(nonVolatileSettings.displayContrast); } if (settingsIsOptionBitSet(BIT_INVERSE_VIDEO) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_INVERSE_VIDEO)) { settingsSetOptionBit(BIT_INVERSE_VIDEO, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_INVERSE_VIDEO)); // Need to perform a full reset on the display to change back to non-inverted #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displaySetInvertedState(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #else displayInit(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #endif } settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], originalNonVolatileSettings.displayBacklightPercentage[DAY]); settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], originalNonVolatileSettings.displayBacklightPercentage[NIGHT]); settingsSet(nonVolatileSettings.displayBacklightPercentageOff, originalNonVolatileSettings.displayBacklightPercentageOff); settingsSet(nonVolatileSettings.backLightTimeout, originalNonVolatileSettings.backLightTimeout); if (nonVolatileSettings.backlightMode != originalNonVolatileSettings.backlightMode) { updateBacklightMode(originalNonVolatileSettings.backlightMode); } if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit)) { gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff); } settingsSet(nonVolatileSettings.contactDisplayPriority, originalNonVolatileSettings.contactDisplayPriority); settingsSet(nonVolatileSettings.splitContact, originalNonVolatileSettings.splitContact); if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_BATTERY_VOLTAGE_IN_HEADER)) { settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_BATTERY_VOLTAGE_IN_HEADER)); } settingsSet(nonVolatileSettings.extendedInfosOnScreen, originalNonVolatileSettings.extendedInfosOnScreen); if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_ALL_LEDS_DISABLED)) { uint8_t state = LedRead(LED_GREEN); settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_ALL_LEDS_DISABLED)); LedWriteDirect(LED_GREEN, (settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_ALL_LEDS_DISABLED) ? 0 : state)); } if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_AUTO_NIGHT)) { settingsSetOptionBit(BIT_AUTO_NIGHT, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_AUTO_NIGHT)); } if (settingsIsOptionBitSet(DISPLAY_SHOW_DISTANCE) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, DISPLAY_SHOW_DISTANCE)) { settingsSetOptionBit(DISPLAY_SHOW_DISTANCE, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, DISPLAY_SHOW_DISTANCE)); } settingsSaveIfNeeded(true); resetOriginalSettingsData(); } }
更改後文本
開啟檔案
/* * Copyright (C) 2019-2025 Roger Clark, VK3KYY / G4KYF * Daniel Caujolle-Bert, F1RMB * * * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. Use of this source code or binary releases for commercial purposes is strictly forbidden. This includes, without limitation, * incorporation in a commercial product or incorporation into a product or project which allows commercial use. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #if defined(PLATFORM_MD9600) #include "hardware/ST7567.h" #elif (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) #include "hardware/HX8353E.h" #else #include "hardware/UC1701.h" #endif #include "user_interface/uiGlobals.h" #include "user_interface/menuSystem.h" #include "user_interface/uiLocalisation.h" #include "user_interface/uiUtilities.h" static void updateScreen(bool isFirstRun); static void handleEvent(uiEvent_t *ev); static void updateBacklightMode(uint8_t mode); static void setDisplayInvert(bool invert); static void checkMinBacklightValue(void); static void buildTimeZoneBufferText(char * buffer); static void applySettings(void); static void exitCallback(void *data); static menuStatus_t menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS; static const int BACKLIGHT_MAX_TIMEOUT = 30; #if defined(PLATFORM_RD5R) static const int CONTRAST_MAX_VALUE = 10;// Maximum value which still seems to be readable static const int CONTRAST_MIN_VALUE = 0;// Minimum value which still seems to be readable #elif ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) static const int CONTRAST_MAX_VALUE = 30;// Maximum value which still seems to be readable static const int CONTRAST_MIN_VALUE = 5;// Minimum value which still seems to be readable #endif static const int BACKLIGHT_TIMEOUT_STEP = 5; static const int BACKLIGHT_MAX_PERCENTAGE = 100; static const int BACKLIGHT_PERCENTAGE_STEP = 10; static const int BACKLIGHT_PERCENTAGE_STEP_SMALL = 1; static const char *contactOrders[] = { "Ct/DB/TA", "DB/Ct/TA", "TA/Ct/DB", "TA/DB/Ct" }; enum { #if defined(HAS_COLOURS) DISPLAY_TYPE_STYLE, #endif DISPLAY_MENU_BRIGHTNESS, #if ! defined(PLATFORM_GD77S) DISPLAY_MENU_BRIGHTNESS_NIGHT, #endif DISPLAY_MENU_BRIGHTNESS_OFF, #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) DISPLAY_MENU_CONTRAST, #endif DISPLAY_MENU_BACKLIGHT_MODE, DISPLAY_MENU_TIMEOUT, DISPLAY_MENU_SCREEN_INVERT, #if ! defined(PLATFORM_GD77S) DISPLAY_AUTO_NIGHT, #endif DISPLAY_MENU_CONTACT_DISPLAY_ORDER, DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT, #if defined(HAS_COLOURS) || defined(PLATFORM_MD9600) DISPLAY_TIME_IN_HEADER, #endif #if ! defined(PLATFORM_MD9600) DISPLAY_BATTERY_UNIT_IN_HEADER, #endif DISPLAY_EXTENDED_INFOS, #if defined(HAS_SOFT_VOLUME) DISPLAY_VISUAL_VOLUME, #endif #if ! defined(PLATFORM_MD9600) DISPLAY_ALL_LEDS_ENABLED, #endif DISPLAY_TIMEZONE_VALUE, DISPLAY_TIME_UTC_OR_LOCAL, DISPLAY_SHOW_DISTANCE, DISPLAY_DMR_LAST_TALKER_ON_SCREEN, NUM_DISPLAY_MENU_ITEMS }; menuStatus_t menuDisplayOptions(uiEvent_t *ev, bool isFirstRun) { if (isFirstRun) { menuDataGlobal.menuOptionsSetQuickkey = 0; menuDataGlobal.menuOptionsTimeout = 0; menuDataGlobal.newOptionSelected = true; menuDataGlobal.numItems = NUM_DISPLAY_MENU_ITEMS; if (originalNonVolatileSettings.magicNumber == 0xDEADBEEF) { // Store original settings, used on cancel event. memcpy(&originalNonVolatileSettings, &nonVolatileSettings, sizeof(settingsStruct_t)); } voicePromptsInit(); voicePromptsAppendPrompt(PROMPT_SILENCE); voicePromptsAppendLanguageString(currentLanguage->display_options); voicePromptsAppendLanguageString(currentLanguage->menu); voicePromptsAppendPrompt(PROMPT_SILENCE); menuSystemRegisterExitCallback(exitCallback, NULL); updateScreen(true); return (MENU_STATUS_LIST_TYPE | MENU_STATUS_SUCCESS); } else { menuDisplayOptionsExitCode = MENU_STATUS_SUCCESS; if (ev->hasEvent || (menuDataGlobal.menuOptionsTimeout > 0)) { handleEvent(ev); } } return menuDisplayOptionsExitCode; } static void updateScreen(bool isFirstRun) { int mNum = 0; char buf[SCREEN_LINE_BUFFER_SIZE]; const char *leftSide = NULL;// initialize to please the compiler const char *rightSideConst = NULL;// initialize to please the compiler char rightSideVar[SCREEN_LINE_BUFFER_SIZE]; voicePrompt_t rightSideUnitsPrompt; const char *rightSideUnitsStr; displayClearBuf(); bool settingOption = uiQuickKeysShowChoices(buf, SCREEN_LINE_BUFFER_SIZE, currentLanguage->display_options); for (int i = MENU_START_ITERATION_VALUE; i <= MENU_END_ITERATION_VALUE; i++) { if ((settingOption == false) || (i == 0)) { mNum = menuGetMenuOffset(NUM_DISPLAY_MENU_ITEMS, i); if (mNum == MENU_OFFSET_BEFORE_FIRST_ENTRY) { continue; } else if (mNum == MENU_OFFSET_AFTER_LAST_ENTRY) { break; } buf[0] = 0; leftSide = NULL; rightSideConst = NULL; rightSideVar[0] = 0; rightSideUnitsPrompt = PROMPT_SILENCE;// use PROMPT_SILENCE as flag that the unit has not been set rightSideUnitsStr = NULL; switch(mNum) { #if defined(HAS_COLOURS) case DISPLAY_TYPE_STYLE: leftSide = currentLanguage->text_size; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", settingsIsOptionBitSet(BIT_UI_USES_DOUBLE_HEIGHT) ? 2 : 1); break; #endif case DISPLAY_MENU_BRIGHTNESS: leftSide = currentLanguage->brightness; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[DAY]); break; #if ! defined(PLATFORM_GD77S) case DISPLAY_MENU_BRIGHTNESS_NIGHT: leftSide = currentLanguage->brightness_night; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentage[NIGHT]); break; #endif case DISPLAY_MENU_BRIGHTNESS_OFF: leftSide = currentLanguage->brightness_off; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d%%", nonVolatileSettings.displayBacklightPercentageOff); break; #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) case DISPLAY_MENU_CONTRAST: leftSide = currentLanguage->contrast; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.displayContrast); break; #endif case DISPLAY_MENU_BACKLIGHT_MODE: { const char *backlightModes[] = { currentLanguage->Auto, currentLanguage->squelch, currentLanguage->manual, currentLanguage->buttons, currentLanguage->none }; leftSide = currentLanguage->mode; rightSideConst = backlightModes[nonVolatileSettings.backlightMode]; } break; case DISPLAY_MENU_TIMEOUT: leftSide = currentLanguage->backlight_timeout; if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS)) { if (nonVolatileSettings.backLightTimeout == 0) { rightSideConst = currentLanguage->no; } else { snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%d", nonVolatileSettings.backLightTimeout); rightSideUnitsPrompt = PROMPT_SECONDS; rightSideUnitsStr = "s"; } } else { rightSideConst = currentLanguage->n_a; } break; case DISPLAY_MENU_SCREEN_INVERT: leftSide = currentLanguage->display_screen_invert; rightSideConst = settingsIsOptionBitSet(BIT_INVERSE_VIDEO) ? currentLanguage->screen_invert : currentLanguage->screen_normal; break; #if ! defined(PLATFORM_GD77S) case DISPLAY_AUTO_NIGHT: leftSide = currentLanguage->auto_night; rightSideConst = settingsIsOptionBitSet(BIT_AUTO_NIGHT) ? currentLanguage->on : currentLanguage->off; break; #endif case DISPLAY_MENU_CONTACT_DISPLAY_ORDER: leftSide = currentLanguage->priority_order; snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", contactOrders[nonVolatileSettings.contactDisplayPriority]); break; case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT: { const char *splitContact[] = { currentLanguage->one_line, currentLanguage->two_lines, currentLanguage->Auto }; leftSide = currentLanguage->contact; rightSideConst = splitContact[nonVolatileSettings.splitContact]; } break; #if defined(HAS_COLOURS) || defined(PLATFORM_MD9600) case DISPLAY_TIME_IN_HEADER: leftSide = currentLanguage->time; rightSideConst = settingsIsOptionBitSet(BIT_DISPLAY_TIME_IN_HEADER) ? currentLanguage->on : currentLanguage->off; break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_BATTERY_UNIT_IN_HEADER: leftSide = currentLanguage->battery; if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER)) { rightSideUnitsPrompt = PROMPT_VOLTS; rightSideUnitsStr = "V"; } else { rightSideUnitsPrompt = PROMPT_PERCENT; rightSideUnitsStr = "%"; } break; #endif case DISPLAY_EXTENDED_INFOS: { const char *extendedInfos[] = { currentLanguage->off, currentLanguage->ts, currentLanguage->pwr, currentLanguage->both }; leftSide = currentLanguage->info; rightSideConst = extendedInfos[nonVolatileSettings.extendedInfosOnScreen]; } break; #if defined(HAS_SOFT_VOLUME) case DISPLAY_VISUAL_VOLUME: leftSide = currentLanguage->volume; rightSideConst = settingsIsOptionBitSet(BIT_VISUAL_VOLUME) ? currentLanguage->on : currentLanguage->off; break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_ALL_LEDS_ENABLED: leftSide = currentLanguage->leds; rightSideConst = settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) ? currentLanguage->off : currentLanguage->on; break; #endif case DISPLAY_TIMEZONE_VALUE: leftSide = currentLanguage->timeZone; buildTimeZoneBufferText(rightSideVar); break; case DISPLAY_TIME_UTC_OR_LOCAL: leftSide = currentLanguage->UTC; rightSideConst = (nonVolatileSettings.timezone & 0x80) ? currentLanguage->no : currentLanguage->yes; break; case DISPLAY_SHOW_DISTANCE: leftSide = currentLanguage->show_distance; rightSideConst = settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) ? currentLanguage->on : currentLanguage->off; break; case DISPLAY_DMR_LAST_TALKER_ON_SCREEN: leftSide = currentLanguage->last_talker; if (nonVolatileSettings.lastTalkerOnScreenTimer > 0) { snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%u", nonVolatileSettings.lastTalkerOnScreenTimer); rightSideUnitsPrompt = PROMPT_SECONDS; rightSideUnitsStr = "s"; } else { rightSideConst = currentLanguage->off; } break; } // workaround for non standard format of line for colour display snprintf(buf, SCREEN_LINE_BUFFER_SIZE, "%s:%s", leftSide, (rightSideVar[0] ? rightSideVar : (rightSideConst ? rightSideConst : ""))); if (i == 0) { bool wasPlaying = voicePromptsIsPlaying(); if (!isFirstRun && (menuDataGlobal.menuOptionsSetQuickkey == 0)) { voicePromptsInit(); } if (!wasPlaying || (menuDataGlobal.newOptionSelected || (menuDataGlobal.menuOptionsTimeout > 0))) { voicePromptsAppendLanguageString(leftSide); } if ((rightSideVar[0] != 0) || ((rightSideVar[0] == 0) && (rightSideConst == NULL))) { voicePromptsAppendString(rightSideVar); } else { voicePromptsAppendLanguageString(rightSideConst); } if (rightSideUnitsPrompt != PROMPT_SILENCE) { voicePromptsAppendPrompt(rightSideUnitsPrompt); } if (rightSideUnitsStr != NULL) { strncat(rightSideVar, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE); } if (menuDataGlobal.menuOptionsTimeout != -1) { promptsPlayNotAfterTx(); } else { menuDataGlobal.menuOptionsTimeout = 0;// clear flag indicating that a QuickKey has just been set } } // QuickKeys if (menuDataGlobal.menuOptionsTimeout > 0) { menuDisplaySettingOption(leftSide, (rightSideVar[0] ? rightSideVar : rightSideConst)); } else { if (rightSideUnitsStr != NULL) { strncat(buf, rightSideUnitsStr, SCREEN_LINE_BUFFER_SIZE); } menuDisplayEntry(i, mNum, buf, (strlen(leftSide) + 1), THEME_ITEM_FG_MENU_ITEM, THEME_ITEM_FG_OPTIONS_VALUE, THEME_ITEM_BG); } } } displayRender(); } static void handleEvent(uiEvent_t *ev) { bool isDirty = false; if ((menuDataGlobal.menuOptionsTimeout > 0) && (!BUTTONCHECK_DOWN(ev, BUTTON_SK2))) { if (voicePromptsIsPlaying() == false) { menuDataGlobal.menuOptionsTimeout--; if (menuDataGlobal.menuOptionsTimeout == 0) { applySettings(); menuSystemPopPreviousMenu(); return; } } } if (ev->events & FUNCTION_EVENT) { isDirty = true; if (ev->function == FUNC_REDRAW) { updateScreen(false); return; } else if ((QUICKKEY_TYPE(ev->function) == QUICKKEY_MENU) && (QUICKKEY_ENTRYID(ev->function) < NUM_DISPLAY_MENU_ITEMS)) { menuDataGlobal.currentItemIndex = QUICKKEY_ENTRYID(ev->function); #if ! defined(PLATFORM_GD77S) // Control the brightness of the current daytime. if ((menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS) || (menuDataGlobal.currentItemIndex == DISPLAY_MENU_BRIGHTNESS_NIGHT)) { if (DAYTIME_CURRENT == DAY) { menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS; } else { menuDataGlobal.currentItemIndex = DISPLAY_MENU_BRIGHTNESS_NIGHT; } } #endif } if ((QUICKKEY_FUNCTIONID(ev->function) != 0)) { menuDataGlobal.menuOptionsTimeout = 1000; } } if (ev->events & BUTTON_EVENT) { if (repeatVoicePromptOnSK1(ev)) { return; } } if ((ev->events & KEY_EVENT) && (menuDataGlobal.menuOptionsSetQuickkey == 0) && (menuDataGlobal.menuOptionsTimeout == 0)) { if (KEYCHECK_PRESS(ev->keys, KEY_DOWN) && (menuDataGlobal.numItems != 0)) { isDirty = true; menuSystemMenuIncrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS); menuDataGlobal.newOptionSelected = true; menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE; } else if (KEYCHECK_PRESS(ev->keys, KEY_UP)) { isDirty = true; menuSystemMenuDecrement(&menuDataGlobal.currentItemIndex, NUM_DISPLAY_MENU_ITEMS); menuDataGlobal.newOptionSelected = true; menuDisplayOptionsExitCode |= MENU_STATUS_LIST_TYPE; } else if (KEYCHECK_SHORTUP(ev->keys, KEY_GREEN)) { applySettings(); menuSystemPopAllAndDisplayRootMenu(); return; } else if (KEYCHECK_SHORTUP(ev->keys, KEY_RED)) { menuSystemPopPreviousMenu(); return; } else if (KEYCHECK_SHORTUP_NUMBER(ev->keys) && BUTTONCHECK_DOWN(ev, BUTTON_SK2)) { menuDataGlobal.menuOptionsSetQuickkey = ev->keys.key; isDirty = true; } } if ((ev->events & (KEY_EVENT | FUNCTION_EVENT)) && (menuDataGlobal.menuOptionsSetQuickkey == 0)) { bool displayIsLit = displayIsBacklightLit(); if (KEYCHECK_PRESS(ev->keys, KEY_RIGHT) #if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) || KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_INCREMENT) #endif || (QUICKKEY_FUNCTIONID(ev->function) == FUNC_RIGHT)) { if (menuDataGlobal.menuOptionsTimeout > 0) { menuDataGlobal.menuOptionsTimeout = 1000; } isDirty = true; menuDataGlobal.newOptionSelected = false; switch(menuDataGlobal.currentItemIndex) { #if defined(HAS_COLOURS) case DISPLAY_TYPE_STYLE: if (settingsIsOptionBitSet(BIT_UI_USES_DOUBLE_HEIGHT) == false) { settingsSetOptionBit(BIT_UI_USES_DOUBLE_HEIGHT, true); } break; #endif case DISPLAY_MENU_BRIGHTNESS: settingsIncrement(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[DAY] > BACKLIGHT_MAX_PERCENTAGE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) BACKLIGHT_MAX_PERCENTAGE); } #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; case DISPLAY_MENU_BRIGHTNESS_OFF: if ((nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[DAY]) && (nonVolatileSettings.displayBacklightPercentageOff < nonVolatileSettings.displayBacklightPercentage[NIGHT])) { settingsIncrement(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) ((nonVolatileSettings.displayBacklightPercentageOff < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentageOff > BACKLIGHT_MAX_PERCENTAGE) { settingsSet(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) BACKLIGHT_MAX_PERCENTAGE); } checkMinBacklightValue(); if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit)) { gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff); } } break; #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) case DISPLAY_MENU_CONTRAST: if (nonVolatileSettings.displayContrast < CONTRAST_MAX_VALUE) { settingsIncrement(nonVolatileSettings.displayContrast, 1); } displaySetContrast(nonVolatileSettings.displayContrast); break; #endif case DISPLAY_MENU_BACKLIGHT_MODE: #if (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_BUTTONS ) #else if (nonVolatileSettings.backlightMode < BACKLIGHT_MODE_NONE) #endif { settingsIncrement(nonVolatileSettings.backlightMode, 1); updateBacklightMode(nonVolatileSettings.backlightMode); } break; case DISPLAY_MENU_TIMEOUT: if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS)) { settingsIncrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP); if (nonVolatileSettings.backLightTimeout > BACKLIGHT_MAX_TIMEOUT) { settingsSet(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_MAX_TIMEOUT); } } break; case DISPLAY_MENU_SCREEN_INVERT: setDisplayInvert(true); break; #if ! defined(PLATFORM_GD77S) case DISPLAY_AUTO_NIGHT: if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) == false) { settingsSetOptionBit(BIT_AUTO_NIGHT, true); } break; case DISPLAY_MENU_BRIGHTNESS_NIGHT: settingsIncrement(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[NIGHT] < BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[NIGHT] > BACKLIGHT_MAX_PERCENTAGE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) BACKLIGHT_MAX_PERCENTAGE); } #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; #endif case DISPLAY_MENU_CONTACT_DISPLAY_ORDER: if (nonVolatileSettings.contactDisplayPriority < CONTACT_DISPLAY_PRIO_TA_DB_CC) { settingsIncrement(nonVolatileSettings.contactDisplayPriority, 1); } break; case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT: if (nonVolatileSettings.splitContact < SPLIT_CONTACT_AUTO) { settingsIncrement(nonVolatileSettings.splitContact, 1); } break; #if defined(HAS_COLOURS) || defined(PLATFORM_MD9600) case DISPLAY_TIME_IN_HEADER: if (settingsIsOptionBitSet(BIT_DISPLAY_TIME_IN_HEADER) == false) { settingsSetOptionBit(BIT_DISPLAY_TIME_IN_HEADER, true); } break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_BATTERY_UNIT_IN_HEADER: if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER) == false) { settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, true); } break; #endif case DISPLAY_EXTENDED_INFOS: if (nonVolatileSettings.extendedInfosOnScreen < INFO_ON_SCREEN_BOTH) { settingsIncrement(nonVolatileSettings.extendedInfosOnScreen, 1); } break; #if defined(HAS_SOFT_VOLUME) case DISPLAY_VISUAL_VOLUME: if (settingsIsOptionBitSet(BIT_VISUAL_VOLUME) == false) { settingsSetOptionBit(BIT_VISUAL_VOLUME, true); } break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_ALL_LEDS_ENABLED: if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED)) { uint8_t state = LedRead(LED_GREEN); settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, false); LedWriteDirect(LED_GREEN, state); } break; #endif case DISPLAY_TIMEZONE_VALUE: { int tz = (nonVolatileSettings.timezone & 0x7F); if (BUTTONCHECK_DOWN(ev, BUTTON_SK2)) { tz++; } else { tz += 4; } if (tz <= ((14 * 4) + SETTINGS_TIMEZONE_UTC)) { settingsSet(nonVolatileSettings.timezone, ((nonVolatileSettings.timezone & ~0x7F) + tz)); } } break; case DISPLAY_TIME_UTC_OR_LOCAL: settingsSet(nonVolatileSettings.timezone, (uint8_t) (nonVolatileSettings.timezone & ~0x80)); break; case DISPLAY_SHOW_DISTANCE: if (settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE) == false) { settingsSetOptionBit(BIT_DISPLAY_CHANNEL_DISTANCE, true); } break; case DISPLAY_DMR_LAST_TALKER_ON_SCREEN: if (nonVolatileSettings.lastTalkerOnScreenTimer < 30U) { settingsIncrement(nonVolatileSettings.lastTalkerOnScreenTimer, 1U); } break; } } else if (KEYCHECK_PRESS(ev->keys, KEY_LEFT) #if defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) || KEYCHECK_SHORTUP(ev->keys, KEY_ROTARY_DECREMENT) #endif || (QUICKKEY_FUNCTIONID(ev->function) == FUNC_LEFT)) { if (menuDataGlobal.menuOptionsTimeout > 0) { menuDataGlobal.menuOptionsTimeout = 1000; } isDirty = true; menuDataGlobal.newOptionSelected = false; switch(menuDataGlobal.currentItemIndex) { #if defined(HAS_COLOURS) case DISPLAY_TYPE_STYLE: if (settingsIsOptionBitSet(BIT_UI_USES_DOUBLE_HEIGHT)) { settingsSetOptionBit(BIT_UI_USES_DOUBLE_HEIGHT, false); } break; #endif case DISPLAY_MENU_BRIGHTNESS: settingsDecrement(nonVolatileSettings.displayBacklightPercentage[DAY], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[DAY] <= BACKLIGHT_PERCENTAGE_STEP) ? 1 : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[DAY] < BACKLIGHT_MIN_USABLE_VALUE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], BACKLIGHT_MIN_USABLE_VALUE); } checkMinBacklightValue(); #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; case DISPLAY_MENU_BRIGHTNESS_OFF: settingsDecrement(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) ((nonVolatileSettings.displayBacklightPercentageOff <= BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentageOff < 0) { settingsSet(nonVolatileSettings.displayBacklightPercentageOff, 0); } if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit)) { gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff); } break; #if ! (defined(PLATFORM_MDUV380) || defined(PLATFORM_MD380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) case DISPLAY_MENU_CONTRAST: if (nonVolatileSettings.displayContrast > CONTRAST_MIN_VALUE) { settingsDecrement(nonVolatileSettings.displayContrast, 1); } displaySetContrast(nonVolatileSettings.displayContrast); break; #endif case DISPLAY_MENU_BACKLIGHT_MODE: if (nonVolatileSettings.backlightMode > BACKLIGHT_MODE_AUTO) { settingsDecrement(nonVolatileSettings.backlightMode, 1); updateBacklightMode(nonVolatileSettings.backlightMode); } break; case DISPLAY_MENU_TIMEOUT: if (((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_AUTO) && (nonVolatileSettings.backLightTimeout >= BACKLIGHT_TIMEOUT_STEP)) || (((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_SQUELCH) || (nonVolatileSettings.backlightMode == BACKLIGHT_MODE_BUTTONS)) && (nonVolatileSettings.backLightTimeout >= (BACKLIGHT_TIMEOUT_STEP * 2)))) { settingsDecrement(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP); } break; case DISPLAY_MENU_SCREEN_INVERT: setDisplayInvert(false); break; #if ! defined(PLATFORM_GD77S) case DISPLAY_AUTO_NIGHT: if (settingsIsOptionBitSet(BIT_AUTO_NIGHT)) { settingsSetOptionBit(BIT_AUTO_NIGHT, false); } break; case DISPLAY_MENU_BRIGHTNESS_NIGHT: settingsDecrement(nonVolatileSettings.displayBacklightPercentage[NIGHT], (int8_t) ((nonVolatileSettings.displayBacklightPercentage[NIGHT] <= BACKLIGHT_PERCENTAGE_STEP) ? 1 : BACKLIGHT_PERCENTAGE_STEP)); if (nonVolatileSettings.displayBacklightPercentage[NIGHT] < BACKLIGHT_MIN_USABLE_VALUE) { settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], BACKLIGHT_MIN_USABLE_VALUE); } checkMinBacklightValue(); #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displayLightTrigger(true); #endif break; #endif case DISPLAY_MENU_CONTACT_DISPLAY_ORDER: if (nonVolatileSettings.contactDisplayPriority > CONTACT_DISPLAY_PRIO_CC_DB_TA) { settingsDecrement(nonVolatileSettings.contactDisplayPriority, 1); } break; case DISPLAY_MENU_CONTACT_DISPLAY_SPLIT_CONTACT: if (nonVolatileSettings.splitContact > SPLIT_CONTACT_SINGLE_LINE_ONLY) { settingsDecrement(nonVolatileSettings.splitContact, 1); } break; #if defined(HAS_COLOURS) || defined(PLATFORM_MD9600) case DISPLAY_TIME_IN_HEADER: if (settingsIsOptionBitSet(BIT_DISPLAY_TIME_IN_HEADER)) { settingsSetOptionBit(BIT_DISPLAY_TIME_IN_HEADER, false); } break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_BATTERY_UNIT_IN_HEADER: if (settingsIsOptionBitSet(BIT_BATTERY_VOLTAGE_IN_HEADER)) { settingsSetOptionBit(BIT_BATTERY_VOLTAGE_IN_HEADER, false); } break; #endif case DISPLAY_EXTENDED_INFOS: if (nonVolatileSettings.extendedInfosOnScreen > INFO_ON_SCREEN_OFF) { settingsDecrement(nonVolatileSettings.extendedInfosOnScreen, 1); } break; #if defined(HAS_SOFT_VOLUME) case DISPLAY_VISUAL_VOLUME: if (settingsIsOptionBitSet(BIT_VISUAL_VOLUME)) { settingsSetOptionBit(BIT_VISUAL_VOLUME, false); } break; #endif #if ! defined(PLATFORM_MD9600) case DISPLAY_ALL_LEDS_ENABLED: if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) == false) { LedWriteDirect(LED_GREEN, 0); settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, true); } break; #endif case DISPLAY_TIMEZONE_VALUE: { int tz = (nonVolatileSettings.timezone & 0x7F); if (BUTTONCHECK_DOWN(ev, BUTTON_SK2)) { tz--; } else { tz -= 4; } if (tz >= ((-12 * 4) + SETTINGS_TIMEZONE_UTC)) { settingsSet(nonVolatileSettings.timezone, ((nonVolatileSettings.timezone & ~0x7F) + tz)); } } break; case DISPLAY_TIME_UTC_OR_LOCAL: settingsSet(nonVolatileSettings.timezone, (uint8_t) (nonVolatileSettings.timezone | 0x80)); break; case DISPLAY_SHOW_DISTANCE: if (settingsIsOptionBitSet(BIT_DISPLAY_CHANNEL_DISTANCE)) { settingsSetOptionBit(BIT_DISPLAY_CHANNEL_DISTANCE, false); } break; case DISPLAY_DMR_LAST_TALKER_ON_SCREEN: if (nonVolatileSettings.lastTalkerOnScreenTimer > 0U) { settingsDecrement(nonVolatileSettings.lastTalkerOnScreenTimer, 1U); } break; } } else if ((ev->keys.event & KEY_MOD_PRESS) && (menuDataGlobal.menuOptionsTimeout > 0)) { menuDataGlobal.menuOptionsTimeout = 0; resetOriginalSettingsData(); menuSystemPopPreviousMenu(); return; } } if (uiQuickKeysIsStoring(ev)) { uiQuickKeysStore(ev, &menuDisplayOptionsExitCode); isDirty = true; } if (isDirty) { updateScreen(false); } } static void updateBacklightMode(uint8_t mode) { settingsSet(nonVolatileSettings.backlightMode, mode); switch (mode) { case BACKLIGHT_MODE_MANUAL: case BACKLIGHT_MODE_NONE: #if ! (defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017)) displayEnableBacklight(false, nonVolatileSettings.displayBacklightPercentageOff); // Could be MANUAL previously, but in OFF state, so turn it OFF blindly. #endif break; case BACKLIGHT_MODE_SQUELCH: case BACKLIGHT_MODE_BUTTONS: if (nonVolatileSettings.backLightTimeout < BACKLIGHT_TIMEOUT_STEP) { settingsSet(nonVolatileSettings.backLightTimeout, (uint8_t) BACKLIGHT_TIMEOUT_STEP); } case BACKLIGHT_MODE_AUTO: displayLightTrigger(true); break; } } static void setDisplayInvert(bool invert) { if (invert == settingsIsOptionBitSet(BIT_INVERSE_VIDEO)) { return;// Don't update unless the setting is actually changing } settingsSetOptionBit(BIT_INVERSE_VIDEO, invert); // Need to perform a full reset on the display to change back to non-inverted #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displaySetInvertedState(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #else displayInit(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #endif } static void checkMinBacklightValue(void) { if ((nonVolatileSettings.displayBacklightPercentageOff >= nonVolatileSettings.displayBacklightPercentage[DAY]) || (nonVolatileSettings.displayBacklightPercentageOff >= nonVolatileSettings.displayBacklightPercentage[NIGHT])) { int8_t minBCL = SAFE_MIN(nonVolatileSettings.displayBacklightPercentage[DAY], nonVolatileSettings.displayBacklightPercentage[NIGHT]); settingsSet(nonVolatileSettings.displayBacklightPercentageOff, (int8_t) (minBCL ? (minBCL - ((nonVolatileSettings.displayBacklightPercentageOff <= BACKLIGHT_PERCENTAGE_STEP) ? BACKLIGHT_PERCENTAGE_STEP_SMALL : BACKLIGHT_PERCENTAGE_STEP)) : 0)); } } static void buildTimeZoneBufferText(char *buffer) { int tz = (nonVolatileSettings.timezone & 0x7F); int hoursPart = abs((tz - SETTINGS_TIMEZONE_UTC) / 4); int minutesPart = 15 * abs(tz % 4);// optimisation . No need to subtract the SETTINGS_TIMEZONE_UTC as we just extra act the modulus 4 part. snprintf(buffer, SCREEN_LINE_BUFFER_SIZE, "%c%2u:%02u", (tz >= SETTINGS_TIMEZONE_UTC) ? '+' : '-', abs(hoursPart), minutesPart); } static void applySettings(void) { // Reset last heard list, otherwise entries won't get updated, accordingly to the new setting value if (nonVolatileSettings.contactDisplayPriority != originalNonVolatileSettings.contactDisplayPriority) { lastHeardInitList(); } // if auto night is enabled, disable override if (settingsIsOptionBitSet(BIT_AUTO_NIGHT) && settingsIsOptionBitSet(BIT_AUTO_NIGHT_OVERRIDE)) { settingsSetOptionBit(BIT_AUTO_NIGHT_OVERRIDE, false); uiDataGlobal.daytimeOverridden = UNDEFINED; } else if ((settingsIsOptionBitSet(BIT_AUTO_NIGHT) == false) && (uiDataGlobal.daytimeOverridden != UNDEFINED)) { settingsSetOptionBit(BIT_AUTO_NIGHT_OVERRIDE, true); settingsSetOptionBit(BIT_AUTO_NIGHT_DAYTIME, (uiDataGlobal.daytimeOverridden == NIGHT)); } if (nonVolatileSettings.lastTalkerOnScreenTimer != originalNonVolatileSettings.lastTalkerOnScreenTimer) { if (nonVolatileSettings.lastTalkerOnScreenTimer == 0) { ticksTimerReset(&uiDataGlobal.DMRLastTalkerOnScreen.timer); } else { ticksTimerStart(&uiDataGlobal.DMRLastTalkerOnScreen.timer, (nonVolatileSettings.lastTalkerOnScreenTimer * 1000U)); } uiDataGlobal.DMRLastTalkerOnScreen.visible = false; } #if ! defined(PLATFORM_GD77S) daytimeThemeApply(DAYTIME_CURRENT); daytimeThemeChangeUpdate(true); #endif // All parameters has already been applied settingsSaveIfNeeded(true); resetOriginalSettingsData(); } static void exitCallback(void *data) { if (originalNonVolatileSettings.magicNumber != 0xDEADBEEF) { bool displayIsLit = displayIsBacklightLit(); if (nonVolatileSettings.displayContrast != originalNonVolatileSettings.displayContrast) { settingsSet(nonVolatileSettings.displayContrast, originalNonVolatileSettings.displayContrast); displaySetContrast(nonVolatileSettings.displayContrast); } if (settingsIsOptionBitSet(BIT_INVERSE_VIDEO) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_INVERSE_VIDEO)) { settingsSetOptionBit(BIT_INVERSE_VIDEO, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_INVERSE_VIDEO)); // Need to perform a full reset on the display to change back to non-inverted #if defined(PLATFORM_MD380) || defined(PLATFORM_MDUV380) || defined(PLATFORM_RT84_DM1701) || defined(PLATFORM_MD2017) displaySetInvertedState(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #else displayInit(settingsIsOptionBitSet(BIT_INVERSE_VIDEO)); #endif } settingsSet(nonVolatileSettings.displayBacklightPercentage[DAY], originalNonVolatileSettings.displayBacklightPercentage[DAY]); settingsSet(nonVolatileSettings.displayBacklightPercentage[NIGHT], originalNonVolatileSettings.displayBacklightPercentage[NIGHT]); settingsSet(nonVolatileSettings.displayBacklightPercentageOff, originalNonVolatileSettings.displayBacklightPercentageOff); settingsSet(nonVolatileSettings.backLightTimeout, originalNonVolatileSettings.backLightTimeout); if (nonVolatileSettings.backlightMode != originalNonVolatileSettings.backlightMode) { updateBacklightMode(originalNonVolatileSettings.backlightMode); } if ((nonVolatileSettings.backlightMode == BACKLIGHT_MODE_MANUAL) && (!displayIsLit)) { gpioSetDisplayBacklightIntensityPercentage(nonVolatileSettings.displayBacklightPercentageOff); } settingsSet(nonVolatileSettings.contactDisplayPriority, originalNonVolatileSettings.contactDisplayPriority); settingsSet(nonVolatileSettings.splitContact, originalNonVolatileSettings.splitContact); settingsSet(nonVolatileSettings.extendedInfosOnScreen, originalNonVolatileSettings.extendedInfosOnScreen); settingsSet(nonVolatileSettings.lastTalkerOnScreenTimer, originalNonVolatileSettings.lastTalkerOnScreenTimer); if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_ALL_LEDS_DISABLED)) { uint8_t state = LedRead(LED_GREEN); settingsSetOptionBit(BIT_ALL_LEDS_DISABLED, settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_ALL_LEDS_DISABLED)); LedWriteDirect(LED_GREEN, (settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, BIT_ALL_LEDS_DISABLED) ? 0 : state)); } // Restore settings bits, if changed. bitfieldOptions_t settingsBits[] = { #if defined(HAS_COLOURS) || defined(PLATFORM_MD9600) BIT_DISPLAY_TIME_IN_HEADER, #endif #if ! defined(PLATFORM_MD9600) BIT_BATTERY_VOLTAGE_IN_HEADER, #endif #if defined(HAS_SOFT_VOLUME) BIT_VISUAL_VOLUME, #endif #if defined(HAS_COLOURS) BIT_UI_USES_DOUBLE_HEIGHT, #endif BIT_AUTO_NIGHT, BIT_DISPLAY_CHANNEL_DISTANCE, }; for (size_t i = 0U; i < ARRAY_SIZE(settingsBits); i++) { if (settingsIsOptionBitSet(settingsBits[i]) != settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, settingsBits[i])) { settingsSetOptionBit(settingsBits[i], settingsIsOptionBitSetFromSettings(&originalNonVolatileSettings, settingsBits[i])); } } #if defined(PLATFORM_RD5R) settingsSetDirty(); #endif settingsSaveIfNeeded(true); resetOriginalSettingsData(); } }
尋找差異