逻辑实现
实现方法
可以使用数组实现,也可以使用链表实现,不论方法怎么样,逻辑是异曲同工。
逻辑讲解
代码
代码编写
1、 声明结构体类型
对相应的数组下标名字用枚举赋值
定义数组下标变量(将枚举类型数值赋值给该变量)
定义函数指针
2、Main_Menu table[20]={},对结构体类型数组进行赋值,(按照相应的树结构)
3、刷新屏幕函数:switch语句:对数组下标(索引值)进行判断选择(按照按键上下左右,对应的结构体成员)
4、将数组下标相对应的枚举名字(当前索引值),作为函数名,赋值给函数指针变量(函数指针指向对应的函数)
current_operation_func=table[func_index].current_operation;
5、调用函数指针指向的函数
(*current_operation_func)(func_index,key_val);//执行当前索引对应的函数
6、编写相应的函数,实现相应的功能。
.h文件
#ifndef __MENU_H
#define __MENU_H
#include "sys.h"
#define ON 1
#define OFF 0
typedef struct
{
u8 Cur_Index;//当前索引项
u8 previous;//上一页
u8 next;//下一页
u8 enter;//确认
u8 back;//返回
void (*current_operation)(u8,u8);// 当前索引执行的函数(界面)
}Main_Menu;
//各界面的索引值
enum
{
_Main_UI=0,
_Wifi_Option,
_Bluetooth_Option,
_Setting_Option,
_Info_Option,
_Wifi_Child,
_Bluetooth_Child,
_Setting_Child,
_Info_Child,
_OLED_Lock,
};
void Main_UI(u8 page_index,u8 key_val);
void Main_Menu_Func(u8 page_index,u8 key_val);
void Wifi_Child(u8 page_index,u8 key_val);
void Bluetooth_Child(u8 page_index,u8 key_val);
void Setting_Child(u8 page_index,u8 key_val);
void Info_Child(u8 page_index,u8 key_val);
void OLED_Lock(u8 page_index,u8 key_val);
void LCD_Refresh(void);
#endif
.c文件
#include "menu.h"
#include "key.h"
#include "lcd.h"
#include "pic.h"
static u8 func_index=_Main_UI;//当前页面索引值
static u8 last_index=_Main_UI;//上一个界面索引值
static void (*current_operation_func)(u8,u8);//定义一个函数指针
//索引表
Main_Menu table[20]=
{
//Cur_Index,previous,next,enter,back,(*current_operation)(u8,u8)
//主界面
{_Main_UI,_Main_UI,_Main_UI,_Wifi_Option,_OLED_Lock,Main_UI},
//主菜单
{_Wifi_Option,_Info_Option,_Bluetooth_Option,_Wifi_Child,_Main_UI,Main_Menu_Func},//Wifi
{_Bluetooth_Option,_Wifi_Option,_Setting_Option,_Bluetooth_Child,_Main_UI,Main_Menu_Func},//蓝牙
{_Setting_Option,_Bluetooth_Option,_Info_Option,_Setting_Child,_Main_UI,Main_Menu_Func},//设置
{_Info_Option,_Setting_Option,_Wifi_Option,_Info_Child,_Main_UI,Main_Menu_Func},//关于信息
//子菜单
{_Wifi_Child,_Wifi_Child,_Wifi_Child,_Wifi_Child,_Wifi_Option,Wifi_Child},//Wifi子菜单
{_Bluetooth_Child,_Bluetooth_Child,_Bluetooth_Child,_Bluetooth_Child,_Bluetooth_Option,Bluetooth_Child},//蓝牙子菜单
{_Setting_Child,_Setting_Child,_Setting_Child,_Setting_Child,_Setting_Option,Setting_Child},//设置子菜单
{_Info_Child,_Info_Child,_Info_Child,_Info_Child,_Info_Option,Info_Child},//关于信息子菜单
{_OLED_Lock,_Main_UI,_Main_UI,_Main_UI,_Main_UI,OLED_Lock},//OLED熄屏
};
/*
函数功能:刷新界面
参数:无
返回值:无
*/
void LCD_Refresh(void)
{
u8 key_val = KEY_Scan(0);
if(key_val!=0)//只有按键按下才刷屏
{
last_index=func_index;//更新上一界面索引值
switch(key_val)
{
case WKUP_PRES: func_index=table[func_index].previous;//更新索引值
break;
case KEYRIGHT_PRES: func_index=table[func_index].enter;//更新索引值
break;
case KEYDOWN_PRES:func_index=table[func_index].next;//更新索引值
break;
case KEYLEFT_PRES:func_index=table[func_index].back;//更新索引值
break;
default:break;
}
LCD_Fill(0,0,128,160,WHITE);//清屏
}
current_operation_func=table[func_index].current_operation;
(*current_operation_func)(func_index,key_val);//执行当前索引对应的函数
}
/*
函数功能:显示主界面
参数:u8 page_index,u8 key_val
返回值:无
*/
void Main_UI(u8 page_index,u8 key_val)
{
LCD_ShowPicture(0,0,100,100,gImage_menu);//显示菜单
}
/*
函数功能:主菜单显示函数
参数:u8 page_index,u8 key_val
返回值:无
*/
void Main_Menu_Func(u8 page_index,u8 key_val)
{
LCD_ShowString(90,140,"Sure",BLACK,WHITE,16,0);//显示确定
LCD_ShowString(0,140,"Return",BLACK,WHITE,16,0);//显示返回
switch(page_index)
{
case _Wifi_Option:LCD_ShowPicture(0,0,100,100,gImage_wifi);;//显示Wifi图标
break;
case _Bluetooth_Option:LCD_ShowPicture(0,0,100,100,gImage_blue);;//显示蓝牙图标
break;
case _Setting_Option:LCD_ShowPicture(0,0,100,100,gImage_install);;//显示设置图标
break;
case _Info_Option:LCD_ShowPicture(0,0,100,100,gImage_information);;//显示关于信息图标
break;
default:break;
}
}
/*
函数功能:Wifi选项子菜单
参数:u8 page_index,u8 key_val
返回值:无
*/
void Wifi_Child(u8 page_index,u8 key_val)
{
static u8 cur_pos=1;
static u8 wifi_status=ON;
static u8 esp_tcpserver=OFF;
static u8 esp_unvarnishedmode=OFF;
if(last_index!=_Wifi_Option)//判断是否是第一次进入此界面
{
switch(key_val)
{
case WKUP_PRES: cur_pos==1?cur_pos=6:cur_pos--;
break;
case KEYRIGHT_PRES://确定(设置)按键
{
switch(cur_pos)
{
case 1:wifi_status=!wifi_status;
if(wifi_status==OFF)
{
esp_tcpserver=OFF;
esp_unvarnishedmode=OFF;
}
break;
case 2:if(wifi_status==ON)
{
esp_tcpserver=OFF;
esp_unvarnishedmode=OFF;
}
break;
case 3:if(wifi_status==ON&&esp_unvarnishedmode==OFF)
esp_tcpserver=!esp_tcpserver;
break;
case 4:if(wifi_status==ON&&esp_tcpserver==OFF)
esp_unvarnishedmode=!esp_unvarnishedmode;
break;
case 5:
break;
case 6:
break;
default:break;
}
}
break;
case KEYDOWN_PRES:cur_pos==6?cur_pos=1:cur_pos++;
break;
default:break;
}
}
else cur_pos=1;//第一次进入此界面,界面指针清零
if(cur_pos<=4)
{
LCD_ShowString(50,50,"wifi",BLUE,WHITE,16,0);
}
else if(cur_pos<=8)
{
LCD_ShowString(50,50,"wifi",BLUE,WHITE,16,0);
}
}
/*
函数功能:蓝牙选项子菜单
参数:u8 page_index,u8 key_val
返回值:无
*/
void Bluetooth_Child(u8 page_index,u8 key_val)
{
static u8 cur_pos=1;
static u8 BL_status=ON;
if(last_index!=_Bluetooth_Option)//判断是否是第一次进入此界面
{
switch(key_val)
{
case WKUP_PRES: cur_pos==1?cur_pos=4:cur_pos--;
break;
case KEYRIGHT_PRES://确定(设置)按键
{
switch(cur_pos)
{
case 1:BL_status=!BL_status;
break;
case 2:
break;
case 3:
break;
case 4:
break;
default:break;
}
}
break;
case KEYDOWN_PRES:cur_pos==4?cur_pos=1:cur_pos++;
break;
default:break;
}
}
else cur_pos=1;//第一次进入此界面,界面指针清零
LCD_ShowString(50,50,"blue",BLUE,WHITE,16,0);
}
/*
函数功能:设置选项子菜单
参数:u8 page_index,u8 key_val
返回值:无
*/
void Setting_Child(u8 page_index,u8 key_val)
{
static u8 cur_pos=1;
if(last_index!=_Setting_Option)//判断是否是第一次进入此界面
{
switch(key_val)
{
case WKUP_PRES: cur_pos==1?cur_pos=6:cur_pos--;
break;
case KEYRIGHT_PRES://确定(设置)按键
{
switch(cur_pos)
{
case 1:
break;
case 2:LCD_ShowString(50,50,"LED",BLUE,WHITE,16,0);;
break;
case 4:LCD_ShowString(50,50,"BEEP",BLUE,WHITE,16,0);
break;
case 5:LCD_ShowString(50,50,"else",BLUE,WHITE,16,0);
break;
case 6:
break;
default:break;
}
}
break;
case KEYDOWN_PRES:cur_pos==6?cur_pos=1:cur_pos++;
break;
default:break;
}
}
else cur_pos=1;//第一次进入此界面,界面指针清零
}
/*
函数功能:关于信息页
参数:u8 page_index,u8 key_val
返回值;无
*/
void Info_Child(u8 page_index,u8 key_val)
{
LCD_ShowString(0,50,"Version 1.0",BLUE,WHITE,16,0);
}
/*
函数功能:OLED熄屏
参数:u8 page_index,u8 key_val
返回值;无
*/
void OLED_Lock(u8 page_index,u8 key_val)
{
LCD_Fill(0,0,128,160,WHITE);//清屏
}