关键字: 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--环形进度条
离线
学习了,楼主给力!
离线