ced/src/ui/central_panel/find_highlight.rs

111 lines
3.0 KiB
Rust
Raw Normal View History

2025-07-05 14:42:45 -04:00
use eframe::egui;
pub(super) fn draw_find_highlights(
2025-07-05 14:42:45 -04:00
ui: &mut egui::Ui,
content: &str,
matches: &[(usize, usize)],
current_match_index: Option<usize>,
galley: &std::sync::Arc<egui::Galley>,
text_area_left: f32,
text_area_top: f32,
2025-07-05 14:42:45 -04:00
font_size: f32,
) {
let font_id = ui
.style()
.text_styles
.get(&egui::TextStyle::Monospace)
.unwrap_or(&egui::FontId::monospace(font_size))
.clone();
for (match_index, &(start_pos, end_pos)) in matches.iter().enumerate() {
let is_current_match = current_match_index == Some(match_index);
draw_single_highlight(
ui,
content,
start_pos,
end_pos,
text_area_left,
text_area_top,
galley,
&font_id,
is_current_match,
);
}
}
2025-07-05 14:42:45 -04:00
fn draw_single_highlight(
ui: &mut egui::Ui,
content: &str,
start_pos: usize,
end_pos: usize,
text_area_left: f32,
text_area_top: f32,
galley: &std::sync::Arc<egui::Galley>,
font_id: &egui::FontId,
is_current_match: bool,
) {
let text_up_to_start = &content[..start_pos.min(content.len())];
2025-07-05 14:42:45 -04:00
let start_line = text_up_to_start.chars().filter(|&c| c == '\n').count();
if start_line >= galley.rows.len() {
return;
}
2025-07-05 14:42:45 -04:00
let line_start_byte_pos = text_up_to_start.rfind('\n').map(|pos| pos + 1).unwrap_or(0);
let line_start_char_pos = content[..line_start_byte_pos].chars().count();
let start_char_pos = content[..start_pos].chars().count();
let start_col = start_char_pos - line_start_char_pos;
let lines: Vec<&str> = content.lines().collect();
if start_line >= lines.len() {
return;
}
let line_text = lines[start_line];
let text_before_match: String = line_text.chars().take(start_col).collect();
let text_before_width = ui.fonts(|fonts| {
fonts
.layout(
text_before_match,
font_id.clone(),
egui::Color32::WHITE,
f32::INFINITY,
)
.size()
.x
});
let galley_row = &galley.rows[start_line];
let start_y = text_area_top + galley_row.min_y();
let line_height = galley_row.height();
2025-07-05 14:42:45 -04:00
let start_x = text_area_left + text_before_width;
let match_text = &content[start_pos..end_pos.min(content.len())];
let match_width = ui.fonts(|fonts| {
fonts
.layout(
match_text.to_string(),
font_id.clone(),
ui.visuals().text_color(),
f32::INFINITY,
)
.size()
.x
});
2025-07-05 14:42:45 -04:00
let highlight_rect = egui::Rect::from_min_size(
egui::pos2(start_x, start_y),
egui::vec2(match_width, line_height),
);
2025-07-05 14:42:45 -04:00
let highlight_color = if is_current_match {
ui.visuals().selection.bg_fill
} else {
ui.visuals().selection.bg_fill.gamma_multiply(0.6)
};
2025-07-05 14:42:45 -04:00
let painter = ui.painter();
painter.rect_filled(highlight_rect, 0.0, highlight_color);
2025-07-05 14:42:45 -04:00
}