关键字: emwin, 自定义控件,卡片面板
这是一个用emwin写的主页面导航+侧边导航的通用程序框架,emwin仿真环境用的是codeblocks(16或17都可)。
##### 本坛首发。
本篇主要介绍了一种卡片式的自定义控件。(由于只是程序框架,所以并不涉及界面美化,我知道丑,所以先说出来~)
---
- 卡片面板
卡片面板是我自己起的名字,不知道此类控件是否有准确的叫法。
在横屏设备中,卡片面板有着大量的应用,通常用来展示同类信息。
下面的截图来自最近沉迷的手游《QQ飞车》。(飞车一局2分钟左右,比王者玩起来轻松太多了,当然我主要是为看它的GUI设计,信吧~)

---
- APP截图
下面是部分APP截图
静态展示

动态展示

---
- 代码实现
##### 原理就是用emwin系统的皮肤设置函数+按钮私有数据。这相当于一种自定义控件实现的简单方法,通过不同的函数+数据结构就能实现不同功能的控件。
1. 结构体类型
typedef struct {
    int Check;
    GUI_COLOR colorPressed;
    GUI_COLOR colorUnPress;
    GUI_FONT *iconFont;
    char iconName[6];
    char btnText[10];
    int ch;
    int sw;
    int mode;
    float batV;
    int batI;
    float power;
} BATINFO_USER_SKIN;2. 结构体定义
static BATINFO_USER_SKIN BatInfoData[] = {
    {ZL_BTN_CHKMODE_NO, GUI_DARKCYAN, GUI_DARKMAGENTA, &awefont24, "\uf0f6", "stm8", 1, 1, ZL_BATINFO_MODE_CC, 12.305, 2000},
    {ZL_BTN_CHKMODE_NO, GUI_DARKCYAN, GUI_DARKMAGENTA, &awefont24, "\uf030", "stm32", 2, 1, ZL_BATINFO_MODE_ST, 10.8, 1500},
    {ZL_BTN_CHKMODE_NO, GUI_DARKCYAN, GUI_DARKMAGENTA, &awefont24, "\uf008", "mcu", 3, 0, ZL_BATINFO_MODE_CV},
    {ZL_BTN_CHKMODE_NO, GUI_DARKCYAN, GUI_DARKMAGENTA, &awefont24, "\uf226", "linux", 4, 1, ZL_BATINFO_MODE_DC, 12.0, 1800},
    {ZL_BTN_CHKMODE_NO, GUI_DARKCYAN, GUI_DARKMAGENTA, &awefont24, "\uf144", "audio", 5},
};3. 卡片面板实现代码
// 卡片面板控件 ok
int button_drawskin_batinfo(const WIDGET_ITEM_DRAW_INFO* pItem)
{
    BATINFO_USER_SKIN *pUsr;
    GUI_RECT rect;
    char acBuf[20];
    int xSize;
    int ySize;
    int strXsizeLen;
    int xPos;
	switch (pItem->Cmd)
	{
    case WIDGET_ITEM_DRAW_TEXT:
            BUTTON_GetText(pItem->hWin, acBuf, sizeof(acBuf));
            rect.x0 = pItem->x0;
            rect.x1 = pItem->x1;
            rect.y0 = pItem->y0;
            rect.y1 = pItem->y1;
            GUI_SetFont(BUTTON_GetFont(pItem->hWin));
            GUI_SetTextMode(GUI_TM_TRANS);
            GUI_SetColor(GUI_LIGHTGREEN);
            rect.y0 = rect.y1 / 12;
            BUTTON_GetUserData(pItem->hWin, &pUsr, sizeof(pUsr));
            GUI_DispStringAt("CH", 3, rect.y0);
            GUI_DispDecAt(pUsr->ch, 15 + 8, rect.y0, 2);
            if (pUsr->sw == 1) {
                strXsizeLen = GUI_GetStringDistX("ON");
                GUI_SetColor(GUI_WHITE);
                GUI_AA_FillRoundedRect(63-2, rect.y0-2, 63+strXsizeLen+2, rect.y0+16, 2);
                GUI_SetColor(GUI_RED);
                GUI_DispStringAt("ON", 63, rect.y0);
                //
                GUI_SetColor(GUI_LIGHTGREEN);
                if (pUsr->mode == ZL_BATINFO_MODE_CC) {
                    GUI_DispStringAt("CC", 58 + 40, rect.y0);
                }
                else if (pUsr->mode == ZL_BATINFO_MODE_CV) {
                    GUI_DispStringAt("CV", 58 + 40, rect.y0);
                }
                else if (pUsr->mode == ZL_BATINFO_MODE_DC) {
                    GUI_DispStringAt("DC", 58 + 40, rect.y0);
                }
                else if (pUsr->mode == ZL_BATINFO_MODE_ST) {
                    GUI_DispStringAt("ST", 58 + 40, rect.y0);
                }
                // vol
                strXsizeLen = 0;
                sprintf(acBuf, "%.3f", pUsr->batV);
                GUI_SetFont(GUI_FONT_24B_ASCII);
                strXsizeLen += GUI_GetStringDistX(acBuf);
                GUI_SetFont(GUI_FONT_16B_ASCII);
                strXsizeLen += GUI_GetStringDistX("V");
                xPos = (WM_GetWindowSizeX(pItem->hWin) - strXsizeLen) / 2;
                GUI_GotoXY(xPos, rect.y0 + 60);
                GUI_SetFont(GUI_FONT_24B_ASCII);
                GUI_DispString(acBuf);
                GUI_GotoY(rect.y0 + 60 + (5));
                GUI_SetFont(GUI_FONT_16B_ASCII);
                GUI_DispString("V");
                // i
                strXsizeLen = 0;
                sprintf(acBuf, "%d", pUsr->batI);
                GUI_SetFont(GUI_FONT_24B_ASCII);
                strXsizeLen += GUI_GetStringDistX(acBuf);
                GUI_SetFont(GUI_FONT_16B_ASCII);
                strXsizeLen += GUI_GetStringDistX("mA");
                xPos = (WM_GetWindowSizeX(pItem->hWin) - strXsizeLen) / 2;
                GUI_GotoXY(xPos, rect.y0 + 60 + 25);
                GUI_SetFont(GUI_FONT_24B_ASCII);
                GUI_DispString(acBuf);
                GUI_GotoY(rect.y0 + 60 + + 25 + (5));
                GUI_SetFont(GUI_FONT_16B_ASCII);
                GUI_DispString("mA");
//                GUI_DispDecAt(pUsr->power, 8 + 50, rect.y0 + 60 + 50, 4);
//                GUI_DispString("mAh");
            }
            else {
                strXsizeLen = GUI_GetStringDistX("OFF");
                GUI_SetColor(GUI_WHITE);
                GUI_AA_FillRoundedRect(63-2, rect.y0-2, 63+strXsizeLen+2, rect.y0+16, 2);
                GUI_SetColor(GUI_RED);
                GUI_DispStringAt("OFF", 63, rect.y0);
            }
        break;
	case WIDGET_ITEM_DRAW_BACKGROUND:
		    BUTTON_GetUserData(pItem->hWin, &pUsr, sizeof(pUsr));
			if (BUTTON_IsPressed(pItem->hWin))
			{
                if (pUsr->sw == 1) {
                    GUI_SetColor(pUsr->colorPressed);
                }
                else {
                    GUI_SetColor(pUsr->colorPressed);
                }
			}
			else
			{
                if (pUsr->sw == 1) {
                    GUI_SetColor(pUsr->colorUnPress);
                }
                else {
                    GUI_SetColor(pUsr->colorPressed);
                }
			}
			GUI_AA_FillRoundedRect(pItem->x0, pItem->y0, pItem->x1, pItem->y1, 0);
            rect.x0 = pItem->x0;
            rect.x1 = pItem->x1;
            rect.y0 = pItem->y0;
            rect.y1 = pItem->y1;
            rect.y0 = rect.y1 / 5;
            GUI_SetColor(GUI_GRAY_E7);
            GUI_DrawHLine(rect.y0, rect.x0, rect.x1);
            GUI_SetPenSize(2);
            GUI_AA_DrawLine(pItem->x0 + 35, pItem->y0 + 1, pItem->x0 + 20 + 30, rect.y0 -1);
			if (pUsr->Check == ZL_BTN_CHKMODE_UP){
                GUI_SetPenSize(5);
                GUI_SetColor(GUI_WHITE);
                GUI_DrawLine(pItem->x0, pItem->y0, pItem->x1, pItem->y0);
			}
			if (pUsr->Check == ZL_BTN_CHKMODE_DOWN){
                GUI_SetPenSize(5);
                GUI_SetColor(GUI_WHITE);
                GUI_DrawLine(pItem->x0, pItem->y1, pItem->x1, pItem->y1);
			}
			if (pUsr->Check == ZL_BTN_CHKMODE_LEFT){
                GUI_SetPenSize(5);
                GUI_SetColor(GUI_WHITE);
                GUI_DrawLine(pItem->x0, pItem->y0, pItem->x0, pItem->y1);
			}
			if (pUsr->Check == ZL_BTN_CHKMODE_RIGHT){
                GUI_SetPenSize(5);
                GUI_SetColor(GUI_WHITE);
                GUI_DrawLine(pItem->x1, pItem->y0, pItem->x1, pItem->y1);
			}
        break;
	default:
		{
			return BUTTON_DrawSkinFlex(pItem);
		}
	}
	return 0;
}控制篇幅,只列出部分代码。
---
最后是工程源码:  emwin-uidemo7-cbprj.zip
离线
为了节约空间和时间,本帖工程内不带字体文件。
需要到前的帖子下载字体,并复制到本工程内。
离线
特别感谢楼主的无私分享!
我默默列一个往期回顾吧:
1. [原创开源]emwin导航界面支持Awesome图标字体
2. [原创开源]emwin侧边导航框架支持按钮选中效果 
3. [原创开源]emwin自定义控件1-卡片面板
4. [原创开源]emwin自定义控件2--环形进度条
离线

太棒了, 我坐等下一个啊
离线
楼主V5啊,下来试试
离线
道友,早点睡吧,身体是**的本钱~
楼主V5啊,下来试试
离线
顶!
离线
求续集 ^_^
离线
感谢楼主分享, 已加入本站精华帖汇总:
185. [原创开源]emwin导航界面支持Awesome图标字体
186. [原创开源]emwin侧边导航框架支持按钮选中效果 
187. [原创开源]emwin自定义控件1-卡片面板
188. [原创开源]emwin自定义控件2--环形进度条
离线
学习了,楼主给力!
离线