Skip to content

Commit

Permalink
Merge pull request #8533 from unoplatform/dev/mazi/flyout-showat
Browse files Browse the repository at this point in the history
Clamp `Popup` and `Flyout` positioning to visible bounds
  • Loading branch information
mergify[bot] authored Apr 15, 2022
2 parents 5e4b71f + a60ce51 commit 919cd95
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/SamplesApp/SamplesApp.UITests/ScreenshotInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public ScreenshotInfo(FileInfo file, string stepName)
public static implicit operator ScreenshotInfo(FileInfo fi) => new ScreenshotInfo(fi, fi.Name);

public Bitmap GetBitmap() => _bitmap ??= new Bitmap(File.FullName);

public int Width => GetBitmap().Width;

public int Height => GetBitmap().Height;

public void Dispose()
{
_bitmap?.Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,20 @@ public void Flyout_Namescope()

_app.FastTap(closeButton);
}

[Test]
[AutoRetry]
public void Flyout_ShowAt_Window_Content()
{
Run("UITests.Windows_UI_Xaml_Controls.FlyoutTests.Flyout_ShowAt_Window_Content");

var windowButton = _app.Marked("WindowButton");

_app.WaitForElement(windowButton);
_app.FastTap(windowButton);

using var result = TakeScreenshot("Result", ignoreInSnapshotCompare: true);
ImageAssert.HasColorAt(result, result.Width / 2, 150, Color.Red);
}
}
}
7 changes: 7 additions & 0 deletions src/SamplesApp/UITests.Shared/UITests.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\Flyout_ShowAt_Window_Content.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\Flyout_TemplatedParent.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -5552,6 +5556,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\Flyout_Namescope.xaml.cs">
<DependentUpon>Flyout_Namescope.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\Flyout_ShowAt_Window_Content.xaml.cs">
<DependentUpon>Flyout_ShowAt_Window_Content.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\Flyout\Flyout_TemplatedParent.xaml.cs">
<DependentUpon>Flyout_TemplatedParent.xaml</DependentUpon>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Page
x:Class="UITests.Windows_UI_Xaml_Controls.FlyoutTests.Flyout_ShowAt_Window_Content"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.Windows_UI_Xaml_Controls.Flyout"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<StackPanel>
<Button Click="ButtonButton_Click">Show at button</Button>
<Button Click="WindowButton_Click" x:Name="WindowButton">Show at window</Button>
</StackPanel>
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Uno.UI.Samples.Controls;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238

namespace UITests.Windows_UI_Xaml_Controls.FlyoutTests
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
[Sample]
public sealed partial class Flyout_ShowAt_Window_Content : Page
{
public Flyout_ShowAt_Window_Content()
{
this.InitializeComponent();
}

private void ButtonButton_Click(object sender, RoutedEventArgs e)
{
Windows.UI.Xaml.Controls.Flyout flyout = new Windows.UI.Xaml.Controls.Flyout();
flyout.Content =
new Border()
{
Width = 300,
Height = 300,
Background = new SolidColorBrush(Windows.UI.Colors.Red),
};

flyout.ShowAt((Button)sender);
}

private void WindowButton_Click(object sender, RoutedEventArgs e)
{
Windows.UI.Xaml.Controls.Flyout flyout = new Windows.UI.Xaml.Controls.Flyout();
flyout.Content =
new Border()
{
Width = 300,
Height = 300,
Background = new SolidColorBrush(Windows.UI.Colors.Red),
};

flyout.ShowAt(global::Windows.UI.Xaml.Window.Current.Content as FrameworkElement);
}
}
}
5 changes: 4 additions & 1 deletion src/Uno.UI/UI/Xaml/Controls/Flyout/FlyoutBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,10 @@ private protected virtual void ShowAtCore(FrameworkElement placementTarget, Flyo
throw new ArgumentException("Invalid flyout position");
}

// UNO TODO: clamp position within contentRect
var visibleBounds = ApplicationView.GetForCurrentView().VisibleBounds;
positionValue = new Point(
positionValue.X.Clamp(visibleBounds.Left, visibleBounds.Right),
positionValue.Y.Clamp(visibleBounds.Top, visibleBounds.Bottom));

SetTargetPosition(positionValue);
}
Expand Down
42 changes: 42 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/Popup/PlacementPopupPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,48 @@ ref controlYPos
{
this.Log().LogDebug($"Calculated placement, finalRect={finalRect}");
}

// Ensure the popup is not positioned fully beyond visible bounds.
// This can happen for example when the user is trying to show a flyout at
// Window.Current.Content - which will match Top position, which would be outside
// the visible bounds (negative Y).

if (finalRect.Bottom < visibleBounds.Top)
{
finalRect = new Rect(
finalRect.Left,
visibleBounds.Top,
finalRect.Width,
finalRect.Height);
}

if (finalRect.Top > visibleBounds.Bottom)
{
finalRect = new Rect(
finalRect.Left,
visibleBounds.Bottom - finalRect.Height,
finalRect.Width,
finalRect.Height);
}

if (finalRect.Right < visibleBounds.Left)
{
finalRect = new Rect(
visibleBounds.Left,
finalRect.Top,
finalRect.Width,
finalRect.Height);
}

if (finalRect.Left > visibleBounds.Right)
{
finalRect = new Rect(
visibleBounds.Right - finalRect.Width,
finalRect.Top,
finalRect.Width,
finalRect.Height);
}

return finalRect;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI/UI/Xaml/Controls/TextBlock/TextVisual.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public void UpdateForeground()

internal override void Render(SKSurface surface)
{
if (!string.IsNullOrEmpty(_owner.Text))
if (!string.IsNullOrEmpty(_owner.Text) && Size != default)
{
UpdateForeground();

Expand Down

0 comments on commit 919cd95

Please sign in to comment.