use std::ops::Range; use crate::{ geometry::{rect::RectF, vector::Vector2F}, json::{self, json, ToJson}, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,}; /// Element which renders it's children in a stack on top of each other./// The first child determines the size of the others.pub struct Stack<V> { children: Vec<AnyElement<V>>,} impl<V> Default for Stack<V> { fn default() -> Self { Self { children: Vec::new(), } }} impl<V> Stack<V> { pub fn new() -> Self { Self::default() }} impl<V: 'static> Element<V> for Stack<V> { type LayoutState = (); type PaintState = (); fn layout( &mut self, mut constraint: SizeConstraint, view: &mut V, cx: &mut LayoutContext<V>, ) -> (Vector2F, Self::LayoutState) { let mut size = constraint.min; let mut children = self.children.iter_mut(); if let Some(bottom_child) = children.next() { size = bottom_child.layout(constraint, view, cx); constraint = SizeConstraint::strict(size); } for child in children { child.layout(constraint, view, cx); } (size, ()) } fn paint( &mut self, scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext<V>, ) -> Self::PaintState { for child in &mut self.children { scene.paint_layer(None, |scene| { child.paint(scene, bounds.origin(), visible_bounds, view, cx); }); } } fn rect_for_text_range( &self, range_utf16: Range<usize>, _: RectF, _: RectF, _: &Self::LayoutState, _: &Self::PaintState, view: &V, cx: &ViewContext<V>, ) -> Option<RectF> { self.children .iter() .rev() .find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx)) } fn debug( &self, bounds: RectF, _: &Self::LayoutState, _: &Self::PaintState, view: &V, cx: &ViewContext<V>, ) -> json::Value { json!({ "type": "Stack", "bounds": bounds.to_json(), "children": self.children.iter().map(|child| child.debug(view, cx)).collect::<Vec<json::Value>>() }) }} impl<V> Extend<AnyElement<V>> for Stack<V> { fn extend<T: IntoIterator<Item = AnyElement<V>>>(&mut self, children: T) { self.children.extend(children) }}
use std::ops::Range;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json::{self, json, ToJson},
AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
};
/// Element which renders it's children in a stack on top of each other.
/// The first child determines the size of the others.
pub struct Stack<V> {
children: Vec<AnyElement<V>>,
}
impl<V> Default for Stack<V> {
fn default() -> Self {
Self {
children: Vec::new(),
}
}
}
impl<V> Stack<V> {
pub fn new() -> Self {
Self::default()
}
}
impl<V: 'static> Element<V> for Stack<V> {
type LayoutState = ();
type PaintState = ();
fn layout(
&mut self,
mut constraint: SizeConstraint,
view: &mut V,
cx: &mut LayoutContext<V>,
) -> (Vector2F, Self::LayoutState) {
let mut size = constraint.min;
let mut children = self.children.iter_mut();
if let Some(bottom_child) = children.next() {
size = bottom_child.layout(constraint, view, cx);
constraint = SizeConstraint::strict(size);
}
for child in children {
child.layout(constraint, view, cx);
}
(size, ())
}
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
for child in &mut self.children {
scene.paint_layer(None, |scene| {
child.paint(scene, bounds.origin(), visible_bounds, view, cx);
});
}
}
fn rect_for_text_range(
&self,
range_utf16: Range<usize>,
_: RectF,
_: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
view: &V,
cx: &ViewContext<V>,
) -> Option<RectF> {
self.children
.iter()
.rev()
.find_map(|child| child.rect_for_text_range(range_utf16.clone(), view, cx))
}
fn debug(
&self,
bounds: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
view: &V,
cx: &ViewContext<V>,
) -> json::Value {
json!({
"type": "Stack",
"bounds": bounds.to_json(),
"children": self.children.iter().map(|child| child.debug(view, cx)).collect::<Vec<json::Value>>()
})
}
}
impl<V> Extend<AnyElement<V>> for Stack<V> {
fn extend<T: IntoIterator<Item = AnyElement<V>>>(&mut self, children: T) {
self.children.extend(children)
}
}