@@ -11,34 +11,54 @@ private void SetupAdornments ()
1111 {
1212 return ;
1313 }
14+
15+ Thickness previousMarginThickness = Margin . Thickness ;
16+ Thickness previousBorderThickness = Border . Thickness ;
17+ Thickness previousPaddingThickness = Padding . Thickness ;
18+
1419 Margin . Parent = this ;
1520 Border . Parent = this ;
1621 Padding . Parent = this ;
1722
1823 // When any adornment's thickness changes, recompute frames and request layout + redraw.
1924 Margin . ThicknessChanged += ( _ , _ ) =>
2025 {
21- Margin . View ? . SetNeedsLayout ( ) ;
22- SetAdornmentFrames ( ) ;
23- SetNeedsLayout ( ) ;
24- SetNeedsDraw ( ) ;
26+ previousMarginThickness = HandleAdornmentThicknessChanged ( Margin , previousMarginThickness ) ;
2527 } ;
2628
2729 Border . ThicknessChanged += ( _ , _ ) =>
2830 {
29- Border . View ? . SetNeedsLayout ( ) ;
30- SetAdornmentFrames ( ) ;
31- SetNeedsLayout ( ) ;
32- SetNeedsDraw ( ) ;
31+ previousBorderThickness = HandleAdornmentThicknessChanged ( Border , previousBorderThickness ) ;
3332 } ;
3433
3534 Padding . ThicknessChanged += ( _ , _ ) =>
3635 {
37- Padding . View ? . SetNeedsLayout ( ) ;
38- SetAdornmentFrames ( ) ;
39- SetNeedsLayout ( ) ;
40- SetNeedsDraw ( ) ;
36+ previousPaddingThickness = HandleAdornmentThicknessChanged ( Padding , previousPaddingThickness ) ;
4137 } ;
38+
39+ Thickness HandleAdornmentThicknessChanged ( IAdornment adornment , Thickness previousThickness )
40+ {
41+ Rectangle oldViewport = GetViewportForAdornmentThickness ( adornment , previousThickness ) ;
42+ Rectangle oldViewportFrame = GetViewportFrameForAdornmentThickness ( adornment , previousThickness ) ;
43+ Thickness currentThickness = adornment . Thickness ;
44+
45+ ( adornment . View as View ) ? . SetNeedsLayout ( ) ;
46+ SetAdornmentFrames ( ) ;
47+ SetNeedsLayout ( ) ;
48+ SetNeedsDraw ( ) ;
49+
50+ if ( oldViewportFrame != GetViewportFrameForAdornmentThickness ( adornment , currentThickness ) )
51+ {
52+ InvalidateAdornmentThicknessChange ( ) ;
53+ }
54+
55+ if ( oldViewport != Viewport )
56+ {
57+ RaiseViewportChangedEvent ( oldViewport ) ;
58+ }
59+
60+ return currentThickness ;
61+ }
4262 }
4363
4464 private void BeginInitAdornments ( )
@@ -345,4 +365,47 @@ internal void SetAdornmentFrames ()
345365 // Border and Padding dynamically update based on Margin's View's Frame changing
346366 Margin . View ? . Frame = Frame with { Location = Point . Empty } ;
347367 }
368+
369+ private Rectangle GetViewportForAdornmentThickness ( IAdornment changedAdornment , Thickness changedThickness )
370+ {
371+ Thickness thickness = GetAdornmentsThicknessForAdornment ( changedAdornment , changedThickness ) ;
372+
373+ return new Rectangle ( _viewportLocation , GetViewportSizeForThickness ( thickness ) ) ;
374+ }
375+
376+ private Rectangle GetViewportFrameForAdornmentThickness ( IAdornment changedAdornment , Thickness changedThickness )
377+ {
378+ Thickness thickness = GetAdornmentsThicknessForAdornment ( changedAdornment , changedThickness ) ;
379+
380+ return new Rectangle ( new Point ( thickness . Left , thickness . Top ) , GetViewportSizeForThickness ( thickness ) ) ;
381+ }
382+
383+ private Size GetViewportSizeForThickness ( Thickness thickness ) =>
384+ new ( Math . Max ( 0 , Frame . Width - thickness . Horizontal ) , Math . Max ( 0 , Frame . Height - thickness . Vertical ) ) ;
385+
386+ private Thickness GetAdornmentsThicknessForAdornment ( IAdornment changedAdornment , Thickness changedThickness )
387+ {
388+ Thickness thickness = Thickness . Empty ;
389+
390+ thickness += ReferenceEquals ( changedAdornment , Margin ) ? changedThickness : Margin . Thickness ;
391+ thickness += ReferenceEquals ( changedAdornment , Border ) ? changedThickness : Border . Thickness ;
392+ thickness += ReferenceEquals ( changedAdornment , Padding ) ? changedThickness : Padding . Thickness ;
393+
394+ return thickness ;
395+ }
396+
397+ private void InvalidateAdornmentThicknessChange ( )
398+ {
399+ if ( SuperView is null )
400+ {
401+ NeedsClearScreenNextIteration ( ) ;
402+
403+ return ;
404+ }
405+
406+ Rectangle invalidationViewport = Frame ;
407+ Point superScroll = SuperView . Viewport . Location ;
408+ invalidationViewport . Offset ( - superScroll . X , - superScroll . Y ) ;
409+ SuperView . SetNeedsDraw ( invalidationViewport ) ;
410+ }
348411}
0 commit comments