From 09a892525cfca8d7326e33a4b183bd780941692e Mon Sep 17 00:00:00 2001 From: Brownard Date: Sun, 21 Sep 2014 18:25:09 +0100 Subject: [PATCH] Modify focus handling Modified the focus handling so that an element more in line with the direction of movement is selected over an element that is closer --- .../Controls/Visuals/FrameworkElement.cs | 54 ++++++++++++++++++---- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/MediaPortal/Source/UI/SkinEngine/Controls/Visuals/FrameworkElement.cs b/MediaPortal/Source/UI/SkinEngine/Controls/Visuals/FrameworkElement.cs index 7257e20..e967964 100644 --- a/MediaPortal/Source/UI/SkinEngine/Controls/Visuals/FrameworkElement.cs +++ b/MediaPortal/Source/UI/SkinEngine/Controls/Visuals/FrameworkElement.cs @@ -1018,9 +1018,9 @@ namespace MediaPortal.UI.SkinEngine.Controls.Visuals // it won't be used as next focus element continue; float distance = BorderDistance(child.ActualBounds, currentFocusRect.Value); - if (bestMatch == null || distance < bestDistance || - distance == bestDistance && topOrLeftDifference < bestTopOrLeftDifference - /* || topOrLeftDifference == bestTopOrLeftDifference && centerDistance < bestCenterDistance*/) + if (bestMatch == null || (distance < bestDistance && topOrLeftDifference < 0) + || (topOrLeftDifference < bestTopOrLeftDifference && (distance == bestDistance || bestTopOrLeftDifference >= 0)) + /*|| topOrLeftDifference == bestTopOrLeftDifference && centerDistance < bestCenterDistance*/) { bestMatch = child; bestDistance = distance; @@ -1058,6 +1058,44 @@ namespace MediaPortal.UI.SkinEngine.Controls.Visuals return (float) Math.Sqrt(distX * distX + distY * distY); } + /// + /// Calculates the horizontal distance from to . + /// + /// + /// + /// Horizontal distance, negative if there is an overlap. + protected static float HorizontalDistance(RectangleF r1, RectangleF r2) + { + if (r1.Right <= r2.Left) + return r2.Left - r1.Right; + if (r1.Left >= r2.Right) + return r1.Left - r2.Right; + if (r1.Left < r2.Left && r1.Right < r2.Right) + return r2.Left - r1.Right; + if (r1.Right > r2.Right && r1.Left > r2.Left) + return r1.Left - r2.Right; + return -r1.Width; + } + + /// + /// Calculates the vertical distance from to . + /// + /// + /// + /// Vertical distance, negative if there is an overlap. + protected static float VerticalDistance(RectangleF r1, RectangleF r2) + { + if (r1.Bottom <= r2.Top) + return r2.Top - r1.Bottom; + if (r1.Top >= r2.Bottom) + return r1.Top - r2.Bottom; + if (r1.Top < r2.Top && r1.Bottom < r2.Bottom) + return r2.Top - r1.Bottom; + if (r1.Bottom > r2.Bottom && r1.Top > r2.Top) + return r1.Top - r2.Bottom; + return -r1.Height; + } + protected PointF GetCenterPosition(RectangleF rect) { return new PointF((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2); @@ -1100,7 +1138,7 @@ namespace MediaPortal.UI.SkinEngine.Controls.Visuals PointF start = new PointF((actualBounds.Right + actualBounds.Left) / 2, actualBounds.Top); PointF end = new PointF((otherRect.Right + otherRect.Left) / 2, otherRect.Bottom); float alpha = CalcDirection(start, end); - topOrLeftDifference = Math.Abs(actualBounds.Left - otherRect.Left); + topOrLeftDifference = HorizontalDistance(actualBounds, otherRect); //Math.Abs(actualBounds.Left - otherRect.Left); return isNear || alpha > DELTA_DOUBLE && alpha < Math.PI - DELTA_DOUBLE; } @@ -1111,8 +1149,8 @@ namespace MediaPortal.UI.SkinEngine.Controls.Visuals PointF start = new PointF((actualBounds.Right + actualBounds.Left) / 2, actualBounds.Bottom); PointF end = new PointF((otherRect.Right + otherRect.Left) / 2, otherRect.Top); float alpha = CalcDirection(start, end); - topOrLeftDifference = Math.Abs(actualBounds.Left - otherRect.Left); - return isNear|| alpha > Math.PI + DELTA_DOUBLE && alpha < 2 * Math.PI - DELTA_DOUBLE; + topOrLeftDifference = HorizontalDistance(actualBounds, otherRect); //Math.Abs(actualBounds.Left - otherRect.Left); + return isNear || alpha > Math.PI + DELTA_DOUBLE && alpha < 2 * Math.PI - DELTA_DOUBLE; } protected bool LocatedLeftOf(RectangleF otherRect, out float topOrLeftDifference) @@ -1122,7 +1160,7 @@ namespace MediaPortal.UI.SkinEngine.Controls.Visuals PointF start = new PointF(actualBounds.Right, (actualBounds.Top + actualBounds.Bottom) / 2); PointF end = new PointF(otherRect.Left, (otherRect.Top + otherRect.Bottom) / 2); float alpha = CalcDirection(start, end); - topOrLeftDifference = Math.Abs(actualBounds.Top - otherRect.Top); + topOrLeftDifference = VerticalDistance(actualBounds, otherRect); //Math.Abs(actualBounds.Top - otherRect.Top); return isNear || alpha < Math.PI / 2 - DELTA_DOUBLE || alpha > 3 * Math.PI / 2 + DELTA_DOUBLE; } @@ -1133,7 +1171,7 @@ namespace MediaPortal.UI.SkinEngine.Controls.Visuals PointF start = new PointF(actualBounds.Left, (actualBounds.Top + actualBounds.Bottom) / 2); PointF end = new PointF(otherRect.Right, (otherRect.Top + otherRect.Bottom) / 2); float alpha = CalcDirection(start, end); - topOrLeftDifference = Math.Abs(actualBounds.Top - otherRect.Top); + topOrLeftDifference = VerticalDistance(actualBounds, otherRect); //Math.Abs(actualBounds.Top - otherRect.Top); return isNear || alpha > Math.PI / 2 + DELTA_DOUBLE && alpha < 3 * Math.PI / 2 - DELTA_DOUBLE; } -- 1.8.1.msysgit.1