Rust利用tauri制作个效率小工具

 更新时间:2023年02月02日 09:37:20   作者:_十九  
日常使用电脑中经常会用到一个quicke工具中的轮盘菜单工具。但quicke免费版很多功能不支持,且它的触发逻辑用的不舒服,经常误触。所以本文就来用tauri自制一个小工具,希望对大家有所帮助

日常使用电脑中经常会用到一个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制作效率小工具内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • rust标准库std::env环境相关的常量

    rust标准库std::env环境相关的常量

    在本章节中, 我们探讨了Rust处理命令行参数的常见的两种方式和处理环境变量的两种常见方式, 抛开Rust的语法, 实际上在命令行参数的处理方式上, 与其它语言大同小异, 可能影响我们习惯的也就只剩下语法,本文介绍rust标准库std::env的相关知识,感兴趣的朋友一起看看吧
    2024-03-03
  • Rust整合Elasticsearch的详细过程(收藏)

    Rust整合Elasticsearch的详细过程(收藏)

    Elasticsearch是基于Lucene构建的开源分布式搜索和分析引擎,支持水平扩展和多语言调用,ELK(Elastic Stack)组合包括Elasticsearch、Kibana、Logstash和Beats,专注于日志数据分析和实时监控,本文介绍Rust整合Elasticsearch的过程,一起看看吧
    2024-11-11
  • Rust 中的 Packages 与 Crates模块化构建的基础及开发流程

    Rust 中的 Packages 与 Crates模块化构建的基础及开发流程

    Rust中的Crate是编译器处理的最小代码单元,可以是二进制或库,每个Crate由一个CrateRoot文件(通常是src/main.rs或src/lib.rs)定义,本文给大家介绍Rust 中的 Packages 与 Crates模块化构建的基础及开发流程,感兴趣的朋友一起看看吧
    2025-02-02
  • 详解thiserror库在Rust中的使用

    详解thiserror库在Rust中的使用

    在编程中,错误处理是一个至关重要的部分,在Rust中,我们经常使用Result和Option类型来进行错误处理,但有时,我们需要创建自定义的错误类型,这就是thiserror库发挥作用的地方,可以极大的简化代码,所以本文就给大家介绍一下如何使用thiserror
    2023-08-08
  • Rust中向量的学习笔记

    Rust中向量的学习笔记

    在Rust语言中,向量是一种动态数组类型,可以存储相同类型的元素,并且可以在运行时改变大小,本文就来介绍一下Rust中向量,感兴趣的可以了解一下
    2024-03-03
  • Rust 中的文件操作示例详解

    Rust 中的文件操作示例详解

    Rust 中的路径操作是跨平台的,std::path 模块提供的了两个用于描述路径的类型,本文给大家介绍Rust 中的文件操作示例详解,感兴趣的朋友一起看看吧
    2021-11-11
  • Rust Atomics and Locks内存序Memory Ordering详解

    Rust Atomics and Locks内存序Memory Ordering详解

    这篇文章主要为大家介绍了Rust Atomics and Locks内存序Memory Ordering详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 如何使用Rust的向量存储值列表

    如何使用Rust的向量存储值列表

    本文介绍了在Rust中使用向量存储值列表的方法,包括创建、更新、读取、遍历、存储多种类型以及内存释放等方面,向量是Rust中常用且强大的集合类型,熟练掌握其用法有助于编写高效且安全的代码
    2025-02-02
  • 如何使用Rust直接编译单个的Solidity合约

    如何使用Rust直接编译单个的Solidity合约

    本文介绍了如何使用Rust语言直接编译Solidity智能合约,特别适用于没有外部依赖或flatten后的合约,一般情况下,Solidity开发者使用Hardhat或Foundry框架,本文给大家介绍如何使用Rust直接编译单个的Solidity合约,感兴趣的朋友一起看看吧
    2024-09-09
  • Rust中箱、包和模块的学习笔记

    Rust中箱、包和模块的学习笔记

    Rust中有三个重要的组织概念:箱、包、模块,本文主要介绍了Rust中箱、包和模块的学习笔记,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03

最新评论