-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
LayoutHandler.cs
142 lines (125 loc) · 4.59 KB
/
LayoutHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#nullable enable
#if __IOS__ || MACCATALYST
using PlatformView = Microsoft.Maui.Platform.LayoutView;
#elif __ANDROID__
using PlatformView = Microsoft.Maui.Platform.LayoutViewGroup;
#elif WINDOWS
using PlatformView = Microsoft.Maui.Platform.LayoutPanel;
#elif TIZEN
using PlatformView = Microsoft.Maui.Platform.LayoutViewGroup;
#elif (NETSTANDARD || !PLATFORM)
using PlatformView = System.Object;
#endif
namespace Microsoft.Maui.Handlers
{
/// <summary>
/// Represents the view handler for the abstract <see cref="ILayout"/> view and its platform-specific implementation.
/// </summary>
/// <seealso href="https://learn.microsoft.com/dotnet/maui/user-interface/handlers/">Conceptual documentation on handlers</seealso>
public partial class LayoutHandler : ILayoutHandler
{
public static IPropertyMapper<ILayout, ILayoutHandler> Mapper = new PropertyMapper<ILayout, ILayoutHandler>(ViewMapper)
{
[nameof(ILayout.Background)] = MapBackground,
[nameof(ILayout.ClipsToBounds)] = MapClipsToBounds,
#if ANDROID || WINDOWS
[nameof(IView.InputTransparent)] = MapInputTransparent,
#endif
};
public static CommandMapper<ILayout, ILayoutHandler> CommandMapper = new(ViewCommandMapper)
{
[nameof(ILayoutHandler.Add)] = MapAdd,
[nameof(ILayoutHandler.Remove)] = MapRemove,
[nameof(ILayoutHandler.Clear)] = MapClear,
[nameof(ILayoutHandler.Insert)] = MapInsert,
[nameof(ILayoutHandler.Update)] = MapUpdate,
[nameof(ILayoutHandler.UpdateZIndex)] = MapUpdateZIndex,
};
public LayoutHandler() : base(Mapper, CommandMapper)
{
}
public LayoutHandler(IPropertyMapper? mapper = null, CommandMapper? commandMapper = null)
: base(mapper ?? Mapper, commandMapper ?? CommandMapper)
{
}
ILayout ILayoutHandler.VirtualView => VirtualView;
PlatformView ILayoutHandler.PlatformView => PlatformView;
/// <summary>
/// Maps the abstract <see cref="IView.Background"/> property to the platform-specific implementations.
/// </summary>
/// <param name="handler">The associated handler.</param>
/// <param name="layout">The associated <see cref="ILayout"/> instance.</param>
public static partial void MapBackground(ILayoutHandler handler, ILayout layout);
#if ANDROID || WINDOWS
/// <summary>
/// Maps the abstract <see cref="IView.InputTransparent"/> property to the platform-specific implementations.
/// </summary>
/// <param name="handler">The associated handler.</param>
/// <param name="layout">The associated <see cref="ILayout"/> instance.</param>
public static partial void MapInputTransparent(ILayoutHandler handler, ILayout layout);
#endif
/// <summary>
/// Maps the abstract <see cref="ILayout.ClipsToBounds"/> property to the platform-specific implementations.
/// </summary>
/// <param name="handler">The associated handler.</param>
/// <param name="layout">The associated <see cref="ILayout"/> instance.</param>
public static void MapClipsToBounds(ILayoutHandler handler, ILayout layout)
{
((PlatformView?)handler.PlatformView)?.UpdateClipsToBounds(layout);
}
public static void MapAdd(ILayoutHandler handler, ILayout layout, object? arg)
{
if (arg is LayoutHandlerUpdate args)
{
handler.Add(args.View);
}
}
public static void MapRemove(ILayoutHandler handler, ILayout layout, object? arg)
{
if (arg is LayoutHandlerUpdate args)
{
handler.Remove(args.View);
}
}
public static void MapInsert(ILayoutHandler handler, ILayout layout, object? arg)
{
if (arg is LayoutHandlerUpdate args)
{
handler.Insert(args.Index, args.View);
}
}
public static void MapClear(ILayoutHandler handler, ILayout layout, object? arg)
{
handler.Clear();
}
static void MapUpdate(ILayoutHandler handler, ILayout layout, object? arg)
{
if (arg is LayoutHandlerUpdate args)
{
handler.Update(args.Index, args.View);
}
}
static void MapUpdateZIndex(ILayoutHandler handler, ILayout layout, object? arg)
{
if (arg is IView view)
{
handler.UpdateZIndex(view);
}
}
/// <summary>
/// Converts a FlowDirection to the appropriate FlowDirection for cross-platform layout
/// </summary>
/// <param name="flowDirection"></param>
/// <returns>The FlowDirection to assume for cross-platform layout</returns>
internal static FlowDirection GetLayoutFlowDirection(FlowDirection flowDirection)
{
#if WINDOWS
// The native LayoutPanel in Windows will automagically flip our layout coordinates if it's in RTL mode.
// So for cross-platform layout purposes, we just always treat things as being LTR and let the Panel sort out the rest.
return FlowDirection.LeftToRight;
#else
return flowDirection;
#endif
}
}
}