当前位置: 首页 > news >正文

【Rust GUI开发入门】编写一个本地音乐播放器(4. 绘制按钮组件)

本系列教程对应的代码已开源在 Github zeedle

开始介绍播放器UI的构建部分,但是不会详细讲解Slint UI的设计基础,没有意义,因为官方文档介绍的已经十分详细了,一些基本用法需要借助参考文档熟悉。

Slint UI支持使用类SVG指令绘制矢量图标,为了保证UI的风格统一性,这里不使用网络上的图标,直接使用Path指令绘制,具体语法参考Path | Slint Docs。
需要绘制的图标如下:

  • 播放/暂停
  • 上一曲
  • 下一曲
  • 播放模式

直接给出.slint代码:

import { Palette } from "std-widgets.slint";
export component NextSongButton inherits Window {callback clicked();TouchArea {clicked => {root.clicked();}Path {width: 100%;height: 100%;MoveTo {x: 0;y: 0;}LineTo {x: 0;y: 100;}LineTo {x: 70;y: 50;}Close { }MoveTo {x: 80;y: 0;}LineTo {x: 80;y: 100;}stroke: Palette.control-foreground;stroke-width: root.width * 0.1;}}
}export component PrevSongButton inherits Window {callback clicked();TouchArea {clicked => {root.clicked();};Path {width: 100%;height: 100%;MoveTo {x: 80;y: 0;}LineTo {x: 80;y: 100;}LineTo {x: 10;y: 50;}Close { }MoveTo {x: 0;y: 0;}LineTo {x: 0;y: 100;}stroke: Palette.control-foreground;stroke-width: root.width * 0.1;}}
}export component PlayPauseButton inherits Window {in-out property <bool> paused:true;callback toggled();TouchArea {clicked => {root.toggled();}if !root.paused:Path {width: 100%;height: 100%;MoveTo {x: 0;y: 0;}LineTo {x: 0;y: 100;}LineTo {x: 30;y: 100;}LineTo {x: 30;y: 0;}Close { }MoveTo {x: 50;y: 0;}LineTo {x: 50;y: 100;}LineTo {x: 80;y: 100;}LineTo {x: 80;y: 0;}Close { }stroke: Palette.control-foreground;stroke-width: root.width * 0.1;}if root.paused:Path {width: 100%;height: 100%;MoveTo {x: 0;y: 0;}LineTo {x: 0;y: 100;}LineTo {x: 80;y: 50;}Close { }stroke: Palette.control-foreground;stroke-width: root.width * 0.1;}}
}export component InOrderButton inherits Window {in-out property <bool> selected;Path {MoveTo {x: 90;y: 50;}ArcTo {x: 50;y: 10;radius-x: 40;radius-y: 40;x-rotation: 0;large-arc: true;sweep: true;}LineTo {x: 40;y: 4;}MoveTo {x: 50;y: 10;}LineTo {x: 42;y: 18;}stroke-width: 1px;stroke: selected ? Palette.accent-background : Palette.foreground;}
}export component RecursiveButton inherits Window {in-out property <bool> selected;Path {MoveTo {x: 90;y: 50;}ArcTo {x: 50;y: 10;radius-x: 40;radius-y: 40;x-rotation: 0;large-arc: true;sweep: true;}LineTo {x: 40;y: 4;}MoveTo {x: 50;y: 10;}LineTo {x: 42;y: 18;}MoveTo {x: 50;y: 40;}LineTo {x: 50;y: 60;}MoveTo {x: 50;y: 40;}LineTo {x: 44;y: 44;}stroke-width: 1px;stroke: selected ? Palette.accent-background : Palette.foreground;}
}@rust-attr(derive(serde::Serialize, serde::Deserialize))
export enum PlayMode { InOrder, Recursive, Random}export component OverlapButton inherits Window {in-out property <PlayMode> mode;callback clicked();TouchArea {width: 100%;height: 100%;clicked => {root.clicked();}if mode == PlayMode.Recursive: RecursiveButton {width: 100%;height: 100%;selected: mode == PlayMode.Recursive || mode == PlayMode.InOrder;}if mode != PlayMode.Recursive: InOrderButton {width: 100%;height: 100%;selected: mode == PlayMode.Recursive || mode == PlayMode.InOrder;}}
}export component RandomButton inherits Window {callback clicked();in-out property <bool> selected;TouchArea {clicked => {root.clicked();};Path {MoveTo {x: 0;y: 20;}LineTo {x: 30;y: 20;}LineTo {x: 70;y: 80;}LineTo {x: 100;y: 80;}LineTo {x: 90;y: 70;}MoveTo {x: 100;y: 80;}LineTo {x: 90;y: 90;}// 第二段MoveTo {x: 0;y: 80;}LineTo {x: 30;y: 80;}LineTo {x: 70;y: 20;}LineTo {x: 100;y: 20;}LineTo {x: 90;y: 30;}MoveTo {x: 100;y: 20;}LineTo {x: 90;y: 10;}stroke: selected ? Palette.accent-background : Palette.foreground;stroke-width: 1px;}}
}

代码解释

从上述指令可以看出,这里使用的绘图指令还是比较简单的,基本就是画直线,画圆弧:

  • MoveTo:移动到某个点,并按下画笔
  • LineTo:从当前位置绘制直线到目标位置,并松开画笔
  • ArcTo:绘制圆弧,参数比较多,可以参考文档
    • radius-x:X轴半径
    • radius-y:Y轴半径
    • sweep:是否为顺时针方向
    • x, y:目标位置
    • x-rotation:椭圆的X轴旋转角

上面.slint代码中,有一些关于属性<property>和组件回调函数<callback>相关的东西:

  • 属性:可以是组件的外观参数(长,宽等),或者指示组件的内部状态,in修饰符代表只能由外部传入(只写),out修饰符代表只能从内部传出(只读),in-out修饰符代表可读可写
  • 回调函数:指定用户点击/拖动…该组件时,要执行的任务
http://www.dtcms.com/a/422921.html

相关文章:

  • Django小说个性化推荐系统 双算法(基于用户+物品) 评论收藏 书架管理 协同过滤推荐算法(源码+文档)✅
  • 微调数据格式详解:适配任务、模型与生态的最佳实践
  • 黑帽seo是什么做模板网站乐云seo效果好
  • 怎么编辑自己的网站企业展示型网站程序
  • java所有线程都是通过Callable和Runnable和Thread实现的
  • 0.7 秒实现精准图像编辑!VAREdit 让 AI 图像编辑告别“拖沓与失控,代码模型已开源。
  • 计算机软件包含网站开发购物网站开发设计类图
  • 【避坑实战】C# WinForm 上位机开发:解决串口粘包+LiveCharts卡顿+InfluxDB存储(免费代码+仿真工具)
  • 开源 C# 快速开发(十二)进程监控
  • 江协科技 CAN总线入门课程(仲裁)
  • Ubuntu 添加右键“复制全路径”菜单
  • 国企网站建设的意义电影影视网站模板免费下载
  • 网站主页设计模板房地产门户网站
  • 前端核心框架vue之(vuex状态篇4/5)
  • SheetGod:让Excel公式变得简单
  • 地信是“安卓”专业还是“苹果”专业?
  • 视频拼接类产品介绍
  • VSCode上配置Spring Boot环境
  • 线程同步实战指南:从 bug 根源到锁优化的终极之路
  • 中文企业展示网站模板优化wordpress后台速度
  • 做网站不赚钱了wordpress代码编辑
  • 云手机在硬件资源方面的优势
  • 技术深度解析:指纹云手机如何通过设备指纹隔离技术重塑多账号安全管理
  • 中国移动获得手机直连卫星通讯牌照:行业变革的催化剂
  • Chapter9—享元模式
  • 常州网站建设公司案例怎样做企业学校网站
  • 建设网站对企业的重要性企业网站网页设计有哪些
  • SpringBoot结合Vue 播放 m3u8 格式视频
  • 网站推广目标关键词龙岩网站设计找哪家好
  • 【论文阅读】ASPS: Augmented Segment Anything Model for Polyp Segmentation