Now the Element trait is designed to be wrapped in a Lifecycle enum that gets placed inside an ElementBox. This allows the framework to store data on behalf of the Element implementation, such as sizes, bounds, and also implementation-specific LayoutState and PaintState types. This makes it easier to reason about which data is available in each Element method.
84 lines
2.0 KiB
Rust
84 lines
2.0 KiB
Rust
use crate::{
|
|
AfterLayoutContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
|
|
SizeConstraint,
|
|
};
|
|
use pathfinder_geometry::vector::Vector2F;
|
|
|
|
pub struct ConstrainedBox {
|
|
child: ElementBox,
|
|
constraint: SizeConstraint,
|
|
}
|
|
|
|
impl ConstrainedBox {
|
|
pub fn new(child: ElementBox) -> Self {
|
|
Self {
|
|
child,
|
|
constraint: SizeConstraint {
|
|
min: Vector2F::zero(),
|
|
max: Vector2F::splat(f32::INFINITY),
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn with_max_width(mut self, max_width: f32) -> Self {
|
|
self.constraint.max.set_x(max_width);
|
|
self
|
|
}
|
|
|
|
pub fn with_max_height(mut self, max_height: f32) -> Self {
|
|
self.constraint.max.set_y(max_height);
|
|
self
|
|
}
|
|
|
|
pub fn with_height(mut self, height: f32) -> Self {
|
|
self.constraint.min.set_y(height);
|
|
self.constraint.max.set_y(height);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl Element for ConstrainedBox {
|
|
type LayoutState = ();
|
|
type PaintState = ();
|
|
|
|
fn layout(
|
|
&mut self,
|
|
mut constraint: SizeConstraint,
|
|
ctx: &mut LayoutContext,
|
|
) -> (Vector2F, Self::LayoutState) {
|
|
constraint.min = constraint.min.max(self.constraint.min);
|
|
constraint.max = constraint.max.min(self.constraint.max);
|
|
let size = self.child.layout(constraint, ctx);
|
|
(size, ())
|
|
}
|
|
|
|
fn after_layout(
|
|
&mut self,
|
|
_: Vector2F,
|
|
_: &mut Self::LayoutState,
|
|
ctx: &mut AfterLayoutContext,
|
|
) {
|
|
self.child.after_layout(ctx);
|
|
}
|
|
|
|
fn paint(
|
|
&mut self,
|
|
bounds: pathfinder_geometry::rect::RectF,
|
|
_: &mut Self::LayoutState,
|
|
ctx: &mut PaintContext,
|
|
) -> Self::PaintState {
|
|
self.child.paint(bounds.origin(), ctx);
|
|
}
|
|
|
|
fn dispatch_event(
|
|
&mut self,
|
|
event: &Event,
|
|
_: pathfinder_geometry::rect::RectF,
|
|
_: &mut Self::LayoutState,
|
|
_: &mut Self::PaintState,
|
|
ctx: &mut EventContext,
|
|
) -> bool {
|
|
self.child.dispatch_event(event, ctx)
|
|
}
|
|
}
|