From 3039185215c0ed72185f64c8e3ec65b7197f4231 Mon Sep 17 00:00:00 2001 From: Ravinder Jangra Date: Fri, 2 Feb 2018 12:08:32 +0530 Subject: [PATCH 1/3] Implementation for #1690 --- Xamarin.Forms.Core/Slider.cs | 32 +++++++++ .../Renderers/SliderRenderer.cs | 65 +++++++++++++++++ .../Renderers/SliderRenderer.cs | 71 +++++++++++++++++++ 3 files changed, 168 insertions(+) diff --git a/Xamarin.Forms.Core/Slider.cs b/Xamarin.Forms.Core/Slider.cs index 3f3961fb5..8c6439071 100644 --- a/Xamarin.Forms.Core/Slider.cs +++ b/Xamarin.Forms.Core/Slider.cs @@ -41,6 +41,14 @@ namespace Xamarin.Forms eh(slider, new ValueChangedEventArgs((double)oldValue, (double)newValue)); }); + public static readonly BindableProperty MinimumTrackColorProperty = BindableProperty.Create(nameof(MinimumTrackColor), typeof(Color), typeof(Slider), default(Color)); + + public static readonly BindableProperty MaximumTrackColorProperty = BindableProperty.Create(nameof(MaximumTrackColor), typeof(Color), typeof(Slider), default(Color)); + + public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Slider), default(Color)); + + public static readonly BindableProperty ThumbImageProperty = BindableProperty.Create(nameof(ThumbImage), typeof(FileImageSource), typeof(Slider), default(FileImageSource)); + readonly Lazy> _platformConfigurationRegistry; public Slider() @@ -66,6 +74,30 @@ namespace Xamarin.Forms Value = val.Clamp(min, max); } + public Color MinimumTrackColor + { + get { return (Color)GetValue(MinimumTrackColorProperty); } + set { SetValue(MinimumTrackColorProperty, value); } + } + + public Color MaximumTrackColor + { + get { return (Color)GetValue(MaximumTrackColorProperty); } + set { SetValue(MaximumTrackColorProperty, value); } + } + + public Color ThumbColor + { + get { return (Color)GetValue(ThumbColorProperty); } + set { SetValue(ThumbColorProperty, value); } + } + + public FileImageSource ThumbImage + { + get { return (FileImageSource)GetValue(ThumbImageProperty); } + set { SetValue(ThumbImageProperty, value); } + } + public double Maximum { get { return (double)GetValue(MaximumProperty); } diff --git a/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs index 81afba8f3..0fc0a3229 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs @@ -1,6 +1,8 @@ using System; using System.ComponentModel; using Android.Content; +using Android.Content.Res; +using Android.Graphics; using Android.Graphics.Drawables; using Android.OS; using Android.Widget; @@ -71,6 +73,12 @@ namespace Xamarin.Forms.Platform.Android _min = slider.Minimum; _max = slider.Maximum; Value = slider.Value; + UpdateSliderColors(); + } + + SeekBar NativeSeekbar + { + get { return Control; } } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) @@ -91,6 +99,63 @@ namespace Xamarin.Forms.Platform.Android Value = view.Value; break; } + + if (e.PropertyName == Slider.MinimumTrackColorProperty.PropertyName) + UpdateMinimumTrackColor(); + else if (e.PropertyName == Slider.MaximumTrackColorProperty.PropertyName) + UpdateMaximumTrackColor(); + else if (e.PropertyName == Slider.ThumbImageProperty.PropertyName) + UpdateThumbImage(); + else if (e.PropertyName == Slider.ThumbColorProperty.PropertyName) + UpdateThumbColor(); + } + + private void UpdateSliderColors() + { + UpdateMinimumTrackColor(); + UpdateMaximumTrackColor(); + if (!string.IsNullOrEmpty(Element.ThumbImage)) + { + UpdateThumbImage(); + } + else + { + UpdateThumbColor(); + } + } + + private void UpdateMinimumTrackColor() + { + if (Element != null && Element.MinimumTrackColor != Color.Default) + { + Control.ProgressDrawable.SetColorFilter(new PorterDuffColorFilter(Element.MinimumTrackColor.ToAndroid(), PorterDuff.Mode.SrcIn)); + } + } + + private void UpdateMaximumTrackColor() + { + if (Element != null && Element.MaximumTrackColor != Color.Default) + { + Control.ForegroundTintList = ColorStateList.ValueOf(Element.MinimumTrackColor.ToAndroid()); + Control.ProgressBackgroundTintList = ColorStateList.ValueOf(Element.MaximumTrackColor.ToAndroid()); + Control.ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn; + } + } + + private void UpdateThumbColor() + { + if (Element != null && Element.ThumbColor != Color.Default) + { + Control.Thumb.SetColorFilter(Element.ThumbColor.ToAndroid(), PorterDuff.Mode.SrcIn); + } + } + + private void UpdateThumbImage() + { + if (Element != null && !string.IsNullOrEmpty(Element.ThumbImage)) + { + Control.SetThumb(Context.GetDrawable(Element.ThumbImage)); + } } protected override void OnLayout(bool changed, int l, int t, int r, int b) diff --git a/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs index aa01c955e..734a93ce4 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs @@ -44,11 +44,74 @@ namespace Xamarin.Forms.Platform.iOS UpdateMaximum(); UpdateMinimum(); UpdateValue(); + UpdateSliderColors(); } base.OnElementChanged(e); } + private void UpdateSliderColors() + { + UpdateMinimumTrackColor(); + UpdateMaximumTrackColor(); + if (!string.IsNullOrEmpty(Element.ThumbImage)) + { + UpdateThumbImage(); + } + else + { + UpdateThumbColor(); + } + } + + private void UpdateMinimumTrackColor() + { + if (Element != null && Element.MinimumTrackColor != Color.Default) + { + Control.MinimumTrackTintColor = Element.MinimumTrackColor.ToUIColor(); + } + } + + private void UpdateMaximumTrackColor() + { + if (Element != null && Element.MaximumTrackColor != Color.Default) + { + Control.MaximumTrackTintColor = Element.MaximumTrackColor.ToUIColor(); + } + } + + private void UpdateThumbColor() + { + if (Element != null && Element.ThumbColor != Color.Default) + { + Control.ThumbTintColor = Element.ThumbColor.ToUIColor(); + } + } + + async void UpdateThumbImage() + { + IImageSourceHandler handler; + FileImageSource source = Element.ThumbImage; + if (source != null && (handler = Internals.Registrar.Registered.GetHandlerForObject(source)) != null) + { + UIImage uiimage; + try + { + uiimage = await handler.LoadImageAsync(source, scale: (float)UIScreen.MainScreen.Scale); + } + catch (OperationCanceledException) + { + uiimage = null; + } + UISlider slider = Control; + if (slider != null && uiimage != null) + { + slider.SetThumbImage(uiimage, UIControlState.Normal); + } + } + ((IVisualElementController)Element).NativeSizeChanged(); + } + protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); @@ -59,6 +122,14 @@ namespace Xamarin.Forms.Platform.iOS UpdateMinimum(); else if (e.PropertyName == Slider.ValueProperty.PropertyName) UpdateValue(); + else if (e.PropertyName == Slider.MinimumTrackColorProperty.PropertyName) + UpdateMinimumTrackColor(); + else if (e.PropertyName == Slider.MaximumTrackColorProperty.PropertyName) + UpdateMaximumTrackColor(); + else if (e.PropertyName == Slider.ThumbImageProperty.PropertyName) + UpdateThumbImage(); + else if (e.PropertyName == Slider.ThumbColorProperty.PropertyName) + UpdateThumbColor(); } void OnControlValueChanged(object sender, EventArgs eventArgs) From f371dd59a4fd2b04cfd0e6bfde0d7e448a09b166 Mon Sep 17 00:00:00 2001 From: Ravinder Jangra Date: Fri, 2 Feb 2018 14:45:57 +0530 Subject: [PATCH 2/3] Updated default(Color) -> Color.Default --- Xamarin.Forms.Core/Slider.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Xamarin.Forms.Core/Slider.cs b/Xamarin.Forms.Core/Slider.cs index 8c6439071..7d04cac98 100644 --- a/Xamarin.Forms.Core/Slider.cs +++ b/Xamarin.Forms.Core/Slider.cs @@ -41,11 +41,11 @@ namespace Xamarin.Forms eh(slider, new ValueChangedEventArgs((double)oldValue, (double)newValue)); }); - public static readonly BindableProperty MinimumTrackColorProperty = BindableProperty.Create(nameof(MinimumTrackColor), typeof(Color), typeof(Slider), default(Color)); + public static readonly BindableProperty MinimumTrackColorProperty = BindableProperty.Create(nameof(MinimumTrackColor), typeof(Color), typeof(Slider), Color.Default); - public static readonly BindableProperty MaximumTrackColorProperty = BindableProperty.Create(nameof(MaximumTrackColor), typeof(Color), typeof(Slider), default(Color)); + public static readonly BindableProperty MaximumTrackColorProperty = BindableProperty.Create(nameof(MaximumTrackColor), typeof(Color), typeof(Slider), Color.Default); - public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Slider), default(Color)); + public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Slider), Color.Default); public static readonly BindableProperty ThumbImageProperty = BindableProperty.Create(nameof(ThumbImage), typeof(FileImageSource), typeof(Slider), default(FileImageSource)); From 9f9dc82c95f1d2521ddc513afd7aaaa3e350c2be Mon Sep 17 00:00:00 2001 From: Ravinder Jangra Date: Tue, 6 Feb 2018 13:07:36 +0530 Subject: [PATCH 3/3] Added UWP + default --- .../Renderers/SliderRenderer.cs | 64 +++++++++++++++---- Xamarin.Forms.Platform.UAP/SliderRenderer.cs | 44 +++++++++++++ .../Renderers/SliderRenderer.cs | 34 ++++++++-- 3 files changed, 125 insertions(+), 17 deletions(-) diff --git a/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs index 0fc0a3229..b1dea7902 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/SliderRenderer.cs @@ -13,6 +13,11 @@ namespace Xamarin.Forms.Platform.Android { double _max, _min; bool _progressChangedOnce; + ColorStateList defaultprogresstintlist, defaultprogressbackgroundtintlist; + ColorFilter defaultthumbcolorfilter; + Drawable defaultthumb; + PorterDuff.Mode defaultprogresstintmode, defaultprogressbackgroundtintmode; + public SliderRenderer(Context context) : base(context) { @@ -65,8 +70,18 @@ namespace Xamarin.Forms.Platform.Android SetNativeControl(seekBar); seekBar.Max = 1000; - seekBar.SetOnSeekBarChangeListener(this); + //defaultthumbcolorfilter = Control.Thumb.ColorFilter; + //defaultprogresstintlist = Control.ProgressTintList; + //defaultprogressbackgroundtintlist = Control.ProgressBackgroundTintList; + + defaultthumbcolorfilter = seekBar.Thumb.ColorFilter; + defaultprogresstintmode = seekBar.ProgressTintMode; + defaultprogressbackgroundtintmode = seekBar.ProgressBackgroundTintMode; + defaultprogresstintlist = seekBar.ProgressTintList; + defaultprogressbackgroundtintlist = seekBar.ProgressBackgroundTintList; + defaultthumb = seekBar.Thumb; + } Slider slider = e.NewElement; @@ -126,35 +141,62 @@ namespace Xamarin.Forms.Platform.Android private void UpdateMinimumTrackColor() { - if (Element != null && Element.MinimumTrackColor != Color.Default) + if (Element != null) { - Control.ProgressDrawable.SetColorFilter(new PorterDuffColorFilter(Element.MinimumTrackColor.ToAndroid(), PorterDuff.Mode.SrcIn)); + if (Element.MinimumTrackColor == Color.Default) + { + Control.ProgressTintList = defaultprogresstintlist; + Control.ProgressTintMode = defaultprogresstintmode; + } + else + { + Control.ProgressTintList = ColorStateList.ValueOf(Element.MinimumTrackColor.ToAndroid()); + Control.ProgressTintMode = PorterDuff.Mode.SrcIn; + } } } private void UpdateMaximumTrackColor() { - if (Element != null && Element.MaximumTrackColor != Color.Default) + if (Element != null) { - Control.ForegroundTintList = ColorStateList.ValueOf(Element.MinimumTrackColor.ToAndroid()); - Control.ProgressBackgroundTintList = ColorStateList.ValueOf(Element.MaximumTrackColor.ToAndroid()); - Control.ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn; + if (Element.MaximumTrackColor == Color.Default) + { + Control.ProgressBackgroundTintList = defaultprogressbackgroundtintlist; + Control.ProgressBackgroundTintMode = defaultprogressbackgroundtintmode; + } + else + { + Control.ProgressBackgroundTintList = ColorStateList.ValueOf(Element.MaximumTrackColor.ToAndroid()); + Control.ProgressBackgroundTintMode = PorterDuff.Mode.SrcIn; + } } } private void UpdateThumbColor() { - if (Element != null && Element.ThumbColor != Color.Default) + if (Element != null) { - Control.Thumb.SetColorFilter(Element.ThumbColor.ToAndroid(), PorterDuff.Mode.SrcIn); + if (Element.ThumbColor == Color.Default) + { + Control.Thumb.SetColorFilter(defaultthumbcolorfilter); + } + else + { + Control.Thumb.SetColorFilter(Element.ThumbColor.ToAndroid(), PorterDuff.Mode.SrcIn); + } + } } private void UpdateThumbImage() { - if (Element != null && !string.IsNullOrEmpty(Element.ThumbImage)) + if (Element != null) { - Control.SetThumb(Context.GetDrawable(Element.ThumbImage)); + if (string.IsNullOrEmpty(Element.ThumbImage)) + Control.SetThumb(defaultthumb); + else + Control.SetThumb(Context.GetDrawable(Element.ThumbImage)); } } diff --git a/Xamarin.Forms.Platform.UAP/SliderRenderer.cs b/Xamarin.Forms.Platform.UAP/SliderRenderer.cs index 4a99801f6..785cafe34 100644 --- a/Xamarin.Forms.Platform.UAP/SliderRenderer.cs +++ b/Xamarin.Forms.Platform.UAP/SliderRenderer.cs @@ -2,11 +2,15 @@ using System.ComponentModel; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Media; namespace Xamarin.Forms.Platform.UWP { public class SliderRenderer : ViewRenderer { + Brush defaultforegroundcolor; + Brush defaultbackgroundcolor; + protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); @@ -24,6 +28,10 @@ namespace Xamarin.Forms.Platform.UWP slider.ValueChanged += OnNativeValueChanged; + defaultforegroundcolor = slider.Foreground; + defaultbackgroundcolor = slider.Background; + + // Even when using Center/CenterAndExpand, a Slider has an oddity where it looks // off-center in its layout by a smidge. The default templates are slightly different // between 8.1/UWP; the 8.1 rows are 17/Auto/32 and UWP are 18/Auto/18. The value of @@ -45,6 +53,37 @@ namespace Xamarin.Forms.Platform.UWP Control.StepFrequency = stepping; Control.SmallChange = stepping; UpdateFlowDirection(); + UpdateSliderColors(); + } + } + + private void UpdateSliderColors() + { + UpdateMinimumTrackColor(); + UpdateMaximumTrackColor(); + } + + private void UpdateMinimumTrackColor() + { + if (Control != null) + { + if (Element.MinimumTrackColor == Color.Default) + Control.Foreground = defaultforegroundcolor; + else + Control.Foreground = Element.MinimumTrackColor.ToBrush(); + + } + } + + private void UpdateMaximumTrackColor() + { + if (Control != null) + { + if (Element.MaximumTrackColor == Color.Default) + Control.Background = defaultbackgroundcolor; + else + Control.Background = Element.MaximumTrackColor.ToBrush(); + } } @@ -63,6 +102,11 @@ namespace Xamarin.Forms.Platform.UWP } else if (e.PropertyName == VisualElement.FlowDirectionProperty.PropertyName) UpdateFlowDirection(); + else if (e.PropertyName == Slider.MinimumTrackColorProperty.PropertyName) + UpdateMinimumTrackColor(); + else if (e.PropertyName == Slider.MaximumTrackColorProperty.PropertyName) + UpdateMaximumTrackColor(); + } protected override void UpdateBackgroundColor() diff --git a/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs b/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs index 734a93ce4..9ca5743db 100644 --- a/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs +++ b/Xamarin.Forms.Platform.iOS/Renderers/SliderRenderer.cs @@ -8,6 +8,7 @@ namespace Xamarin.Forms.Platform.iOS public class SliderRenderer : ViewRenderer { SizeF _fitSize; + UIColor defaultmintrackcolor, defaultmaxtrackcolor, defaultthumbcolor; public override SizeF SizeThatFits(SizeF size) { @@ -36,6 +37,10 @@ namespace Xamarin.Forms.Platform.iOS Control.SizeToFit(); _fitSize = Control.Bounds.Size; + defaultmintrackcolor = Control.MinimumTrackTintColor; + defaultmaxtrackcolor = Control.MaximumTrackTintColor; + defaultthumbcolor = Control.ThumbTintColor; + // except if your not running iOS 7... then it fails... if (_fitSize.Width <= 0 || _fitSize.Height <= 0) _fitSize = new SizeF(22, 22); // Per the glorious documentation known as the SDK docs @@ -66,25 +71,34 @@ namespace Xamarin.Forms.Platform.iOS private void UpdateMinimumTrackColor() { - if (Element != null && Element.MinimumTrackColor != Color.Default) + if (Element != null) { - Control.MinimumTrackTintColor = Element.MinimumTrackColor.ToUIColor(); + if (Element.MinimumTrackColor == Color.Default) + Control.MinimumTrackTintColor = defaultmintrackcolor; + else + Control.MinimumTrackTintColor = Element.MinimumTrackColor.ToUIColor(); } } private void UpdateMaximumTrackColor() { - if (Element != null && Element.MaximumTrackColor != Color.Default) + if (Element != null) { - Control.MaximumTrackTintColor = Element.MaximumTrackColor.ToUIColor(); + if (Element.MaximumTrackColor == Color.Default) + Control.MaximumTrackTintColor = defaultmaxtrackcolor; + else + Control.MaximumTrackTintColor = Element.MaximumTrackColor.ToUIColor(); } } private void UpdateThumbColor() { - if (Element != null && Element.ThumbColor != Color.Default) + if (Element != null) { - Control.ThumbTintColor = Element.ThumbColor.ToUIColor(); + if (Element.ThumbColor == Color.Default) + Control.ThumbTintColor = defaultthumbcolor; + else + Control.ThumbTintColor = Element.ThumbColor.ToUIColor(); } } @@ -109,6 +123,14 @@ namespace Xamarin.Forms.Platform.iOS slider.SetThumbImage(uiimage, UIControlState.Normal); } } + else + { + UISlider slider = Control; + if (slider != null) + { + slider.SetThumbImage(null, UIControlState.Normal); + } + } ((IVisualElementController)Element).NativeSizeChanged(); }