file_dialog.rs
1 #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release 2 3 use eframe::egui; 4 5 fn main() { 6 let options = eframe::NativeOptions { 7 drag_and_drop_support: true, 8 ..Default::default() 9 }; 10 eframe::run_native( 11 "Native file dialogs and drag-and-drop files", 12 options, 13 Box::new(|_cc| Box::new(MyApp::default())), 14 ); 15 } 16 17 #[derive(Default)] 18 struct MyApp { 19 dropped_files: Vec<egui::DroppedFile>, 20 picked_path: Option<String>, 21 } 22 23 impl eframe::App for MyApp { 24 fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { 25 egui::CentralPanel::default().show(ctx, |ui| { 26 ui.label("Drag-and-drop files onto the window!"); 27 28 if ui.button("Open fileā¦").clicked() { 29 if let Some(path) = rfd::FileDialog::new().pick_file() { 30 self.picked_path = Some(path.display().to_string()); 31 } 32 } 33 34 if let Some(picked_path) = &self.picked_path { 35 ui.horizontal(|ui| { 36 ui.label("Picked file:"); 37 ui.monospace(picked_path); 38 }); 39 } 40 41 // Show dropped files (if any): 42 if !self.dropped_files.is_empty() { 43 ui.group(|ui| { 44 ui.label("Dropped files:"); 45 46 for file in &self.dropped_files { 47 let mut info = if let Some(path) = &file.path { 48 path.display().to_string() 49 } else if !file.name.is_empty() { 50 file.name.clone() 51 } else { 52 "???".to_owned() 53 }; 54 if let Some(bytes) = &file.bytes { 55 info += &format!(" ({} bytes)", bytes.len()); 56 } 57 ui.label(info); 58 } 59 }); 60 } 61 }); 62 63 self.detect_files_being_dropped(ctx); 64 } 65 } 66 67 impl MyApp { 68 fn detect_files_being_dropped(&mut self, ctx: &egui::Context) { 69 use egui::*; 70 71 // Preview hovering files: 72 if !ctx.input().raw.hovered_files.is_empty() { 73 let mut text = "Dropping files:\n".to_owned(); 74 for file in &ctx.input().raw.hovered_files { 75 if let Some(path) = &file.path { 76 text += &format!("\n{}", path.display()); 77 } else if !file.mime.is_empty() { 78 text += &format!("\n{}", file.mime); 79 } else { 80 text += "\n???"; 81 } 82 } 83 84 let painter = 85 ctx.layer_painter(LayerId::new(Order::Foreground, Id::new("file_drop_target"))); 86 87 let screen_rect = ctx.input().screen_rect(); 88 painter.rect_filled(screen_rect, 0.0, Color32::from_black_alpha(192)); 89 painter.text( 90 screen_rect.center(), 91 Align2::CENTER_CENTER, 92 text, 93 TextStyle::Heading.resolve(&ctx.style()), 94 Color32::WHITE, 95 ); 96 } 97 98 // Collect dropped files: 99 if !ctx.input().raw.dropped_files.is_empty() { 100 self.dropped_files = ctx.input().raw.dropped_files.clone(); 101 } 102 } 103 }