Implement buttons and labels

This commit is contained in:
Frank A. Krueger 2017-11-09 16:09:48 -08:00
parent 27c58d3449
commit 36367a3158
11 changed files with 385 additions and 6 deletions

View File

@ -6,6 +6,7 @@ using Xamarin.Forms.Internals;
[assembly: Dependency (typeof (ResourcesProvider))] [assembly: Dependency (typeof (ResourcesProvider))]
[assembly: ExportRenderer (typeof (Button), typeof (ButtonRenderer))] [assembly: ExportRenderer (typeof (Button), typeof (ButtonRenderer))]
[assembly: ExportRenderer (typeof (Label), typeof (LabelRenderer))]
namespace Ooui.Forms namespace Ooui.Forms
{ {

View File

@ -8,5 +8,12 @@ namespace Ooui.Forms.Extensions
{ {
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)
{
if (color == Xamarin.Forms.Color.Default)
return defaultColor.ToOouiColor ();
return color.ToOouiColor ();
}
} }
} }

View File

@ -0,0 +1,16 @@
using System;
using Xamarin.Forms;
namespace Ooui.Forms.Extensions
{
public static class ElementExtensions
{
public static SizeRequest GetSizeRequest (this Ooui.Element self, double widthConstraint, double heightConstraint,
double minimumWidth = -1, double minimumHeight = -1)
{
var request = new Size (double.PositiveInfinity, double.PositiveInfinity);
var minimum = new Size (double.PositiveInfinity, double.PositiveInfinity);
return new SizeRequest (request, minimum);
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using Xamarin.Forms;
namespace Ooui.Forms.Extensions
{
public static class FontExtensions
{
public static void SetStyleFont (this View view, Style style)
{
}
public static string ToOouiTextAlign (this TextAlignment align)
{
switch (align) {
case TextAlignment.Start:
default:
return "start";
case TextAlignment.Center:
return "center";
case TextAlignment.End:
return "end";
}
}
}
}

View File

@ -1,12 +1,140 @@
using System; using System;
using System.ComponentModel;
using System.Diagnostics;
using Ooui.Forms.Extensions;
using Xamarin.Forms; using Xamarin.Forms;
namespace Ooui.Forms.Renderers namespace Ooui.Forms.Renderers
{ {
public class ButtonRenderer : ViewRenderer<Xamarin.Forms.Button, Ooui.Button> public class ButtonRenderer : ViewRenderer<Xamarin.Forms.Button, Ooui.Button>
{ {
public ButtonRenderer () Ooui.Color _buttonTextColorDefaultDisabled;
Ooui.Color _buttonTextColorDefaultHighlighted;
Ooui.Color _buttonTextColorDefaultNormal;
protected override void Dispose (bool disposing)
{ {
if (Control != null) {
Control.Clicked -= OnButtonTouchUpInside;
}
base.Dispose (disposing);
}
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged (e);
if (e.NewElement != null) {
if (Control == null) {
SetNativeControl (new Ooui.Button ());
Debug.Assert (Control != null, "Control != null");
_buttonTextColorDefaultNormal = Ooui.Colors.Black;
_buttonTextColorDefaultHighlighted = Ooui.Colors.Black;
_buttonTextColorDefaultDisabled = Ooui.Colors.Black;
Control.Clicked += OnButtonTouchUpInside;
}
UpdateText ();
UpdateFont ();
UpdateBorder ();
UpdateImage ();
UpdateTextColor ();
}
}
protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged (sender, e);
if (e.PropertyName == Xamarin.Forms.Button.TextProperty.PropertyName)
UpdateText ();
else if (e.PropertyName == Xamarin.Forms.Button.TextColorProperty.PropertyName)
UpdateTextColor ();
else if (e.PropertyName == Xamarin.Forms.Button.FontProperty.PropertyName)
UpdateFont ();
else if (e.PropertyName == Xamarin.Forms.Button.BorderWidthProperty.PropertyName || e.PropertyName == Xamarin.Forms.Button.BorderRadiusProperty.PropertyName || e.PropertyName == Xamarin.Forms.Button.BorderColorProperty.PropertyName)
UpdateBorder ();
else if (e.PropertyName == Xamarin.Forms.Button.ImageProperty.PropertyName)
UpdateImage ();
}
void OnButtonTouchUpInside (object sender, EventArgs eventArgs)
{
((IButtonController)Element)?.SendPressed ();
((IButtonController)Element)?.SendReleased ();
((IButtonController)Element)?.SendClicked ();
}
void UpdateBorder ()
{
var uiButton = Control;
var button = Element;
if (button.BorderColor != Xamarin.Forms.Color.Default)
uiButton.Style.BorderColor = button.BorderColor.ToOouiColor ();
uiButton.Style.BorderWidth = Math.Max (0f, (float)button.BorderWidth);
uiButton.Style.BorderRadius = button.BorderRadius;
}
void UpdateFont ()
{
Element.SetStyleFont (Control.Style);
}
void UpdateImage ()
{
//IImageSourceHandler handler;
//FileImageSource source = Element.Image;
//if (source != null && (handler = Internals.Registrar.Registered.GetHandlerForObject<IImageSourceHandler> (source)) != null) {
// UIImage uiimage;
// try {
// uiimage = await handler.LoadImageAsync (source, scale: (float)UIScreen.MainScreen.Scale);
// }
// catch (OperationCanceledException) {
// uiimage = null;
// }
// Ooui.Button button = Control;
// if (button != null && uiimage != null) {
// button.SetImage (uiimage.ImageWithRenderingMode (UIImageRenderingMode.AlwaysOriginal), UIControlState.Normal);
// button.ImageView.ContentMode = UIViewContentMode.ScaleAspectFit;
// ComputeEdgeInsets (Control, Element.ContentLayout);
// }
//}
//else {
// Control.SetImage (null, UIControlState.Normal);
// ClearEdgeInsets (Control);
//}
//((IVisualElementController)Element).NativeSizeChanged ();
}
void UpdateText ()
{
var newText = Element.Text;
if (Control.Text != newText) {
Control.Text = Element.Text;
}
}
void UpdateTextColor ()
{
if (Element.TextColor == Xamarin.Forms.Color.Default) {
Control.Style.Color = _buttonTextColorDefaultNormal;
Control.Style.Color = _buttonTextColorDefaultHighlighted;
Control.Style.Color = _buttonTextColorDefaultDisabled;
}
else {
Control.Style.Color = Element.TextColor.ToOouiColor ();
Control.Style.Color = Element.TextColor.ToOouiColor ();
Control.Style.Color = _buttonTextColorDefaultDisabled;
}
} }
} }
} }

View File

@ -0,0 +1,180 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using Ooui.Forms.Extensions;
using Xamarin.Forms;
using NativeLabel = Ooui.Span;
namespace Ooui.Forms.Renderers
{
public class LabelRenderer : ViewRenderer<Xamarin.Forms.Label, NativeLabel>
{
SizeRequest _perfectSize;
bool _perfectSizeValid;
public override SizeRequest GetDesiredSize (double widthConstraint, double heightConstraint)
{
if (!_perfectSizeValid) {
_perfectSize = GetPerfectSize ();
_perfectSize.Minimum = new Size (Math.Min (10, _perfectSize.Request.Width), _perfectSize.Request.Height);
_perfectSizeValid = true;
}
var widthFits = widthConstraint >= _perfectSize.Request.Width;
var heightFits = heightConstraint >= _perfectSize.Request.Height;
if (widthFits && heightFits)
return _perfectSize;
var result = base.GetDesiredSize (widthConstraint, heightConstraint);
var tinyWidth = Math.Min (10, result.Request.Width);
result.Minimum = new Size (tinyWidth, result.Request.Height);
if (widthFits || Element.LineBreakMode == LineBreakMode.NoWrap)
return result;
bool containerIsNotInfinitelyWide = !double.IsInfinity (widthConstraint);
if (containerIsNotInfinitelyWide) {
bool textCouldHaveWrapped = Element.LineBreakMode == LineBreakMode.WordWrap || Element.LineBreakMode == LineBreakMode.CharacterWrap;
bool textExceedsContainer = result.Request.Width > widthConstraint;
if (textExceedsContainer || textCouldHaveWrapped) {
var expandedWidth = Math.Max (tinyWidth, widthConstraint);
result.Request = new Size (expandedWidth, result.Request.Height);
}
}
return result;
}
SizeRequest GetPerfectSize ()
{
return new SizeRequest (new Size (100, 22));
}
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Label> e)
{
if (e.NewElement != null) {
if (Control == null) {
SetNativeControl (new NativeLabel ());
}
UpdateText ();
UpdateTextColor ();
UpdateFont ();
UpdateLineBreakMode ();
UpdateAlignment ();
}
base.OnElementChanged (e);
}
protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged (sender, e);
if (e.PropertyName == Xamarin.Forms.Label.HorizontalTextAlignmentProperty.PropertyName)
UpdateAlignment ();
else if (e.PropertyName == Xamarin.Forms.Label.VerticalTextAlignmentProperty.PropertyName)
UpdateAlignment ();
else if (e.PropertyName == Xamarin.Forms.Label.TextColorProperty.PropertyName)
UpdateTextColor ();
else if (e.PropertyName == Xamarin.Forms.Label.FontProperty.PropertyName)
UpdateFont ();
else if (e.PropertyName == Xamarin.Forms.Label.TextProperty.PropertyName)
UpdateText ();
else if (e.PropertyName == Xamarin.Forms.Label.FormattedTextProperty.PropertyName)
UpdateText ();
else if (e.PropertyName == Xamarin.Forms.Label.LineBreakModeProperty.PropertyName)
UpdateLineBreakMode ();
}
protected override void SetBackgroundColor (Xamarin.Forms.Color color)
{
if (color == Xamarin.Forms.Color.Default)
Style.BackgroundColor = Colors.Clear;
else
Style.BackgroundColor = color.ToOouiColor();
}
void UpdateAlignment ()
{
Control.Style.TextAlign = Element.HorizontalTextAlignment.ToOouiTextAlign ();
Control.Style.VerticalAlign = Element.VerticalTextAlignment.ToOouiTextAlign ();
}
void UpdateLineBreakMode ()
{
_perfectSizeValid = false;
//switch (Element.LineBreakMode)
//{
// case LineBreakMode.NoWrap:
// Control.LineBreakMode = UILineBreakMode.Clip;
// Control.Lines = 1;
// break;
// case LineBreakMode.WordWrap:
// Control.LineBreakMode = UILineBreakMode.WordWrap;
// Control.Lines = 0;
// break;
// case LineBreakMode.CharacterWrap:
// Control.LineBreakMode = UILineBreakMode.CharacterWrap;
// Control.Lines = 0;
// break;
// case LineBreakMode.HeadTruncation:
// Control.LineBreakMode = UILineBreakMode.HeadTruncation;
// Control.Lines = 1;
// break;
// case LineBreakMode.MiddleTruncation:
// Control.LineBreakMode = UILineBreakMode.MiddleTruncation;
// Control.Lines = 1;
// break;
// case LineBreakMode.TailTruncation:
// Control.LineBreakMode = UILineBreakMode.TailTruncation;
// Control.Lines = 1;
// break;
//}
}
bool isTextFormatted;
void UpdateText ()
{
_perfectSizeValid = false;
var values = Element.GetValues (Xamarin.Forms.Label.FormattedTextProperty, Xamarin.Forms.Label.TextProperty, Xamarin.Forms.Label.TextColorProperty);
var formatted = values[0] as FormattedString;
if (formatted != null) {
Control.Text = (string)values[1];
isTextFormatted = true;
}
else {
Control.Text = (string)values[1];
isTextFormatted = false;
}
}
void UpdateFont ()
{
if (isTextFormatted)
return;
_perfectSizeValid = false;
Element.SetStyleFont (Control.Style);
}
void UpdateTextColor ()
{
if (isTextFormatted)
return;
_perfectSizeValid = false;
var textColor = (Xamarin.Forms.Color)Element.GetValue (Xamarin.Forms.Label.TextColorProperty);
Control.Style.Color = textColor.ToOouiColor(Xamarin.Forms.Color.Black);
}
}
}

