From 3cbbe3c7323684aebbcbcffd48dcb84e5dcc8297 Mon Sep 17 00:00:00 2001 From: xiaji Date: Sat, 11 Apr 2026 07:51:19 +0800 Subject: [PATCH] feat(gui): add settings button and config dialog --- src/gui.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/src/gui.rs b/src/gui.rs index c955c83..339c74f 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -15,6 +15,12 @@ pub struct AppState { pub vm_status: String, pub log_buffer: Vec, pub is_connected: bool, + pub host: String, + pub port: u16, + pub show_settings: bool, + pub token_id: String, + pub token_secret: String, + pub token_secret_shown: bool, } impl AppState { @@ -25,20 +31,30 @@ impl AppState { let token = env::var("PROXMOX_TOKEN").unwrap_or_default(); let vm_id: u32 = env::var("VM_ID").unwrap_or_default().parse().unwrap_or(100); let node = env::var("NODE").unwrap_or_else(|_| "proxmox".to_string()); + let token_id = env::var("PROXMOX_TOKEN_ID").unwrap_or_default(); + let token_secret = env::var("PROXMOX_TOKEN_SECRET").unwrap_or_default(); + let port: u16 = env::var("PROXMOX_PORT").ok().and_then(|p| p.parse().ok()).unwrap_or(8006); - let client = if !host.is_empty() && !token.is_empty() { - let (token_id, token_secret) = if let Some(pos) = token.find('=') { + let (tok_id, tok_secret) = if !token_id.is_empty() && !token_secret.is_empty() { + (token_id.clone(), token_secret.clone()) + } else if !token.is_empty() { + if let Some(pos) = token.find('=') { (token[..pos].to_string(), token[pos+1..].to_string()) } else { (token.clone(), token.clone()) - }; - let c = ProxmoxClient::new(&host, &token_id, &token_secret); + } + } else { + (String::new(), String::new()) + }; + + let client = if !host.is_empty() && !tok_id.is_empty() && !tok_secret.is_empty() { + let c = ProxmoxClient::new(&host, &tok_id, &tok_secret); Arc::new(Mutex::new(Some(c))) } else { Arc::new(Mutex::new(None)) }; - let is_connected = !host.is_empty() && !token.is_empty(); + let is_connected = !host.is_empty() && !tok_id.is_empty() && !tok_secret.is_empty(); Self { client, @@ -47,6 +63,12 @@ impl AppState { vm_status: "未知".to_string(), log_buffer: vec!["程序启动".to_string()], is_connected, + host, + port, + show_settings: false, + token_id: tok_id, + token_secret: tok_secret, + token_secret_shown: false, } } @@ -111,6 +133,12 @@ impl eframe::App for App { let mut st = state.write().unwrap(); + ui.with_layout(egui::Layout::right_to_left(egui::Align::Min), |ui| { + if ui.button("设置").clicked() { + st.show_settings = !st.show_settings; + } + }); + ui.horizontal(|ui| { ui.label("连接状态: "); ui.label(if st.is_connected { "● 已连接" } else { "○ 未连接" }); @@ -233,6 +261,54 @@ impl eframe::App for App { ui.label(log); } }); + + let show_settings = st.show_settings; + let mut host = st.host.clone(); + let mut port = st.port; + let token_secret = st.token_secret.clone(); + let token_secret_shown = st.token_secret_shown; + let token_id = st.token_id.clone(); + let state_clone = state.clone(); + + if show_settings { + egui::Window::new("设置") + .collapsible(false) + .resizable(false) + .show(ctx, |ui| { + ui.label("Base URL"); + ui.label(format!("https://{}:{}/api2/json/", host, port)); + ui.horizontal(|ui| { + ui.label("Host"); + ui.text_edit_singleline(&mut host); + }); + ui.horizontal(|ui| { + ui.label("端口"); + ui.add(egui::DragValue::new(&mut port).range(1..=65535)); + }); + ui.horizontal(|ui| { + ui.label("Token Secret"); + if token_secret_shown { + ui.label(&token_secret); + } else if !token_secret.is_empty() { + ui.label("已保存"); + } else { + ui.label("未设置"); + } + }); + if ui.button("应用设置").clicked() { + let ts = token_secret.clone(); + let tid = token_id.clone(); + if !host.is_empty() && !tid.is_empty() && !ts.is_empty() { + let client = ProxmoxClient::new(&host, &tid, &ts); + state_clone.write().unwrap().client = Arc::new(Mutex::new(Some(client))); + state_clone.write().unwrap().is_connected = true; + state_clone.write().unwrap().add_log("已应用设置"); + } + } + ui.separator(); + ui.label("提示: 修改后需点击应用设置以生效"); + }); + } }); } } \ No newline at end of file