硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2149|回复: 5
收起左侧

[emWin] 【分享】低内存用KNOB实现一个环形触控滑块。

[复制链接]

20

主题

110

回帖

170

积分

初级会员

积分
170
发表于 2019-4-11 20:06:37 | 显示全部楼层 |阅读模式
现在的智能设备上经常见到那种环形的滑块,很炫酷。最近做项目也想做个这样的滑块,不过emwin没提供这样的控件。参考了坛友的分享自己魔改了一个出来。精简了一些代码,内存占用低,性能比较好。
参考:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=30614&extra=page%3D1%26filter%3Ddigest%26digest%3D1
http://www.armbbs.cn/forum.php?mod=viewthread&tid=91792&extra=page%3D1

在F103上实测,只有旋钮控件情况下只需35Kb动态内存,这是实际不影响手指操作体验的大小,再大就要更多内存。操作时略微卡顿(F103跟不上了。。),欢迎大佬们来优化。
缺点是滑块另外画的,比较难看。因为没使用32bpp内存设备,所以旋钮控件自带的滑块用不了,欢迎大佬来实现更好看的滑块。
模拟器:
QQ截图20190411194848.jpg

  1. /*********************************************************************
  2. *                                                                    *
  3. *                SEGGER Microcontroller GmbH & Co. KG                *
  4. *        Solutions for real time microcontroller applications        *
  5. *                                                                    *
  6. **********************************************************************
  7. *                                                                    *
  8. * C-file generated by:                                               *
  9. *                                                                    *
  10. *        GUI_Builder for emWin version 5.32                          *
  11. *        Compiled Oct  8 2015, 11:59:02                              *
  12. *        (c) 2015 Segger Microcontroller GmbH & Co. KG               *
  13. *                                                                    *
  14. **********************************************************************
  15. *                                                                    *
  16. *        Internet: www.segger.com  Support: support@segger.com       *
  17. *                                                                    *
  18. **********************************************************************
  19. */

  20. // USER START (Optionally insert additional includes)
  21. // USER END

  22. #include "DIALOG.h"

  23. /*********************************************************************
  24. *
  25. *       Defines
  26. *
  27. **********************************************************************
  28. */
  29. #define ID_WINDOW_0  (GUI_ID_USER + 0x00)
  30. #define ID_KNOB_0 (GUI_ID_USER + 0x01)


  31. // USER START (Optionally insert additional defines)
  32. #define KNOB_XSIZE 85 //旋钮控件的大小,越大约占内存
  33. #define KNOB_YSIZE 85
  34. #define KNOB_STEP 5  //画环时的弧长系数

  35. #define AA_FACT 3 //抗锯齿质量
  36. // USER END

  37. /*********************************************************************
  38. *
  39. *       Static data
  40. *
  41. **********************************************************************
  42. */

  43. // USER START (Optionally insert additional static data)
  44. // USER END
  45. /*********************************************************************
  46. *
  47. *       _aDialogCreate
  48. */
  49. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  50.   { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
  51.   // USER START (Optionally insert additional widgets)
  52.   { KNOB_CreateIndirect, "", ID_KNOB_0, 115, 45, KNOB_XSIZE, KNOB_YSIZE, WM_CF_SHOW}
  53.   // USER END
  54. };

  55. /*********************************************************************
  56. *
  57. *       Static code
  58. *
  59. **********************************************************************
  60. */

  61. // USER START (Optionally insert additional static code)
  62. /*--------------- 画环形滑块 -----------------

  63. */
  64. static void _DrawWheel(KNOB_Handle hKnob) {
  65.         GUI_COLOR mycolor;

  66.         I32       Value;
  67.         int       xPos, yPos;
  68.         int ArcStart = 360 - KNOB_STEP, ArcEnd = 360;
  69.         int i=0, step;
  70.         Value = 360 - KNOB_GetValue(hKnob) / 10; //获取当前值
  71.         step = Value / KNOB_STEP; //算出需要画内部弧形的个数

  72.         xPos = 115 + KNOB_XSIZE / 2; //计算坐标,确保环和内部弧形是以旋钮控件中心为原点
  73.         yPos = 45 + KNOB_YSIZE / 2;

  74.         GUI_SetFont(&GUI_Font13B_ASCII);

  75.         GUI_AA_EnableHiRes(); //开高分辨率模式
  76.         GUI_AA_SetFactor(AA_FACT); //抗锯齿因子,关闭抗锯齿可减少卡顿

  77.         /*画圆环*/
  78.         GUI_SetPenSize(16); //使用弧线画环,可以调整画笔实现弧线粗细
  79.         GUI_SetColor(0x00f5ec80);
  80.         GUI_AA_DrawArc(xPos*AA_FACT, yPos*AA_FACT, 38*AA_FACT, 38*AA_FACT, 0, 360);


  81.         /*根据旋钮值画内部弧形*/
  82.         GUI_SetColor(0x00FFFFD0);
  83.         GUI_SetPenSize(8);
  84.         for(; i<=step-1; i++)
  85.         {   //增大KNOB_STEP可减少画弧形的次数,可减少卡顿,但滑块变化精度变低
  86.                 GUI_AA_DrawArc(xPos*AA_FACT, yPos*AA_FACT, 38*AA_FACT, 38*AA_FACT,  ArcStart, ArcEnd);
  87.                
  88.                 ArcEnd = ArcStart; //上一个弧形的初角度成为下一个弧形的末角度
  89.                 ArcStart = ArcStart - KNOB_STEP;//下一个弧形的初角度
  90.         }
  91.         GUI_SetColor(0x000000FF);
  92.         for(; i<=step; i++) //最后几段弧形作为滑块指示
  93.         {
  94.                 GUI_AA_DrawArc(xPos*AA_FACT, yPos*AA_FACT, 38*AA_FACT, 38*AA_FACT,  ArcStart, ArcEnd);
  95.                
  96.                 ArcEnd = ArcStart; //上一个弧形的初角度成为下一个弧形的末角度
  97.                 ArcStart = ArcStart - KNOB_STEP;//下一个弧形的初角度
  98.         }

  99.         GUI_AA_DisableHiRes();//关闭高分辨率
  100.         GUI_SetColor(GUI_WHITE);
  101.         GUI_DispDecAt(Value,xPos-16,yPos-3, 5);
  102.                
  103.        
  104. }
  105. // USER END

  106. /*********************************************************************
  107. *
  108. *       _cbDialog
  109. */
  110. static void _cbDialog(WM_MESSAGE * pMsg) {
  111.   WM_HWIN hItem;
  112.   // USER START (Optionally insert additional variables)
  113.   static GUI_MEMDEV_Handle   hMemKnobSmall;
  114.   // USER END

  115.   switch (pMsg->MsgId) {
  116.   case WM_INIT_DIALOG:
  117.     //
  118.     // Initialization of 'Window'
  119.     //
  120.     hItem = pMsg->hWin;
  121.     WINDOW_SetBkColor(hItem, GUI_MAKE_COLOR(0x00738640));
  122.         //
  123.     // 初始化旋钮
  124.     //
  125.         KNOB_SetRange(WM_GetDialogItem(pMsg->hWin,ID_KNOB_0), 0, 3600);
  126.         KNOB_SetOffset(WM_GetDialogItem(pMsg->hWin,ID_KNOB_0), 0);
  127.         KNOB_SetPeriod(WM_GetDialogItem(pMsg->hWin,ID_KNOB_0), 100); //控制旋钮减速度
  128.         KNOB_SetPos(WM_GetDialogItem(pMsg->hWin,ID_KNOB_0),3600);
  129.     // USER END
  130.     break;
  131.   // USER START (Optionally insert additional message handling)
  132.         case WM_PAINT:
  133.         _DrawWheel(WM_GetDialogItem(pMsg->hWin,ID_KNOB_0));
  134.         break;
  135.   // USER END
  136.   default:
  137.     WM_DefaultProc(pMsg);
  138.     break;
  139.   }
  140. }

  141. /*********************************************************************
  142. *
  143. *       Public code
  144. *
  145. **********************************************************************
  146. */
  147. /*********************************************************************
  148. *
  149. *       CreateWindow
  150. */
  151. WM_HWIN CreateKNOB(void);
  152. WM_HWIN CreateKNOB(void) {
  153.   WM_HWIN hWin;

  154.   hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  155.   return hWin;
  156. }

  157. // USER START (Optionally insert additional public code)
  158. // USER END

  159. /*************************** End of file ****************************/
