Refactoring menu code to be non-blocking
Added macros for GPIO read/write
This commit is contained in:
201
source/menu.c
201
source/menu.c
@@ -40,6 +40,45 @@
|
||||
|
||||
#define MENU_TIMER_PERIOD_MS (100) //100mS for 10Hz update
|
||||
|
||||
#define MENU_STACK_SIZE 4
|
||||
#define MENU_ITEM_SIZE 10
|
||||
|
||||
typedef struct Menu_s Menu_t;
|
||||
|
||||
typedef int (*MenuHandler_t)(Menu_t *menu);
|
||||
|
||||
|
||||
struct Menu_s
|
||||
{
|
||||
MenuHandler_t handler;
|
||||
bool init;
|
||||
bool draw;
|
||||
int selected;
|
||||
MENU_ITEM_t items[MENU_ITEM_SIZE];
|
||||
int itemCount;
|
||||
int displayIndex;
|
||||
|
||||
};
|
||||
|
||||
typedef struct MenuData_s
|
||||
{
|
||||
int stackCount;
|
||||
Menu_t menuStack[MENU_STACK_SIZE];
|
||||
Menu_t *currentMenu;
|
||||
|
||||
} MenuData_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool exitToMainScreen;
|
||||
} MENU_t;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -47,6 +86,8 @@
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
static MenuData_t _menuData;
|
||||
|
||||
MENU_t menu;
|
||||
|
||||
MENU_ITEM_t mainMenu[MAIN_MENU_NUM_TX10];
|
||||
@@ -69,6 +110,9 @@ extern uint8_t Port_State[];
|
||||
|
||||
extern HARDWARE_FIX_t hwf;
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Static Function Declarations
|
||||
******************************************************************************/
|
||||
@@ -92,10 +136,126 @@ static void DisplayLanguageMenu(uint32_t selected);
|
||||
static void DisplayRegulatoryInfo(void);
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Static Functions
|
||||
******************************************************************************/
|
||||
|
||||
static int handleMainMenu(Menu_t *menu)
|
||||
{
|
||||
if (menu->init)
|
||||
{
|
||||
int itemCount = 0;
|
||||
|
||||
menu->items[itemCount].pMonoIcon = menuMore;
|
||||
menu->items[itemCount].id = MENU_ID_SYSINFO;
|
||||
strcpy(menu->items[itemCount].text, "System Information"); //System info screen
|
||||
itemCount++;
|
||||
|
||||
menu->items[itemCount].pMonoIcon = menuMore;
|
||||
menu->items[itemCount].id = MENU_ID_FREQUENCIES;
|
||||
strcpy(menu->items[itemCount].text, "Frequencies"); //Frequency Selection Menu
|
||||
itemCount++;
|
||||
|
||||
menu->items[itemCount].pMonoIcon = 0;
|
||||
menu->items[itemCount].id = MENU_ID_AUTOSHUTDOWN;
|
||||
strcpy(menu->items[itemCount].text, "Auto Shutdown"); //Auto Shutdown selection
|
||||
itemCount++;
|
||||
|
||||
menu->items[itemCount].pMonoIcon = menuMore;
|
||||
menu->items[itemCount].id = MENU_ID_LANGUAGE;
|
||||
strcpy(menu->items[itemCount].text, "Language"); //Language Selection Menu
|
||||
itemCount++;
|
||||
|
||||
menu->itemCount = itemCount;
|
||||
menu->init = false;
|
||||
|
||||
menu->draw = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch(KEY_GetPressed())
|
||||
{
|
||||
case KEY_UP:
|
||||
{
|
||||
if(--menu->selected < 0)
|
||||
{
|
||||
menu->selected = 0;
|
||||
}
|
||||
menu->draw = true;
|
||||
break;
|
||||
}
|
||||
case KEY_DOWN:
|
||||
{
|
||||
if(++menu->selected >= menu->itemCount)
|
||||
{
|
||||
menu->selected = menu->itemCount - 1;
|
||||
}
|
||||
menu->draw = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (menu->draw)
|
||||
{
|
||||
|
||||
LCD_Clear();
|
||||
|
||||
if(menu->selected >= (menu->displayIndex + MENU_MAX_LINES_DISPLAYED))
|
||||
{
|
||||
menu->displayIndex++;
|
||||
}
|
||||
else if(menu->selected < menu->displayIndex)
|
||||
{
|
||||
menu->displayIndex--;
|
||||
}
|
||||
|
||||
|
||||
// Draw menu items
|
||||
MENU_ITEM_t *item;
|
||||
|
||||
for(uint32_t i = menu->displayIndex; i < menu->displayIndex + menu->itemCount; i++) //this can draw extra lines off the screen but we don't care
|
||||
{
|
||||
item = &menu->items[i];
|
||||
|
||||
//Menu strings
|
||||
FL_DrawTranslatedString(item->text, MENU_MAIN_TEXT_X, MENU_MAIN_TEXT_Y_START + (i-menu->displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT);
|
||||
|
||||
|
||||
// Draw item status
|
||||
if (item->pMonoIcon != NULL)
|
||||
{
|
||||
GL_DrawMonoBitmap(item->pMonoIcon, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i-menu->displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET);
|
||||
}
|
||||
|
||||
if (item->id == MENU_ID_AUTOSHUTDOWN)
|
||||
{
|
||||
FL_DrawTranslatedString(tmr_GetAutoSDTimerString(), MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i - menu->displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Draw selection bar
|
||||
uint32_t selRectY0 = MENU_MAIN_TEXT_Y_START + (menu->selected - menu->displayIndex)*MENU_LINE_HEIGHT;
|
||||
GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR);
|
||||
|
||||
//Draw menu icons
|
||||
//Use DrawMenuBitmap(mainMenu[i], x, y)
|
||||
|
||||
//DrawMenuScrollBar(displayIndex, menuNum);
|
||||
|
||||
LCD_Update();
|
||||
|
||||
menu->draw = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -865,6 +1025,11 @@ void MENU_Init(void)
|
||||
ClearMenuItems(mainMenu, MAIN_MENU_NUM_TX10);
|
||||
ClearMenuItems(langMenu, LANG_MENU_NUM);
|
||||
|
||||
for (int i=0; i < MENU_STACK_SIZE; ++i)
|
||||
{
|
||||
_menuData.menuStack[i].selected = 0;
|
||||
_menuData.menuStack[i].handler = NULL;
|
||||
}
|
||||
|
||||
//main menu
|
||||
uint32_t i = 0;
|
||||
@@ -1093,6 +1258,42 @@ void MENU_DisplayMain(uint32_t selected)
|
||||
|
||||
|
||||
|
||||
void Menu_init(void)
|
||||
{
|
||||
_menuData.currentMenu = NULL;
|
||||
_menuData.stackCount = 0;
|
||||
|
||||
for (int i=0; i<MENU_STACK_SIZE; ++i)
|
||||
{
|
||||
_menuData.menuStack[i].displayIndex = 0;
|
||||
|
||||
for (int j=0; j<MENU_ITEM_SIZE; ++j)
|
||||
{
|
||||
_menuData.menuStack[i].items[j].id = MENU_ID_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Menu_mainMenu(void)
|
||||
{
|
||||
sys.guiMode = GUI_MODE_MENU;
|
||||
|
||||
Menu_t *menu = &_menuData.menuStack[0];
|
||||
|
||||
menu->handler = handleMainMenu;
|
||||
menu->selected = 0;
|
||||
menu->init = true;
|
||||
|
||||
_menuData.currentMenu = menu;
|
||||
}
|
||||
|
||||
void Menu_service(void)
|
||||
{
|
||||
// run the menu state machine and prevent blocking
|
||||
if (_menuData.currentMenu != NULL)
|
||||
{
|
||||
_menuData.currentMenu->handler(_menuData.currentMenu);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user