From 69469ee1f46afe45045b72bf7c067f7a20012814 Mon Sep 17 00:00:00 2001 From: iorebuild Date: Sat, 9 Aug 2025 22:45:15 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=86=99=E5=AE=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Window.slint | 14 +++++++++- config.toml | 2 ++ logo.ico | Bin 0 -> 3586 bytes resource.rc | 1 + resource.res | Bin 0 -> 3680 bytes src/main.rs | 59 ++++++++++++++++++++++++++++++---------- tftp.png | Bin 0 -> 6087 bytes 7 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 config.toml create mode 100644 logo.ico create mode 100644 resource.rc create mode 100644 resource.res create mode 100644 tftp.png diff --git a/components/Window.slint b/components/Window.slint index 20cb447..074ec35 100644 --- a/components/Window.slint +++ b/components/Window.slint @@ -1,12 +1,22 @@ import { Button, VerticalBox } from "std-widgets.slint"; +export global Globals { + //启动按钮状态 + in-out property StartEnable: false; + //停止按钮状态 + in-out property StopEnable: false; +} + export component MainWindow inherits Window { + title: "VoileTftpTools"; + icon: @image-url("../tftp.png"); height: 180px; width: 320px; - title: "VoileTftpTools"; default-font-family: "Segoe UI"; default-font-size: 16px; default-font-weight: 700; + in-out property StartEnable <=> Globals.StartEnable; + in-out property StopEnable <=> Globals.StopEnable; //选择路径回调 callback BrowserFolder() -> string; property SelectFolder: ""; @@ -39,6 +49,7 @@ export component MainWindow inherits Window { height: parent.height; width: parent.width; text: "启动"; + enabled: StartEnable; clicked => { StartTftp(); } @@ -54,6 +65,7 @@ export component MainWindow inherits Window { height: parent.height; width: parent.width; text: "停止"; + enabled: StopEnable; clicked => { StopTftp(); } diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..f78fda6 --- /dev/null +++ b/config.toml @@ -0,0 +1,2 @@ +[build] +rustflags = ["-C", "link-arg=resource.res"] \ No newline at end of file diff --git a/logo.ico b/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..6abbaedc0534abf247f0faadbed054012052c590 GIT binary patch literal 3586 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 F{soEmn|A;J literal 0 HcmV?d00001 diff --git a/resource.rc b/resource.rc new file mode 100644 index 0000000..8904c5a --- /dev/null +++ b/resource.rc @@ -0,0 +1 @@ +0001 ICON "logo.ico" \ No newline at end of file diff --git a/resource.res b/resource.res new file mode 100644 index 0000000000000000000000000000000000000000..ab3084b40346f59196d5de00e3433f1b7a83115c GIT binary patch literal 3680 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, } - async fn start_tftp_server(dir: PathBuf) -> Result<(JoinHandle<()>, AbortHandle)> { let task = tokio::spawn(async move { println!("Starting TFTP server at: {:?}", dir); @@ -34,39 +34,70 @@ async fn main() { let state = Arc::new(Mutex::new(ServerState { abort_handle: None })); let folder_path = Arc::new(Mutex::new(String::new())); let path_clone = folder_path.clone(); + let ui_weak = ui.as_weak(); //选择路径按钮的回调函数 ui.on_BrowserFolder(move || { let result = FileDialog::new() .set_directory("/") .pick_folder(); - let path = result.map(|p| p.to_string_lossy().into_owned()) + let mut path = result.map(|p| p.to_string_lossy().into_owned()) .unwrap_or_default(); + if path == "" { + println!("TFTP Dir Empty !"); + if let Some(ui) = ui_weak.upgrade() { + ui.set_StartEnable(false); + } + path = String::from(""); + } + else { + if let Some(ui) = ui_weak.upgrade() { + ui.set_StartEnable(true); + } + } *path_clone.lock().unwrap() = path.clone(); // 存储到变量 SharedString::from(path) }); //启动按钮的回调函数 let state_clone = state.clone(); let path_clone = Arc::clone(&folder_path); + let ui_weak = ui.as_weak(); ui.on_StartTftp(move || { - // let Dir = PathBuf::from("C:/Users/anonymous/Desktop/Rust/VoiletTftp/target/release"); let dir = PathBuf::from(&*path_clone.lock().unwrap()); - println!("{:?}",dir); - let state = state_clone.clone(); - tokio::spawn(async move { - match start_tftp_server(dir).await { - Ok((_handle, abort_handle)) => { - println!("Server started"); - // 存储 abort_handle 以便停止 - state.lock().unwrap().abort_handle = Some(abort_handle); - } - Err(e) => eprintln!("Error: {}", e), + if dir.iter().count() == 0 { + println!("TFTP Dir Empty !"); + if let Some(ui) = ui_weak.upgrade() { + ui.set_StartEnable(true); + ui.set_StopEnable(false); } - }); + } + else { + if let Some(ui) = ui_weak.upgrade() { + ui.set_StartEnable(false); + ui.set_StopEnable(true); + } + println!("{:?}",dir); + let state = state_clone.clone(); + tokio::spawn(async move { + match start_tftp_server(dir).await { + Ok((_handle, abort_handle)) => { + println!("Server started"); + // 存储 abort_handle 以便停止 + state.lock().unwrap().abort_handle = Some(abort_handle); + } + Err(e) => eprintln!("Error: {}", e), + } + }); + } }); //停止按钮的回调函数 + let ui_weak = ui.as_weak(); let state_clone = state.clone(); ui.on_StopTftp(move || { + if let Some(ui) = ui_weak.upgrade() { + ui.set_StartEnable(true); + ui.set_StopEnable(false); + } if let Some(handle) = state_clone.lock().unwrap().abort_handle.take() { handle.abort(); println!("Server stopped"); diff --git a/tftp.png b/tftp.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a524402da986a6f10093fefe80968114a86646 GIT binary patch literal 6087 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 A=l}o! literal 0 HcmV?d00001