-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
420 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
...it.Samples/Uno.Toolkit.Samples.Shared/Content/Helpers/ResponsiveExtensionsSamplePage.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<Page x:Class="Uno.Toolkit.Samples.Content.Helpers.ResponsiveExtensionsSamplePage" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:sample="using:Uno.Toolkit.Samples" | ||
xmlns:utu="using:Uno.Toolkit.UI" | ||
mc:Ignorable="d" | ||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> | ||
<Page.Resources> | ||
<Orientation x:Key="NarrowOrientation">Vertical</Orientation> | ||
<Orientation x:Key="WideOrientation">Horizontal</Orientation> | ||
<x:Double x:Key="NarrowFontSize">15</x:Double> | ||
<x:Double x:Key="WideFontSize">30</x:Double> | ||
<SolidColorBrush x:Key="NarrowRed">Crimson</SolidColorBrush> | ||
<SolidColorBrush x:Key="WideBlue">Blue</SolidColorBrush> | ||
</Page.Resources> | ||
|
||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> | ||
<sample:SamplePageLayout IsDesignAgnostic="True"> | ||
<sample:SamplePageLayout.DesignAgnosticTemplate> | ||
<DataTemplate> | ||
<StackPanel Spacing="20"> | ||
<TextBlock Text="Orientation test | Normal=Vertical | Wide=Horizontal" FontWeight="Bold" /> | ||
<StackPanel Orientation="{utu:Responsive Normal={StaticResource NarrowOrientation}, Wide={StaticResource WideOrientation}}"> | ||
<TextBlock Text="A" /> | ||
<TextBlock Text="B" /> | ||
<TextBlock Text="C" /> | ||
</StackPanel> | ||
|
||
<TextBlock Text="Text test" FontWeight="Bold" /> | ||
<TextBlock Text="{utu:Responsive Narrow='Narrow Threshold 300', Normal='Normal Threshold 600', Wide='Wide Threshold 800'}" /> | ||
|
||
<TextBlock Text="FontSize test" FontWeight="Bold" /> | ||
<TextBlock Text="Normal 15 Wide 30" | ||
FontSize="{utu:Responsive Normal={StaticResource NarrowFontSize}, | ||
Wide={StaticResource WideFontSize}}" /> | ||
|
||
<TextBlock Text="Color test | Normal Red | Wide Blue" FontWeight="Bold" /> | ||
<Border Width="30" | ||
Height="30" | ||
HorizontalAlignment="Left" | ||
Background="{utu:Responsive Normal={StaticResource NarrowRed}, | ||
Wide={StaticResource WideBlue}}" /> | ||
</StackPanel> | ||
</DataTemplate> | ||
</sample:SamplePageLayout.DesignAgnosticTemplate> | ||
</sample:SamplePageLayout> | ||
</Grid> | ||
</Page> |
41 changes: 41 additions & 0 deletions
41
...Samples/Uno.Toolkit.Samples.Shared/Content/Helpers/ResponsiveExtensionsSamplePage.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Runtime.InteropServices.WindowsRuntime; | ||
using System.Text; | ||
using Uno.Toolkit.Samples.Entities; | ||
using Uno.Toolkit.Samples.Helpers; | ||
using Uno.Toolkit.Samples.ViewModels; | ||
using Windows.Foundation; | ||
using Windows.Foundation.Collections; | ||
#if IS_WINUI | ||
using Microsoft.UI; | ||
using Microsoft.UI.Xaml; | ||
using Microsoft.UI.Xaml.Controls; | ||
using Microsoft.UI.Xaml.Controls.Primitives; | ||
using Microsoft.UI.Xaml.Data; | ||
using Microsoft.UI.Xaml.Input; | ||
using Microsoft.UI.Xaml.Media; | ||
using Microsoft.UI.Xaml.Navigation; | ||
#else | ||
using Windows.UI; | ||
using Windows.UI.Xaml; | ||
using Windows.UI.Xaml.Controls; | ||
using Windows.UI.Xaml.Controls.Primitives; | ||
using Windows.UI.Xaml.Data; | ||
using Windows.UI.Xaml.Input; | ||
using Windows.UI.Xaml.Media; | ||
using Windows.UI.Xaml.Navigation; | ||
#endif | ||
|
||
namespace Uno.Toolkit.Samples.Content.Helpers; | ||
|
||
[SamplePage(SampleCategory.Helpers, "Responsive Extensions")] | ||
public sealed partial class ResponsiveExtensionsSamplePage : Page | ||
{ | ||
public ResponsiveExtensionsSamplePage() | ||
{ | ||
this.InitializeComponent(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
#if HAS_UNO | ||
#define UNO14502_WORKAROUND // https://github.com/unoplatform/uno/issues/14502 | ||
#endif | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.UI.Xaml; | ||
using Microsoft.UI.Xaml.Media; | ||
using Windows.Foundation; | ||
|
||
namespace Uno.Toolkit.UI.Helpers; | ||
|
||
internal interface IResponsiveCallback | ||
{ | ||
void OnSizeChanged(Size size, ResponsiveLayout layout); | ||
} | ||
|
||
public partial class ResponsiveLayout : DependencyObject | ||
{ | ||
#region DependencyProperty: Narrowest | ||
|
||
public static DependencyProperty NarrowestProperty { get; } = DependencyProperty.Register( | ||
nameof(Narrowest), | ||
typeof(double), | ||
typeof(ResponsiveLayout), | ||
new PropertyMetadata(0d)); | ||
|
||
public double Narrowest | ||
{ | ||
get => (double)GetValue(NarrowestProperty); | ||
set => SetValue(NarrowestProperty, value); | ||
} | ||
|
||
#endregion | ||
#region DependencyProperty: Narrow | ||
|
||
public static DependencyProperty NarrowProperty { get; } = DependencyProperty.Register( | ||
nameof(Narrow), | ||
typeof(double), | ||
typeof(ResponsiveLayout), | ||
new PropertyMetadata(0d)); | ||
|
||
public double Narrow | ||
{ | ||
get => (double)GetValue(NarrowProperty); | ||
set => SetValue(NarrowProperty, value); | ||
} | ||
|
||
#endregion | ||
#region DependencyProperty: Normal | ||
|
||
public static DependencyProperty NormalProperty { get; } = DependencyProperty.Register( | ||
nameof(Normal), | ||
typeof(double), | ||
typeof(ResponsiveLayout), | ||
new PropertyMetadata(0d)); | ||
|
||
public double Normal | ||
{ | ||
get => (double)GetValue(NormalProperty); | ||
set => SetValue(NormalProperty, value); | ||
} | ||
|
||
#endregion | ||
#region DependencyProperty: Wide | ||
|
||
public static DependencyProperty WideProperty { get; } = DependencyProperty.Register( | ||
nameof(Wide), | ||
typeof(double), | ||
typeof(ResponsiveLayout), | ||
new PropertyMetadata(0d)); | ||
|
||
public double Wide | ||
{ | ||
get => (double)GetValue(WideProperty); | ||
set => SetValue(WideProperty, value); | ||
} | ||
|
||
#endregion | ||
#region DependencyProperty: Widest | ||
|
||
public static DependencyProperty WidestProperty { get; } = DependencyProperty.Register( | ||
nameof(Widest), | ||
typeof(double), | ||
typeof(ResponsiveLayout), | ||
new PropertyMetadata(0d)); | ||
|
||
public double Widest | ||
{ | ||
get => (double)GetValue(WidestProperty); | ||
set => SetValue(WidestProperty, value); | ||
} | ||
|
||
#endregion | ||
|
||
public static ResponsiveLayout Create(double narrowest, double narrow, double normal, double wide, double widest) => new() | ||
{ | ||
Narrowest = narrowest, | ||
Narrow = narrow, | ||
Normal = normal, | ||
Wide = wide, | ||
Widest = widest, | ||
}; | ||
} | ||
|
||
internal class ResponsiveHelper | ||
{ | ||
private static readonly Lazy<ResponsiveHelper> _instance = new Lazy<ResponsiveHelper>(() => new ResponsiveHelper()); | ||
private readonly List<WeakReference> _callbacks = new(); | ||
#if UNO14502_WORKAROUND | ||
private List<IResponsiveCallback> _hardCallbackReferences = new(); | ||
#endif | ||
|
||
public ResponsiveLayout Layout { get; private set; } = ResponsiveLayout.Create(150, 300, 600, 800, 1080); | ||
public Size WindowSize { get; private set; } = Size.Empty; | ||
|
||
public static ResponsiveHelper GetForCurrentView() => _instance.Value; | ||
|
||
private ResponsiveHelper() { } | ||
|
||
public void HookupEvent(Window window) | ||
{ | ||
WindowSize = new Size(window.Bounds.Width, window.Bounds.Height); | ||
|
||
window.SizeChanged += OnWindowSizeChanged; | ||
} | ||
|
||
private void OnWindowSizeChanged(object sender, WindowSizeChangedEventArgs e) | ||
{ | ||
WindowSize = e.Size; | ||
|
||
// Clean up collected references | ||
_callbacks.RemoveAll(reference => !reference.IsAlive); | ||
|
||
foreach (var reference in _callbacks.ToArray()) | ||
{ | ||
if (reference.IsAlive && reference.Target is IResponsiveCallback callback) | ||
{ | ||
#if UNO14502_WORKAROUND | ||
// Note: In ResponsiveExtensionsSamplePage, if we are using SamplePageLayout with the template, | ||
// it seems to keep the controls (_weakTarget) alive, even if we navigate out and back (new page). | ||
// However, if we remove the SamplePageLayout, and add the template as a child instead, | ||
// the controls will be properly collected. | ||
|
||
// We are using a hard reference to keep the markup extension alive. | ||
// We need to check if its reference target is still alive. If it is not, then it should be removed. | ||
if (callback is ResponsiveExtension { _weakTarget: { IsAlive: false } }) | ||
{ | ||
_hardCallbackReferences.Remove(callback); | ||
_callbacks.Remove(reference); | ||
|
||
continue; | ||
} | ||
#endif | ||
callback.OnSizeChanged(WindowSize, Layout); | ||
} | ||
} | ||
} | ||
|
||
internal void Register(IResponsiveCallback host) | ||
{ | ||
#if UNO14502_WORKAROUND | ||
// The workaround is only needed for ResponsiveExtension (MarkupExtension) | ||
if (host is ResponsiveExtension) | ||
{ | ||
_hardCallbackReferences.Add(host); | ||
} | ||
#endif | ||
|
||
var wr = new WeakReference(host); | ||
_callbacks.Add(wr); | ||
} | ||
} |
Oops, something went wrong.