迪文科技论坛

 找回密码
 立即注册
搜索
查看: 172|回复: 0

【2023.6.17获奖项目】基于迪文圆形屏的双旋转菜单显示方案

[复制链接]

567

主题

167

回帖

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11978
发表于 2024-1-11 11:54:37 | 显示全部楼层 |阅读模式
【开源】基于迪文圆形屏的双旋钮菜单显示方案

该方案基于迪文圆形屏设计,有两种菜单显示选择,一种是显示八个图片在左右滑动的时候所有图标会以圆周的形式进行运动,无触摸状态图标自行归位;第二种是显示14个图标,类似FIFO模式的进出,即先进先出队列。


一、背景介绍

圆形屏幕和方形屏幕不同,所以在想有什么适合圆形屏幕的菜单,经过一段时间的思考,发现可以做一个旋转菜单。


二、设计想法

我之前发布在迪文开发者论坛发布过一款圆屏雷达Demo,上面有对应显示雷达点位设计,让8个点位显示在离中心点不同的角度,让每个点不进行重叠,这次设计也使用了这个方案。

这次设计一共设计了两种菜单。

第一种是显示八个图片,在左右滑动的时候所有图标会以圆周的形式进行运动,并设计了一个归位功能,当屏幕不再触摸的时候,图标会自行归位,这里的实现需要检测触摸松开。图标自动归位主要是在触摸松开里进行一个归位处理,归位处理则检测运动的角度,如果不是能整除45则递增或者递减,显示八个图标刚好就是45度。

第二种设计比较麻烦,因为要显示14个图标,这时候就需要有一个地方可以让图标进行替换,而且是那种FIFO模式的进出。这块设计非常麻烦,足足耗费了我两个晚上。刚开始我是想就用8个变量图标,然后到一定角度时显示不同的图标,不过发现这个极其复杂。后面我就定义了14个变量图标,把这些变量图标藏在一个图片后面,这样就用类似FIFO的模式把变量图标一个一个的扔出去就行了。


三、具体设计

(一)准备素材

这里我给大家分享一个阿里巴巴对外提供的矢量图库【https://www.iconfont.cn/home/index】,下面是我准备的图标和背景图片。

(二)UI界面设计

第一种就是放8个变量图标即可。

第二种就是放14个变量图标,加上一个置顶图片,用于遮盖其他变量图标。

然后在创建两个页面,用于菜单点击后的显示,一共设计了两个,分别对应两个旋转菜单。


(三)代码设计

