@@ -188,13 +188,37 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
188188 self . state . id
189189 }
190190
191- /// Set layout rectangle .
191+ /// Set the layout [`Rect`] .
192192 ///
193- /// Intended to be called on child widget in container's `layout`
194- /// implementation.
193+ /// A container widget should call the [`Widget::layout`] method on its children in
194+ /// its own [`Widget::layout`] implementation, then possibly modify the returned [`Size`], and
195+ /// finally call this `set_layout_rect` method on the child to set the final layout [`Rect`].
196+ ///
197+ /// The child will receive the [`LifeCycle::Size`] event informing them of the final [`Size`].
198+ ///
199+ /// [`Widget::layout`]: trait.Widget.html#tymethod.layout
200+ /// [`Rect`]: struct.Rect.html
201+ /// [`Size`]: struct.Size.html
202+ /// [`LifeCycle::Size`]: enum.LifeCycle.html#variant.Size
195203 pub fn set_layout_rect ( & mut self , ctx : & mut LayoutCtx , data : & T , env : & Env , layout_rect : Rect ) {
204+ let mut needs_merge = false ;
205+
206+ let old_size = self . state . layout_rect . map ( |r| r. size ( ) ) ;
207+ let new_size = layout_rect. size ( ) ;
208+
196209 self . state . layout_rect = Some ( layout_rect) ;
197210
211+ if old_size. is_none ( ) || old_size. unwrap ( ) != new_size {
212+ let mut child_ctx = LifeCycleCtx {
213+ command_queue : ctx. command_queue ,
214+ base_state : & mut self . state ,
215+ window_id : ctx. window_id ,
216+ } ;
217+ let size_event = LifeCycle :: Size ( new_size) ;
218+ self . inner . lifecycle ( & mut child_ctx, & size_event, data, env) ;
219+ needs_merge = true ;
220+ }
221+
198222 if WidgetPod :: set_hot_state (
199223 & mut self . inner ,
200224 ctx. command_queue ,
@@ -205,6 +229,10 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
205229 data,
206230 env,
207231 ) {
232+ needs_merge = true ;
233+ }
234+
235+ if needs_merge {
208236 ctx. base_state . merge_up ( & self . state ) ;
209237 }
210238 }
@@ -215,9 +243,12 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
215243 self . layout_rect ( )
216244 }
217245
218- /// The layout rectangle.
246+ /// Returns the layout [`Rect`].
247+ ///
248+ /// This will be the same [`Rect`] that was set by [`set_layout_rect`].
219249 ///
220- /// This will be same value as set by `set_layout_rect`.
250+ /// [`Rect`]: struct.Rect.html
251+ /// [`set_layout_rect`]: #method.set_layout_rect
221252 pub fn layout_rect ( & self ) -> Rect {
222253 self . state . layout_rect . unwrap_or_default ( )
223254 }
@@ -790,6 +821,11 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
790821
791822 true
792823 }
824+ LifeCycle :: Size ( _) => {
825+ // We are a descendant of a widget that received the Size event.
826+ // This event was meant only for our parent, so don't recurse.
827+ false
828+ }
793829 //NOTE: this is not sent here, but from the special set_hot_state method
794830 LifeCycle :: HotChanged ( _) => false ,
795831 LifeCycle :: FocusChanged ( _) => {
0 commit comments