use crate::app::TextEditor; use eframe::egui; pub(crate) fn find_window(app: &mut TextEditor, ctx: &egui::Context) { let visuals = &ctx.style().visuals; let mut should_close = false; let mut query_changed = false; egui::Window::new("Find") .collapsible(false) .resizable(false) .movable(true) .anchor(egui::Align2::CENTER_CENTER, egui::Vec2::ZERO) .frame(egui::Frame { fill: visuals.window_fill, stroke: visuals.window_stroke, corner_radius: egui::CornerRadius::same(8), shadow: visuals.window_shadow, inner_margin: egui::Margin::same(16), outer_margin: egui::Margin::same(0), }) .show(ctx, |ui| { ui.vertical(|ui| { ui.set_min_width(300.0); ui.horizontal(|ui| { ui.label("Find:"); let response = ui.add( egui::TextEdit::singleline(&mut app.find_query) .desired_width(200.0) .hint_text("Enter search text..."), ); if response.changed() { query_changed = true; } if !response.has_focus() { response.request_focus(); } if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) { app.find_next(); response.request_focus(); } }); ui.add_space(8.0); ui.horizontal(|ui| { let case_sensitive_changed = ui .checkbox(&mut app.case_sensitive_search, "Case sensitive") .changed(); if case_sensitive_changed { query_changed = true; } }); ui.add_space(8.0); ui.horizontal(|ui| { let match_text = if app.find_matches.is_empty() { if app.find_query.is_empty() { "".to_string() } else { "No matches found".to_string() } } else if let Some(current) = app.current_match_index { format!("{} of {} matches", current + 1, app.find_matches.len()) } else { format!("{} matches found", app.find_matches.len()) }; ui.label(egui::RichText::new(match_text).weak()); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { if ui.button("✕").clicked() { should_close = true; } ui.add_space(4.0); let next_enabled = !app.find_matches.is_empty(); ui.add_enabled_ui(next_enabled, |ui| { if ui.button("Next").clicked() { app.find_next(); } }); let prev_enabled = !app.find_matches.is_empty(); ui.add_enabled_ui(prev_enabled, |ui| { if ui.button("Previous").clicked() { app.find_previous(); } }); }); }); }); }); if query_changed { app.update_find_matches(); } if should_close { app.show_find = false; } ctx.input(|i| { if i.key_pressed(egui::Key::Escape) { app.show_find = false; } else if i.key_pressed(egui::Key::F3) { if i.modifiers.shift { app.find_previous(); } else { app.find_next(); } } }); }