Jmhh247 发表于 2019-9-27 20:20:26

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

本帖最后由 Jmhh247 于 2019-9-27 20:24 编辑

关键字: 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;
    char btnText;
    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;


3. 控件用户接口

(这里只完成了最有用的部分,有源码可以按需魔改。。。)


// !!!----以下接口必须在控件初始化私有数据后才能调用----

// 设置环形值 ok
int zl_roundlevel_set_value(WM_HWIN hItem, int value)
{
    BATINFO_USER_SKIN *pUsr;
    char strbuf;


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


控制篇幅,只列出部分代码。


---
最后是工程源码:   

编辑原因:修改排版。




Jmhh247 发表于 2019-9-27 20:25:31

为了节约服务器空间和上传时间,本帖工程内不带字体文件。

需要到前的帖子 [原创开源]emWin导航界面支持Awesome图标字体 下载,复制到本帖工程内。

eric2013 发表于 2019-9-28 09:56:29

非常感谢楼主分享。

chenlijian80 发表于 2019-9-28 10:06:55

感谢楼主无私奉献,让吾等受益匪浅、、

Jmhh247 发表于 2019-9-28 11:57:36

chenlijian80 发表于 2019-9-28 10:06
感谢楼主无私奉献,让吾等受益匪浅、、

一起学习!

Jmhh247 发表于 2019-9-28 15:23:15

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


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


- 动画延迟

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

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


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

---
- 动态展示

只有第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);
    }
}




caicaptain2 发表于 2019-9-29 07:57:24

Jmhh247 发表于 2019-9-28 15:23
测试一下:环形进度条动画延迟效果




什么平台mcu测试这个比较流畅?配置的emwin ram到多少了?

Jmhh247 发表于 2019-9-29 08:32:57

caicaptain2 发表于 2019-9-29 07:57
什么平台mcu测试这个比较流畅?配置的emwin ram到多少了?

帖子里是在电脑上测试的。

还没在MCU上实测,F429来跑问题不大

l10618 发表于 2019-10-24 14:18:19

最近BOSS想要做个圆形的进度条,来学习一下怎样实现

xk2yx 发表于 2019-11-16 15:40:10

谢谢,,学习了。。

cplmaomao 发表于 2019-12-13 14:55:06

还是挺牛逼的~

crazymcu 发表于 2019-12-16 18:57:24

mark一下,感谢楼主分享

zhao_sj 发表于 2019-12-18 11:38:48

我搞到F429上面显示了很顺畅

ewrest 发表于 2019-12-24 09:17:54

很好的思路

ssis909 发表于 2019-12-27 11:01:26

这个用画圆弧加定时器控件重绘就可以实现,要是可以做成环形滑动按钮就好了

xk2yx 发表于 2019-12-30 10:49:26

不错。。。。。

a3607 发表于 2024-3-15 11:26:45

非常感谢楼主分享。
页: [1]
查看完整版本: [原创开源]emwin自定义控件2--环形进度条