Open Zeenobit opened 4 months ago
I can also get it to work by manually refreshing the stylesheet on the container entity every time a button is added:
let mut style_sheet = style_sheet_query.get_mut(container_entity).unwrap();
style_sheet.refresh();
Am I just missing a setting that should do this automatically, or is this the intended usage?
This is a limitation on current implementation, since if we tracked all entities insertion/deletion on the whole tree, this could be very expensive. I tried to do that, but the FPS hit was very noticeable, so I removed.
When observers get merged (probably 0.14), I'll implement this hierarchy change detection again and with observers, this should be fine, performance-wise.
Until there, I'll leave the issue open, to track this problem.
Ran into this as well. Ended up doing something like this as I only have one stylesheet:
fn refresh_css(
q_node_added: Query<Entity, Added<Style>>,
mut q_ui_root: Query<&mut StyleSheet, With<UiRoot>>,
) {
for _ in q_node_added.iter() {
for mut style in &mut q_ui_root {
style.refresh();
}
}
}
Could the problem be simplified by introducing a concept of "Global Stylesheets" to the crate?
If we assume most users would have a single global stylesheet, or a flat stack of global stylesheets, maybe this could be defined as a resource. Then any time a new node is added, it gets all the global stylesheets in order of the stack.
The hierarchical node-based stylesheets could then be implemented as the next iteration.
I think even with hierarchical stylesheets, the idea of global stylesheets would still be useful.
Just a suggestion!
Also, as it stands, it doesn't seem like the styles get updated based on style sheet rules either. I tried adding classes to an element, and it doesn't update the style to match the selector (i.e. I had #ControlButton .selected
defined in CSS, but adding the "selected" class doesn't update the node to match the selected style).
Is this the same problem? Do I need to manually refresh the stylesheet when adding classes?
From what I can see those are only updated on StyleSheet
change:
Only thing that is reacting to change are pseudoclasses, as those have all entities as MatchedEntities
and select FilteredEntities
based on Interaction
.
You could try the update system with Query<Entity, Or<(Added<Style>, Added<Class>, Changed<Class>)>
while the change detection is not working. (untested)
So I've managed to work around most of my issues by essentially having a root style sheet and refreshing it manually when a new node is added as @Xenira suggested.
This doesn't seem to work for removed nodes though. When a control button is removed, my application crashes in bevy_ecss
:
fn any_component<T: Component>(world: &World, entities: &SmallVec<[Entity; 8]>) -> bool {
// ...
for e in entities {
if let Some(ticks) = world.entity(*e).get_change_ticks::<T>() { // !!! CRASH: Entity doesn't exist
// ...
}
}
false
}
I tried to work around this by listening to nodes being removed, and modifying my refresh system as such:
fn refresh_style(
added: Query<(), Added<Node>>,
removed: RemovedComponents<Node>,
mut style_sheet: Query<&mut StyleSheet>,
) {
let root_entity: Entity = ...;
if !added.is_empty() || !removed.is_empty() {
style_sheet.get_mut(root_entity).unwrap().refresh();
}
}
But this doesn't seem to resolve the crash.
Is there anything I can do to "untrack" an entity when it's removed?
Edit:
Solved. It was an ordering issue with my refresh_style
system. Moving it to run after my UI logic is updated solved the problem.
I'm trying to use
bevy_ecss
in my project, but for some reason my stylesheets aren't cascading to child nodes that are added after the initial UI setup.I have some entities that spawn in the world, and each entities is associated with a named button. All buttons have the exact same name:
ControlButton
and are added to a parent node namedControlButtonContainer
.The system which adds the buttons on entity spawn runs in
Update
schedule. The systems which spawns the button container (for which the cascading does seem to work) run inStartup
schedule.In my CSS, I have:
For some reason the
ControlButtonContainer
gets the correct style. ButControlButton
never gets the correct style.I can work around the issue by just adding the style sheet to every
ControlButton
. This is what makes me think the issue is from the library and not my code.Is there something I'm missing?
I also can't seem to get hot reload to work either (changing the CSS file and saving doesn't do anything). I'm also not sure why I'm getting inconsistent ordering between
padding
andmargin
in my CSS file (which I figured through pure trial and error). I'm not sure if these issues are related!This is how I'm initializing the plugin:
Any help would be appreciated!