这里代码设计需要获取触摸情况。一共是两个页面,根据获取的按键值,判断进入的是哪一种菜单模式。然后获取滑动差值和结束触摸,将这些差值和结束触摸事件发送给相关的函数。

  1. //获取触摸位置
  2. void get_tp_status()
  3. {
  4.     static u16 get_timer = 0;
  5.     static u16 SildeValue = 0;
  6.     static u16 lastX = 0;

  7.     u16 SildeTemp = 0;
  8.     u16 Va[3] = 0;
  9.     u8 i = 0, j = 0;
  10.    
  11.     get_timer++;
  12.     if(get_timer >= 1000)
  13.     {
  14.         get_timer = 0;

  15.         SildeTemp = Read_Dgus(0x4000);
  16.         if(SildeTemp != 0x0000)
  17.         {
  18.             SildeValue = SildeTemp;
  19.             SildeTemp = 0x0000;
  20.             write_dgus_vp(0x4000, &SildeTemp, 1);    //清除
  21.             Va[0] = 0x0000;
  22.             Va[1] = 0x0000;
  23.             Va[2] = 0x0000;
  24.             write_dgus_vp(0x0016, Va, 3);
  25.             if(SildeValue == 0x0001)
  26.             {
  27.                 Va[0] = 0x0006;
  28.                 silde1MenuCurrent = 6;
  29.                 write_dgus_vp(0x17F0, Va, 1);   //中间默认图标
  30.                 silde1_angle = 0;
  31.                 for(i = 0;i < 8;i++)
  32.                 {
  33.                     silde1_pos_set(i, 0);
  34.                 }
  35.             }
  36.             else if(SildeValue == 0x0002)
  37.             {
  38.                 Va[0] = 0x0006;
  39.                 silde2MenuCurrent = 0;
  40.                 write_dgus_vp(0x27F0, Va, 1);   //中间默认图标
  41.                 silde2_angle = DEFAULT_ANGLE;
  42.                 for(i = 0;i < 8;i++)
  43.                 {
  44.                     silde2_pos_set(i, DEFAULT_ANGLE, i);
  45.                 }
  46.             }
  47.         }

  48.         if(SildeValue == 0x0001)
  49.         {
  50.             SildeTemp = Read_Dgus(0x4010);
  51.             if(SildeTemp != 0x0000)
  52.             {
  53.                 SildeTemp = 0x0000;
  54.                 write_dgus_vp(0x4010, &SildeTemp, 1);    //清除
  55.                
  56.                 if(silde1MenuCurrent == 0)
  57.                 {
  58.                     switch_screen(0x00);
  59.                 }
  60.                 else
  61.                 {
  62.                     u8 display_text[] = {'M', 'e', 'n', 'u', 0x00, 0x00};
  63.                     display_text[4] = silde1MenuCurrent + 0x30;
  64.                     write_dgus_vp(0x4100, display_text, 3);
  65.                     switch_screen(0x03);
  66.                 }
  67.             }
  68.         }
  69.         else if(SildeValue == 0x0002)
  70.         {
  71.             SildeTemp = Read_Dgus(0x4020);
  72.             if(SildeTemp != 0x0000)
  73.             {
  74.                 SildeTemp = 0x0000;
  75.                 write_dgus_vp(0x4020, &SildeTemp, 1);    //清除
  76.                
  77.                 if(silde2MenuCurrent == 0)
  78.                 {
  79.                     switch_screen(0x00);
  80.                 }
  81.                 else
  82.                 {
  83.                     u8 display_text[] = {'M', 'e', 'n', 'u', 0x00, 0x00};
  84.                     if(silde2MenuCurrent < 10)
  85.                     {
  86.                         display_text[4] = silde2MenuCurrent + 0x30;
  87.                     }
  88.                     else
  89.                     {
  90.                         display_text[4] = silde2MenuCurrent / 10 + 0x30;
  91.                         display_text[5] = silde2MenuCurrent % 10 + 0x30;
  92.                     }
  93.                     write_dgus_vp(0x4200, display_text, 3);
  94.                     switch_screen(0x04);
  95.                 }
  96.             }
  97.         }

  98.         

  99.         if(SildeValue > 0)
  100.         {
  101.             if(SildeValue == 1)
  102.             {
  103.                 for(i = 0;i < 3;i++)    //获取触摸值
  104.                 {
  105.                     Va[i] = Read_Dgus(0x0016 + i);
  106.                     if(Va[0] == 0x5A03)
  107.                     {
  108.                         //UART2_Sendbyte(Va[i] / 256);
  109.                         //UART2_Sendbyte(Va[i] % 256);  
  110.                     }
  111.                     else
  112.                     {
  113.                         break;
  114.                     }
  115.                 }
  116.                 if(Va[0] == 0x5A03)
  117.                 {
  118.                     if(lastX != 0)
  119.                     {
  120.                         s16 move = Va[1] - lastX;
  121.                         silde1_move(move);
  122.                         lastX = Va[1];
  123.                     }
  124.                     else
  125.                     {
  126.                         lastX = Va[1];
  127.                     }
  128.                 }
  129.                 else if(Va[0] == 0x5A02)    //松开
  130.                 {
  131.                     lastX = 0;
  132.                     //自动归位
  133.                     silde1_reset();
  134.                     Va[0] = 0x0000;
  135.                     Va[1] = 0x0000;
  136.                     Va[2] = 0x0000;
  137.                     write_dgus_vp(0x0016, Va, 3);
  138.                 }
  139.             }
  140.             else if(SildeValue == 2)
  141.             {
  142.                 for(i = 0;i < 3;i++)    //获取触摸值
  143.                 {
  144.                     Va[i] = Read_Dgus(0x0016 + i);
  145.                     if(Va[0] == 0x5A03)
  146.                     {
  147.                         //UART2_Sendbyte(Va[i] / 256);
  148.                         //UART2_Sendbyte(Va[i] % 256);  
  149.                     }
  150.                     else
  151.                     {
  152.                         break;
  153.                     }
  154.                 }
  155.                 if(Va[0] == 0x5A03)
  156.                 {
  157.                     if(lastX != 0)
  158.                     {
  159.                         s16 move = Va[1] - lastX;
  160.                         silde2_move(move);
  161.                         lastX = Va[1];
  162.                     }
  163.                     else
  164.                     {
  165.                         lastX = Va[1];
  166.                     }
  167.                 }
  168.                 else if(Va[0] == 0x5A02)    //松开
  169.                 {
  170.                     lastX = 0;
  171.                     //自动归位
  172.                     silde2_reset();
  173.                     Va[0] = 0x0000;
  174.                     Va[1] = 0x0000;
  175.                     Va[2] = 0x0000;
  176.                     write_dgus_vp(0x0016, Va, 3);
  177.                 }
  178.             }
  179.         }        
  180.     }   
  181. }
