Newer
Older
use bevy::{
prelude::{Entity, Query},
reflect::{FromReflect, Reflect},
};
use morphorm::Cache;
pub use morphorm::GeometryChanged;
#[derive(Debug, Reflect, FromReflect, Default, Clone, Copy, PartialEq)]
pub struct Rect {
pub posx: f32,
pub posy: f32,
pub width: f32,
pub height: f32,
pub z_index: f32,
}
impl Rect {
pub fn contains(&self, point: &(f32, f32)) -> bool {
(point.0 >= self.posx && point.0 <= self.posx + self.width)
&& (point.1 >= self.posy && point.1 <= self.posy + self.height)
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct Space {
pub left: f32,
pub right: f32,
pub top: f32,
pub bottom: f32,
}
#[derive(Debug, Default, Clone, Copy)]
pub struct Size {
pub width: f32,
pub height: f32,
}
#[derive(Default, Debug)]
space: HashMap<WrappedIndex, Space>,
size: HashMap<WrappedIndex, Size>,
child_width_max: HashMap<WrappedIndex, f32>,
child_height_max: HashMap<WrappedIndex, f32>,
child_width_sum: HashMap<WrappedIndex, f32>,
child_height_sum: HashMap<WrappedIndex, f32>,
grid_row_max: HashMap<WrappedIndex, f32>,
grid_col_max: HashMap<WrappedIndex, f32>,
horizontal_free_space: HashMap<WrappedIndex, f32>,
horizontal_stretch_sum: HashMap<WrappedIndex, f32>,
vertical_free_space: HashMap<WrappedIndex, f32>,
vertical_stretch_sum: HashMap<WrappedIndex, f32>,
stack_first_child: HashMap<WrappedIndex, bool>,
stack_last_child: HashMap<WrappedIndex, bool>,
/// A map of node IDs to their `GeometryChanged` flags
///
/// 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.
pub(crate) geometry_changed: HashMap<WrappedIndex, GeometryChanged>,
self.space.insert(node_index, Default::default());
self.child_width_max.insert(node_index, Default::default());
self.child_height_max.insert(node_index, Default::default());
self.child_width_sum.insert(node_index, Default::default());
self.child_height_sum.insert(node_index, Default::default());
self.grid_row_max.insert(node_index, Default::default());
self.grid_col_max.insert(node_index, Default::default());
self.horizontal_free_space
.insert(node_index, Default::default());
self.horizontal_stretch_sum
.insert(node_index, Default::default());
self.vertical_free_space
.insert(node_index, Default::default());
self.vertical_stretch_sum
.insert(node_index, Default::default());
self.stack_first_child
.insert(node_index, Default::default());
self.stack_last_child.insert(node_index, Default::default());
self.size.insert(node_index, Default::default());
self.visible.insert(node_index, true);
}
/// Attempts to initialize the node if it hasn't already been initialized.
/// Returns an iterator over nodes whose layout have been changed since the last update
pub fn iter_changed(&self) -> Iter<'_, WrappedIndex, GeometryChanged> {
pub(crate) struct DataCache<'borrow, 'world, 'state> {
pub query: &'borrow Query<'world, 'state, &'static crate::node::Node>,
pub cache: &'borrow mut LayoutCache,
}
impl<'b, 'w, 's> Cache for DataCache<'b, 'w, 's> {
type Item = WrappedIndex;
if let Some(value) = self.cache.visible.get(&node) {
return *value;
}
true
}
fn geometry_changed(&self, node: Self::Item) -> GeometryChanged {
if let Some(geometry_changed) = self.cache.geometry_changed.get(&node) {
return *geometry_changed;
}
GeometryChanged::default()
}
fn set_geo_changed(&mut self, node: Self::Item, flag: GeometryChanged, value: bool) {
// This method is guaranteed to be called by morphorm every layout so we'll attempt to initialize here
if value {
// Setting a flag -> Add entry if it does not already exist
let geometry_changed = self.cache.geometry_changed.entry(node).or_default();
} else {
// Unsetting a flag -> Don't add entry if it does not exist
if let Some(geometry_changed) = self.cache.geometry_changed.get_mut(&node) {
geometry_changed.set(flag, value);
if geometry_changed.is_empty() {
return rect.width;
}
0.0
}
fn height(&self, node: Self::Item) -> f32 {
return rect.height;
}
0.0
}
fn posx(&self, node: Self::Item) -> f32 {
return rect.posx;
}
0.0
}
fn posy(&self, node: Self::Item) -> f32 {
return rect.posy;
}
0.0
}
fn left(&self, node: Self::Item) -> f32 {
return space.left;
}
0.0
}
fn right(&self, node: Self::Item) -> f32 {
return space.right;
}
0.0
}
fn top(&self, node: Self::Item) -> f32 {
return space.top;
}
0.0
}
fn bottom(&self, node: Self::Item) -> f32 {
return space.bottom;
}
0.0
}
fn new_width(&self, node: Self::Item) -> f32 {
return size.width;
}
0.0
}
fn new_height(&self, node: Self::Item) -> f32 {
return size.height;
}
0.0
}
fn child_width_max(&self, node: Self::Item) -> f32 {
}
/// Get the computed sum of the widths of the child nodes
fn child_width_sum(&self, node: Self::Item) -> f32 {
}
/// Get the computed maximum width of the child nodes
fn child_height_max(&self, node: Self::Item) -> f32 {
}
/// Get the computed sum of the widths of the child nodes
fn child_height_sum(&self, node: Self::Item) -> f32 {
}
/// Get the computed maximum grid row
fn grid_row_max(&self, node: Self::Item) -> f32 {
}
/// Get the computed maximum grid column
fn grid_col_max(&self, node: Self::Item) -> f32 {
}
// Setters
fn set_visible(&mut self, node: Self::Item, value: bool) {
*self.cache.visible.get_mut(&node).unwrap() = value;
}
fn set_child_width_sum(&mut self, node: Self::Item, value: f32) {
*self.cache.child_width_sum.get_mut(&node).unwrap() = value;
}
fn set_child_height_sum(&mut self, node: Self::Item, value: f32) {
*self.cache.child_height_sum.get_mut(&node).unwrap() = value;
}
fn set_child_width_max(&mut self, node: Self::Item, value: f32) {
*self.cache.child_width_max.get_mut(&node).unwrap() = value;
}
fn set_child_height_max(&mut self, node: Self::Item, value: f32) {
*self.cache.child_height_max.get_mut(&node).unwrap() = value;
}
fn horizontal_free_space(&self, node: Self::Item) -> f32 {
*self.cache.horizontal_free_space.get(&node).unwrap()
}
fn set_horizontal_free_space(&mut self, node: Self::Item, value: f32) {
*self.cache.horizontal_free_space.get_mut(&node).unwrap() = value;
}
fn vertical_free_space(&self, node: Self::Item) -> f32 {
*self.cache.vertical_free_space.get(&node).unwrap()
}
fn set_vertical_free_space(&mut self, node: Self::Item, value: f32) {
*self.cache.vertical_free_space.get_mut(&node).unwrap() = value;
}
fn horizontal_stretch_sum(&self, node: Self::Item) -> f32 {
*self.cache.horizontal_stretch_sum.get(&node).unwrap()
}
fn set_horizontal_stretch_sum(&mut self, node: Self::Item, value: f32) {
*self.cache.horizontal_stretch_sum.get_mut(&node).unwrap() = value;
}
fn vertical_stretch_sum(&self, node: Self::Item) -> f32 {
*self.cache.vertical_stretch_sum.get(&node).unwrap()
}
fn set_vertical_stretch_sum(&mut self, node: Self::Item, value: f32) {
*self.cache.vertical_stretch_sum.get_mut(&node).unwrap() = value;
}
fn set_grid_row_max(&mut self, node: Self::Item, value: f32) {
*self.cache.grid_row_max.get_mut(&node).unwrap() = value;
}
fn set_grid_col_max(&mut self, node: Self::Item, value: f32) {
*self.cache.grid_row_max.get_mut(&node).unwrap() = value;
}
fn set_width(&mut self, node: Self::Item, value: f32) {
let rect = self.cache.rect.entry(node).or_default();
}
fn set_height(&mut self, node: Self::Item, value: f32) {
let rect = self.cache.rect.entry(node).or_default();
let rect = self.cache.rect.entry(node).or_default();
let rect = self.cache.rect.entry(node).or_default();
}
fn set_left(&mut self, node: Self::Item, value: f32) {
if let Some(space) = self.cache.space.get_mut(&node) {
space.left = value;
}
}
fn set_right(&mut self, node: Self::Item, value: f32) {
if let Some(space) = self.cache.space.get_mut(&node) {
space.right = value;
}
}
fn set_top(&mut self, node: Self::Item, value: f32) {
if let Some(space) = self.cache.space.get_mut(&node) {
space.top = value;
}
}
fn set_bottom(&mut self, node: Self::Item, value: f32) {
if let Some(space) = self.cache.space.get_mut(&node) {
space.bottom = value;
}
}
fn set_new_width(&mut self, node: Self::Item, value: f32) {
if let Some(size) = self.cache.size.get_mut(&node) {
size.width = value;
}
}
fn set_new_height(&mut self, node: Self::Item, value: f32) {
if let Some(size) = self.cache.size.get_mut(&node) {
size.height = value;
}
}
fn stack_first_child(&self, node: Self::Item) -> bool {
}
fn set_stack_first_child(&mut self, node: Self::Item, value: bool) {
*self.cache.stack_first_child.get_mut(&node).unwrap() = value;
}
fn stack_last_child(&self, node: Self::Item) -> bool {
}
fn set_stack_last_child(&mut self, node: Self::Item, value: bool) {
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
*self.cache.stack_last_child.get_mut(&node).unwrap() = value;
}
}
/// A layout data sent to widgets on layout.
///
/// Similar and interchangeable with [Rect]
/// ```
/// use kayak_core::layout_cache::Rect;
/// use kayak_core::Layout;
///
/// let layout = Layout::default();
/// let rect : Rect = layout.into();
/// let layout : Layout = rect.into();
/// ```
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct Layout {
/// width of the component
pub width: f32,
/// height of the component
pub height: f32,
/// x-coordinates of the component
pub x: f32,
/// y-coordinates of the component
pub y: f32,
/// z-coordinates of the component
pub z: f32,
}
impl Layout {
/// Returns the position as a Kayak position type
pub fn pos(&self) -> (f32, f32) {
(self.x, self.y)
}
}
impl From<Layout> for Rect {
fn from(layout: Layout) -> Self {
Rect {
posx: layout.x,
posy: layout.y,
width: layout.width,
height: layout.height,
z_index: layout.z,
}
}
}
impl From<Rect> for Layout {
fn from(rect: Rect) -> Self {
Layout {
width: rect.width,
height: rect.height,
x: rect.posx,
y: rect.posy,
z: rect.z_index,
}
}
}
///
/// Struct used for [crate::OnLayout] as layout event data.
///
pub struct LayoutEvent {
/// Layout of target component
pub layout: Layout,
/// Flags denoting the layout change.
///
/// Note: The flags can potentially all be unset in cases where the [target's] layout did
/// not change, but one of its immediate children did.
///
/// [target's]: LayoutEvent::target
pub flags: GeometryChanged,
/// The node ID of the element receiving the layout event.
pub target: Entity,
}
impl LayoutEvent {
pub(crate) fn new(rect: Rect, geometry_change: GeometryChanged, index: Entity) -> LayoutEvent {
LayoutEvent {
layout: rect.into(),
flags: geometry_change,
target: index,
}