View File

@ -18,7 +18,7 @@ namespace Ooui.Forms
{ {
bool disposedValue = false; // To detect redundant calls bool disposedValue = false; // To detect redundant calls
readonly Color _defaultColor = Color.Clear; readonly Color _defaultColor = Colors.Clear;
readonly PropertyChangedEventHandler _propertyChangedHandler; readonly PropertyChangedEventHandler _propertyChangedHandler;
@ -165,6 +165,11 @@ namespace Ooui.Forms
element.SendViewInitialized (nativeView); element.SendViewInitialized (nativeView);
} }
public virtual SizeRequest GetDesiredSize (double widthConstraint, double heightConstraint)
{
return NativeView.GetSizeRequest (widthConstraint, heightConstraint);
}
protected virtual void Dispose (bool disposing) protected virtual void Dispose (bool disposing)
{ {
if (!disposedValue) { if (!disposedValue) {

View File

@ -8,8 +8,6 @@ namespace Ooui
{ {
public byte R, G, B, A; 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) public Color (byte r, byte g, byte b, byte a)
{ {
R = r; R = r;
@ -37,7 +35,7 @@ namespace Ooui
public static Color FromStyleValue (StyleValue styleColor) public static Color FromStyleValue (StyleValue styleColor)
{ {
return Clear; return Colors.Clear;
} }
} }
} }

10
Ooui/Colors.cs Normal file
View File

@ -0,0 +1,10 @@
using System;
namespace Ooui
{
public static class Colors
{
public static readonly Color Clear = new Color (0, 0, 0, 0);
public static readonly Color Black = new Color (0, 0, 0, 255);
}
}

View File

@ -107,6 +107,13 @@ namespace Ooui
set => this["border-left-width"] = value; set => this["border-left-width"] = value;
} }
public Value BorderRadius {
get => this["border-radius"];
set {
this["border-radius"] = value;
}
}
public Value BorderWidth { public Value BorderWidth {
get => this["border-top-width"]; get => this["border-top-width"];
set { set {

View File

@ -15,6 +15,8 @@ namespace Samples
BackgroundColor = Color.Gold, BackgroundColor = Color.Gold,
}; };
var countButton = new Button { var countButton = new Button {
Text = "Increase",
VerticalOptions = LayoutOptions.FillAndExpand,
}; };
countButton.Clicked += (sender, e) => { countButton.Clicked += (sender, e) => {
var v = int.Parse (countLabel.Text); var v = int.Parse (countLabel.Text);