//! Frontend for ComfyUI-Rust using egui use eframe::egui; // Simple UI that connects to our local backend pub struct ComfyUiFrontend { prompt: String, negative_prompt: String, width: u32, height: u32, steps: u32, cfg_scale: f32, is_generating: bool, model_name: String, } impl ComfyUiFrontend { pub fn new(_cc: &eframe::CreationContext) -> Self { Self { prompt: "A beautiful sunset over the ocean".to_string(), negative_prompt: "".to_string(), width: 512, height: 512, steps: 30, cfg_scale: 7.0, is_generating: false, model_name: "stable-diffusion-v1-4".to_string(), } } fn generate_image(&mut self) { if self.is_generating { return; } self.is_generating = true; let prompt = self.prompt.clone(); // Simulate async operation by spawning background task that updates UI after delay std::thread::spawn(move || { // Simulate network delay and processing time (5 seconds) std::thread::sleep(std::time::Duration::from_secs(3)); println!("Image generation completed for: {}", prompt); }); } } impl eframe::App for ComfyUiFrontend { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { egui::CentralPanel::default().show(ctx, |ui| { ui.heading("ComfyUI-Rust Frontend"); // Model selection ui.horizontal(|ui| { ui.label("Model:"); ui.text_edit_singleline(&mut self.model_name); }); // Prompt input ui.separator(); ui.label("Prompt:"); ui.text_edit_multiline(&mut self.prompt); ui.label("Negative Prompt:"); ui.text_edit_multiline(&mut self.negative_prompt); // Generation parameters ui.separator(); ui.horizontal(|ui| { ui.label("Width:"); ui.add(egui::Slider::new(&mut self.width, 256..=1024).step_by(64.0)); ui.label("Height:"); ui.add(egui::Slider::new(&mut self.height, 256..=1024).step_by(64.0)); }); ui.horizontal(|ui| { ui.label("Steps:"); ui.add(egui::Slider::new(&mut self.steps, 10..=100).step_by(1.0)); ui.label("CFG Scale:"); ui.add(egui::Slider::new(&mut self.cfg_scale, 1.0..=20.0).step_by(0.5)); }); // Generate button if ui.button("Generate Image").clicked() { self.generate_image(); } // Status and image preview ui.separator(); if self.is_generating { ui.label("Generating image..."); } else { ui.label("Ready to generate"); } }); } } fn main() -> eframe::Result<()> { let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() .with_title("ComfyUI-Rust Frontend") .with_inner_size([800.0, 600.0]) .with_min_inner_size([400.0, 300.0]), ..Default::default() }; eframe::run_native( "ComfyUI-Rust", options, Box::new(|cc| Box::new(ComfyUiFrontend::new(cc))), ) }