1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-26 09:45:33 +03:00

Fix handling of readonly items, cmsMenuChange() and formatting

This commit is contained in:
Alberto García Hierro 2019-04-26 15:31:31 +01:00
parent 09fb7c5834
commit eb08d79fd9
2 changed files with 306 additions and 294 deletions

View file

@ -56,6 +56,7 @@
#include "config/parameter_group_ids.h" #include "config/parameter_group_ids.h"
// For 'ARM' related // For 'ARM' related
#include "fc/fc_core.h"
#include "fc/config.h" #include "fc/config.h"
#include "fc/rc_controls.h" #include "fc/rc_controls.h"
#include "fc/runtime_config.h" #include "fc/runtime_config.h"
@ -172,16 +173,16 @@ bool cmsInMenu = false;
typedef struct cmsCtx_s { typedef struct cmsCtx_s {
const CMS_Menu *menu; // menu for this context const CMS_Menu *menu; // menu for this context
uint8_t page;// page in the menu uint8_t page; // page in the menu
int8_t cursorRow;// cursorRow in the page int8_t cursorRow; // cursorRow in the page
}cmsCtx_t; } cmsCtx_t;
static cmsCtx_t menuStack[10]; static cmsCtx_t menuStack[10];
static uint8_t menuStackIdx = 0; static uint8_t menuStackIdx = 0;
static int8_t pageCount; // Number of pages in the current menu static int8_t pageCount; // Number of pages in the current menu
static const OSD_Entry *pageTop;// First entry for the current page static const OSD_Entry *pageTop; // First entry for the current page
static uint8_t pageMaxRow;// Max row in the current page static uint8_t pageMaxRow; // Max row in the current page
static cmsCtx_t currentCtx; static cmsCtx_t currentCtx;
@ -189,17 +190,15 @@ static cmsCtx_t currentCtx;
static char menuErrLabel[21 + 1] = "RANDOM DATA"; static char menuErrLabel[21 + 1] = "RANDOM DATA";
static const OSD_Entry menuErrEntries[] = static const OSD_Entry menuErrEntries[] = {
{ { "BROKEN MENU", OME_Label, NULL, NULL, 0 },
{ "BROKEN MENU", OME_Label, NULL, NULL, 0}, { menuErrLabel, OME_Label, NULL, NULL, 0 },
{ menuErrLabel, OME_Label, NULL, NULL, 0},
OSD_BACK_ENTRY, OSD_BACK_ENTRY,
OSD_END_ENTRY, OSD_END_ENTRY,
}; };
static const CMS_Menu menuErr = static const CMS_Menu menuErr = {
{
"MENUERR", "MENUERR",
OME_MENU, OME_MENU,
NULL, NULL,
@ -272,7 +271,7 @@ static void cmsFormatFloat(int32_t value, char *floatString)
uint8_t k; uint8_t k;
// np. 3450 // np. 3450
itoa(100000 + value, floatString, 10);// Create string from abs of integer value itoa(100000 + value, floatString, 10); // Create string from abs of integer value
// 103450 // 103450
@ -372,7 +371,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_Bool: case OME_Bool:
if (IS_PRINTVALUE(p, screenRow) && p->data) { if (IS_PRINTVALUE(p, screenRow) && p->data) {
if (*((uint8_t *) (p->data))) { if (*((uint8_t *)(p->data))) {
strcpy(buff, "YES"); strcpy(buff, "YES");
} else { } else {
strcpy(buff, "NO "); strcpy(buff, "NO ");
@ -400,7 +399,7 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_TAB: case OME_TAB:
if (IS_PRINTVALUE(p, screenRow)) { if (IS_PRINTVALUE(p, screenRow)) {
const OSD_TAB_t *ptr = p->data; const OSD_TAB_t *ptr = p->data;
char * str = (char *) ptr->names[*ptr->val]; char * str = (char *)ptr->names[*ptr->val];
strncpy(buff, str, CMS_DRAW_BUFFER_LEN); strncpy(buff, str, CMS_DRAW_BUFFER_LEN);
cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_DRAW_BUFFER_LEN); cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_DRAW_BUFFER_LEN);
CLR_PRINTVALUE(p, screenRow); CLR_PRINTVALUE(p, screenRow);
@ -409,17 +408,29 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
case OME_UINT8: case OME_UINT8:
if (IS_PRINTVALUE(p, screenRow) && p->data) { if (IS_PRINTVALUE(p, screenRow) && p->data) {
const uint8_t *val;
if (IS_READONLY(p)) {
val = p->data;
} else {
const OSD_UINT8_t *ptr = p->data; const OSD_UINT8_t *ptr = p->data;
itoa(*ptr->val, buff, 10); val = ptr->val;
}
itoa(*val, buff, 10);
cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_NUM_FIELD_LEN); cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_NUM_FIELD_LEN);
CLR_PRINTVALUE(p, screenRow); CLR_PRINTVALUE(p, screenRow);
} }
break; break;
case OME_INT8: case OME_INT8:
if (IS_PRINTVALUE(p, row) && p->data) { if (IS_PRINTVALUE(p, screenRow) && p->data) {
const int8_t *val;
if (IS_READONLY(p)) {
val = p->data;
} else {
const OSD_INT8_t *ptr = p->data; const OSD_INT8_t *ptr = p->data;
itoa(*ptr->val, buff, 10); val = ptr->val;
}
itoa(*val, buff, 10);
cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_NUM_FIELD_LEN); cnt = cmsDrawMenuItemValue(pDisplay, buff, row, CMS_NUM_FIELD_LEN);
CLR_PRINTVALUE(p, screenRow); CLR_PRINTVALUE(p, screenRow);
} }
@ -473,25 +484,25 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
const void *valuePointer = settingGetValuePointer(var); const void *valuePointer = settingGetValuePointer(var);
switch (SETTING_TYPE(var)) { switch (SETTING_TYPE(var)) {
case VAR_UINT8: case VAR_UINT8:
value = *(uint8_t *) valuePointer; value = *(uint8_t *)valuePointer;
break; break;
case VAR_INT8: case VAR_INT8:
value = *(int8_t *) valuePointer; value = *(int8_t *)valuePointer;
break; break;
case VAR_UINT16: case VAR_UINT16:
value = *(uint16_t *) valuePointer; value = *(uint16_t *)valuePointer;
break; break;
case VAR_INT16: case VAR_INT16:
value = *(int16_t *) valuePointer; value = *(int16_t *)valuePointer;
break; break;
case VAR_UINT32: case VAR_UINT32:
value = *(uint32_t *) valuePointer; value = *(uint32_t *)valuePointer;
break; break;
case VAR_FLOAT: case VAR_FLOAT:
// XXX: This bypasses the data types. However, we // XXX: This bypasses the data types. However, we
// don't have any VAR_FLOAT settings which require // don't have any VAR_FLOAT settings which require
// a data type yet. // a data type yet.
ftoa(*(float *) valuePointer, buff); ftoa(*(float *)valuePointer, buff);
break; break;
case VAR_STRING: case VAR_STRING:
strncpy(buff, valuePointer, sizeof(buff)); strncpy(buff, valuePointer, sizeof(buff));
@ -509,12 +520,13 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, const OSD_Entry *p, uint8_t
switch (SETTING_MODE(var)) { switch (SETTING_MODE(var)) {
case MODE_DIRECT: case MODE_DIRECT:
if (SETTING_TYPE(var) == VAR_UINT32) { if (SETTING_TYPE(var) == VAR_UINT32) {
tfp_sprintf(buff, "%u", (unsigned) value); tfp_sprintf(buff, "%u", (unsigned)value);
} else { } else {
tfp_sprintf(buff, "%d", (int) value); tfp_sprintf(buff, "%d", (int)value);
} }
break; break;
case MODE_LOOKUP: { case MODE_LOOKUP:
{
const char *str = settingLookupValueName(var, value); const char *str = settingLookupValueName(var, value);
strncpy(buff, str ? str : "INVALID", sizeof(buff) - 1); strncpy(buff, str ? str : "INVALID", sizeof(buff) - 1);
} }
@ -605,13 +617,12 @@ static void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTimeUs)
// Cursor manipulation // Cursor manipulation
while ((pageTop + currentCtx.cursorRow)->type == OME_Label)// skip label while (cmsElementIsLabel((pageTop + currentCtx.cursorRow)->type)) // skip label
currentCtx.cursorRow++; currentCtx.cursorRow++;
cmsPageDebug(); cmsPageDebug();
if (pDisplay->cursorRow >= 0 if (pDisplay->cursorRow >= 0 && currentCtx.cursorRow != pDisplay->cursorRow) {
&& currentCtx.cursorRow != pDisplay->cursorRow) {
room -= displayWrite(pDisplay, leftMenuColumn, top + pDisplay->cursorRow * linesPerMenuItem, " "); room -= displayWrite(pDisplay, leftMenuColumn, top + pDisplay->cursorRow * linesPerMenuItem, " ");
} }
@ -630,7 +641,7 @@ static void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTimeUs)
for (i = 0, p = pageTop; i < maxMenuItems && p->type != OME_END; i++, p++) { for (i = 0, p = pageTop; i < maxMenuItems && p->type != OME_END; i++, p++) {
if (IS_PRINTLABEL(p, i)) { if (IS_PRINTLABEL(p, i)) {
uint8_t coloff = leftMenuColumn; uint8_t coloff = leftMenuColumn;
coloff += (p->type == OME_Label) ? 0 : 1; coloff += cmsElementIsLabel(p->type) ? 0 : 1;
room -= displayWrite(pDisplay, coloff, top + i * linesPerMenuItem, p->text); room -= displayWrite(pDisplay, coloff, top + i * linesPerMenuItem, p->text);
CLR_PRINTLABEL(p, i); CLR_PRINTLABEL(p, i);
if (room < 30) { if (room < 30) {
@ -648,9 +659,10 @@ static void cmsDrawMenu(displayPort_t *pDisplay, uint32_t currentTimeUs)
for (i = 0, p = pageTop; i < maxMenuItems && p->type != OME_END; i++, p++) { for (i = 0, p = pageTop; i < maxMenuItems && p->type != OME_END; i++, p++) {
if (IS_PRINTVALUE(p, i)) { if (IS_PRINTVALUE(p, i)) {
room -= cmsDrawMenuEntry(pDisplay, p, top + i * linesPerMenuItem, i); room -= cmsDrawMenuEntry(pDisplay, p, top + i * linesPerMenuItem, i);
if (room < 30) if (room < 30) {
return; return;
} }
}
if (p->type == OME_BACK_AND_END) { if (p->type == OME_BACK_AND_END) {
break; break;
} }
@ -672,10 +684,8 @@ static void cmsMenuCountPage(displayPort_t *pDisplay)
STATIC_UNIT_TESTED long cmsMenuBack(displayPort_t *pDisplay); // Forward; will be resolved after merging STATIC_UNIT_TESTED long cmsMenuBack(displayPort_t *pDisplay); // Forward; will be resolved after merging
long cmsMenuChange(displayPort_t *pDisplay, const void *ptr) long cmsMenuChange(displayPort_t *pDisplay, const CMS_Menu *pMenu, const OSD_Entry *from)
{ {
const CMS_Menu *pMenu = (const CMS_Menu *) ptr;
if (!pMenu) { if (!pMenu) {
return 0; return 0;
} }
@ -683,12 +693,9 @@ long cmsMenuChange(displayPort_t *pDisplay, const void *ptr)
#ifdef CMS_MENU_DEBUG #ifdef CMS_MENU_DEBUG
if (pMenu->GUARD_type != OME_MENU) { if (pMenu->GUARD_type != OME_MENU) {
// ptr isn't pointing to a CMS_Menu. // ptr isn't pointing to a CMS_Menu.
if (pMenu->GUARD_type <= OME_MAX) if (pMenu->GUARD_type <= OME_MAX) {
{
strncpy(menuErrLabel, pMenu->GUARD_text, sizeof(menuErrLabel) - 1); strncpy(menuErrLabel, pMenu->GUARD_text, sizeof(menuErrLabel) - 1);
} } else {
else
{
strncpy(menuErrLabel, "LABEL UNKNOWN", sizeof(menuErrLabel) - 1); strncpy(menuErrLabel, "LABEL UNKNOWN", sizeof(menuErrLabel) - 1);
} }
pMenu = &menuErr; pMenu = &menuErr;
@ -703,7 +710,7 @@ long cmsMenuChange(displayPort_t *pDisplay, const void *ptr)
currentCtx.menu = pMenu; currentCtx.menu = pMenu;
currentCtx.cursorRow = 0; currentCtx.cursorRow = 0;
if (pMenu->onEnter && (pMenu->onEnter(NULL) == MENU_CHAIN_BACK)) { if (pMenu->onEnter && (pMenu->onEnter(from) == MENU_CHAIN_BACK)) {
return cmsMenuBack(pDisplay); return cmsMenuBack(pDisplay);
} }
@ -754,7 +761,7 @@ void cmsMenuOpen(void)
if (!pCurrentDisplay) if (!pCurrentDisplay)
return; return;
cmsInMenu = true; cmsInMenu = true;
currentCtx = (cmsCtx_t ) {&menuMain, 0, 0}; currentCtx = (cmsCtx_t){ &menuMain, 0, 0 };
ENABLE_ARMING_FLAG(ARMING_DISABLED_CMS_MENU); ENABLE_ARMING_FLAG(ARMING_DISABLED_CMS_MENU);
} else { } else {
// Switch display // Switch display
@ -791,7 +798,7 @@ void cmsMenuOpen(void)
maxMenuItems = pCurrentDisplay->rows; maxMenuItems = pCurrentDisplay->rows;
} }
cmsMenuChange(pCurrentDisplay, currentCtx.menu); cmsMenuChange(pCurrentDisplay, currentCtx.menu, NULL);
} }
static void cmsTraverseGlobalExit(const CMS_Menu *pMenu) static void cmsTraverseGlobalExit(const CMS_Menu *pMenu)
@ -812,7 +819,7 @@ static void cmsTraverseGlobalExit(const CMS_Menu *pMenu)
long cmsMenuExit(displayPort_t *pDisplay, const void *ptr) long cmsMenuExit(displayPort_t *pDisplay, const void *ptr)
{ {
int exitType = (int) ptr; int exitType = (int)ptr;
switch (exitType) { switch (exitType) {
case CMS_EXIT_SAVE: case CMS_EXIT_SAVE:
case CMS_EXIT_SAVEREBOOT: case CMS_EXIT_SAVEREBOOT:
@ -822,10 +829,9 @@ long cmsMenuExit(displayPort_t *pDisplay, const void *ptr)
cmsTraverseGlobalExit(&menuMain); cmsTraverseGlobalExit(&menuMain);
if (currentCtx.menu->onExit) if (currentCtx.menu->onExit)
currentCtx.menu->onExit((OSD_Entry *) NULL); // Forced exit currentCtx.menu->onExit((OSD_Entry *)NULL); // Forced exit
if ((exitType == CMS_POPUP_SAVE) if ((exitType == CMS_POPUP_SAVE) || (exitType == CMS_POPUP_SAVEREBOOT)) {
|| (exitType == CMS_POPUP_SAVEREBOOT)) {
// traverse through the menu stack and call their onExit functions // traverse through the menu stack and call their onExit functions
for (int i = menuStackIdx - 1; i >= 0; i--) { for (int i = menuStackIdx - 1; i >= 0; i--) {
if (menuStack[i].menu->onExit) { if (menuStack[i].menu->onExit) {
@ -852,11 +858,7 @@ long cmsMenuExit(displayPort_t *pDisplay, const void *ptr)
displayResync(pDisplay); // Was max7456RefreshAll(); why at this timing? displayResync(pDisplay); // Was max7456RefreshAll(); why at this timing?
stopMotors(); fcReboot(false);
stopPwmAllMotors();
delay(200);
systemReset();
} }
DISABLE_ARMING_FLAG(ARMING_DISABLED_CMS_MENU); DISABLE_ARMING_FLAG(ARMING_DISABLED_CMS_MENU);
@ -903,7 +905,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
} }
if (key == CMS_KEY_SAVEMENU) { if (key == CMS_KEY_SAVEMENU) {
cmsMenuChange(pDisplay, &cmsx_menuSaveExit); cmsMenuChange(pDisplay, &cmsx_menuSaveExit, NULL);
return BUTTON_PAUSE; return BUTTON_PAUSE;
} }
@ -938,7 +940,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
switch (p->type) { switch (p->type) {
case OME_Submenu: case OME_Submenu:
if (key == CMS_KEY_RIGHT) { if (key == CMS_KEY_RIGHT) {
cmsMenuChange(pDisplay, p->data); cmsMenuChange(pDisplay, p->data, p);
res = BUTTON_PAUSE; res = BUTTON_PAUSE;
} }
break; break;
@ -967,7 +969,7 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_Bool: case OME_Bool:
if (p->data) { if (p->data) {
uint8_t *val = (uint8_t *) p->data; uint8_t *val = (uint8_t *)p->data;
if (key == CMS_KEY_RIGHT) if (key == CMS_KEY_RIGHT)
*val = 1; *val = 1;
else else
@ -990,6 +992,9 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
case OME_UINT8: case OME_UINT8:
case OME_FLOAT: case OME_FLOAT:
if (IS_READONLY(p)) {
break;
}
if (p->data) { if (p->data) {
const OSD_UINT8_t *ptr = p->data; const OSD_UINT8_t *ptr = p->data;
if (key == CMS_KEY_RIGHT) { if (key == CMS_KEY_RIGHT) {
@ -1025,6 +1030,9 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
break; break;
case OME_INT8: case OME_INT8:
if (IS_READONLY(p)) {
break;
}
if (p->data) { if (p->data) {
const OSD_INT8_t *ptr = p->data; const OSD_INT8_t *ptr = p->data;
if (key == CMS_KEY_RIGHT) { if (key == CMS_KEY_RIGHT) {
@ -1087,49 +1095,54 @@ STATIC_UNIT_TESTED uint16_t cmsHandleKey(displayPort_t *pDisplay, uint8_t key)
const setting_t *var = settingGet(ptr->val); const setting_t *var = settingGet(ptr->val);
setting_min_t min = settingGetMin(var); setting_min_t min = settingGetMin(var);
setting_max_t max = settingGetMax(var); setting_max_t max = settingGetMax(var);
float step = ptr->step ? : 1; float step = ptr->step ?: 1;
if (key != CMS_KEY_RIGHT) { if (key != CMS_KEY_RIGHT) {
step = -step; step = -step;
} }
const void *valuePointer = settingGetValuePointer(var); const void *valuePointer = settingGetValuePointer(var);
switch (SETTING_TYPE(var)) { switch (SETTING_TYPE(var)) {
case VAR_UINT8: { case VAR_UINT8:
uint8_t val = *(uint8_t *) valuePointer; {
val = MIN(MAX(val + step, (uint8_t)min), (uint8_t )max); uint8_t val = *(uint8_t *)valuePointer;
*(uint8_t *) valuePointer = val; val = MIN(MAX(val + step, (uint8_t)min), (uint8_t)max);
*(uint8_t *)valuePointer = val;
break; break;
} }
case VAR_INT8: { case VAR_INT8:
int8_t val = *(int8_t *) valuePointer; {
val = MIN(MAX(val + step, (int8_t)min), (int8_t )max); int8_t val = *(int8_t *)valuePointer;
*(int8_t *) valuePointer = val; val = MIN(MAX(val + step, (int8_t)min), (int8_t)max);
*(int8_t *)valuePointer = val;
break; break;
} }
case VAR_UINT16: { case VAR_UINT16:
uint16_t val = *(uint16_t *) valuePointer; {
val = MIN(MAX(val + step, (uint16_t)min), (uint16_t )max); uint16_t val = *(uint16_t *)valuePointer;
*(uint16_t *) valuePointer = val; val = MIN(MAX(val + step, (uint16_t)min), (uint16_t)max);
*(uint16_t *)valuePointer = val;
break; break;
} }
case VAR_INT16: { case VAR_INT16:
int16_t val = *(int16_t *) valuePointer; {
val = MIN(MAX(val + step, (int16_t)min), (int16_t )max); int16_t val = *(int16_t *)valuePointer;
*(int16_t *) valuePointer = val; val = MIN(MAX(val + step, (int16_t)min), (int16_t)max);
*(int16_t *)valuePointer = val;
break; break;
} }
case VAR_UINT32: { case VAR_UINT32:
uint32_t val = *(uint32_t *) valuePointer; {
val = MIN(MAX(val + step, (uint32_t)min), (uint32_t )max); uint32_t val = *(uint32_t *)valuePointer;
*(uint32_t *) valuePointer = val; val = MIN(MAX(val + step, (uint32_t)min), (uint32_t)max);
*(uint32_t *)valuePointer = val;
break; break;
} }
case VAR_FLOAT: { case VAR_FLOAT:
float val = *(float *) valuePointer; {
val = MIN(MAX(val + step, (float)min), (float )max); float val = *(float *)valuePointer;
*(float *) valuePointer = val; val = MIN(MAX(val + step, (float)min), (float)max);
*(float *)valuePointer = val;
break; break;
} }
break;
case VAR_STRING: case VAR_STRING:
break; break;
} }
@ -1270,9 +1283,8 @@ static uint16_t cmsScanKeys(timeMs_t currentTimeMs, timeMs_t lastCalledMs, int16
void cmsUpdate(uint32_t currentTimeUs) void cmsUpdate(uint32_t currentTimeUs)
{ {
#ifdef USE_RCDEVICE #ifdef USE_RCDEVICE
if(rcdeviceInMenu) if(rcdeviceInMenu) {
{ return ;
return;
} }
#endif #endif

View file

@ -30,7 +30,7 @@ void cmsHandler(timeUs_t currentTimeUs);
bool cmsDisplayPortSelect(displayPort_t *instance); bool cmsDisplayPortSelect(displayPort_t *instance);
void cmsMenuOpen(void); void cmsMenuOpen(void);
long cmsMenuChange(displayPort_t *pPort, const void *ptr); long cmsMenuChange(displayPort_t *pPort, const CMS_Menu *menu, const OSD_Entry *from);
long cmsMenuExit(displayPort_t *pPort, const void *ptr); long cmsMenuExit(displayPort_t *pPort, const void *ptr);
void cmsYieldDisplay(displayPort_t *pPort, timeMs_t duration); void cmsYieldDisplay(displayPort_t *pPort, timeMs_t duration);
void cmsUpdate(uint32_t currentTimeUs); void cmsUpdate(uint32_t currentTimeUs);