|
本帖最后由 yanggang2880 于 2012-4-27 20:08 编辑
在论坛上获取资源很久了,今天也上传一个我的菜单程序。
此菜单的特点是可以像做网页定义CSS样式一样,定义菜单的显示样式。
包括:菜单项排版,选中不选中文字的颜色,选中不选择按钮图片,图片和文字的排版方式等等。结合美工可以在液晶屏上做出漂亮且功能强大的菜单。
部分代码来自“傻孩子”的菜单实现,在此感谢一下。
以下代码在我的板子上调试通过。
typedef struct IMAGE_RESOURCE
{
uint_16 resource_id;
uint_16 pic_id;
uint_16 xe;
uint_16 ye;
uint_16 xs;
uint_16 ys;
}ImageResource;
//剪切图片资源
const ImageResource ImageResourceList[] =
{
{1, BUTTONPICTURE, 0x67, 0x24, 0xDE, 0x3C}, //按钮图标1,未选择
{2, BUTTONPICTURE, 0x67, 0x43, 0xDE, 0x58}, //按钮图标1,选择
{3, BUTTONPICTURE, 0x67, 0x64, 0xDB, 0x73}, //按钮图标2,未选择
{4, BUTTONPICTURE, 0x67, 0x7E, 0xDB, 0x8D}, //按钮图标2,选择
{0, 0, 0, 0, 0, 0}
};
typedef struct MENUSTYLE
{
uint_8 style;
uint_8 col; //菜单最大列数
uint_8 row; //菜单最大行数
uint_8 dx; //水平间距
uint_8 dy; //垂直间距
uint_8 space_x; //文字跟图片起始地址的差值
uint_8 space_y;
ImageResource* imgid_sel; //被选中时菜单按钮图标句柄,NULL没图片不显示,(需LCD GUI支持图片上文字背景色不显示)
ImageResource* imgid_normal; //不被选中时菜单按钮图标句柄,NULL没图片不显示
uint_32 f_color_sel; //前景色被选择时
uint_32 f_color_normal; //前景色不被选中时
uint_32 b_color_sel; //背景色被选择时
uint_32 b_color_normal; //背景色不被选中时
uint_16 x0; //菜单绘制的起始位置
uint_16 y0;
//......
//还可以定义一些字体类型,文字大小等等
}MenuStyle;
typedef struct MENUITEM
{
char *DisplayString;
void (*Subs)();
struct MENUITEM *ChildrenMenus;
struct MENUITEM *ParentMenus;
}MenuItem;
typedef struct MENU
{
char* MenuName;
uint_8 MenuItemCount;
uint_8 select; //当前被选中的
MenuStyle* menu_style; //菜单风格选择
MenuItem* pMenuItem;
}Menu;
const MenuStyle MenuStyleList[] =
{
{1, 1, 5, 0, 0x1F, 8, 5, (ImageResource*)(&ImageResourceList[1]), (ImageResource*)(&ImageResourceList[0]), COLOR_BLACK, COLOR_BLACK, COLOR_WHITE, COLOR_WHITE, 0x64, 0x24},
{2, 2, 6, 0x8F, 0x14, 7, 1, (ImageResource*)(&ImageResourceList[3]), (ImageResource*)(&ImageResourceList[2]), COLOR_BLACK, COLOR_BLACK, COLOR_WHITE, COLOR_WHITE, 0x1E, 0x20},
{0, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, 0}
};
MenuItem MainMenuItem[5];
MenuItem SettingsMenuItem[12];
Menu MainMenu;
Menu SettingsMenu;
Menu* g_pCurMenu;
void NullSubs(void)
{
;
}
static Menu* GetCurMenu(MenuItem* pMenuItem)
{
Menu* pMenu = NULL;
if (pMenuItem == MainMenuItem)
{
pMenu = &MainMenu;
}
else if (pMenuItem == SettingsMenuItem)
{
pMenu = &SettingsMenu;
}
return pMenu;
}
static void ImagePaint(uint_16 x, uint_16 y, ImageResource* image)
{
;//根据具体的LCD屏调用GUI函数
}
static void TextPaint(uint_16 x, uint_16 y, uint_32 fcolor, uint_32 bcolor, const char* s)
{
;//根据具体的LCD屏调用GUI函数
}
static void MenuItemPaint(uint_16 x, uint_16 y, uint_8 space_x, uint_8 space_y, ImageResource* image, uint_32 fcolor, uint_32 bcolor, const char* s)
{
if (NULL != image)
{
ImagePaint(x, y, image);
}
TextPaint(x+space_x, y+space_y, fcolor, bcolor, s);
}
static void MenuFramePaint(const char* title)
{
;//根据具体的LCD屏调用GUI函数,包括清屏,绘制菜单标题等
}
//菜单绘制
void MenuPaint(uint_8 mode, uint_8 select, Menu* pMenu)
{
uint_8 i;
uint_16 x;
uint_16 y;
uint_8 col = 0;
uint_8 row = 0;
ImageResource* image;
uint_32 fcolor;
uint_32 bcolor;
uint_8 space_x;
uint_8 space_y;
MenuStyle* pMenuStyle;
if (NULL == pMenu)
{
return;
}
pMenuStyle = pMenu->menu_style;
if (NULL == pMenuStyle)
{
return;
}
x = pMenuStyle->x0;
y = pMenuStyle->y0;
space_x = pMenuStyle->space_x;
space_y = pMenuStyle->space_y;
if (mode == 0) //只绘制变化部分
{
x = pMenuStyle->x0;
y = pMenuStyle->y0;
if (pMenu->select != select)
{
//撤销原选中项
image = pMenuStyle->imgid_normal;;
fcolor = pMenuStyle->f_color_normal;
bcolor = pMenuStyle->b_color_normal;
x = x + (pMenu->select/pMenuStyle->row)*pMenuStyle->dx;
y = y + (pMenu->select%pMenuStyle->row)*pMenuStyle->dy;
MenuItemPaint(x, y, space_x, space_y, image, fcolor, bcolor, pMenu->pMenuItem[pMenu->select].DisplayString);
//更新新的选中项
x = pMenuStyle->x0;
y = pMenuStyle->y0;
image = pMenuStyle->imgid_sel;;
fcolor = pMenuStyle->f_color_sel;
bcolor = pMenuStyle->b_color_sel;
x = x + (select/pMenuStyle->row)*pMenuStyle->dx;
y = y + (select%pMenuStyle->row)*pMenuStyle->dy;
MenuItemPaint(x, y, space_x, space_y, image, fcolor, bcolor, pMenu->pMenuItem[select].DisplayString);
pMenu->select = select;
}
}
else //全部绘制
{
MenuFramePaint(pMenu->MenuName);
for (i=0; i<pMenu->MenuItemCount; i++)
{
if (i == pMenu->select)
{
image = pMenuStyle->imgid_sel;
fcolor = pMenuStyle->f_color_sel;
bcolor = pMenuStyle->b_color_sel;
}
else
{
image = pMenuStyle->imgid_normal;;
fcolor = pMenuStyle->f_color_normal;
bcolor = pMenuStyle->b_color_normal;
}
MenuItemPaint(x, y, space_x, space_y, image, fcolor, bcolor, pMenu->pMenuItem.DisplayString);
y += pMenuStyle->dy;
row++;
if (row == pMenuStyle->row)
{
row = 0;
col++;
x += pMenuStyle->dx;
y = pMenuStyle->y0;
}
}
}
}
//获取当前被选中的项值
uint_8 GetMenuSel(Menu* pMenu)
{
return pMenu->select;
}
//获取目录项个数
uint_8 GetMenuItemCount(Menu* pMenu)
{
return pMenu->MenuItemCount;
}
//设置目录初始化函数
void SettingsMenuInit(void)
{
SettingsMenu.select = 0;
SettingsMenu.menu_style = (MenuStyle*)(&MenuStyleList[1]);
SettingsMenu.MenuItemCount = 12;
SettingsMenu.pMenuItem = SettingsMenuItem;
SettingsMenu.MenuName = "Settings";
SettingsMenuItem[0].DisplayString = "Test1";
SettingsMenuItem[0].Subs = NullSubs;
SettingsMenuItem[0].ChildrenMenus = NULL;
SettingsMenuItem[0].ParentMenus = MainMenuItem;
SettingsMenuItem[1].DisplayString = "Test2";
SettingsMenuItem[1].Subs = NullSubs;
SettingsMenuItem[1].ChildrenMenus = NULL;
SettingsMenuItem[1].ParentMenus = MainMenuItem;
SettingsMenuItem[2].DisplayString = "Test3";
SettingsMenuItem[2].Subs = NullSubs;
SettingsMenuItem[2].ChildrenMenus = NULL;
SettingsMenuItem[2].ParentMenus = MainMenuItem;
SettingsMenuItem[3].DisplayString = "Test4";
SettingsMenuItem[3].Subs = NullSubs;
SettingsMenuItem[3].ChildrenMenus = NULL;
SettingsMenuItem[3].ParentMenus = MainMenuItem;
SettingsMenuItem[4].DisplayString = "Test5";
SettingsMenuItem[4].Subs = NullSubs;
SettingsMenuItem[4].ChildrenMenus = NULL;
SettingsMenuItem[4].ParentMenus = MainMenuItem;
SettingsMenuItem[5].DisplayString = "Test6";
SettingsMenuItem[5].Subs = NullSubs;
SettingsMenuItem[5].ChildrenMenus = NULL;
SettingsMenuItem[5].ParentMenus = MainMenuItem;
SettingsMenuItem[6].DisplayString = "Test7";
SettingsMenuItem[6].Subs = NullSubs;
SettingsMenuItem[6].ChildrenMenus = NULL;
SettingsMenuItem[6].ParentMenus = MainMenuItem;
SettingsMenuItem[7].DisplayString = "Test8";
SettingsMenuItem[7].Subs = NullSubs;
SettingsMenuItem[7].ChildrenMenus = NULL;
SettingsMenuItem[7].ParentMenus = MainMenuItem;
SettingsMenuItem[8].DisplayString = "Test9";
SettingsMenuItem[8].Subs = NullSubs;
SettingsMenuItem[8].ChildrenMenus = NULL;
SettingsMenuItem[8].ParentMenus = MainMenuItem;
SettingsMenuItem[9].DisplayString = "Test10";
SettingsMenuItem[9].Subs = NullSubs;
SettingsMenuItem[9].ChildrenMenus = NULL;
SettingsMenuItem[9].ParentMenus = MainMenuItem;
SettingsMenuItem[10].DisplayString = "Test11";
SettingsMenuItem[10].Subs = NullSubs;
SettingsMenuItem[10].ChildrenMenus = NULL;
SettingsMenuItem[10].ParentMenus = MainMenuItem;
SettingsMenuItem[11].DisplayString = "Back";
SettingsMenuItem[11].Subs = NullSubs;
SettingsMenuItem[11].ChildrenMenus = MainMenuItem;
SettingsMenuItem[11].ParentMenus = MainMenuItem;
}
//根目录初始化
void MainMenuInit(void)
{
MainMenu.select = 0;
MainMenu.menu_style = (MenuStyle*)(&MenuStyleList[0]);
MainMenu.MenuItemCount = 5;
MainMenu.pMenuItem = MainMenuItem;
MainMenu.MenuName = "Main Menu";
MainMenuItem[0].DisplayString = "Test1;
MainMenuItem[0].Subs = NullSubs;
MainMenuItem[0].ChildrenMenus = NULL;
MainMenuItem[0].ParentMenus = NULL;
MainMenuItem[1].DisplayString = "Test2";
MainMenuItem[1].Subs = NullSubs;
MainMenuItem[1].ChildrenMenus = NULL;
MainMenuItem[1].ParentMenus = NULL;
MainMenuItem[2].DisplayString = "Test3";
MainMenuItem[2].Subs = NullSubs;
MainMenuItem[2].ChildrenMenus = NULL;
MainMenuItem[2].ParentMenus = NULL;
MainMenuItem[3].DisplayString = "Settings";
MainMenuItem[3].Subs = NullSubs;
MainMenuItem[3].ChildrenMenus = SettingsMenuItem;
MainMenuItem[3].ParentMenus = NULL;
MainMenuItem[4].DisplayString = "Test4";
MainMenuItem[4].Subs = NullSubs;
MainMenuItem[4].ChildrenMenus = NULL;
MainMenuItem[4].ParentMenus = NULL;
g_pCurMenu = &MainMenu;
}
void MenuInit(vodi)
{
MainMenuInit();
SettingsMenuInit();
}
void EventKeyEnter(void)
{
g_pCurMenu->pMenuItem[g_pCurMenu->select].Subs();
if (NULL != g_pCurMenu->pMenuItem[g_pCurMenu->select].ChildrenMenus)
{
g_pCurMenu = GetCurMenu(g_pCurMenu->pMenuItem[g_pCurMenu->select].ChildrenMenus);
g_pCurMenu->select = 0;
//更换目录,整个重绘
MenuPaint(1, 0, g_pCurMenu);
}
}
void EventKeyUp(void)
{
uint_8 sel;
sel = GetMenuSel(g_pCurMenu);
if (sel > 0)
{
sel--;
MenuPaint(0, sel, g_pCurMenu);
}
}
void EventKeyDown(void)
{
uint_8 sel;
sel = GetMenuSel(g_pCurMenu);
if (sel < GetMenuItemCount(g_pCurMenu)-1)
{
sel++;
MenuPaint(0, sel, g_pCurMenu);
}
}
void Test(void)
{
MenuInit();
while (1)
{
//调用按键扫描
}
}
有图有真相,贴上我已经实现的几种样式。
1.单排纯文本样式。
{4, 1, 8, 0, 0x11, 0x14, 0, NULL, NULL, 0x001F, COLOR_WHITE, COLOR_WHITE, 0x001F, 0x70, 0x1A},
2.多排纯文本样式。
{5, 4, 8, 0x40, 0x11, 0x14, 0, NULL, NULL, 0x001F, COLOR_WHITE, COLOR_WHITE, 0x001F, 0x10, 0x30},
3.图文并茂模式,文字在图片上,单排
{1, 1, 5, 0, 0x1F, 8, 5, (ImageResource*)(&ImageResourceList[1]), (ImageResource*)(&ImageResourceList[0]), COLOR_BLACK, COLOR_BLACK, COLOR_WHITE, COLOR_WHITE, 0x64, 0x24},
4.图文并茂模式,文字在图片上,多排
{2, 2, 6, 0x8F, 0x14, 7, 1, (ImageResource*)(&ImageResourceList[3]), (ImageResource*)(&ImageResourceList[2]), COLOR_BLACK, COLOR_BLACK, COLOR_WHITE, COLOR_WHITE, 0x1E, 0x20},
5.图文并茂模式,文字图片分离显示
{3, 1, 10, 0, 0x11, 0x14, 0, (ImageResource*)(&ImageResourceList[5]), (ImageResource*)(&ImageResourceList[4]), 0xFFE0, COLOR_WHITE, COLOR_BLACK, COLOR_BLACK, 0x10, 0x1A},
要做的好看,还是需要美工的配合啊。或者网上找一些按钮图片素材。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|