1010using System . Windows . Controls ;
1111using System . Windows . Documents ;
1212using System . Windows . Media ;
13+ using iNKORE . UI . WPF . Helpers ;
1314
1415namespace iNKORE . UI . WPF . Modern . Controls . Helpers
1516{
@@ -163,6 +164,20 @@ public static void SetFocusVisualSecondaryThickness(FrameworkElement element, Th
163164
164165 #endregion
165166
167+ #region FocusVisualPrimaryCornerRadius
168+
169+ public static CornerRadius GetFocusVisualPrimaryCornerRadius ( FrameworkElement element ) => ( CornerRadius ) element . GetValue ( FocusVisualPrimaryCornerRadiusProperty ) ;
170+ private static void SetFocusVisualPrimaryCornerRadius ( FrameworkElement element , CornerRadius value ) => element . SetValue ( FocusVisualPrimaryCornerRadiusProperty , value ) ;
171+
172+ public static readonly DependencyProperty FocusVisualPrimaryCornerRadiusProperty =
173+ DependencyProperty . RegisterAttached (
174+ "FocusVisualPrimaryCornerRadius" ,
175+ typeof ( CornerRadius ) ,
176+ typeof ( FocusVisualHelper ) ,
177+ new FrameworkPropertyMetadata ( new CornerRadius ( 0 ) ) ) ;
178+
179+ #endregion
180+
166181 #region FocusVisualMargin
167182
168183 /// <summary>
@@ -393,7 +408,7 @@ static void ShowFocusVisual(Control control, FrameworkElement target)
393408 {
394409 HideFocusVisual ( ) ;
395410
396- AdornerLayer adornerlayer = AdornerLayer . GetAdornerLayer ( target ) ;
411+ AdornerLayer adornerlayer = GetAdornerLayer ( target ) ;
397412 if ( adornerlayer == null )
398413 return ;
399414
@@ -414,6 +429,17 @@ static void ShowFocusVisual(Control control, FrameworkElement target)
414429 }
415430 }
416431
432+ static AdornerLayer ? GetAdornerLayer ( FrameworkElement element )
433+ {
434+ var scrollPresenter = element . FindAscendant < ScrollContentPresenter > ( ) ;
435+ if ( scrollPresenter ? . Parent is AdornerDecorator adornerDecorator )
436+ {
437+ return adornerDecorator . AdornerLayer ;
438+ }
439+
440+ return AdornerLayer . GetAdornerLayer ( element ) ;
441+ }
442+
417443 static void OnControlIsVisibleChanged ( object sender , DependencyPropertyChangedEventArgs e )
418444 {
419445 ( ( Control ) sender ) . IsVisibleChanged -= OnControlIsVisibleChanged ;
@@ -483,11 +509,15 @@ private static void OnFocusVisualIsVisibleChanged(object sender, DependencyPrope
483509 }
484510 else
485511 {
512+ var focusVisualMargin = GetFocusVisualMargin ( focusedElement ) ;
513+
514+ ApplyCornerRadiusToFocusVisual ( focusVisual , focusedElement , focusVisualMargin ) ;
515+
486516 TransferValue ( focusedElement , focusVisual , FocusVisualPrimaryBrushProperty ) ;
487517 TransferValue ( focusedElement , focusVisual , FocusVisualPrimaryThicknessProperty ) ;
488518 TransferValue ( focusedElement , focusVisual , FocusVisualSecondaryBrushProperty ) ;
489519 TransferValue ( focusedElement , focusVisual , FocusVisualSecondaryThicknessProperty ) ;
490- focusVisual . Margin = GetFocusVisualMargin ( focusedElement ) ;
520+ focusVisual . Margin = focusVisualMargin ;
491521 }
492522
493523 SetFocusedElement ( focusVisual , focusedElement ) ;
@@ -510,6 +540,39 @@ private static void OnFocusVisualIsVisibleChanged(object sender, DependencyPrope
510540 }
511541 }
512542
543+ private static void ApplyCornerRadiusToFocusVisual ( Control focusVisual , FrameworkElement focusedElement , Thickness focusVisualMargin )
544+ {
545+ var cornerRadius = GetCornerRadiusForFocusedElement ( focusedElement ) ;
546+ if ( cornerRadius is CornerRadius focusedCornerRadius && focusedCornerRadius != default )
547+ {
548+ var focusVisualCornerRadius = new CornerRadius (
549+ GetSumIfSourceIsNonZero ( focusedCornerRadius . TopLeft , - ( focusVisualMargin . Left + focusVisualMargin . Top ) / 2 ) ,
550+ GetSumIfSourceIsNonZero ( focusedCornerRadius . TopRight , - ( focusVisualMargin . Right + focusVisualMargin . Top ) / 2 ) ,
551+ GetSumIfSourceIsNonZero ( focusedCornerRadius . BottomLeft , - ( focusVisualMargin . Left + focusVisualMargin . Bottom ) / 2 ) ,
552+ GetSumIfSourceIsNonZero ( focusedCornerRadius . BottomRight , - ( focusVisualMargin . Right + focusVisualMargin . Bottom ) / 2 ) ) ;
553+
554+ ControlHelper . SetCornerRadius ( focusVisual , focusVisualCornerRadius ) ;
555+ var topLeftRadius = GetSumIfSourceIsNonZero ( focusVisualCornerRadius . TopLeft , GetFocusVisualSecondaryThickness ( focusedElement ) . Left ) ;
556+ var topRightRadius = GetSumIfSourceIsNonZero ( focusVisualCornerRadius . TopRight , GetFocusVisualSecondaryThickness ( focusedElement ) . Right ) ;
557+ var bottomRightRadius = GetSumIfSourceIsNonZero ( focusVisualCornerRadius . BottomLeft , GetFocusVisualSecondaryThickness ( focusedElement ) . Left ) ;
558+ var bottomLeftRadius = GetSumIfSourceIsNonZero ( focusVisualCornerRadius . BottomRight , GetFocusVisualSecondaryThickness ( focusedElement ) . Right ) ;
559+
560+ SetFocusVisualPrimaryCornerRadius ( focusVisual , new CornerRadius ( topLeftRadius , topRightRadius , bottomRightRadius , bottomLeftRadius ) ) ;
561+ }
562+ }
563+
564+ private static CornerRadius ? GetCornerRadiusForFocusedElement ( FrameworkElement focusedElement )
565+ {
566+ var cornerRadiusTarget = focusedElement . GetValue ( TemplateFocusTargetProperty ) as FrameworkElement ;
567+ cornerRadiusTarget ??= focusedElement ;
568+ return cornerRadiusTarget switch
569+ {
570+ var _ when cornerRadiusTarget . GetValue ( Border . CornerRadiusProperty ) is CornerRadius borderResult && borderResult != default => borderResult ,
571+ var _ when cornerRadiusTarget . GetValue ( ControlHelper . CornerRadiusProperty ) is CornerRadius controlResult => controlResult ,
572+ _ => null
573+ } ;
574+ }
575+
513576 private static void TransferValue ( DependencyObject source , DependencyObject target , DependencyProperty dp )
514577 {
515578 if ( ! source . HasDefaultValue ( dp ) )
@@ -518,6 +581,12 @@ private static void TransferValue(DependencyObject source, DependencyObject targ
518581 }
519582 }
520583
584+ private static double GetSumIfSourceIsNonZero ( double source , double adjustment ) => source switch
585+ {
586+ 0 => 0 ,
587+ _ => source + adjustment
588+ } ;
589+
521590 private sealed class FocusVisualAdorner : Adorner
522591 {
523592 public FocusVisualAdorner ( Control focusedElement , UIElement adornedElement , Style focusVisualStyle ) : base ( adornedElement )
@@ -531,13 +600,18 @@ public FocusVisualAdorner(Control focusedElement, UIElement adornedElement, Styl
531600 Control control = new Control ( ) ;
532601 SetIsSystemFocusVisual ( control , false ) ;
533602 control . Style = focusVisualStyle ;
534- control . Margin = GetFocusVisualMargin ( focusedElement ) ;
603+
604+ var focusVisualMargin = GetFocusVisualMargin ( focusedElement ) ;
605+ control . Margin = focusVisualMargin ;
606+
607+ ApplyCornerRadiusToFocusVisual ( control , focusedElement , focusVisualMargin ) ;
608+
535609 TransferValue ( focusedElement , control , FocusVisualPrimaryBrushProperty ) ;
536610 TransferValue ( focusedElement , control , FocusVisualPrimaryThicknessProperty ) ;
537611 TransferValue ( focusedElement , control , FocusVisualSecondaryBrushProperty ) ;
538612 TransferValue ( focusedElement , control , FocusVisualSecondaryThicknessProperty ) ;
539613 _adorderChild = control ;
540- IsClipEnabled = true ;
614+ IsClipEnabled = false ;
541615 IsHitTestVisible = false ;
542616 IsEnabled = false ;
543617 AddVisualChild ( _adorderChild ) ;
0 commit comments