Add ImageButton Renderer on Tizen (#4436)

This commit is contained in:
Seungkeun Lee 2018-11-16 20:00:45 +09:00 коммит произвёл Rui Marinho
Родитель 86d4d43a67
Коммит d6ddd53ed5
4 изменённых файлов: 276 добавлений и 2 удалений

Просмотреть файл

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using ElmSharp;
namespace Xamarin.Forms.Platform.Tizen.Native
{
public class BorderRectangle : RoundRectangle
{
public BorderRectangle(EvasObject parent) : base(parent) { }
public int BorderWidth { get; set; }
protected override void DrawPoints()
{
ClearPoints();
if (BorderWidth > 0)
{
IReadOnlyList<int> radius = GetRadius();
DrawRect(radius[0], radius[1], radius[2], radius[3],
0, 0, Width, Height);
DrawRect(Math.Max(radius[0] - BorderWidth, 0),
Math.Max(radius[1] - BorderWidth, 0),
Math.Max(radius[2] - BorderWidth, 0),
Math.Max(radius[3] - BorderWidth, 0),
BorderWidth, BorderWidth, Width - BorderWidth * 2, Height - BorderWidth * 2);
}
}
protected void DrawRect(int topLeft, int topRight, int bottomLeft, int bottomRight, int startX, int startY, int width, int height)
{
int[] radius = new int[4];
int maxR = Math.Min(width / 2, height / 2);
radius[0] = Math.Min(topLeft, maxR);
radius[1] = Math.Min(topRight, maxR);
radius[2] = Math.Min(bottomLeft, maxR);
radius[3] = Math.Min(bottomRight, maxR);
Point first = new Point(-1, -1);
for (int i = 0; i <= radius[0]; i++)
{
int x = i;
int dx = radius[0] - x;
int y = radius[0] - (int)Math.Sqrt((radius[0] * radius[0]) - (dx * dx));
AddRelativePoint(startX + x, startY + y);
if (first.X < 0 && first.Y < 0)
{
first.X = startX + x;
first.Y = startY + y;
}
}
AddRelativePoint(startX + width - radius[1], startY);
for (int i = width - radius[1]; i <= width; i++)
{
int x = i;
int dx = radius[1] - (width - x);
int y = radius[1] - (int)Math.Sqrt((radius[1] * radius[1]) - (dx * dx));
AddRelativePoint(startX + x, startY + y);
}
AddRelativePoint(startX + width, startY + height - radius[3]);
for (int i = width; i >= width - radius[3]; i--)
{
int x = i;
int dx = radius[3] - (width - x);
int y = height - radius[3] + (int)Math.Sqrt((radius[3] * radius[3]) - (dx * dx));
AddRelativePoint(startX + x, startY + y);
}
AddRelativePoint(startX + radius[2], startY + height);
for (int i = radius[2]; i >= 0; i--)
{
int x = i;
int dx = radius[2] - x;
int y = height - radius[2] + (int)Math.Sqrt((radius[2] * radius[2]) - (dx * dx));
AddRelativePoint(startX + x, startY + y);
}
AddRelativePoint((int)first.X, (int)first.Y);
}
}
}

Просмотреть файл

@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using ElmSharp;
namespace Xamarin.Forms.Platform.Tizen.Native
{
public class RoundRectangle : Polygon
{
int[] _radius = new int[4];
readonly int[] _radius = new int[4];
public RoundRectangle(EvasObject parent) : base(parent)
{
}
@ -29,6 +30,11 @@ namespace Xamarin.Forms.Platform.Tizen.Native
_radius[3] = bottomRight;
}
public IReadOnlyList<int> GetRadius()
{
return _radius;
}
public void Draw()
{
DrawPoints();
@ -96,7 +102,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native
}
}
void AddRelativePoint(int x, int y)
protected void AddRelativePoint(int x, int y)
{
AddPoint(X + x, Y + y);
}

Просмотреть файл

@ -35,6 +35,7 @@ using System.Reflection;
[assembly: ExportRenderer(typeof(TableView), typeof(TableViewRenderer))]
[assembly: ExportRenderer(typeof(NativeViewWrapper), typeof(NativeViewWrapperRenderer))]
[assembly: ExportRenderer(typeof(WebView), typeof(WebViewRenderer))]
[assembly: ExportRenderer(typeof(ImageButton), typeof(ImageButtonRenderer))]
[assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))]
[assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImageSourceHandler))]

Просмотреть файл

