日常使用电脑中经常会用到一个quicke
工具中的轮盘菜单工具。
但quicke免费版很多功能不支持,且它的触发逻辑用的不舒服,经常误触。
本着靠人不让靠自己,自己动手丰衣足食的理念,用tauri撸一个小工具。
先看效果
要解决的问题
唤起方式
因为要通过鼠标进行交互,所以必然会影响系统默认的鼠标行为。
为了减少交互冲突,选择长按右键唤起菜单。
就要解决如下问题:
1、默认情况要阻止右键鼠标的事件传递给操作系统
2、当右键按住时间小于设置长按唤起时间,要自动给系统发送一个右键按下和右键松开的事件
由于tauri没有提供相关的api,所以要从Rust的crate中找看看有没有相关包。
经过一番搜索,找到了rdev
这个包,它提供了基础的系统级的鼠标键盘事件处理。
使用rdev::grab
就可以监听鼠标键盘事件, 并且阻止事件传递
tauri::async_runtime::spawn(async move { rdev::grab(move |event| { let is_block: bool = match event.event_type { EventType::ButtonPress(button) => { match button { Button::Right => { unsafe { !IS_SIMULATE } } _ => { false } } } EventType::ButtonRelease(button) => { match button { Button::Right => { unsafe { !IS_SIMULATE } } _ => { false } } } _ => { false } }; if is_block { None } else { Some(event) } }).unwrap(); });
通过tauri::async_runtime::spawn
创建个异步任务
IS_SIMULATE
是一个全局变量默认false
会阻止右击事件,自动触发事件前会设置为true
,使事件不被阻止,完成后再设置为false
rdev::grab
通过流处理让右键的按下和松开返回个None
阻止事件传递。
菜单出现的位置
我们希望唤起菜单中心在鼠标当前位置,所以
1、获取右击按下时的系统坐标信息
2、把系统的坐标传递给菜单窗口实现定位
由于rdev
的鼠标点击事件没有鼠标位置信息,所以我们要在鼠标移动时保存坐标信息
EventType::MouseMove { x, y } => { unsafe { MOUSE_POSITION = (x, y); } false }
按下鼠标是传递坐标
EventType::ButtonPress(button) => { unsafe { if !IS_SIMULATE { roulette_window.emit("buttondown", ButtonPayload { button: get_button_name(&button), x: MOUSE_POSITION.0, y: MOUSE_POSITION.1 }).unwrap(); } } match button { Button::Right => { unsafe { !IS_SIMULATE } } _ => { false } } }
同时我们把窗口设置全屏展示,这样系统的坐标 == 鼠标在窗口的坐标。
接下来在窗口内绘制需要数量的扇形就完成了基本的制作。
这里使用SVG来绘制扇形菜单
菜单数据:
const config: { id: string; text?: string; image?: string; callback?: () => void; }[] = []
tip: 根据菜单数量已经提前计算path需要的坐标信息
在react内渲染
<svg className='menu' width={SIZE * 2} height={SIZE * 2} xmlns="http://www.w3.org/2000/svg"> <g> <circle id='center' className='center' cx={SIZE} cy={SIZE} r={CENTER_SIZE} /> { active && ( active.id === 'close' ? ( <text className='center-text' x={SIZE} y={SIZE} fill='red' > 关闭 </text> ) : ( <text className='center-text' x={SIZE} y={SIZE} > {active?.text} </text> ) ) } </g> { menu.map(({ id, text, image, points, center }) => ( <g key={id}> <path id={id} className='item' d={`M ${points[0][0]} ${points[0][1]} A ${SIZE} ${SIZE}, 0, 0, 1, ${points[1][0]} ${points[1][1]} L ${points[2][0]} ${points[2][1]} A ${CENTER_SIZE} ${CENTER_SIZE}, 0, 0, 0, ${points[3][0]} ${points[3][1]} Z`} /> { image && ( <image className='item-img' xlinkHref={image} x={center[0] - 15} y={center[1] - 25} width='30' /> ) } { text && ( <text className='item-text' x={center[0]} y={center[1] + 25} > {text} </text> ) } </g> )) } </svg>
在窗口内通过document.addEventListener
监听mousemove
获取鼠标所在的块上,当松开鼠标时就能执行对应的任务。
最后
目前的菜单功能都是写死在代码里的,之后会加上配置功能,并且支持自己编写代码来控制每个菜单对应的具体操作。
后续还可以加上根据焦点应用来分别展示不同的菜单数据。
到此这篇关于Rust利用tauri制作个效率小工具的文章就介绍到这了,更多相关Rust tauri制作效率小工具内容请搜索好代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持好代码网!