use crate::prelude::*; /// Asks its child in the shorter of a cap and the box this widget was given, /// and answers what the child used, held to the same cap. /// /// A cap on the box is a widget rather than a [`SizeRule`] because a box is /// whoever asked's to decide: a rule that read the box it was given would be /// decided again by every path that hands a widget one, including the ones /// that re-place a drawing without asking it anything, and the decision would /// then depend on which path arrived last. A widget is drawn again whenever /// its own box changes, so the comparison is made where the answer can be /// kept -- `longer_than` narrows the windows this drawing holds for, and /// `holds` says the box lengths. /// /// The box is what a text wraps at and what a scroll takes its viewport from, /// which is why capping the answer alone is not the same thing. pub struct MaxSize { pub inner: StrongWidget, pub x: Option, pub y: Option, } impl MaxSize { fn max(&self, axis: Axis) -> Option { match axis { Axis::X => self.x, Axis::Y => self.y, } } } impl Widget for MaxSize { fn draw(&mut self, painter: &mut Painter) -> Size { let align = painter.alignment(); let mut region = UiRegion::FULL; for axis in Axis::BOTH { let Some(max) = self.max(axis) else { continue; }; let own = painter.region_len(axis); if painter.longer_than(own, max, axis) { region[axis] = max.align(align[axis]); } } let mut size = painter.widget_at(&self.inner, region).size(); for axis in Axis::BOTH { // The child may draw past the box it was given -- a text too tall // for it -- and the cap is a promise about the length as well. A // share passes through: it is a length only to whoever divides // one, and that is this widget's parent rather than this widget, // which has already given the share the box the cap allows. if let Some(max) = self.max(axis) && painter.longer_than(size[axis].without_leftover(), max, axis) { size[axis] = max.into(); } } size } }