您尚未登录。

楼主 #1 2019-09-27 12:26:00

Jmhh247
会员
注册时间: 2018-12-21
已发帖子: 262
积分: 262

[原创开源]emwin自定义控件2--环形进度条

关键字: emwin, 自定义控件,环形进度条


这是一个用emwin写的主页面导航+侧边导航的通用程序框架,emwin仿真环境用的是codeblocks(16或17都可)。



本篇主要分享了一种环形进度条的自定义控件。(由于只是程序框架,所以并不涉及界面美化,我知道丑,所以先说出来~)


  本坛首发!


---
- 环形进度条

很常见的控件,就算现在没用,以后一定用的上!



---
- APP截图

下面是部分APP截图


静态展示

FluxBB bbcode 测试

动态展示

FluxBB bbcode 测试



---
- 核心代码

##### 原理就是用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

离线

楼主 #2 2019-09-27 13:10:32

Jmhh247
会员
注册时间: 2018-12-21
已发帖子: 262
积分: 262

Re: [原创开源]emwin自定义控件2--环形进度条

忘记说了,本帖工程不带字体文件,需要去第1个帖子下载-[ [原创开源]emwin导航界面支持Awesome图标字体]https://whycan.cn/t_2917.html

离线

楼主 #4 2019-09-28 15:16:26

Jmhh247
会员
注册时间: 2018-12-21
已发帖子: 262
积分: 262

Re: [原创开源]emwin自定义控件2--环形进度条

测试一下:环形进度条动画延迟效果


(只是测试,比较简陋,暂时不整理工程出来~)


- 动画延迟

动画延迟效果,就是有一个收敛的过程,不是一步到位的。

比如抽奖的表盘,不是你转一下就停,而是有一个延迟过程才停下来。


!!!----("动画延迟"-这个叫法可能不专业~)


---
- 动态展示

只有第1个环形进度条带延迟效果,仔细看可以看到,其它进度条都是直接停下来,而第1个进度条经过一段延迟才停下来。

(gif有撕裂感,是gif工具的问题,实际很流畅)


FluxBB bbcode 测试

---
- 核心代码

##### 原理是:不直接更新设置值,而是通过一个定时器间接更新设置值,从而实现动画延迟。


#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);
	}
}

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn