Implement VisualElementRenderers
This commit is contained in:
parent
3d148e7e9f
commit
a828fb9b0b
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Ooui.Forms
|
||||
{
|
||||
public class VisualElementChangedEventArgs : ElementChangedEventArgs<VisualElement>
|
||||
{
|
||||
public VisualElementChangedEventArgs (VisualElement oldElement, VisualElement newElement)
|
||||
: base (oldElement, newElement)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ElementChangedEventArgs<TElement> : EventArgs where TElement : Xamarin.Forms.Element
|
||||
{
|
||||
public ElementChangedEventArgs (TElement oldElement, TElement newElement)
|
||||
{
|
||||
OldElement = oldElement;
|
||||
NewElement = newElement;
|
||||
}
|
||||
|
||||
public TElement NewElement { get; private set; }
|
||||
|
||||
public TElement OldElement { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Ooui.Forms.Extensions
|
||||
{
|
||||
public static class ColorExtensions
|
||||
{
|
||||
public static Color ToOouiColor (this Xamarin.Forms.Color color)
|
||||
{
|
||||
return new Color ((byte)(color.R * 255.0 + 0.5), (byte)(color.G * 255.0 + 0.5), (byte)(color.B * 255.0 + 0.5), (byte)(color.A * 255.0 + 0.5));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ using System.IO;
|
|||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ooui;
|
||||
|
||||
namespace Xamarin.Forms
|
||||
{
|
||||
|
@ -33,6 +34,13 @@ namespace Xamarin.Forms
|
|||
});
|
||||
}
|
||||
|
||||
public static event EventHandler<ViewInitializedEventArgs> ViewInitialized;
|
||||
|
||||
public static void SendViewInitialized (this VisualElement self, Ooui.Element nativeView)
|
||||
{
|
||||
ViewInitialized?.Invoke (self, new ViewInitializedEventArgs { View = self, NativeView = nativeView });
|
||||
}
|
||||
|
||||
class OouiDeviceInfo : DeviceInfo
|
||||
{
|
||||
public override Size PixelScreenSize => new Size (640, 480);
|
||||
|
@ -93,5 +101,11 @@ namespace Xamarin.Forms
|
|||
throw new NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewInitializedEventArgs
|
||||
{
|
||||
public VisualElement View { get; set; }
|
||||
public Ooui.Element NativeView { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,14 @@ namespace Ooui.Forms
|
|||
{
|
||||
public interface IVisualElementRenderer : IRegisterable, IDisposable
|
||||
{
|
||||
event EventHandler<VisualElementChangedEventArgs> ElementChanged;
|
||||
|
||||
VisualElement Element { get; }
|
||||
|
||||
Ooui.Element NativeView { get; }
|
||||
|
||||
void SetElement (VisualElement element);
|
||||
|
||||
void SetElementSize (Size size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Renderers\" />
|
||||
<Folder Include="Extensions\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Ooui\Ooui.csproj" />
|
||||
|
|
|
@ -11,7 +11,9 @@ namespace Ooui.Forms
|
|||
{
|
||||
bool _disposed;
|
||||
|
||||
public Element Element { get; private set; }
|
||||
readonly PlatformRenderer _renderer;
|
||||
|
||||
public Ooui.Element Element => _renderer;
|
||||
|
||||
public Page Page { get; private set; }
|
||||
|
||||
|
@ -26,6 +28,11 @@ namespace Ooui.Forms
|
|||
view.IsPlatformEnabled = newvalue != null;
|
||||
});
|
||||
|
||||
public Platform ()
|
||||
{
|
||||
_renderer = new PlatformRenderer (this);
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
|
@ -40,7 +47,7 @@ namespace Ooui.Forms
|
|||
public static IVisualElementRenderer CreateRenderer (VisualElement element)
|
||||
{
|
||||
var renderer = Registrar.Registered.GetHandler<IVisualElementRenderer> (element.GetType ()) ?? new DefaultRenderer ();
|
||||
//renderer.SetElement (element);
|
||||
renderer.SetElement (element);
|
||||
return renderer;
|
||||
}
|
||||
|
||||
|
@ -77,11 +84,16 @@ namespace Ooui.Forms
|
|||
Page.Platform = this;
|
||||
AddChild (Page);
|
||||
|
||||
//Page.DescendantRemoved += HandleChildRemoved;
|
||||
Page.DescendantRemoved += HandleChildRemoved;
|
||||
|
||||
Application.Current.NavigationProxy.Inner = this;
|
||||
}
|
||||
|
||||
void HandleChildRemoved (object sender, ElementEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException ();
|
||||
}
|
||||
|
||||
void AddChild (VisualElement view)
|
||||
{
|
||||
if (!Application.IsApplicationOrNull (view.RealParent))
|
||||
|
@ -91,11 +103,8 @@ namespace Ooui.Forms
|
|||
var viewRenderer = CreateRenderer (view);
|
||||
SetRenderer (view, viewRenderer);
|
||||
|
||||
//_renderer.View.AddSubview (viewRenderer.NativeView);
|
||||
//if (viewRenderer.ViewController != null)
|
||||
// _renderer.AddChildViewController (viewRenderer.ViewController);
|
||||
//viewRenderer.NativeView.Frame = new RectangleF (0, 0, _renderer.View.Bounds.Width, _renderer.View.Bounds.Height);
|
||||
//viewRenderer.SetElementSize (new Size (_renderer.View.Bounds.Width, _renderer.View.Bounds.Height));
|
||||
_renderer.AppendChild (viewRenderer.NativeView);
|
||||
viewRenderer.SetElementSize (new Size (640, 480));
|
||||
}
|
||||
else
|
||||
Console.Error.WriteLine ("Potential view double add");
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Ooui.Forms
|
||||
{
|
||||
public abstract class PlatformEffect : PlatformEffect<Ooui.Element, Ooui.Element>
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Ooui.Forms
|
||||
{
|
||||
public class PlatformRenderer : Ooui.Div
|
||||
{
|
||||
readonly Platform platform;
|
||||
|
||||
public Platform Platform => platform;
|
||||
|
||||
public PlatformRenderer (Platform platform)
|
||||
{
|
||||
this.platform = platform;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ using Xamarin.Forms;
|
|||
|
||||
namespace Ooui.Forms.Renderers
|
||||
{
|
||||
public class ButtonRenderer : ElementRenderer<Xamarin.Forms.Button, Ooui.Button>
|
||||
public class ButtonRenderer : ViewRenderer<Xamarin.Forms.Button, Ooui.Button>
|
||||
{
|
||||
public ButtonRenderer()
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Ooui.Forms.Renderers
|
|||
{
|
||||
public class DefaultRenderer : VisualElementRenderer<VisualElement>
|
||||
{
|
||||
public DefaultRenderer () : base ("div")
|
||||
public DefaultRenderer ()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Ooui.Forms.Renderers
|
||||
{
|
||||
public class ElementRenderer<TElement, TNativeElement> : IVisualElementRenderer where TElement : View where TNativeElement : Ooui.Element
|
||||
{
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false; // To detect redundant calls
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!disposedValue) {
|
||||
if (disposing) {
|
||||
// TODO: dispose managed state (managed objects).
|
||||
}
|
||||
|
||||
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
|
||||
// TODO: set large fields to null.
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
|
||||
// ~ElementRenderer() {
|
||||
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
// Dispose(false);
|
||||
// }
|
||||
|
||||
// This code added to correctly implement the disposable pattern.
|
||||
public void Dispose ()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
Dispose (true);
|
||||
// TODO: uncomment the following line if the finalizer is overridden above.
|
||||
// GC.SuppressFinalize(this);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using Ooui.Forms.Extensions;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Ooui.Forms.Renderers
|
||||
{
|
||||
public class ViewRenderer<TElement, TNativeElement> : VisualElementRenderer<TElement> where TElement : View where TNativeElement : Ooui.Element
|
||||
{
|
||||
Color _defaultColor;
|
||||
|
||||
public TNativeElement Control { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the native control is disposed of when this renderer is disposed
|
||||
/// Can be overridden in deriving classes
|
||||
/// </summary>
|
||||
protected virtual bool ManageNativeControlLifetime => true;
|
||||
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
base.Dispose (disposing);
|
||||
|
||||
if (disposing && Control != null && ManageNativeControlLifetime) {
|
||||
Control = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnElementChanged (ElementChangedEventArgs<TElement> e)
|
||||
{
|
||||
base.OnElementChanged (e);
|
||||
|
||||
if (e.OldElement != null)
|
||||
e.OldElement.FocusChangeRequested -= ViewOnFocusChangeRequested;
|
||||
|
||||
if (e.NewElement != null) {
|
||||
if (Control != null && e.OldElement != null && e.OldElement.BackgroundColor != e.NewElement.BackgroundColor || e.NewElement.BackgroundColor != Xamarin.Forms.Color.Default)
|
||||
SetBackgroundColor (e.NewElement.BackgroundColor);
|
||||
|
||||
e.NewElement.FocusChangeRequested += ViewOnFocusChangeRequested;
|
||||
}
|
||||
|
||||
UpdateIsEnabled ();
|
||||
}
|
||||
|
||||
protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (Control != null) {
|
||||
if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
|
||||
UpdateIsEnabled ();
|
||||
else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
|
||||
SetBackgroundColor (Element.BackgroundColor);
|
||||
}
|
||||
|
||||
base.OnElementPropertyChanged (sender, e);
|
||||
}
|
||||
|
||||
protected override void OnRegisterEffect (PlatformEffect effect)
|
||||
{
|
||||
base.OnRegisterEffect (effect);
|
||||
//effect.Control = Control;
|
||||
}
|
||||
|
||||
protected override void SetAutomationId (string id)
|
||||
{
|
||||
if (Control == null)
|
||||
base.SetAutomationId (id);
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetBackgroundColor (Xamarin.Forms.Color color)
|
||||
{
|
||||
if (Control == null)
|
||||
return;
|
||||
|
||||
if (color == Xamarin.Forms.Color.Default)
|
||||
Control.Style.BackgroundColor = _defaultColor;
|
||||
else
|
||||
Control.Style.BackgroundColor = color.ToOouiColor ();
|
||||
}
|
||||
|
||||
protected void SetNativeControl (Ooui.Element uiview)
|
||||
{
|
||||
_defaultColor = Color.FromStyleValue (uiview.Style.BackgroundColor);
|
||||
Control = (TNativeElement)uiview;
|
||||
|
||||
if (Element.BackgroundColor != Xamarin.Forms.Color.Default)
|
||||
SetBackgroundColor (Element.BackgroundColor);
|
||||
|
||||
UpdateIsEnabled ();
|
||||
|
||||
this.AppendChild (uiview);
|
||||
}
|
||||
|
||||
protected override void SendVisualElementInitialized (VisualElement element, Ooui.Element nativeView)
|
||||
{
|
||||
base.SendVisualElementInitialized (element, Control);
|
||||
}
|
||||
|
||||
void UpdateIsEnabled ()
|
||||
{
|
||||
if (Element == null || Control == null)
|
||||
return;
|
||||
|
||||
var uiControl = Control as Ooui.Element;
|
||||
if (uiControl == null)
|
||||
return;
|
||||
uiControl.IsDisabled = !Element.IsEnabled;
|
||||
}
|
||||
|
||||
void ViewOnFocusChangeRequested (object sender, VisualElement.FocusRequestArgs focusRequestArgs)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,133 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Ooui.Forms.Extensions;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Ooui.Forms
|
||||
{
|
||||
public class VisualElementRenderer<TElement> : Element, IVisualElementRenderer where TElement : VisualElement
|
||||
public class VisualElementRenderer<TElement> : Ooui.Element, IVisualElementRenderer where TElement : VisualElement
|
||||
{
|
||||
public VisualElementRenderer (string tagName) : base (tagName)
|
||||
readonly Color _defaultColor = Color.Clear;
|
||||
|
||||
readonly PropertyChangedEventHandler _propertyChangedHandler;
|
||||
|
||||
public TElement Element { get; private set; }
|
||||
|
||||
VisualElement IVisualElementRenderer.Element => Element;
|
||||
|
||||
public Element NativeView => this;
|
||||
|
||||
event EventHandler<VisualElementChangedEventArgs> IVisualElementRenderer.ElementChanged {
|
||||
add { _elementChangedHandlers.Add (value); }
|
||||
remove { _elementChangedHandlers.Remove (value); }
|
||||
}
|
||||
|
||||
readonly List<EventHandler<VisualElementChangedEventArgs>> _elementChangedHandlers =
|
||||
new List<EventHandler<VisualElementChangedEventArgs>> ();
|
||||
|
||||
public VisualElementRenderer () : base ("div")
|
||||
{
|
||||
_propertyChangedHandler = OnElementPropertyChanged;
|
||||
}
|
||||
|
||||
protected virtual void OnElementChanged (ElementChangedEventArgs<TElement> e)
|
||||
{
|
||||
var args = new VisualElementChangedEventArgs (e.OldElement, e.NewElement);
|
||||
for (int i = 0; i < _elementChangedHandlers.Count; i++) {
|
||||
_elementChangedHandlers[i] (this, args);
|
||||
}
|
||||
|
||||
var changed = ElementChanged;
|
||||
if (changed != null)
|
||||
changed (this, e);
|
||||
}
|
||||
|
||||
public event EventHandler<ElementChangedEventArgs<TElement>> ElementChanged;
|
||||
|
||||
void IVisualElementRenderer.SetElement (VisualElement element)
|
||||
{
|
||||
SetElement ((TElement)element);
|
||||
}
|
||||
|
||||
public void SetElement (TElement element)
|
||||
{
|
||||
var oldElement = Element;
|
||||
Element = element;
|
||||
|
||||
if (oldElement != null)
|
||||
oldElement.PropertyChanged -= _propertyChangedHandler;
|
||||
|
||||
if (element != null) {
|
||||
if (element.BackgroundColor != Xamarin.Forms.Color.Default || (oldElement != null && element.BackgroundColor != oldElement.BackgroundColor))
|
||||
SetBackgroundColor (element.BackgroundColor);
|
||||
|
||||
//if (_tracker == null) {
|
||||
// _tracker = new VisualElementTracker (this);
|
||||
// _tracker.NativeControlUpdated += (sender, e) => UpdateNativeWidget ();
|
||||
//}
|
||||
|
||||
//if (AutoPackage && _packager == null) {
|
||||
// _packager = new VisualElementPackager (this);
|
||||
// _packager.Load ();
|
||||
//}
|
||||
|
||||
//if (AutoTrack && _events == null) {
|
||||
// _events = new EventTracker (this);
|
||||
// _events.LoadEvents (this);
|
||||
//}
|
||||
|
||||
element.PropertyChanged += _propertyChangedHandler;
|
||||
}
|
||||
|
||||
OnElementChanged (new ElementChangedEventArgs<TElement> (oldElement, element));
|
||||
|
||||
if (element != null)
|
||||
SendVisualElementInitialized (element, this);
|
||||
|
||||
if (Element != null && !string.IsNullOrEmpty (Element.AutomationId))
|
||||
SetAutomationId (Element.AutomationId);
|
||||
}
|
||||
|
||||
public void SetElementSize (Size size)
|
||||
{
|
||||
Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion (Element, new Rectangle (Element.X, Element.Y, size.Width, size.Height));
|
||||
}
|
||||
|
||||
protected virtual void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName) {
|
||||
SetBackgroundColor (Element.BackgroundColor);
|
||||
}
|
||||
else if (e.PropertyName == Layout.IsClippedToBoundsProperty.PropertyName) {
|
||||
//UpdateClipToBounds ();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnRegisterEffect (PlatformEffect effect)
|
||||
{
|
||||
//effect.Container = this;
|
||||
}
|
||||
|
||||
protected virtual void SetAutomationId (string id)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void SetBackgroundColor (Xamarin.Forms.Color color)
|
||||
{
|
||||
if (color == Xamarin.Forms.Color.Default)
|
||||
Style.BackgroundColor = _defaultColor;
|
||||
else
|
||||
Style.BackgroundColor = color.ToOouiColor ();
|
||||
}
|
||||
|
||||
protected virtual void UpdateNativeWidget ()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void SendVisualElementInitialized (VisualElement element, Element nativeView)
|
||||
{
|
||||
element.SendViewInitialized (nativeView);
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
|
|
9
Ooui.sln
9
Ooui.sln
|
@ -81,7 +81,12 @@ Global
|
|||
$1.scope = text/x-csharp
|
||||
$0.CSharpFormattingPolicy = $2
|
||||
$2.scope = text/x-csharp
|
||||
$2.SpacingAfterMethodDeclarationName = True
|
||||
$2.SpaceAfterMethodCallName = True
|
||||
$2.NewLinesForBracesInProperties = False
|
||||
$2.NewLinesForBracesInAccessors = False
|
||||
$2.NewLinesForBracesInAnonymousMethods = False
|
||||
$2.NewLinesForBracesInControlBlocks = False
|
||||
$2.NewLinesForBracesInAnonymousTypes = False
|
||||
$2.NewLinesForBracesInObjectCollectionArrayInitializers = False
|
||||
$2.NewLinesForBracesInLambdaExpressionBody = False
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
using System;
|
||||
|
||||
using StyleValue = System.Object;
|
||||
|
||||
namespace Ooui
|
||||
{
|
||||
public struct Color
|
||||
{
|
||||
public byte R, G, B, A;
|
||||
|
||||
public static Color Clear => new Color (0, 0, 0, 0);
|
||||
|
||||
public Color (byte r, byte g, byte b, byte a)
|
||||
{
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
A = a;
|
||||
}
|
||||
|
||||
public double Red {
|
||||
get => R / 255.0;
|
||||
set => R = value >= 1.0 ? (byte)255 : ((value <= 0.0) ? (byte)0 : (byte)(value * 255.0 + 0.5));
|
||||
|
@ -22,5 +34,10 @@ namespace Ooui
|
|||
get => A / 255.0;
|
||||
set => A = value >= 1.0 ? (byte)255 : ((value <= 0.0) ? (byte)0 : (byte)(value * 255.0 + 0.5));
|
||||
}
|
||||
|
||||
public static Color FromStyleValue (StyleValue styleColor)
|
||||
{
|
||||
return Clear;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,12 @@ namespace Ooui
|
|||
set => SetProperty (ref hidden, value, "hidden");
|
||||
}
|
||||
|
||||
bool disabled = false;
|
||||
public bool IsDisabled {
|
||||
get => disabled;
|
||||
set => SetProperty (ref disabled, value, "disabled");
|
||||
}
|
||||
|
||||
public event TargetEventHandler Clicked {
|
||||
add => AddEventListener ("click", value);
|
||||
remove => RemoveEventListener ("click", value);
|
||||
|
|
Loading…
Reference in New Issue