forked from dotnet/maui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Controls.Compatibility for tizen (dotnet#493)
- Loading branch information
Showing
10 changed files
with
545 additions
and
56 deletions.
There are no files selected for viewing
277 changes: 277 additions & 0 deletions
277
src/Controls/src/Core/Compatibility/Handlers/Tizen/FrameRenderer.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,277 @@ | ||
#nullable enable | ||
|
||
using System.ComponentModel; | ||
using Microsoft.Maui.Controls.Platform; | ||
using Microsoft.Maui.Graphics; | ||
using SkiaSharp; | ||
using Tizen.UIExtensions.NUI; | ||
using IMeasurable = Tizen.UIExtensions.Common.IMeasurable; | ||
using TColor = Tizen.UIExtensions.Common.Color; | ||
using NColor = Tizen.NUI.Color; | ||
using TShadow = Tizen.NUI.Shadow; | ||
using TLayoutParamPolicies = Tizen.NUI.BaseComponents.LayoutParamPolicies; | ||
|
||
namespace Microsoft.Maui.Controls.Handlers.Compatibility | ||
{ | ||
public class FrameRenderer : ContentViewGroup, IPlatformViewHandler, IMeasurable | ||
{ | ||
public static IPropertyMapper<Frame, FrameRenderer> Mapper | ||
= new PropertyMapper<Frame, FrameRenderer>(ViewRenderer.VisualElementRendererMapper) | ||
{ | ||
[Frame.HasShadowProperty.PropertyName] = (h, _) => h.UpdateShadow(), | ||
[VisualElement.BackgroundColorProperty.PropertyName] = (h, _) => h.UpdateBackgroundColor(), | ||
[VisualElement.BackgroundProperty.PropertyName] = (h, _) => h.UpdateBackground(), | ||
[Frame.CornerRadiusProperty.PropertyName] = (h, _) => h.UpdateCornerRadius(), | ||
[Frame.BorderColorProperty.PropertyName] = (h, _) => h.UpdateBorderColor(), | ||
[Microsoft.Maui.Controls.Compatibility.Layout.IsClippedToBoundsProperty.PropertyName] = (h, _) => h.UpdateClippedToBounds(), | ||
[Frame.ContentProperty.PropertyName] = (h, _) => h.UpdateContent() | ||
}; | ||
|
||
public static CommandMapper<Frame, FrameRenderer> CommandMapper | ||
= new CommandMapper<Frame, FrameRenderer>(ViewRenderer.VisualElementRendererCommandMapper); | ||
|
||
bool _disposed; | ||
|
||
SKClipperView _clipperView; | ||
|
||
IMauiContext? _mauiContext; | ||
ViewHandlerDelegator<Frame> _viewHandlerWrapper; | ||
IPlatformViewHandler? _contentHandler; | ||
|
||
|
||
public FrameRenderer() : base(null) | ||
{ | ||
_clipperView = new SKClipperView() | ||
{ | ||
WidthSpecification = TLayoutParamPolicies.MatchParent, | ||
HeightSpecification = TLayoutParamPolicies.MatchParent | ||
}; | ||
_clipperView.DrawClippingArea += OnDrawClippingArea; | ||
|
||
Children.Add(_clipperView); | ||
|
||
BorderlineColor = NColor.Black; | ||
BorderlineWidth = 1.0.ToScaledPixel(); | ||
_viewHandlerWrapper = new ViewHandlerDelegator<Frame>(Mapper, CommandMapper, this); | ||
} | ||
|
||
protected Frame? Element | ||
{ | ||
get { return _viewHandlerWrapper.Element; } | ||
set | ||
{ | ||
if (value != null) | ||
(this as IPlatformViewHandler).SetVirtualView(value); | ||
} | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
if (_disposed) | ||
return; | ||
|
||
_disposed = true; | ||
|
||
if (disposing) | ||
{ | ||
if (Element != null) | ||
{ | ||
Element.PropertyChanged -= OnElementPropertyChanged; | ||
} | ||
|
||
Element?.Handler?.DisconnectHandler(); | ||
} | ||
|
||
base.Dispose(disposing); | ||
} | ||
|
||
protected virtual void OnElementChanged(ElementChangedEventArgs<Frame> e) | ||
{ | ||
if (e.NewElement != null) | ||
{ | ||
CrossPlatformArrange = e.NewElement.CrossPlatformArrange; | ||
CrossPlatformMeasure = e.NewElement.CrossPlatformMeasure; | ||
} | ||
} | ||
|
||
protected virtual void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs e) | ||
{ | ||
if (_disposed) | ||
{ | ||
return; | ||
} | ||
|
||
if (Element != null && e.PropertyName != null) | ||
_viewHandlerWrapper.UpdateProperty(e.PropertyName); | ||
} | ||
|
||
void OnDrawClippingArea(object? sender, SkiaSharp.Views.Tizen.SKPaintSurfaceEventArgs e) | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
var canvas = e.Surface.Canvas; | ||
var directRect = e.Info.Rect; | ||
canvas.Clear(); | ||
|
||
if (!Element.IsClippedToBounds) | ||
{ | ||
canvas.Clear(SKColors.White); | ||
return; | ||
} | ||
var radius = ((double)Element.CornerRadius).ToScaledPixel(); | ||
using var paint = new SKPaint | ||
{ | ||
Color = SKColors.White, | ||
}; | ||
canvas.DrawRoundRect(directRect, new SKSize(radius, radius), paint); | ||
} | ||
|
||
void UpdateClippedToBounds() | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
_clipperView.Invalidate(); | ||
} | ||
|
||
void UpdateBackgroundColor() | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
BackgroundColor = Element.BackgroundColor.ToNUIColor(); | ||
} | ||
|
||
void UpdateBackground() | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
var color = ((Paint)Element.Background)?.ToColor(); | ||
if (color != null) | ||
BackgroundColor = color.ToNUIColor(); | ||
} | ||
|
||
void UpdateBorderColor() | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
if (Element.BorderColor.IsNotDefault()) | ||
BorderlineColor = Element.BorderColor.ToNUIColor(); | ||
else | ||
BorderlineColor = Tizen.NUI.Color.Black; | ||
} | ||
|
||
void UpdateShadow() | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
if (Element.HasShadow) | ||
{ | ||
BoxShadow = new TShadow(6.0.ToScaledPixel(), TColor.FromHex("#111111").ToNative()); | ||
} | ||
else | ||
{ | ||
BoxShadow = null; | ||
} | ||
} | ||
|
||
void UpdateCornerRadius() | ||
{ | ||
if (Element == null || _disposed) | ||
return; | ||
|
||
CornerRadius = ((double)Element.CornerRadius).ToScaledPixel(); | ||
} | ||
|
||
void UpdateContent() | ||
{ | ||
var content = Element?.Content; | ||
|
||
if (_contentHandler != null) | ||
{ | ||
if (_contentHandler.PlatformView != null) | ||
{ | ||
_clipperView.Remove(_contentHandler.PlatformView); | ||
} | ||
_contentHandler?.Dispose(); | ||
_contentHandler = null; | ||
} | ||
|
||
|
||
if (content == null || _mauiContext == null || _disposed) | ||
{ | ||
return; | ||
} | ||
|
||
var platformView = content.ToPlatform(_mauiContext); | ||
platformView.WidthSpecification = TLayoutParamPolicies.MatchParent; | ||
platformView.HeightSpecification = TLayoutParamPolicies.MatchParent; | ||
_clipperView.Add(platformView); | ||
if (content.Handler is IPlatformViewHandler thandler) | ||
{ | ||
_contentHandler = thandler; | ||
} | ||
} | ||
|
||
#region IPlatformViewHandler | ||
Size IViewHandler.GetDesiredSize(double widthConstraint, double heightConstraint) | ||
{ | ||
if (Element?.Handler is IPlatformViewHandler pvh && Element is IContentView cv) | ||
{ | ||
return pvh.MeasureVirtualView(widthConstraint, heightConstraint, cv.CrossPlatformMeasure); | ||
} | ||
else | ||
{ | ||
return Graphics.Size.Zero; | ||
} | ||
} | ||
|
||
bool IViewHandler.HasContainer { get => false; set { } } | ||
|
||
object? IViewHandler.ContainerView => null; | ||
|
||
IView? IViewHandler.VirtualView => Element; | ||
|
||
object IElementHandler.PlatformView => this; | ||
|
||
Maui.IElement? IElementHandler.VirtualView => Element; | ||
|
||
IMauiContext? IElementHandler.MauiContext => _mauiContext; | ||
|
||
Tizen.NUI.BaseComponents.View? IPlatformViewHandler.PlatformView => this; | ||
|
||
Tizen.NUI.BaseComponents.View? IPlatformViewHandler.ContainerView => this; | ||
|
||
void IViewHandler.PlatformArrange(Graphics.Rect rect) => | ||
this.PlatformArrangeHandler(rect); | ||
|
||
void IElementHandler.SetMauiContext(IMauiContext mauiContext) => | ||
_mauiContext = mauiContext; | ||
|
||
void IElementHandler.SetVirtualView(Maui.IElement view) => | ||
_viewHandlerWrapper.SetVirtualView(view, OnElementChanged, false); | ||
|
||
void IElementHandler.UpdateValue(string property) | ||
{ | ||
if (Element != null) | ||
{ | ||
OnElementPropertyChanged(Element, new PropertyChangedEventArgs(property)); | ||
} | ||
} | ||
|
||
void IElementHandler.Invoke(string command, object? args) | ||
{ | ||
_viewHandlerWrapper.Invoke(command, args); | ||
} | ||
|
||
void IElementHandler.DisconnectHandler() | ||
{ | ||
_viewHandlerWrapper.DisconnectHandler(); | ||
} | ||
#endregion | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
src/Controls/src/Core/Compatibility/Handlers/Tizen/ViewRenderer.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,77 @@ | ||
#nullable enable | ||
using Tizen.UIExtensions.NUI; | ||
using PlatformView = Tizen.NUI.BaseComponents.View; | ||
|
||
namespace Microsoft.Maui.Controls.Handlers.Compatibility | ||
{ | ||
public abstract partial class ViewRenderer : ViewRenderer<View, PlatformView> | ||
{ | ||
} | ||
|
||
public abstract partial class ViewRenderer<TElement, TPlatformView> : VisualElementRenderer<TElement>, IPlatformViewHandler | ||
where TElement : View, IView | ||
where TPlatformView : PlatformView | ||
{ | ||
TPlatformView? _platformView; | ||
ViewGroup? _container; | ||
|
||
public TPlatformView? Control => ((IElementHandler)this).PlatformView as TPlatformView ?? _platformView; | ||
object? IElementHandler.PlatformView => _platformView; | ||
|
||
public ViewRenderer() : this(VisualElementRendererMapper, VisualElementRendererCommandMapper) | ||
{ | ||
} | ||
|
||
internal ViewRenderer(IPropertyMapper mapper, CommandMapper? commandMapper = null) | ||
: base(mapper, commandMapper) | ||
{ | ||
} | ||
|
||
protected virtual TPlatformView CreateNativeControl() | ||
{ | ||
return default(TPlatformView)!; | ||
} | ||
|
||
protected void SetNativeControl(TPlatformView control) | ||
{ | ||
SetNativeControl(control, this); | ||
} | ||
|
||
internal void SetNativeControl(TPlatformView control, ViewGroup container) | ||
{ | ||
if (Control != null) | ||
{ | ||
Children.Remove(Control); | ||
} | ||
|
||
_container = container; | ||
_platformView = control; | ||
|
||
var toAdd = container == this ? control : (PlatformView)container; | ||
toAdd.WidthSpecification = Tizen.NUI.BaseComponents.LayoutParamPolicies.MatchParent; | ||
toAdd.HeightSpecification = Tizen.NUI.BaseComponents.LayoutParamPolicies.MatchParent; | ||
Children.Add(toAdd); | ||
} | ||
|
||
private protected override void DisconnectHandlerCore() | ||
{ | ||
if (_platformView != null && Element != null) | ||
{ | ||
// We set the PlatformView to null so no one outside of this handler tries to access | ||
// PlatformView. PlatformView access should be isolated to the instance passed into | ||
// DisconnectHandler | ||
var oldPlatformView = _platformView; | ||
_platformView = null; | ||
DisconnectHandler(oldPlatformView); | ||
} | ||
|
||
base.DisconnectHandlerCore(); | ||
} | ||
|
||
protected virtual void DisconnectHandler(TPlatformView oldPlatformView) | ||
{ | ||
} | ||
|
||
PlatformView? IPlatformViewHandler.ContainerView => _container; | ||
} | ||
} |
Oops, something went wrong.