复制代码


评分

参与人数 1金币 +100 收起 理由
eric2013 + 100 赞一个!

查看全部评分

回复

使用道具 举报

36

主题

1446

回帖

1554

积分

至尊会员

积分
1554
发表于 2019-4-11 20:21:49 | 显示全部楼层
不错
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107397
QQ
发表于 2019-4-12 00:38:28 | 显示全部楼层
非常感谢楼主分享。
回复

使用道具 举报

36

主题

2040

回帖

2148

积分

至尊会员

积分
2148
发表于 2019-4-12 10:40:37 | 显示全部楼层
在WM_PAINT消息里面放,比较耗资源,这个消息会经常进入,有没有尝试过在KNOB的回调函数里面实现。

        _DrawWheel(WM_GetDialogItem(pMsg->hWin,ID_KNOB_0));
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

20

主题

110

回帖

170

积分

初级会员

积分
170
 楼主| 发表于 2019-4-12 14:36:29 | 显示全部楼层
本帖最后由 飛饵 于 2019-4-12 14:39 编辑
byccc 发表于 2019-4-12 10:40
在WM_PAINT消息里面放,比较耗资源,这个消息会经常进入,有没有尝试过在KNOB的回调函数里面实现。

     ...

试了下好像不行。
我是在KNOB回调函数的WM_PAINT里调用绘制函数,这样可以吗?
回复

使用道具 举报

20

主题

110

回帖

170

积分

初级会员

积分
170
 楼主| 发表于 2019-4-12 14:36:36 | 显示全部楼层
本帖最后由 飛饵 于 2019-4-12 14:39 编辑
byccc 发表于 2019-4-12 10:40
在WM_PAINT消息里面放,比较耗资源,这个消息会经常进入,有没有尝试过在KNOB的回调函数里面实现。

     ...

试了下好像不行。
我是在KNOB回调函数的WM_PAINT里调用绘制函数,这样可以吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-30 05:32 , Processed in 0.182369 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表