- 添加项目图标文件(app-icon.png、各平台图标) - 配置开发环境文件(.env、.nvmrc、.npmrc) - 添加静态资源文件(背景图片、字体、音频) - 初始化Tauri后端结构(build.rs、main.rs、模块文件) - 配置前端项目结构(TypeScript、Vue组件、样式) - 添加Node.js API服务基础结构 - 配置构建和开发工具(vite、prettier、gitignore)
84 lines
3.3 KiB
Rust
84 lines
3.3 KiB
Rust
use crate::audio::play_prompt_tone_imp;
|
||
use crate::window::{WindowLabel, create_popup_window::create_popup_window_impl, derive::TargetLocation};
|
||
use tauri::{AppHandle, Runtime, tray::TrayIconBuilder};
|
||
|
||
/// 创建并设置系统托盘图标
|
||
///
|
||
/// 该函数会检查是否已存在相同ID的托盘图标以避免重复添加,
|
||
/// 并为托盘图标绑定点击事件处理函数,点击时直接打开弹出框窗口。
|
||
pub fn setup_tray<R: Runtime>(app: &AppHandle<R>) -> Result<(), String> {
|
||
let tray_id = WindowLabel::MAIN_TRAY.as_ref();
|
||
// 检查是否已经存在托盘图标,避免重复添加
|
||
if app.tray_by_id(tray_id).is_some() {
|
||
return Ok(());
|
||
}
|
||
|
||
// 获取默认窗口图标
|
||
let icon = app.default_window_icon().ok_or("获取默认窗口图标失败")?.clone();
|
||
|
||
// 创建托盘图标(不关联菜单)
|
||
use std::sync::Arc;
|
||
let app_shared = Arc::new(app.clone());
|
||
TrayIconBuilder::with_id(tray_id)
|
||
.icon(icon)
|
||
.tooltip("智评会议")
|
||
.on_tray_icon_event(move |_tray, event| {
|
||
// 处理托盘图标点击事件
|
||
if let tauri::tray::TrayIconEvent::Click {
|
||
button_state: tauri::tray::MouseButtonState::Up,
|
||
rect,
|
||
..
|
||
} = event
|
||
{
|
||
let app_handle = Arc::clone(&app_shared);
|
||
// 如果popup窗口不存在,则创建并显示弹出框窗口
|
||
tauri::async_runtime::spawn(async move {
|
||
// 获取主显示器的缩放因子
|
||
let scale_factor = (*app_handle).primary_monitor().ok().flatten().map(|monitor| monitor.scale_factor()).unwrap_or(1.0);
|
||
|
||
let target = get_target_location(&rect, scale_factor);
|
||
|
||
// 直接调用后端函数创建弹出框窗口
|
||
let _ = create_popup_window_impl(&app_handle, &target, "auto").await;
|
||
play_prompt_tone_imp();
|
||
});
|
||
}
|
||
})
|
||
.build(app)
|
||
.map_err(|e| format!("创建托盘图标失败: {}", e))?;
|
||
|
||
// 托盘图标创建成功
|
||
Ok(())
|
||
}
|
||
|
||
/**
|
||
* 获取目标位置信息
|
||
*/
|
||
fn get_target_location(rect: &tauri::Rect, scale_factor: f64) -> TargetLocation {
|
||
// 使用scale_factor将物理坐标转换为逻辑坐标
|
||
// 在托盘图标的上下文中,默认使用1.0作为scale_factor
|
||
// 这样可以确保返回的坐标始终是逻辑坐标
|
||
|
||
let x = match rect.position {
|
||
tauri::Position::Physical(physical_position) => (physical_position.x as f64 / scale_factor) as i32,
|
||
tauri::Position::Logical(logical_position) => logical_position.x as i32,
|
||
};
|
||
|
||
let y = match rect.position {
|
||
tauri::Position::Physical(physical_position) => (physical_position.y as f64 / scale_factor) as i32,
|
||
tauri::Position::Logical(logical_position) => logical_position.y as i32,
|
||
};
|
||
|
||
let width = match rect.size {
|
||
tauri::Size::Physical(physical_size) => (physical_size.width as f64 / scale_factor) as u32,
|
||
tauri::Size::Logical(logical_size) => logical_size.width as u32,
|
||
};
|
||
|
||
let height = match rect.size {
|
||
tauri::Size::Physical(physical_size) => (physical_size.height as f64 / scale_factor) as u32,
|
||
tauri::Size::Logical(logical_size) => logical_size.height as u32,
|
||
};
|
||
|
||
TargetLocation { x, y, width, height }
|
||
}
|