@@ -22,8 +22,8 @@ use crate::bloom::Bloom;
2222use crate :: kurbo:: { Affine , Insets , Rect , Shape , Size } ;
2323use crate :: piet:: RenderContext ;
2424use crate :: {
25- BoxConstraints , Command , Data , Env , Event , EventCtx , LayoutCtx , LifeCycle , LifeCycleCtx ,
26- PaintCtx , Target , UpdateCtx , Widget , WidgetId ,
25+ BoxConstraints , Command , Data , Env , Event , EventCtx , InternalEvent , InternalLifeCycle ,
26+ LayoutCtx , LifeCycle , LifeCycleCtx , PaintCtx , Target , UpdateCtx , Widget , WidgetId ,
2727} ;
2828
2929/// Our queue type
@@ -366,7 +366,7 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
366366 }
367367
368368 // log if we seem not to be laid out when we should be
369- if !matches ! ( event, Event :: WindowConnected | Event :: Size ( _) )
369+ if !matches ! ( event, Event :: WindowConnected | Event :: Internal ( InternalEvent :: Size ( _) ) )
370370 && self . state . layout_rect . is_none ( )
371371 {
372372 log:: warn!(
@@ -403,12 +403,40 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
403403 let mut recurse = true ;
404404 let mut hot_changed = None ;
405405 let child_event = match event {
406+ Event :: Internal ( internal) => match internal {
407+ InternalEvent :: Size ( size) => {
408+ child_ctx. request_layout ( ) ;
409+ recurse = ctx. is_root ;
410+ Event :: Internal ( InternalEvent :: Size ( * size) )
411+ }
412+ InternalEvent :: MouseLeave => {
413+ let had_hot = child_ctx. base_state . is_hot ;
414+ child_ctx. base_state . is_hot = false ;
415+ if had_hot {
416+ hot_changed = Some ( false ) ;
417+ }
418+ recurse = had_active || had_hot;
419+ Event :: Internal ( InternalEvent :: MouseLeave )
420+ }
421+ InternalEvent :: TargetedCommand ( target, cmd) => {
422+ match target {
423+ Target :: Window ( _) => Event :: Command ( cmd. clone ( ) ) ,
424+ Target :: Widget ( id) if * id == child_ctx. widget_id ( ) => {
425+ Event :: Command ( cmd. clone ( ) )
426+ }
427+ Target :: Widget ( id) => {
428+ // Recurse when the target widget could be our descendant.
429+ // The bloom filter we're checking can return false positives.
430+ recurse = child_ctx. base_state . children . may_contain ( id) ;
431+ Event :: Internal ( InternalEvent :: TargetedCommand ( * target, cmd. clone ( ) ) )
432+ }
433+ Target :: Global => {
434+ panic ! ( "Target::Global should be converted before WidgetPod" )
435+ }
436+ }
437+ }
438+ } ,
406439 Event :: WindowConnected => Event :: WindowConnected ,
407- Event :: Size ( size) => {
408- child_ctx. request_layout ( ) ;
409- recurse = ctx. is_root ;
410- Event :: Size ( * size)
411- }
412440 Event :: MouseDown ( mouse_event) => {
413441 let had_hot = child_ctx. base_state . is_hot ;
414442 let now_hot = rect. winding ( mouse_event. pos ) != 0 ;
@@ -438,15 +466,6 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
438466 mouse_event. pos -= rect. origin ( ) . to_vec2 ( ) ;
439467 Event :: MouseMove ( mouse_event)
440468 }
441- Event :: MouseLeave => {
442- let had_hot = child_ctx. base_state . is_hot ;
443- child_ctx. base_state . is_hot = false ;
444- if had_hot {
445- hot_changed = Some ( false ) ;
446- }
447- recurse = had_active || had_hot;
448- Event :: MouseLeave
449- }
450469 Event :: KeyDown ( e) => {
451470 recurse = child_ctx. has_focus ( ) ;
452471 Event :: KeyDown ( * e)
@@ -472,17 +491,6 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
472491 Event :: Timer ( * id)
473492 }
474493 Event :: Command ( cmd) => Event :: Command ( cmd. clone ( ) ) ,
475- Event :: TargetedCommand ( target, cmd) => match target {
476- Target :: Window ( _) => Event :: Command ( cmd. clone ( ) ) ,
477- Target :: Widget ( id) if * id == child_ctx. widget_id ( ) => Event :: Command ( cmd. clone ( ) ) ,
478- Target :: Widget ( id) => {
479- // Recurse when the target widget could be our descendant.
480- // The bloom filter we're checking can return false positives.
481- recurse = child_ctx. base_state . children . may_contain ( id) ;
482- Event :: TargetedCommand ( * target, cmd. clone ( ) )
483- }
484- Target :: Global => panic ! ( "Target::Global should be converted before WidgetPod" ) ,
485- } ,
486494 } ;
487495 if let Some ( is_hot) = hot_changed {
488496 let hot_changed_event = LifeCycle :: HotChanged ( is_hot) ;
@@ -502,6 +510,70 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
502510
503511 pub fn lifecycle ( & mut self , ctx : & mut LifeCycleCtx , event : & LifeCycle , data : & T , env : & Env ) {
504512 let recurse = match event {
513+ LifeCycle :: Internal ( internal) => match internal {
514+ InternalLifeCycle :: RouteWidgetAdded => {
515+ // if this is called either we were just created, in
516+ // which case we need to change lifecycle event to
517+ // WidgetAdded or in case we were already created
518+ // we just pass this event down
519+ if self . old_data . is_none ( ) {
520+ self . lifecycle ( ctx, & LifeCycle :: WidgetAdded , data, env) ;
521+ return ;
522+ } else {
523+ if self . state . children_changed {
524+ self . state . children . clear ( ) ;
525+ self . state . focus_chain . clear ( ) ;
526+ }
527+ self . state . children_changed
528+ }
529+ }
530+ InternalLifeCycle :: RouteFocusChanged { old, new } => {
531+ self . state . request_focus = None ;
532+
533+ let this_changed = if * old == Some ( self . state . id ) {
534+ Some ( false )
535+ } else if * new == Some ( self . state . id ) {
536+ Some ( true )
537+ } else {
538+ None
539+ } ;
540+
541+ if let Some ( change) = this_changed {
542+ // Only send FocusChanged in case there's actual change
543+ if old != new {
544+ self . state . has_focus = change;
545+ let event = LifeCycle :: FocusChanged ( change) ;
546+ self . inner . lifecycle ( ctx, & event, data, env) ;
547+ }
548+ false
549+ } else {
550+ self . state . has_focus = false ;
551+ // Recurse when the target widgets could be our descendants.
552+ // The bloom filter we're checking can return false positives.
553+ match ( old, new) {
554+ ( Some ( old) , _) if self . state . children . may_contain ( old) => true ,
555+ ( _, Some ( new) ) if self . state . children . may_contain ( new) => true ,
556+ _ => false ,
557+ }
558+ }
559+ }
560+ #[ cfg( test) ]
561+ InternalLifeCycle :: DebugRequestState { widget, state_cell } => {
562+ if * widget == self . id ( ) {
563+ state_cell. set ( self . state . clone ( ) ) ;
564+ false
565+ } else {
566+ // Recurse when the target widget could be our descendant.
567+ // The bloom filter we're checking can return false positives.
568+ self . state . children . may_contain ( & widget)
569+ }
570+ }
571+ #[ cfg( test) ]
572+ InternalLifeCycle :: DebugInspectState ( f) => {
573+ f. call ( & self . state ) ;
574+ true
575+ }
576+ } ,
505577 LifeCycle :: AnimFrame ( _) => {
506578 let r = self . state . request_anim ;
507579 self . state . request_anim = false ;
@@ -515,74 +587,12 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
515587
516588 true
517589 }
518- LifeCycle :: RouteWidgetAdded => {
519- // if this is called either we were just created, in
520- // which case we need to change lifecycle event to
521- // WidgetAdded or in case we were already created
522- // we just pass this event down
523- if self . old_data . is_none ( ) {
524- self . lifecycle ( ctx, & LifeCycle :: WidgetAdded , data, env) ;
525- return ;
526- } else {
527- if self . state . children_changed {
528- self . state . children . clear ( ) ;
529- self . state . focus_chain . clear ( ) ;
530- }
531- self . state . children_changed
532- }
533- }
534590 LifeCycle :: HotChanged ( _) => false ,
535- LifeCycle :: RouteFocusChanged { old, new } => {
536- self . state . request_focus = None ;
537-
538- let this_changed = if * old == Some ( self . state . id ) {
539- Some ( false )
540- } else if * new == Some ( self . state . id ) {
541- Some ( true )
542- } else {
543- None
544- } ;
545-
546- if let Some ( change) = this_changed {
547- // Only send FocusChanged in case there's actual change
548- if old != new {
549- self . state . has_focus = change;
550- let event = LifeCycle :: FocusChanged ( change) ;
551- self . inner . lifecycle ( ctx, & event, data, env) ;
552- }
553- false
554- } else {
555- self . state . has_focus = false ;
556- // Recurse when the target widgets could be our descendants.
557- // The bloom filter we're checking can return false positives.
558- match ( old, new) {
559- ( Some ( old) , _) if self . state . children . may_contain ( old) => true ,
560- ( _, Some ( new) ) if self . state . children . may_contain ( new) => true ,
561- _ => false ,
562- }
563- }
564- }
565591 LifeCycle :: FocusChanged ( _) => {
566592 // We are a descendant of a widget that has/had focus.
567593 // Descendants don't inherit focus, so don't recurse.
568594 false
569595 }
570- #[ cfg( test) ]
571- LifeCycle :: DebugRequestState { widget, state_cell } => {
572- if * widget == self . id ( ) {
573- state_cell. set ( self . state . clone ( ) ) ;
574- false
575- } else {
576- // Recurse when the target widget could be our descendant.
577- // The bloom filter we're checking can return false positives.
578- self . state . children . may_contain ( & widget)
579- }
580- }
581- #[ cfg( test) ]
582- LifeCycle :: DebugInspectState ( f) => {
583- f. call ( & self . state ) ;
584- true
585- }
586596 } ;
587597
588598 if recurse {
@@ -598,7 +608,7 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
598608
599609 // we need to (re)register children in case of one of the following events
600610 match event {
601- LifeCycle :: WidgetAdded | LifeCycle :: RouteWidgetAdded => {
611+ LifeCycle :: WidgetAdded | LifeCycle :: Internal ( InternalLifeCycle :: RouteWidgetAdded ) => {
602612 self . state . children_changed = false ;
603613 ctx. base_state . children = ctx. base_state . children . union ( self . state . children ) ;
604614 ctx. base_state . focus_chain . extend ( & self . state . focus_chain ) ;
0 commit comments