Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colorpicker #20

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using Android.Graphics;
using Android.Views;
using Xamarin.Forms;

class CornerRadiusOutlineProvider : ViewOutlineProvider
{
Element element;

public CornerRadiusOutlineProvider(Element formsElement)
{
element = formsElement;
}

public override void GetOutline(Android.Views.View view, Outline outline)
{
float scale = view.Resources.DisplayMetrics.Density;
double width = (double)element.GetValue(VisualElement.WidthProperty) * scale;
double height = (double)element.GetValue(VisualElement.HeightProperty) * scale;
float minDimension = (float)Math.Min(height, width);
float radius = minDimension / 2f;
Rect rect = new Rect(0, 0, (int)width, (int)height);
outline.SetRoundRect(rect, radius);
}
}
39 changes: 39 additions & 0 deletions src/TemplateUI.Gallery.Android/Effects/RoundEffect.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ResolutionGroupName("Xamarin")]
[assembly: ExportEffect(typeof(TemplateUI.Gallery.Droid.Effects.RoundEffect), nameof(TemplateUI.Gallery.Droid.Effects.RoundEffect))]
namespace TemplateUI.Gallery.Droid.Effects
{
public class RoundEffect : PlatformEffect
{
ViewOutlineProvider originalProvider;
Android.Views.View effectTarget;

protected override void OnAttached()
{
try
{
effectTarget = Control ?? Container;
originalProvider = effectTarget.OutlineProvider;
effectTarget.OutlineProvider = new CornerRadiusOutlineProvider(Element);
effectTarget.ClipToOutline = true;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to set corner radius: {ex.Message}");
}
}

protected override void OnDetached()
{
if (effectTarget != null)
{
effectTarget.OutlineProvider = originalProvider;
effectTarget.ClipToOutline = false;
}
}
}
}
131 changes: 131 additions & 0 deletions src/TemplateUI.Gallery.Android/Renderers/GradientLayoutRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using Android.Content;
using Android.Graphics;
using TemplateUI.Controls;
using TemplateUI.Gallery.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(GradientLayout), typeof(GradientLayoutRenderer))]

// @author: https://stackoverflow.com/users/9654227/na2axl
namespace TemplateUI.Gallery.Droid.Renderers
{
public class GradientLayoutRenderer : VisualElementRenderer<AbsoluteLayout>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this rendererer? Using Xamarin.Forms Brushes we would also support other platforms such as macOS.

{
private GradientLayout gradientLayout;
List<int> droidColorSpectrumArgb = new List<int>();

public GradientLayoutRenderer(Context context) : base(context)
{
}

protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
{
int startX;
int startY;
int endX;
int endY;

switch (this.gradientLayout.Mode)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case we need this, we could move this code to extension methods. Pass a Color collection and return the LinearGradient to draw.

{
case GradientColorStackMode.ToLeft:
startX = 0;
startY = 0;
endX = Width;
endY = 0;
break;
case GradientColorStackMode.ToRight:
startX = Width;
startY = 0;
endX = 0;
endY = 0;
break;
case GradientColorStackMode.ToBottom:
startX = 0;
startY = Height;
endX = 0;
endY = 0;
break;
case GradientColorStackMode.ToTop:
startX = 0;
startY = 0;
endX = 0;
endY = Height;
break;
case GradientColorStackMode.ToTopLeft:
startX = 0;
startY = 0;
endX = Width;
endY = Height;
break;
case GradientColorStackMode.ToTopRight:
startX = Width;
startY = 0;
endX = 0;
endY = Height;
break;
case GradientColorStackMode.ToBottomLeft:
startX = 0;
startY = Height;
endX = Width;
endY = 0;
break;
case GradientColorStackMode.ToBottomRight:
startX = Width;
startY = Height;
endX = 0;
endY = 0;
break;
default:
startX = 0;
startY = 0;
endX = 0;
endY = Height;
break;
}

LinearGradient gradient = new LinearGradient(startX, startY, endX, endY, colors: this.droidColorSpectrumArgb.ToArray(), positions: null, tile: Shader.TileMode.Clamp);

var paint = new Android.Graphics.Paint()
{
Dither = true,
};
paint.SetShader(gradient);
canvas.DrawRect(0, 0, Width, Height, paint);
base.DispatchDraw(canvas);
}

protected override void OnElementChanged(ElementChangedEventArgs<AbsoluteLayout> e)
{
base.OnElementChanged(e);

if (e.OldElement != null || Element == null)
{
return;
}
try
{
this.gradientLayout = e.NewElement as GradientLayout;
List<Xamarin.Forms.Color> colorSpectrum = new List<Xamarin.Forms.Color>();
colorSpectrum.AddRange(gradientLayout.Colors);

List<Android.Graphics.Color> droidColorSpectrum = new List<Android.Graphics.Color>();
foreach (Xamarin.Forms.Color col in colorSpectrum)
{
droidColorSpectrum.Add(col.ToAndroid());
}

foreach (Android.Graphics.Color droidColor in droidColorSpectrum)
{
this.droidColorSpectrumArgb.Add(droidColor.ToArgb());
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.ComponentModel;
using Android.Content;
using Android.Graphics;
using TemplateUI.Controls;
using TemplateUI.Gallery.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(OpacityGradientLayout), typeof(OpacityGradientLayoutRenderer))]

// @author: https://stackoverflow.com/users/9654227/na2axl
namespace TemplateUI.Gallery.Droid.Renderers
{
public class OpacityGradientLayoutRenderer : VisualElementRenderer<AbsoluteLayout>
{
private OpacityGradientLayout opacityGradientLayout;

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
Invalidate();
}

public OpacityGradientLayoutRenderer(Context context) : base(context)
{
// REDRAW
this.SetWillNotDraw(false);
}

protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
{
// horizontal gradient
Xamarin.Forms.Color selectedColor = Xamarin.Forms.Color.Red;
if (opacityGradientLayout != null)
{
selectedColor = this.opacityGradientLayout.SelectedColor;
}
var horizontalGradient = new LinearGradient(0, 0, Width, 0, Android.Graphics.Color.White, selectedColor.ToAndroid(), Shader.TileMode.Clamp);

// vertical gradient
Xamarin.Forms.Color alpha100 = Xamarin.Forms.Color.FromHsla(Xamarin.Forms.Color.Black.Hue, 1.0d, 0.5d, 0.0d);
var verticalGradient = new LinearGradient(0, 0, 0, Height, alpha100.ToAndroid(), Android.Graphics.Color.Black, Shader.TileMode.Clamp);

// draw horizontal gradient
var horizontalPaint = new Android.Graphics.Paint()
{
Dither = true,
};
horizontalPaint.SetShader(horizontalGradient);
canvas.DrawRect(0, 0, Width, Height, horizontalPaint);

// draw vertical gradient
var verticalPaint = new Android.Graphics.Paint()
{
Dither = true,
};
verticalPaint.SetShader(verticalGradient);
canvas.DrawRect(0, 0, Width, Height, verticalPaint);

base.DispatchDraw(canvas);
}

protected override void OnElementChanged(ElementChangedEventArgs<AbsoluteLayout> e)
{
base.OnElementChanged(e);

if (e.OldElement != null || Element == null)
{
return;
}
try
{
this.opacityGradientLayout = e.NewElement as OpacityGradientLayout;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
}
}
}
}
86 changes: 86 additions & 0 deletions src/TemplateUI.Gallery.Android/Renderers/RadialPickerRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.ComponentModel;
using Android.Content;
using Android.Graphics;
using TemplateUI.Controls;
using TemplateUI.Gallery.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(RadialPicker), typeof(RadialPickerRenderer))]

