use eframe::egui::{self, Color32, Pos2, Rect, RichText, Rounding, Sense, Stroke, Vec2};
pub fn panel_heading(ui: &mut egui::Ui, tag: &str, title: &str) {
let text = ui
.visuals()
.override_text_color
.unwrap_or_else(|| Color32::from_rgb(244, 244, 244));
let muted = ui.visuals().widgets.inactive.fg_stroke.color;
let border = ui.visuals().widgets.inactive.bg_stroke.color;
ui.vertical(|ui| {
ui.label(RichText::new(tag).size(11.0).color(muted));
ui.label(RichText::new(title).size(16.0).strong().color(text));
});
ui.add_space(2.0);
let (rect, _) = ui.allocate_exact_size(Vec2::new(ui.available_width(), 1.0), Sense::hover());
ui.painter().line_segment(
[rect.left_center(), rect.right_center()],
Stroke::new(1.0, border),
);
}
pub fn field_label(ui: &mut egui::Ui, label: &str) {
let muted = ui.visuals().widgets.inactive.fg_stroke.color;
ui.label(RichText::new(label).size(11.0).color(muted));
}
pub fn muted_label(ui: &mut egui::Ui, text: impl Into<String>) {
let muted = ui.visuals().widgets.inactive.fg_stroke.color;
ui.label(RichText::new(text.into()).size(10.0).color(muted));
}
pub fn paint_background(
ui: &mut egui::Ui,
_phase: f32,
fill: Color32,
_grid: Color32,
_watermark: Color32,
background_image: Option<&egui::TextureHandle>,
background_opacity: f32,
) {
let rect = ui.max_rect();
let painter = ui.painter().clone();
painter.rect_filled(rect, Rounding::ZERO, fill);
if let Some(texture) = background_image {
let alpha = (background_opacity.clamp(0.0, 0.62) * 255.0).round() as u8;
if alpha > 0 {
painter.image(
texture.id(),
cover_rect(rect, texture.size_vec2()),
Rect::from_min_max(Pos2::ZERO, Pos2::new(1.0, 1.0)),
Color32::from_white_alpha(alpha),
);
let light = u16::from(fill.r()) + u16::from(fill.g()) + u16::from(fill.b()) > 410;
let veil_strength = (background_opacity / 0.62).clamp(0.0, 1.0);
painter.rect_filled(
rect,
Rounding::ZERO,
if light {
Color32::from_white_alpha((78.0 * veil_strength).round() as u8)
} else {
Color32::from_black_alpha((92.0 * veil_strength).round() as u8)
},
);
}
}
}
fn cover_rect(target: Rect, image_size: Vec2) -> Rect {
if image_size.x <= 0.0 || image_size.y <= 0.0 {
return target;
}
let scale = (target.width() / image_size.x).max(target.height() / image_size.y);
let size = image_size * scale;
Rect::from_center_size(target.center(), size)
}