diff --git a/Ooui.Forms/Exports.cs b/Ooui.Forms/Exports.cs index fc910e4..566c468 100644 --- a/Ooui.Forms/Exports.cs +++ b/Ooui.Forms/Exports.cs @@ -5,6 +5,7 @@ using Xamarin.Forms; using Xamarin.Forms.Internals; [assembly: Dependency (typeof (ResourcesProvider))] +[assembly: ExportRenderer (typeof (BoxView), typeof (BoxRenderer))] [assembly: ExportRenderer (typeof (Button), typeof (ButtonRenderer))] [assembly: ExportRenderer (typeof (Label), typeof (LabelRenderer))] diff --git a/Ooui.Forms/Extensions/ColorExtensions.cs b/Ooui.Forms/Extensions/ColorExtensions.cs index 547fc56..ad432ab 100644 --- a/Ooui.Forms/Extensions/ColorExtensions.cs +++ b/Ooui.Forms/Extensions/ColorExtensions.cs @@ -6,7 +6,7 @@ namespace Ooui.Forms.Extensions { 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)); + 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)); } public static Color ToOouiColor (this Xamarin.Forms.Color color, Xamarin.Forms.Color defaultColor) diff --git a/Ooui.Forms/Forms.cs b/Ooui.Forms/Forms.cs index cb0fefd..c5a39f7 100644 --- a/Ooui.Forms/Forms.cs +++ b/Ooui.Forms/Forms.cs @@ -26,6 +26,7 @@ namespace Xamarin.Forms Device.SetIdiom (TargetIdiom.Desktop); Device.PlatformServices = new OouiPlatformServices (); Device.Info = new OouiDeviceInfo (); + Color.SetAccent (Color.FromHex ("#0000EE")); // Safari Blue Registrar.RegisterAll (new[] { typeof(ExportRendererAttribute), diff --git a/Ooui.Forms/Renderers/BoxRenderer.cs b/Ooui.Forms/Renderers/BoxRenderer.cs new file mode 100644 index 0000000..ee64082 --- /dev/null +++ b/Ooui.Forms/Renderers/BoxRenderer.cs @@ -0,0 +1,41 @@ +using System; +using System.ComponentModel; +using Ooui.Forms.Extensions; +using Xamarin.Forms; + +namespace Ooui.Forms.Renderers +{ + public class BoxRenderer : VisualElementRenderer + { + Ooui.Color _colorToRenderer; + + protected override void OnElementChanged (ElementChangedEventArgs e) + { + base.OnElementChanged (e); + + if (Element != null) + SetBackgroundColor (Element.BackgroundColor); + } + + protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e) + { + base.OnElementPropertyChanged (sender, e); + if (e.PropertyName == BoxView.ColorProperty.PropertyName) + SetBackgroundColor (Element.BackgroundColor); + } + + protected override void SetBackgroundColor (Xamarin.Forms.Color color) + { + if (Element == null) + return; + + var elementColor = Element.Color; + if (!elementColor.IsDefault) + _colorToRenderer = elementColor.ToOouiColor (); + else + _colorToRenderer = Colors.Clear; + + Style.BackgroundColor = _colorToRenderer; + } + } +} diff --git a/Ooui/Client.js b/Ooui/Client.js index bff2f13..b6a1cd7 100644 --- a/Ooui/Client.js +++ b/Ooui/Client.js @@ -1,5 +1,5 @@ -var debug = false; +var debug = true; const nodes = {}; diff --git a/Ooui/Color.cs b/Ooui/Color.cs index 7b914ad..476e1cd 100644 --- a/Ooui/Color.cs +++ b/Ooui/Color.cs @@ -1,20 +1,21 @@ using System; - +using Newtonsoft.Json; using StyleValue = System.Object; namespace Ooui { - public struct Color + [Newtonsoft.Json.JsonConverter (typeof (ColorJsonConverter))] + public struct Color : IEquatable { public byte R, G, B, A; public Color (byte r, byte g, byte b, byte a) - { - R = r; - G = g; - B = b; - A = a; - } + { + R = r; + G = g; + B = b; + A = a; + } public double Red { get => R / 255.0; @@ -33,9 +34,70 @@ namespace Ooui set => A = value >= 1.0 ? (byte)255 : ((value <= 0.0) ? (byte)0 : (byte)(value * 255.0 + 0.5)); } - public static Color FromStyleValue (StyleValue styleColor) - { + public override bool Equals (object obj) + { + if (obj is Color other) + return R == other.R && G == other.G && B == other.B && A == other.A; + return false; + } + + public bool Equals (Color other) => R == other.R && G == other.G && B == other.B && A == other.A; + + public override int GetHashCode () => R.GetHashCode () + G.GetHashCode () * 2 + B.GetHashCode () * 3 + A.GetHashCode () * 5; + + public static Color FromStyleValue (StyleValue styleColor) + { + if (styleColor is Color c) + return c; + if (styleColor is string s) + return Parse (s); return Colors.Clear; - } - } + } + + public static Color Parse (string styleValue) + { + if (string.IsNullOrWhiteSpace (styleValue) || styleValue.Length < 4) + throw new ArgumentException ("Cannot parse empty strings", nameof (styleValue)); + + if (styleValue.Length > 32) + throw new ArgumentException ("Color string is too long", nameof (styleValue)); + + if (styleValue == "inherit") + return Colors.Clear; + + //if (styleValue[0] == '#' && styleValue.Length == 4) { + //} + + //if (styleValue[0] == '#' && styleValue.Length == 7) { + //} + + throw new ArgumentException ($"Cannot parse color string `{styleValue}`", nameof (styleValue)); + } + + public override string ToString () + { + if (A == 255) + return string.Format ("#{0:x2}{1:x2}{2:x2}", R, G, B); + return string.Format ("rgba({0},{1},{2},{3})", R, G, B, A / 255.0); + } + } + + class ColorJsonConverter : Newtonsoft.Json.JsonConverter + { + public override bool CanConvert (Type objectType) + { + return objectType == typeof (Color); + } + + public override object ReadJson (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var str = reader.ReadAsString (); + return Color.Parse (str); + } + + public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue (value.ToString ()); + } + } }