namespace TemplateUI.Gallery.Droid.Renderers
{
public class RadialPickerRenderer : VisualElementRenderer<AbsoluteLayout>
{
private OpacityGradientLayout opacityGradientLayout;

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
Invalidate();
}

public RadialPickerRenderer(Context context) : base(context)
{
// REDRAW
this.SetWillNotDraw(false);
}

protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
{
// radial gradient
Xamarin.Forms.Color selectedColor = Xamarin.Forms.Color.Red;
if (opacityGradientLayout != null)
{
selectedColor = this.opacityGradientLayout.SelectedColor;
}

var fromSaturation = Xamarin.Forms.Color.FromRgba(1.0d, 1.0d, 1.0d, 1.0d);
var toSaturation = Xamarin.Forms.Color.FromRgba(1.0d, 1.0d, 1.0d, 0.0d);
var radialGradient = new RadialGradient(300.0f, 300.0f, 300.0f, fromSaturation.ToAndroid(), toSaturation.ToAndroid(), Shader.TileMode.Clamp);

// sweep gradient
int[] colors = new int[] { Android.Graphics.Color.Red.ToArgb(), Android.Graphics.Color.Yellow.ToArgb(), Android.Graphics.Color.Green.ToArgb(), Android.Graphics.Color.Cyan.ToArgb(), Android.Graphics.Color.Blue.ToArgb(), Android.Graphics.Color.Magenta.ToArgb(), Android.Graphics.Color.Red.ToArgb() };
float[] positions = new float[0];
var sweepGradient = new SweepGradient(300.0f, 300.0f, colors, positions: null);

// draw vertical gradient
var verticalPaint = new Android.Graphics.Paint()
{
Dither = true,
};
verticalPaint.SetShader(sweepGradient);
canvas.DrawRect(0, 0, Width, Height, verticalPaint);

// draw horizontal gradient
var horizontalPaint = new Android.Graphics.Paint()
{
Dither = true,
};
horizontalPaint.SetShader(radialGradient);
canvas.DrawRect(0, 0, Width, Height, horizontalPaint);


base.DispatchDraw(canvas);
}

protected override void OnElementChanged(ElementChangedEventArgs<AbsoluteLayout> e)
{
base.OnElementChanged(e);

if (e.OldElement != null || Element == null)
{
return;
}
try
{
this.opacityGradientLayout = e.NewElement as OpacityGradientLayout;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(@"ERROR:", ex.Message);
}
}
}
}
Loading