关键字: emwin, 自定义控件,环形进度条
这是一个用emwin写的主页面导航+侧边导航的通用程序框架,emwin仿真环境用的是codeblocks(16或17都可)。
本篇主要分享了一种环形进度条的自定义控件。(由于只是程序框架,所以并不涉及界面美化,我知道丑,所以先说出来~)
本坛首发!
---
- 环形进度条
很常见的控件,就算现在没用,以后一定用的上!
---
- 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},
};
static BATINFO_USER_SKIN *pBtnUser[GUI_COUNTOF(BatInfoData)];
3. 控件用户接口
(这里只完成了最有用的部分,有源码可以按需魔改。。。)
// !!!----以下接口必须在控件初始化私有数据后才能调用----
// 设置环形值 ok
int zl_roundlevel_set_value(WM_HWIN hItem, int value)
{
BATINFO_USER_SKIN *pUsr;
char strbuf[6];
if (value > 100) {
value = 100;
}
// 更新进度环
BUTTON_GetUserData(hItem, &pUsr, sizeof(pUsr));
pUsr->ch = value;
// 更新数字值
sprintf(strbuf, "%i %%", value);
BUTTON_SetText(hItem, strbuf);
}
// 设置进度条颜色 ok
int zl_roundlevel_set_color(WM_HWIN hItem, GUI_COLOR color)
{
BATINFO_USER_SKIN *pUsr;
BUTTON_GetUserData(hItem, &pUsr, sizeof(pUsr));
pUsr->colorPressed = color;
WM_InvalidateWindow(hItem);
}
// 设置文字颜色 ok
int zl_roundlevel_set_valuecolor(WM_HWIN hItem, GUI_COLOR color)
{
BUTTON_SetTextColor(hItem, BUTTON_CI_UNPRESSED, color);
BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, color);
}
4. 环形进度条实现代码
// 环形进度条实现 ok
int button_drawskin_roundlevel(const WIDGET_ITEM_DRAW_INFO* pItem)
{
BATINFO_USER_SKIN *pUsr;
char acBuf[20];
int xPos;
int yPos;
int r;
switch (pItem->Cmd)
{
case WIDGET_ITEM_DRAW_BACKGROUND:
BUTTON_GetUserData(pItem->hWin, &pUsr, sizeof(pUsr));
if (BUTTON_IsPressed(pItem->hWin))
{
GUI_SetColor(pUsr->colorUnPress);
}
else
{
GUI_SetColor(pUsr->colorUnPress);
}
// 计算半径
r = (pItem->x1 < pItem->y1) ? pItem->x1 : pItem->y1;
if (r % 2) {
r -= 3;
}
else {
r -= 2;
}
xPos = pItem->x1 / 2;
yPos = pItem->y1 / 2;
// 外圆
GUI_AA_FillCircle(xPos, yPos, r / 2);
// 内圆
GUI_SetColor(GUI_DARKCYAN);
GUI_AA_FillCircle(xPos, yPos, r / 2 - (r / 6));
// 进度环
GUI_SetColor(pUsr->colorPressed);
GUI_SetPenSize(r/6 - 1);
GUI_AA_DrawArc(xPos, yPos, r / 2 - (r / 6 / 2) - 1, 0, 0, pUsr->ch * 3.6);
break;
default:
{
return BUTTON_DrawSkinFlex(pItem);
}
}
return 0;
}
控制篇幅,只列出部分代码。
---
最后是工程源码: emwin-uidemo8-cbprj.zip
离线
忘记说了,本帖工程不带字体文件,需要去第1个帖子下载-[ [原创开源]emwin导航界面支持Awesome图标字体]https://whycan.cn/t_2917.html
离线
测试一下:环形进度条动画延迟效果
(只是测试,比较简陋,暂时不整理工程出来~)
- 动画延迟
动画延迟效果,就是有一个收敛的过程,不是一步到位的。
比如抽奖的表盘,不是你转一下就停,而是有一个延迟过程才停下来。
!!!----("动画延迟"-这个叫法可能不专业~)
---
- 动态展示
只有第1个环形进度条带延迟效果,仔细看可以看到,其它进度条都是直接停下来,而第1个进度条经过一段延迟才停下来。
(gif有撕裂感,是gif工具的问题,实际很流畅)
---
- 核心代码
##### 原理是:不直接更新设置值,而是通过一个定时器间接更新设置值,从而实现动画延迟。
#define ID_TIMER_TIME 1
static void _cb_round(WM_MESSAGE * pMsg)
{
static WM_HTIMER hTimerTime;
WM_HWIN hWin;
int Id;
BATINFO_USER_SKIN *pUsr;
static int value = 0;
hWin = pMsg->hWin;
BUTTON_GetUserData(hWin, &pUsr, sizeof(pUsr));
switch (pMsg->MsgId)
{
case WM_TIMER:
Id = WM_GetTimerId(pMsg->Data.v);
if (pUsr->ch < pUsr->sw) {
pUsr->ch++;
}
else if (pUsr->ch > pUsr->sw) {
pUsr->ch--;
}
zl_roundlevel_set_value(hWin, pUsr->ch);
WM_RestartTimer(pMsg->Data.v, 30);
break;
default:
BUTTON_Callback(pMsg);
}
}
离线