Skip to content
Snippets Groups Projects
Commit bdfc6456 authored by StarToaster's avatar StarToaster
Browse files

Improve text calculations. Improved bevy_scene example.

parent f3aba8fe
No related branches found
No related tags found
No related merge requests found
...@@ -79,17 +79,20 @@ fn move_active_tile(mut tile: Query<(&mut Transform, &ActiveTile)>) { ...@@ -79,17 +79,20 @@ fn move_active_tile(mut tile: Query<(&mut Transform, &ActiveTile)>) {
/// A system that moves the ghost tile to the cursor's position /// A system that moves the ghost tile to the cursor's position
fn move_ghost_tile( fn move_ghost_tile(
event_context: Res<EventDispatcher>,
mut tile: Query<&mut Transform, With<GhostTile>>, mut tile: Query<&mut Transform, With<GhostTile>>,
mut cursor_moved: EventReader<CursorMoved>, mut cursor_moved: EventReader<CursorMoved>,
camera_transform: Query<&GlobalTransform, With<WorldCamera>>, camera_transform: Query<&GlobalTransform, With<WorldCamera>>,
windows: Res<Windows>, windows: Res<Windows>,
) { ) {
for _ in cursor_moved.iter() { for _ in cursor_moved.iter() {
let world_pos = cursor_to_world(&windows, &camera_transform.single()); if !event_context.contains_cursor() {
let tile_pos = world_to_tile(world_pos); let world_pos = cursor_to_world(&windows, &camera_transform.single());
let mut ghost = tile.single_mut(); let tile_pos = world_to_tile(world_pos);
ghost.translation.x = tile_pos.x; let mut ghost = tile.single_mut();
ghost.translation.y = tile_pos.y; ghost.translation.x = tile_pos.x;
ghost.translation.y = tile_pos.y;
}
} }
} }
......
...@@ -3,6 +3,7 @@ use bevy::{ ...@@ -3,6 +3,7 @@ use bevy::{
utils::HashMap, utils::HashMap,
}; };
use kayak_font::KayakFont; use kayak_font::KayakFont;
use morphorm::Hierarchy;
use crate::{ use crate::{
layout::{DataCache, Rect}, layout::{DataCache, Rect},
...@@ -21,7 +22,6 @@ pub fn calculate_nodes( ...@@ -21,7 +22,6 @@ pub fn calculate_nodes(
query: Query<Entity, With<DirtyNode>>, query: Query<Entity, With<DirtyNode>>,
all_styles_query: Query<&KStyle>, all_styles_query: Query<&KStyle>,
node_query: Query<(Entity, &Node)>, node_query: Query<(Entity, &Node)>,
nodes_no_entity_query: Query<&'static Node>,
) { ) {
let mut new_nodes = HashMap::<Entity, (Node, bool)>::default(); let mut new_nodes = HashMap::<Entity, (Node, bool)>::default();
// This is the maximum recursion depth for this method. // This is the maximum recursion depth for this method.
...@@ -95,6 +95,7 @@ pub fn calculate_nodes( ...@@ -95,6 +95,7 @@ pub fn calculate_nodes(
&context, &context,
&fonts, &fonts,
&font_mapping, &font_mapping,
&query,
// &node_query, // &node_query,
dirty_entity, dirty_entity,
&mut styles, &mut styles,
...@@ -139,18 +140,30 @@ pub fn calculate_nodes( ...@@ -139,18 +140,30 @@ pub fn calculate_nodes(
log::trace!("{:?} needs layout!", entity.id()); log::trace!("{:?} needs layout!", entity.id());
} }
} }
}
}
{ pub fn calculate_layout(
let context = context.as_mut(); mut commands: Commands,
if let Ok(tree) = context.tree.try_read() { mut context: ResMut<KayakRootContext>,
// tree.dump(); nodes_no_entity_query: Query<&'static Node>,
let node_tree = &*tree; ) {
if let Ok(mut cache) = context.layout_cache.try_write() { let context = context.as_mut();
let mut data_cache = DataCache { if let Ok(tree) = context.tree.try_read() {
cache: &mut cache, // tree.dump();
query: &nodes_no_entity_query, let node_tree = &*tree;
}; if let Ok(mut cache) = context.layout_cache.try_write() {
morphorm::layout(&mut data_cache, node_tree, &nodes_no_entity_query); let mut data_cache = DataCache {
cache: &mut cache,
query: &nodes_no_entity_query,
};
morphorm::layout(&mut data_cache, node_tree, &nodes_no_entity_query);
for (entity, change) in cache.geometry_changed.iter() {
if !change.is_empty() {
for child in tree.child_iter(*entity) {
commands.entity(child.0).insert(DirtyNode);
}
} }
} }
} }
...@@ -163,11 +176,12 @@ fn create_primitive( ...@@ -163,11 +176,12 @@ fn create_primitive(
fonts: &Assets<KayakFont>, fonts: &Assets<KayakFont>,
font_mapping: &FontMapping, font_mapping: &FontMapping,
// query: &Query<(Entity, &Node)>, // query: &Query<(Entity, &Node)>,
dirty: &Query<Entity, With<DirtyNode>>,
id: WrappedIndex, id: WrappedIndex,
styles: &mut KStyle, styles: &mut KStyle,
) -> (RenderPrimitive, bool) { ) -> (RenderPrimitive, bool) {
let mut render_primitive = RenderPrimitive::from(&styles.clone()); let mut render_primitive = RenderPrimitive::from(&styles.clone());
let mut needs_layout = false; let mut needs_layout = true;
match &mut render_primitive { match &mut render_primitive {
RenderPrimitive::Text { RenderPrimitive::Text {
...@@ -183,38 +197,40 @@ fn create_primitive( ...@@ -183,38 +197,40 @@ fn create_primitive(
// self.bind(id, &asset); // self.bind(id, &asset);
if let Ok(node_tree) = context.tree.try_read() { if let Ok(node_tree) = context.tree.try_read() {
if let Some(parent_id) = node_tree.get_parent(id) { if let Some(parent_id) = node_tree.get_parent(id) {
if let Some(parent_layout) = context.get_layout(&parent_id) { if !dirty.contains(parent_id.0) {
properties.max_size = (parent_layout.width, parent_layout.height); if let Some(parent_layout) = context.get_layout(&parent_id) {
properties.max_size = (parent_layout.width, parent_layout.height);
if properties.max_size.0 == 0.0 || properties.max_size.1 == 0.0 {
needs_layout = true; if properties.max_size.0 == 0.0 || properties.max_size.1 == 0.0 {
} needs_layout = true;
} else {
// --- Calculate Text Layout --- // needs_layout = false;
*text_layout = font.measure(&content, *properties); }
let measurement = text_layout.size();
if context.get_geometry_changed(&parent_id) {
// --- Apply Layout --- // needs_layout = true;
if matches!(styles.width, StyleProp::Default) { }
styles.width = StyleProp::Value(Units::Pixels(measurement.0));
// --- Calculate Text Layout --- //
*text_layout = font.measure(&content, *properties);
let measurement = text_layout.size();
// --- Apply Layout --- //
if matches!(styles.width, StyleProp::Default) {
styles.width = StyleProp::Value(Units::Pixels(measurement.0));
}
if matches!(styles.height, StyleProp::Default) {
styles.height = StyleProp::Value(Units::Pixels(measurement.1));
}
} }
if matches!(styles.height, StyleProp::Default) {
styles.height = StyleProp::Value(Units::Pixels(measurement.1));
}
} else {
needs_layout = true;
} }
} else {
needs_layout = true;
} }
} else {
needs_layout = true;
} }
} else {
needs_layout = true;
} }
} }
_ => {} _ => {
needs_layout = false;
}
} }
if needs_layout { if needs_layout {
......
...@@ -8,7 +8,7 @@ use bevy::{ ...@@ -8,7 +8,7 @@ use bevy::{
use morphorm::Hierarchy; use morphorm::Hierarchy;
use crate::{ use crate::{
calculate_nodes::calculate_nodes, calculate_nodes::{calculate_layout, calculate_nodes},
children::KChildren, children::KChildren,
clone_component::{clone_state, clone_system, EntityCloneSystems, PreviousWidget}, clone_component::{clone_state, clone_system, EntityCloneSystems, PreviousWidget},
context_entities::ContextEntities, context_entities::ContextEntities,
...@@ -111,6 +111,18 @@ impl KayakRootContext { ...@@ -111,6 +111,18 @@ impl KayakRootContext {
} }
} }
pub(crate) fn get_geometry_changed(&self, id: &WrappedIndex) -> bool {
if let Ok(cache) = self.layout_cache.try_read() {
if let Some(geometry_changed) = cache.geometry_changed.get(id) {
!geometry_changed.is_empty()
} else {
false
}
} else {
false
}
}
/// Adds a new set of systems for a widget type. /// Adds a new set of systems for a widget type.
/// Update systems are ran every frame and return true or false depending on if the widget has "changed". /// Update systems are ran every frame and return true or false depending on if the widget has "changed".
/// Render systems are ran only if the widget has changed and are meant to re-render children and handle /// Render systems are ran only if the widget has changed and are meant to re-render children and handle
...@@ -709,12 +721,18 @@ impl Plugin for KayakContextPlugin { ...@@ -709,12 +721,18 @@ impl Plugin for KayakContextPlugin {
fn calculate_ui(world: &mut World) { fn calculate_ui(world: &mut World) {
// dbg!("Calculating nodes!"); // dbg!("Calculating nodes!");
let mut system = IntoSystem::into_system(calculate_nodes); let mut node_system = IntoSystem::into_system(calculate_nodes);
system.initialize(world); node_system.initialize(world);
let mut layout_system = IntoSystem::into_system(calculate_layout);
layout_system.initialize(world);
for _ in 0..5 { for _ in 0..5 {
system.run((), world); node_system.run((), world);
system.apply_buffers(world); node_system.apply_buffers(world);
layout_system.run((), world);
layout_system.apply_buffers(world);
world.resource_scope::<KayakRootContext, _>(|world, mut context| { world.resource_scope::<KayakRootContext, _>(|world, mut context| {
LayoutEventDispatcher::dispatch(&mut context, world); LayoutEventDispatcher::dispatch(&mut context, world);
}); });
......
...@@ -67,7 +67,7 @@ pub(crate) struct LayoutCache { ...@@ -67,7 +67,7 @@ pub(crate) struct LayoutCache {
/// ///
/// This should only contain entries for nodes that have _at least one_ flag set. /// This should only contain entries for nodes that have _at least one_ flag set.
/// If a node does not have any flags set, then they should be removed from the map. /// If a node does not have any flags set, then they should be removed from the map.
geometry_changed: HashMap<WrappedIndex, GeometryChanged>, pub(crate) geometry_changed: HashMap<WrappedIndex, GeometryChanged>,
visible: HashMap<WrappedIndex, bool>, visible: HashMap<WrappedIndex, bool>,
} }
......
...@@ -179,7 +179,10 @@ pub fn window_render( ...@@ -179,7 +179,10 @@ pub fn window_render(
} }
<ClipBundle <ClipBundle
styles={KStyle { styles={KStyle {
padding: StyleProp::Value(Edge::all(Units::Pixels(10.0))), top: Units::Pixels(10.0).into(),
left: Units::Pixels(10.0).into(),
right: Units::Pixels(10.0).into(),
bottom: Units::Pixels(10.0).into(),
..Default::default() ..Default::default()
}} }}
children={window_children.clone()} children={window_children.clone()}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment