use bevy::prelude::*;
use bevy::text::TextCursorStyle;
#[derive(Resource, Clone, Copy, Debug)]
pub struct PfCaretBlink {
pub period_secs: f32,
pub min_alpha: f32,
pub smooth: bool,
}
impl Default for PfCaretBlink {
fn default() -> Self {
Self {
period_secs: 1.06,
min_alpha: 0.0,
smooth: false,
}
}
}
#[derive(Component, Clone, Copy, Debug)]
pub struct PfCaretBase(pub Color);
pub(crate) fn blink_carets(
time: Res<Time>,
blink: Res<PfCaretBlink>,
opacity_count: Res<crate::provider::PfOpacityCount>,
ancestors: Query<&ChildOf>,
opacities: Query<&crate::provider::PfOpacity>,
mut carets: Query<(Entity, &PfCaretBase, &mut TextCursorStyle)>,
) {
if carets.is_empty() {
return;
}
let period = blink.period_secs.max(1.0 / 60.0);
let phase = (time.elapsed_secs() / period).fract();
let factor = if blink.smooth {
let tri = 1.0 - (phase * 2.0 - 1.0).abs();
blink.min_alpha + (1.0 - blink.min_alpha) * tri
} else if phase < 0.5 {
1.0
} else {
blink.min_alpha
};
for (entity, base, mut style) in &mut carets {
let mut opacity = 1.0;
if opacity_count.0 > 0 {
let mut cur = entity;
loop {
if let Ok(o) = opacities.get(cur) {
opacity *= o.value;
}
match ancestors.get(cur) {
Ok(p) => cur = p.parent(),
Err(_) => break,
}
}
}
let base_alpha = base.0.alpha();
let target = base.0.with_alpha(base_alpha * factor * opacity);
if style.color != target {
style.color = target;
}
}
}