Skip to content

Commit 13ec2fb

Browse files
jeromelabanebariche
authored andcommitted
feat: Adjust the Popup hierarchy
1 parent ecbbe90 commit 13ec2fb

File tree

30 files changed

+412
-100
lines changed

30 files changed

+412
-100
lines changed

src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.Reflection.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,16 @@ private static void ThrowOnErrorSymbol(ISymbol symbol)
749749
var trimmedNamespace = type.PreferredXamlNamespace.Split('?').First();
750750
var clrNamespaces = _knownNamespaces.UnoGetValueOrDefault(trimmedNamespace, new string[0]);
751751

752+
if (
753+
type.PreferredXamlNamespace == XamlConstants.PresentationXamlXmlNamespace
754+
&& type.Name == "Popup"
755+
)
756+
{
757+
// Special case for the legacy type "Windows.UI.Xaml.Controls.Popup" where
758+
// using "Popup" in XAML will always point to the Primitives version of the type.
759+
return _findType(XamlConstants.Namespaces.Primitives + ".Popup");
760+
}
761+
752762
foreach (var clrNamespace in clrNamespaces)
753763
{
754764
if(_findType!(clrNamespace + "." + type.Name) is { } result)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<UserControl
2+
x:Class="Uno.UI.Tests.Windows_UI_XAML_Controls.PopupTests.Controls.When_Popup"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:local="using:Uno.UI.Tests.Windows_UI_XAML_Controls.PopupTests.Controls"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
mc:Ignorable="d"
9+
d:DesignHeight="300"
10+
d:DesignWidth="400">
11+
12+
<Grid>
13+
<Popup x:Name="myPopup" />
14+
</Grid>
15+
</UserControl>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Runtime.InteropServices.WindowsRuntime;
6+
using Windows.Foundation;
7+
using Windows.Foundation.Collections;
8+
using Windows.UI.Xaml;
9+
using Windows.UI.Xaml.Controls;
10+
using Windows.UI.Xaml.Controls.Primitives;
11+
using Windows.UI.Xaml.Data;
12+
using Windows.UI.Xaml.Input;
13+
using Windows.UI.Xaml.Media;
14+
using Windows.UI.Xaml.Navigation;
15+
16+
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
17+
18+
namespace Uno.UI.Tests.Windows_UI_XAML_Controls.PopupTests.Controls
19+
{
20+
public sealed partial class When_Popup : UserControl
21+
{
22+
public When_Popup()
23+
{
24+
this.InitializeComponent();
25+
}
26+
}
27+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Microsoft.VisualStudio.TestTools.UnitTesting;
7+
using Uno.Extensions;
8+
using Uno.UI.Tests.Windows_UI_XAML_Controls.PopupTests.Controls;
9+
using Windows.Foundation;
10+
using Windows.UI.Xaml.Controls;
11+
using Windows.UI.Xaml.Controls.Primitives;
12+
13+
namespace Uno.UI.Tests.PivotTests
14+
{
15+
[TestClass]
16+
public class Given_Popup
17+
{
18+
[TestMethod]
19+
public void When_Popup()
20+
{
21+
var SUT = new When_Popup();
22+
23+
Assert.IsTrue(SUT.FindName("myPopup")?.GetType() == typeof(Windows.UI.Xaml.Controls.Primitives.Popup));
24+
}
25+
26+
[TestMethod]
27+
public void When_Popup_Forwarding_Legacy_To_Official()
28+
{
29+
var SUT = new Windows.UI.Xaml.Controls.Popup();
30+
Windows.UI.Xaml.Controls.Primitives.Popup primitiveSUT = SUT;
31+
32+
void ValidateEquality()
33+
{
34+
Assert.AreEqual(SUT.PopupPanel, primitiveSUT.PopupPanel);
35+
Assert.AreEqual(SUT.Child, primitiveSUT.Child);
36+
Assert.AreEqual(SUT.VerticalOffset, primitiveSUT.VerticalOffset);
37+
Assert.AreEqual(SUT.HorizontalOffset, primitiveSUT.HorizontalOffset);
38+
Assert.AreEqual(SUT.LightDismissOverlayMode, primitiveSUT.LightDismissOverlayMode);
39+
Assert.AreEqual(SUT.IsOpen, primitiveSUT.IsOpen);
40+
Assert.AreEqual(SUT.IsLightDismissEnabled, primitiveSUT.IsLightDismissEnabled);
41+
}
42+
43+
SUT.PopupPanel = new PopupPanel(SUT);
44+
ValidateEquality();
45+
SUT.Child = new TextBlock();
46+
ValidateEquality();
47+
SUT.VerticalOffset = 42.42;
48+
ValidateEquality();
49+
SUT.HorizontalOffset = 42.42;
50+
ValidateEquality();
51+
SUT.LightDismissOverlayMode = LightDismissOverlayMode.Off;
52+
ValidateEquality();
53+
SUT.IsOpen = !SUT.IsOpen;
54+
ValidateEquality();
55+
SUT.IsLightDismissEnabled = !SUT.IsLightDismissEnabled;
56+
ValidateEquality();
57+
}
58+
59+
[TestMethod]
60+
public void When_Popup_Forwarding_Official_To_Legacy()
61+
{
62+
var SUT = new Windows.UI.Xaml.Controls.Popup();
63+
Windows.UI.Xaml.Controls.Primitives.Popup primitiveSUT = SUT;
64+
65+
void ValidateEquality()
66+
{
67+
Assert.AreEqual(SUT.PopupPanel, primitiveSUT.PopupPanel);
68+
Assert.AreEqual(SUT.Child, primitiveSUT.Child);
69+
Assert.AreEqual(SUT.VerticalOffset, primitiveSUT.VerticalOffset);
70+
Assert.AreEqual(SUT.HorizontalOffset, primitiveSUT.HorizontalOffset);
71+
Assert.AreEqual(SUT.LightDismissOverlayMode, primitiveSUT.LightDismissOverlayMode);
72+
Assert.AreEqual(SUT.IsOpen, primitiveSUT.IsOpen);
73+
Assert.AreEqual(SUT.IsLightDismissEnabled, primitiveSUT.IsLightDismissEnabled);
74+
}
75+
76+
primitiveSUT.PopupPanel = new PopupPanel(SUT);
77+
ValidateEquality();
78+
primitiveSUT.Child = new TextBlock();
79+
ValidateEquality();
80+
primitiveSUT.VerticalOffset = 42.42;
81+
ValidateEquality();
82+
primitiveSUT.HorizontalOffset = 42.42;
83+
ValidateEquality();
84+
primitiveSUT.LightDismissOverlayMode = LightDismissOverlayMode.Off;
85+
ValidateEquality();
86+
primitiveSUT.IsOpen = !SUT.IsOpen;
87+
ValidateEquality();
88+
primitiveSUT.IsLightDismissEnabled = !SUT.IsLightDismissEnabled;
89+
ValidateEquality();
90+
}
91+
}
92+
}

src/Uno.UI/Generated/3.0.0.0/Windows.UI.Xaml.Controls.Primitives/Popup.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Windows.UI.Xaml.Controls.Primitives
77
#endif
88
public partial class Popup : global::Windows.UI.Xaml.FrameworkElement
99
{
10-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
10+
#if false
1111
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
1212
public double VerticalOffset
1313
{
@@ -21,7 +21,7 @@ public double VerticalOffset
2121
}
2222
}
2323
#endif
24-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
24+
#if false
2525
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
2626
public bool IsOpen
2727
{
@@ -35,7 +35,7 @@ public bool IsOpen
3535
}
3636
}
3737
#endif
38-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
38+
#if false
3939
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
4040
public bool IsLightDismissEnabled
4141
{
@@ -49,7 +49,7 @@ public bool IsLightDismissEnabled
4949
}
5050
}
5151
#endif
52-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
52+
#if false
5353
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
5454
public double HorizontalOffset
5555
{
@@ -77,7 +77,7 @@ public double HorizontalOffset
7777
}
7878
}
7979
#endif
80-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
80+
#if false
8181
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
8282
public global::Windows.UI.Xaml.UIElement Child
8383
{
@@ -91,7 +91,7 @@ public double HorizontalOffset
9191
}
9292
}
9393
#endif
94-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
94+
#if false
9595
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
9696
public global::Windows.UI.Xaml.Controls.LightDismissOverlayMode LightDismissOverlayMode
9797
{
@@ -129,7 +129,7 @@ public bool IsConstrainedToRootBounds
129129
}
130130
}
131131
#endif
132-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
132+
#if false
133133
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
134134
public static global::Windows.UI.Xaml.DependencyProperty ChildProperty { get; } =
135135
Windows.UI.Xaml.DependencyProperty.Register(
@@ -145,39 +145,39 @@ public bool IsConstrainedToRootBounds
145145
typeof(global::Windows.UI.Xaml.Controls.Primitives.Popup),
146146
new FrameworkPropertyMetadata(default(global::Windows.UI.Xaml.Media.Animation.TransitionCollection)));
147147
#endif
148-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
148+
#if false
149149
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
150150
public static global::Windows.UI.Xaml.DependencyProperty HorizontalOffsetProperty { get; } =
151151
Windows.UI.Xaml.DependencyProperty.Register(
152152
nameof(HorizontalOffset), typeof(double),
153153
typeof(global::Windows.UI.Xaml.Controls.Primitives.Popup),
154154
new FrameworkPropertyMetadata(default(double)));
155155
#endif
156-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
156+
#if false
157157
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
158158
public static global::Windows.UI.Xaml.DependencyProperty IsLightDismissEnabledProperty { get; } =
159159
Windows.UI.Xaml.DependencyProperty.Register(
160160
nameof(IsLightDismissEnabled), typeof(bool),
161161
typeof(global::Windows.UI.Xaml.Controls.Primitives.Popup),
162162
new FrameworkPropertyMetadata(default(bool)));
163163
#endif
164-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
164+
#if false
165165
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
166166
public static global::Windows.UI.Xaml.DependencyProperty IsOpenProperty { get; } =
167167
Windows.UI.Xaml.DependencyProperty.Register(
168168
nameof(IsOpen), typeof(bool),
169169
typeof(global::Windows.UI.Xaml.Controls.Primitives.Popup),
170170
new FrameworkPropertyMetadata(default(bool)));
171171
#endif
172-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
172+
#if false
173173
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
174174
public static global::Windows.UI.Xaml.DependencyProperty VerticalOffsetProperty { get; } =
175175
Windows.UI.Xaml.DependencyProperty.Register(
176176
nameof(VerticalOffset), typeof(double),
177177
typeof(global::Windows.UI.Xaml.Controls.Primitives.Popup),
178178
new FrameworkPropertyMetadata(default(double)));
179179
#endif
180-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
180+
#if false
181181
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
182182
public static global::Windows.UI.Xaml.DependencyProperty LightDismissOverlayModeProperty { get; } =
183183
Windows.UI.Xaml.DependencyProperty.Register(
@@ -193,7 +193,7 @@ public bool IsConstrainedToRootBounds
193193
typeof(global::Windows.UI.Xaml.Controls.Primitives.Popup),
194194
new FrameworkPropertyMetadata(default(bool)));
195195
#endif
196-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
196+
#if false
197197
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
198198
public Popup() : base()
199199
{
@@ -230,7 +230,7 @@ public Popup() : base()
230230
// Forced skipping of method Windows.UI.Xaml.Controls.Primitives.Popup.VerticalOffsetProperty.get
231231
// Forced skipping of method Windows.UI.Xaml.Controls.Primitives.Popup.ChildTransitionsProperty.get
232232
// Forced skipping of method Windows.UI.Xaml.Controls.Primitives.Popup.IsLightDismissEnabledProperty.get
233-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
233+
#if false
234234
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
235235
public event global::System.EventHandler<object> Closed
236236
{
@@ -246,7 +246,7 @@ public Popup() : base()
246246
}
247247
}
248248
#endif
249-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
249+
#if false
250250
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
251251
public event global::System.EventHandler<object> Opened
252252
{

src/Uno.UI/Mixins/DependencyPropertyMixins.tt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@
99
.Property("BackgroundSizing", "BackgroundSizing", "default")
1010
.Property("HorizontalContentAlignment", "HorizontalAlignment", "(Uno.UI.FeatureConfiguration.Control.UseLegacyContentAlignment ? HorizontalAlignment.Left : HorizontalAlignment.Center)")
1111
.Property("VerticalContentAlignment", "VerticalAlignment", "(Uno.UI.FeatureConfiguration.Control.UseLegacyContentAlignment ? VerticalAlignment.Top : VerticalAlignment.Center)")
12-
.Class("PopupBase")
13-
.Property("IsOpen", "bool", "false")
14-
.Property("Child", "UIElement", "null", frameworkPropertyOption: "ValueInheritsDataContext")
15-
.Property("IsLightDismissEnabled", "bool", "true")
16-
//.Property("ChildTransitions", "TransitionCollection", "null")
17-
.Property("HorizontalOffset", "double", "0")
18-
.Property("VerticalOffset", "double", "0")
19-
.Class("Popover", condition: "XAMARIN_IOS")
20-
.Property("Anchor", "View", "null")
2112
.Class("NativePopup", condition: "XAMARIN_ANDROID")
2213
.Property("Anchor", "View", "null")
2314
.Class("Picker", condition: "XAMARIN_IOS")
@@ -96,7 +87,14 @@
9687
.Namespace("Windows.UI.Xaml.Controls.Primitives")
9788
.Class("SelectorItem")
9889
.Property("IsSelected", "bool", "false")
99-
90+
.Class("Popup")
91+
.Property("IsOpen", "bool", "false")
92+
.Property("Child", "UIElement", "null", frameworkPropertyOption: "ValueInheritsDataContext")
93+
.Property("IsLightDismissEnabled", "bool", "true")
94+
//.Property("ChildTransitions", "TransitionCollection", "null")
95+
.Property("HorizontalOffset", "double", "0")
96+
.Property("VerticalOffset", "double", "0")
97+
10098
.Namespace("Uno.UI.Controls.Legacy")
10199
.Class("ListViewBase", condition: "XAMARIN_IOS")
102100
.Property("DisplayMemberPath", "string", "string.Empty")

src/Uno.UI/Mock/Popup.net.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using System.Text;
55
using System.Threading.Tasks;
66

7-
namespace Windows.UI.Xaml.Controls
7+
namespace Windows.UI.Xaml.Controls.Primitives
88
{
99
public partial class Popup
1010
{
@@ -13,9 +13,8 @@ partial void InitializePartial()
1313
PopupPanel = new PopupPanel(this);
1414
}
1515

16-
protected override void OnIsOpenChanged(bool oldIsOpen, bool newIsOpen)
16+
partial void OnIsOpenChangedPartialNative(bool oldIsOpen, bool newIsOpen)
1717
{
18-
base.OnIsOpenChanged(oldIsOpen, newIsOpen);
1918
if (newIsOpen)
2019
{
2120
PopupPanel.Visibility = Visibility.Visible;
@@ -26,10 +25,8 @@ protected override void OnIsOpenChanged(bool oldIsOpen, bool newIsOpen)
2625
}
2726
}
2827

29-
protected override void OnChildChanged(UIElement oldChild, UIElement newChild)
28+
partial void OnChildChangedPartialNative(UIElement oldChild, UIElement newChild)
3029
{
31-
base.OnChildChanged(oldChild, newChild);
32-
3330
PopupPanel.Children.Remove(oldChild);
3431
PopupPanel.Children.Add(newChild);
3532
}

src/Uno.UI/UI/Xaml/Controls/AutoSuggestBox/AutoSuggestBox.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Uno.UI.DataBinding;
1010
using Windows.Foundation;
1111
using Windows.Foundation.Collections;
12+
using Windows.UI.Xaml.Controls.Primitives;
1213
using Windows.UI.Xaml.Input;
1314
using Windows.UI.Xaml.Media;
1415

src/Uno.UI/UI/Xaml/Controls/Flyout/FlyoutBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public partial class FlyoutBase : DependencyObject
3535

3636
internal bool m_isPositionedAtPoint;
3737

38-
protected internal Windows.UI.Xaml.Controls.Popup _popup;
38+
protected internal Popup _popup;
3939
private bool _isLightDismissEnabled = true;
4040
private readonly SerialDisposable _sizeChangedDisposable = new SerialDisposable();
4141

@@ -65,7 +65,7 @@ private void EnsurePopupCreated()
6565
ResourceResolver.ApplyResource(this, LightDismissOverlayBackgroundProperty, "FlyoutLightDismissOverlayBackground", isThemeResourceExtension: true);
6666

6767
var child = CreatePresenter();
68-
_popup = new Windows.UI.Xaml.Controls.Popup()
68+
_popup = new Popup()
6969
{
7070
Child = child,
7171
IsLightDismissEnabled = _isLightDismissEnabled,
@@ -432,7 +432,7 @@ public static void ShowAttachedFlyout(FrameworkElement flyoutOwner)
432432
flyout?.ShowAt(flyoutOwner);
433433
}
434434

435-
internal static Rect CalculateAvailableWindowRect(bool isMenuFlyout, Controls.Popup popup, object placementTarget, bool hasTargetPosition, Point positionPoint, bool isFull)
435+
internal static Rect CalculateAvailableWindowRect(bool isMenuFlyout, Popup popup, object placementTarget, bool hasTargetPosition, Point positionPoint, bool isFull)
436436
{
437437
// UNO TODO: UWP also uses values coming from the input pane and app bars, if any.
438438
// Make sure of migrate to XamlRoot: https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.xamlroot

src/Uno.UI/UI/Xaml/Controls/MenuFlyout/CascadingMenuHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ public void OnVisibilityChanged()
711711
internal void OnPresenterSizeChanged(
712712
object pSender,
713713
SizeChangedEventArgs args,
714-
Controls.Popup popup)
714+
Popup popup)
715715
{
716716
Control ownerAsControl = m_wpOwner?.Target as Control;
717717

0 commit comments

Comments
 (0)