复制代码

这个是第一种滑动旋转的函数:

  1. //滑动旋转
  2. void silde1_move(s16 dis)
  3. {
  4.     u16 i = 0;
  5.    
  6.     silde1_angle = silde1_angle + (dis / 2);
  7.     while(silde1_angle < 0)
  8.     {
  9.         silde1_angle += 360;
  10.     }
  11.     while(silde1_angle > 360)
  12.     {
  13.         silde1_angle -= 360;
  14.     }
  15.     for(i = 0;i < 8;i++)
  16.     {
  17.         silde1_pos_set(i, silde1_angle);
  18.     }   
  19. }
复制代码

这是第一种自动归位的函数:

  1. //自动归位
  2. void silde1_reset()
  3. {
  4.     u8 add_flag = 0;
  5.     u8 i = 0;

  6.    
  7.     if(silde1_angle % 45 > 22)
  8.     {
  9.         add_flag = 1;
  10.     }
  11.     else if(silde1_angle % 45 <= 22 && (silde1_angle % 45) != 0)
  12.     {
  13.         add_flag = 2;
  14.     }
  15.     while(1)
  16.     {
  17.         if(add_flag == 1)
  18.         {
  19.             silde1_angle++;
  20.         }
  21.         else if(add_flag == 2)
  22.         {
  23.             silde1_angle--;
  24.         }
  25.         
  26.         for(i = 0;i < 8;i++)
  27.         {
  28.             silde1_pos_set(i, silde1_angle);
  29.         }
  30.         if(silde1_angle % 45 == 0)
  31.         {
  32.             break;
  33.         }
  34.         Delay_ms(5);
  35.     }

  36.     if(silde1_angle % 45 == 0)
  37.     {
  38.         silde1MenuCurrent = 7 - Read_Dgus(0x1000 + 0x100 * (((silde1_angle / 45) + 1) % 8));
  39.         write_dgus_vp(0x17F0, &silde1MenuCurrent, 1);
  40.         //UART2_Sendbyte(silde1MenuCurrent % 256);
  41.     }   
  42. }
复制代码

第二种的相对比较复杂,大家可以自行下载源码去阅读,这里就不贴出来了。

这是演示时的图片,大家可以看一下。


四、总结

这次设计让我觉得迪文屏的自定义功能还是挺强的,不仅局限于图片,这种自定义动画显示的也是挺流畅的,这让我有了更多的设计想法,让我们一起期待更好的设计吧~

视频展示链接:https://www.bilibili.com/video/BV1qM4y1n72p/



备注说明:如需源码,请参考此链接:http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=8377


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-11-24 09:08 , Processed in 0.114507 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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