@ -0,0 +1,183 @@
using System;
using ElmSharp;
using EButton = ElmSharp.Button;
namespace Xamarin.Forms.Platform.Tizen
{
public class ImageButtonRenderer : ViewRenderer<ImageButton, Box>
{
public ImageButtonRenderer()
{
RegisterPropertyHandler(ImageButton.SourceProperty, UpdateSource);
RegisterPropertyHandler(ImageButton.PaddingProperty, UpdatePadding);
RegisterPropertyHandler(ImageButton.CornerRadiusProperty, UpdateRadius);
RegisterPropertyHandler(ImageButton.BorderWidthProperty, UpdateBorderWidth);
RegisterPropertyHandler(ImageButton.BorderColorProperty, UpdateBorderColor);
RegisterPropertyHandler(ImageButton.AspectProperty, UpdateAspect);
}
Native.Image _image;
EButton _button;
Native.RoundRectangle _round;
Native.BorderRectangle _border;
protected override void OnElementChanged(ElementChangedEventArgs<ImageButton> e)
{
if (Control == null)
{
SetNativeControl(new Box(Forms.NativeParent));
Control.SetLayoutCallback(OnLayout);
_round = new Native.RoundRectangle(Forms.NativeParent);
_round.Show();
_border = new Native.BorderRectangle(Forms.NativeParent);
_border.Show();
_image = new Native.Image(Forms.NativeParent);
_image.Show();
_button = new EButton(Forms.NativeParent)
{
Style = "transparent"
};
_button.Clicked += OnClicked;
_button.Pressed += OnPressed;
_button.Released += OnReleased;
_button.Show();
Control.PackEnd(_round);
Control.PackEnd(_image);
Control.PackEnd(_border);
Control.PackEnd(_button);
}
base.OnElementChanged(e);
}
protected virtual void UpdateAfterLoading()
{
_image.IsOpaque = Element.IsOpaque;
}
protected override ElmSharp.Size Measure(int availableWidth, int availableHeight)
{
var size = _image.Measure(availableHeight, availableHeight);
size.Width += Forms.ConvertToScaledPixel(Element.Padding.HorizontalThickness);
size.Height += Forms.ConvertToScaledPixel(Element.Padding.VerticalThickness);
return size;
}
protected override void UpdateBackgroundColor(bool initialize)
{
_round.Color = Element.BackgroundColor.ToNative();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_button != null)
{
_button.Clicked -= OnClicked;
_button.Pressed -= OnPressed;
_button.Released -= OnReleased;
_button = null;
}
}
base.Dispose(disposing);
}
void OnReleased(object sender, EventArgs e)
{
(Element as IButtonController)?.SendReleased();
}
void OnPressed(object sender, EventArgs e)
{
(Element as IButtonController)?.SendPressed();
}
void OnClicked(object sender, EventArgs e)
{
(Element as IButtonController)?.SendClicked();
}
void OnLayout()
{
var outter = Control.Geometry;
var width = outter.Width - Forms.ConvertToScaledPixel(Element.Padding.HorizontalThickness);
var height = outter.Height - Forms.ConvertToScaledPixel(Element.Padding.VerticalThickness);
var left = outter.Left + Forms.ConvertToScaledPixel(Element.Padding.Left);
var top = outter.Top + Forms.ConvertToScaledPixel(Element.Padding.Top);
var imageBound = new Rect(left, top, width, height);
_image.Geometry = imageBound;
_button.Geometry = outter;
_round.Draw(outter);
_border.Draw(outter);
}
void UpdatePadding()
{
Control.MarkChanged();
}
async void UpdateSource()
{
ImageSource source = Element.Source;
(Element as IImageController)?.SetIsLoading(true);
if (Control != null)
{
bool success = await _image.LoadFromImageSourceAsync(source);
if (!IsDisposed && success)
{
(Element as IVisualElementController)?.NativeSizeChanged();
UpdateAfterLoading();
}
}
if (!IsDisposed)
((IImageController)Element).SetIsLoading(false);
}
void UpdateRadius(bool init)
{
if (Element.CornerRadius > 0)
{
_round.SetRadius(Forms.ConvertToScaledPixel(Element.CornerRadius));
_border.SetRadius(Forms.ConvertToScaledPixel(Element.CornerRadius));
}
else
{
_round.SetRadius(0);
_border.SetRadius(0);
}
if (!init)
{
_round.Draw();
_border.Draw();
}
}
void UpdateBorderWidth(bool init)
{
if (Element.BorderWidth > 0)
{
_border.BorderWidth = Forms.ConvertToScaledPixel(Element.BorderWidth);
}
else
{
_border.BorderWidth = 0;
}
if (!init)
{
_border.Draw();
}
}
void UpdateBorderColor()
{
_border.Color = Element.BorderColor.ToNative();
}
void UpdateAspect()
{
_image.Aspect = Element.Aspect;
}
}
}