use crate::ecs::widget::{Brush, BrushInherit, Brushes, DEFAULT_BACKGROUND, DEFAULT_FOREGROUND};
use bevy_ecs::hierarchy::ChildOf;
use bevy_ecs::prelude::*;
use tracing::trace;
pub fn resolve_inherited_brushes(
mut commands: Commands,
query: Query<(Entity, Option<&Brushes>), With<BrushInherit>>,
parent_query: Query<&ChildOf>,
all_brushes: Query<&Brushes>,
) {
for (entity, brushes_opt) in query.iter() {
let parent_brushes = find_parent_brushes(entity, &parent_query, &all_brushes);
let resolved = match brushes_opt {
Some(brushes) => {
resolve_brush_fields(brushes, parent_brushes.as_ref())
}
None => {
match parent_brushes {
Some(parent) => parent.clone(),
None => Brushes {
foreground: DEFAULT_FOREGROUND,
background: DEFAULT_BACKGROUND,
},
}
}
};
commands
.entity(entity)
.insert(resolved)
.remove::<BrushInherit>();
trace!(
entity = ?entity,
"[resolve_inherited_brushes] Brushes resolved"
);
}
}
fn find_parent_brushes(
entity: Entity,
parent_query: &Query<&ChildOf>,
all_brushes: &Query<&Brushes>,
) -> Option<Brushes> {
let mut current = entity;
while let Ok(child_of) = parent_query.get(current) {
let parent = child_of.parent();
if let Ok(parent_brushes) = all_brushes.get(parent) {
if !parent_brushes.foreground.is_inherit() && !parent_brushes.background.is_inherit() {
return Some(parent_brushes.clone());
}
}
current = parent;
}
None
}
fn resolve_brush_fields(brushes: &Brushes, parent_brushes: Option<&Brushes>) -> Brushes {
let foreground = if brushes.foreground.is_inherit() {
parent_brushes
.and_then(|p| p.foreground.as_color())
.map(Brush::Solid)
.unwrap_or(DEFAULT_FOREGROUND)
} else {
brushes.foreground.clone()
};
let background = if brushes.background.is_inherit() {
parent_brushes
.and_then(|p| p.background.as_color())
.map(Brush::Solid)
.unwrap_or(DEFAULT_BACKGROUND)
} else {
brushes.background.clone()
};
Brushes {
foreground,
background,
}
}