@@ -18,7 +18,9 @@ use std::collections::VecDeque;
1818
1919use crate :: bloom:: Bloom ;
2020use crate :: kurbo:: { Affine , Insets , Point , Rect , Shape , Size , Vec2 } ;
21- use crate :: piet:: { FontBuilder , RenderContext , Text , TextLayout , TextLayoutBuilder } ;
21+ use crate :: piet:: {
22+ FontBuilder , PietTextLayout , RenderContext , Text , TextLayout , TextLayoutBuilder ,
23+ } ;
2224use crate :: {
2325 BoxConstraints , Color , Command , Data , Env , Event , EventCtx , InternalEvent , InternalLifeCycle ,
2426 LayoutCtx , LifeCycle , LifeCycleCtx , PaintCtx , Region , Target , UpdateCtx , Widget , WidgetId ,
@@ -45,6 +47,8 @@ pub struct WidgetPod<T, W> {
4547 old_data : Option < T > ,
4648 env : Option < Env > ,
4749 inner : W ,
50+ // stashed layout so we don't recompute this when debugging
51+ debug_widget_text : Option < PietTextLayout > ,
4852}
4953
5054/// Generic state for all widgets in the hierarchy.
@@ -139,6 +143,7 @@ impl<T, W: Widget<T>> WidgetPod<T, W> {
139143 old_data : None ,
140144 env : None ,
141145 inner,
146+ debug_widget_text : None ,
142147 }
143148 }
144149
@@ -333,25 +338,32 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
333338 /// [`paint`]: trait.Widget.html#tymethod.paint
334339 /// [`paint_with_offset`]: #method.paint_with_offset
335340 pub fn paint ( & mut self , ctx : & mut PaintCtx , data : & T , env : & Env ) {
341+ // we need to do this before we borrow from self
342+ if env. get ( Env :: DEBUG_WIDGET_ID ) {
343+ self . make_widget_id_layout_if_needed ( self . state . id , ctx, env) ;
344+ }
345+
336346 let mut inner_ctx = PaintCtx {
337347 render_ctx : ctx. render_ctx ,
338348 window_id : ctx. window_id ,
339349 z_ops : Vec :: new ( ) ,
340350 region : ctx. region . clone ( ) ,
341351 base_state : & self . state ,
342352 focus_widget : ctx. focus_widget ,
353+ depth : ctx. depth ,
343354 } ;
344355 self . inner . paint ( & mut inner_ctx, data, env) ;
345- ctx. z_ops . append ( & mut inner_ctx. z_ops ) ;
346356
347- if env. get ( Env :: DEBUG_PAINT ) {
357+ let debug_layout = env. get ( Env :: DEBUG_PAINT ) ;
358+ let debug_ids = env. get ( Env :: DEBUG_WIDGET_ID ) && inner_ctx. is_hot ( ) ;
359+
360+ if debug_layout {
348361 self . debug_paint_layout_bounds ( & mut inner_ctx, env) ;
349362 }
350-
351- if env. get ( Env :: DEBUG_WIDGET_ID ) {
363+ if debug_ids {
352364 self . debug_paint_widget_ids ( & mut inner_ctx, env) ;
353365 }
354-
366+ ctx . z_ops . append ( & mut inner_ctx . z_ops ) ;
355367 self . state . invalid = Region :: EMPTY ;
356368 }
357369
@@ -390,30 +402,43 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
390402 } ) ;
391403 }
392404
405+ fn make_widget_id_layout_if_needed ( & mut self , id : WidgetId , ctx : & mut PaintCtx , env : & Env ) {
406+ if self . debug_widget_text . is_none ( ) {
407+ let font = ctx
408+ . text ( )
409+ . new_font_by_name ( env. get ( crate :: theme:: FONT_NAME ) , 10.0 )
410+ . build ( )
411+ . unwrap ( ) ;
412+ let id_string = id. to_raw ( ) . to_string ( ) ;
413+ self . debug_widget_text = ctx
414+ . text ( )
415+ . new_text_layout ( & font, & id_string, f64:: INFINITY )
416+ . build ( )
417+ . ok ( ) ;
418+ }
419+ }
420+
393421 fn debug_paint_widget_ids ( & self , ctx : & mut PaintCtx , env : & Env ) {
394- let font = ctx
395- . text ( )
396- . new_font_by_name ( env. get ( crate :: theme:: FONT_NAME ) , 10.0 )
397- . build ( )
398- . unwrap ( ) ;
399- let id_string = ctx. widget_id ( ) . to_raw ( ) . to_string ( ) ;
400- let text = ctx
401- . text ( )
402- . new_text_layout ( & font, & id_string, f64:: INFINITY )
403- . build ( )
404- . unwrap ( ) ;
405- let text_size = Size :: new ( text. width ( ) , 10.0 ) ;
406- let origin = ctx. size ( ) . to_vec2 ( ) - text_size. to_vec2 ( ) ;
407- let origin = Point :: new ( origin. x . max ( 0.0 ) , origin. y . max ( 0.0 ) ) ;
408-
409- let text_pos = origin + Vec2 :: new ( 0. , 8.0 ) ;
410- ctx. fill ( Rect :: from_origin_size ( origin, text_size) , & Color :: WHITE ) ;
411- ctx. stroke (
412- Rect :: from_origin_size ( origin, text_size) ,
413- & Color :: rgb ( 1.0 , 0. , 0. ) ,
414- 1.0 ,
415- ) ;
416- ctx. draw_text ( & text, text_pos, & Color :: BLACK ) ;
422+ // we clone because we need to move it for paint_with_z_index
423+ let text = self . debug_widget_text . clone ( ) ;
424+ if let Some ( text) = text {
425+ let text_size = Size :: new ( text. width ( ) , 10.0 ) ;
426+ let origin = ctx. size ( ) . to_vec2 ( ) - text_size. to_vec2 ( ) ;
427+ let border_color = env. get_debug_color ( ctx. widget_id ( ) . to_raw ( ) ) ;
428+
429+ ctx. paint_with_z_index ( ctx. depth ( ) , move |ctx| {
430+ let origin = Point :: new ( origin. x . max ( 0.0 ) , origin. y . max ( 0.0 ) ) ;
431+
432+ let text_pos = origin + Vec2 :: new ( 0. , 8.0 ) ;
433+ ctx. fill ( Rect :: from_origin_size ( origin, text_size) , & Color :: WHITE ) ;
434+ ctx. stroke (
435+ Rect :: from_origin_size ( origin, text_size) ,
436+ & border_color,
437+ 1.0 ,
438+ ) ;
439+ ctx. draw_text ( & text, text_pos, & Color :: BLACK ) ;
440+ } )
441+ }
417442 }
418443
419444 fn debug_paint_layout_bounds ( & self , ctx : & mut PaintCtx , env : & Env ) {
@@ -739,14 +764,21 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
739764
740765 ctx. base_state . merge_up ( & self . state ) ;
741766
742- // we need to (re)register children in case of one of the following events
767+ // any work we need to do after certain events:
743768 match event {
769+ // we need to (re)register children in case of one of the following events
744770 LifeCycle :: WidgetAdded | LifeCycle :: Internal ( InternalLifeCycle :: RouteWidgetAdded ) => {
745771 self . state . children_changed = false ;
746772 ctx. base_state . children = ctx. base_state . children . union ( self . state . children ) ;
747773 ctx. base_state . focus_chain . extend ( & self . state . focus_chain ) ;
748774 ctx. register_child ( self . id ( ) ) ;
749775 }
776+ // if we're painting widget ids, we should always paint when hot changes
777+ LifeCycle :: HotChanged ( _) => {
778+ if env. get ( Env :: DEBUG_WIDGET_ID ) {
779+ ctx. request_paint ( ) ;
780+ }
781+ }
750782 _ => ( ) ,
751783 }
752784 }
0 commit comments