搜索
bottom↓
回复: 33

多种样式的菜单在LCD屏上的实现

  [复制链接]

出0入0汤圆

发表于 2012-4-26 21:43:31 | 显示全部楼层 |阅读模式
本帖最后由 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, 杜汶泽)

出0入0汤圆

发表于 2012-4-26 22:00:23 | 显示全部楼层
无图无真相!~

出0入0汤圆

 楼主| 发表于 2012-4-26 22:08:36 | 显示全部楼层
ljt80158015 发表于 2012-4-26 22:00
无图无真相!~

明天有空再抓个图来。

出0入0汤圆

发表于 2012-4-26 22:11:25 | 显示全部楼层
本帖最后由 ljt80158015 于 2012-4-26 22:20 编辑

如果能实现树形菜单,那就太好了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-4-26 22:11:59 | 显示全部楼层
有空研究研究

出0入0汤圆

发表于 2012-4-27 10:31:49 | 显示全部楼层
有空看看!~!~~

出0入0汤圆

发表于 2012-4-27 11:23:42 | 显示全部楼层
果然比较复杂~~

出0入0汤圆

发表于 2012-4-27 11:27:49 | 显示全部楼层
不错。。。。。。。。。

出0入0汤圆

 楼主| 发表于 2012-4-27 20:21:48 | 显示全部楼层
ljt80158015 发表于 2012-4-26 22:11
如果能实现树形菜单,那就太好了。

可以实现的。不过我显示方式是一屏只显示一个菜单。显示下个菜单的时候就切画面。

出0入0汤圆

发表于 2012-4-28 10:13:48 | 显示全部楼层
相当不错!~

出0入0汤圆

发表于 2012-5-23 00:54:28 | 显示全部楼层
好教程值得看看!!

出15入9汤圆

发表于 2012-5-23 02:01:36 | 显示全部楼层
代码封装得不错。遇到那些文本框和菜单混排的界面就有点麻烦了。

出0入0汤圆

发表于 2012-5-23 05:44:38 | 显示全部楼层
这个不错的,感觉做菜单时间非常要耐心的事。

出0入0汤圆

发表于 2012-5-23 16:03:19 | 显示全部楼层
不错,学习!!!

出0入0汤圆

发表于 2012-5-23 16:11:13 | 显示全部楼层
很值得学习啊

出0入0汤圆

发表于 2012-6-14 10:46:26 | 显示全部楼层
楼主为什么不把完整源码公开一下?有图没有真相~!!!!

出0入0汤圆

发表于 2012-6-16 10:24:09 来自手机 | 显示全部楼层
关注中!求真相

出0入0汤圆

发表于 2013-5-2 09:16:01 | 显示全部楼层
頂一下,有空再看看~~~~

出0入0汤圆

发表于 2013-5-2 09:30:58 | 显示全部楼层
相当不错的东西

出0入0汤圆

发表于 2013-5-2 10:01:22 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2013-5-3 08:01:09 来自手机 | 显示全部楼层
动态输入的内容如何显示呢?

出0入0汤圆

发表于 2013-5-3 08:34:48 | 显示全部楼层
菜单应该有动态输入内容显示,自动返回上一层(长时间未操作)吧!和你的很类似。有机会交流一下

出0入0汤圆

发表于 2013-5-3 09:25:00 来自手机 | 显示全部楼层
不错不错

出0入0汤圆

发表于 2013-5-3 12:35:24 | 显示全部楼层
学习。。。。。。。。。。。。。

出0入0汤圆

发表于 2013-5-5 00:51:00 来自手机 | 显示全部楼层
非常不的资料!!

出0入0汤圆

发表于 2013-5-5 17:42:49 | 显示全部楼层
不錯

出0入0汤圆

发表于 2013-5-5 22:00:38 来自手机 | 显示全部楼层
很強大,頂樓主

出0入0汤圆

发表于 2013-5-12 09:19:05 | 显示全部楼层
学习了,谢谢分享

出0入0汤圆

发表于 2013-5-12 22:42:19 | 显示全部楼层
谢谢楼主的辛勤劳作  

出0入0汤圆

发表于 2013-5-12 23:09:10 | 显示全部楼层
LCD 菜单 好东西 学习了

出0入0汤圆

发表于 2014-9-10 15:45:52 | 显示全部楼层
mark,学习,。

出0入0汤圆

发表于 2014-9-11 17:54:46 | 显示全部楼层
代码质量非常高!!赞一个!

出0入0汤圆

发表于 2014-10-11 16:12:54 | 显示全部楼层
这个真心好。实现了图文混排,代码简洁。

出0入0汤圆

发表于 2014-10-11 23:39:19 来自手机 | 显示全部楼层
无图无真相,如果代码能配合图就更好了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-4 02:23

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表