Switch ThumbColor (#6312)
authorAndrei Nitescu <nitescua@yahoo.com>
Thu, 4 Jul 2019 00:08:56 +0000 (03:08 +0300)
committerSamantha Houts <samhouts@users.noreply.github.com>
Thu, 4 Jul 2019 00:08:56 +0000 (17:08 -0700)
fixes #5415

Xamarin.Forms.Controls/CoreGalleryPages/SwitchCoreGalleryPage.cs
Xamarin.Forms.Core/Properties/AssemblyInfo.cs
Xamarin.Forms.Core/Switch.cs
Xamarin.Forms.CustomAttributes/TestAttributes.cs
Xamarin.Forms.Platform.Android/AppCompat/SwitchRenderer.cs
Xamarin.Forms.Platform.Android/Renderers/SwitchRenderer.cs
Xamarin.Forms.Platform.UAP/SwitchRenderer.cs
Xamarin.Forms.Platform.iOS/Renderers/SwitchRenderer.cs

index f7e53ba..ac58e02 100644 (file)
@@ -14,11 +14,11 @@ namespace Xamarin.Forms.Controls
                        get { return false; }
                }
 
-               protected override void Build (StackLayout stackLayout)
+               protected override void Build(StackLayout stackLayout)
                {
-                       base.Build (stackLayout);
+                       base.Build(stackLayout);
 
-                       var isToggledContainer = new ValueViewContainer<Switch> (Test.Switch.IsToggled, new Switch (), "IsToggled", value => value.ToString ());
+                       var isToggledContainer = new ValueViewContainer<Switch>(Test.Switch.IsToggled, new Switch(), "IsToggled", value => value.ToString());
 
                        var onColoredSwitch = new Switch() { OnColor = Color.HotPink };
 
@@ -36,8 +36,16 @@ namespace Xamarin.Forms.Controls
                        onColorContainer.ContainerLayout.Children.Add(changeOnColorButton);
                        onColorContainer.ContainerLayout.Children.Add(clearOnColorButton);
 
+                       var thumbColorSwitch = new Switch() { ThumbColor = Color.Yellow };
+                       var thumbColorContainer = new ValueViewContainer<Switch>(Test.Switch.ThumbColor, thumbColorSwitch, nameof(Switch.ThumbColor), value => value.ToString());
+                       var changeThumbColorButton = new Button { Text = "Change ThumbColor", Command = new Command(() => thumbColorSwitch.ThumbColor = Color.Azure) };
+                       var clearThumbColorButton = new Button { Text = "Clear ThumbColor", Command = new Command(() => thumbColorSwitch.ThumbColor = Color.Default) };
+                       thumbColorContainer.ContainerLayout.Children.Add(changeThumbColorButton);
+                       thumbColorContainer.ContainerLayout.Children.Add(clearThumbColorButton);
+
                        Add(isToggledContainer);
                        Add(onColorContainer);
+                       Add(thumbColorContainer);
                }
        }
 }
\ No newline at end of file
index 9d78cb8..f41f968 100644 (file)
@@ -110,6 +110,7 @@ using Xamarin.Forms.StyleSheets;
 [assembly: StyleProperty("-xf-orientation", typeof(StackLayout), nameof(StackLayout.OrientationProperty))]
 [assembly: StyleProperty("-xf-visual", typeof(VisualElement), nameof(VisualElement.VisualProperty))]
 [assembly: StyleProperty("-xf-vertical-text-alignment", typeof(Label), nameof(Label.VerticalTextAlignmentProperty))]
+[assembly: StyleProperty("-xf-thumb-color", typeof(Switch), nameof(Switch.ThumbColorProperty))]
 
 //shell
 [assembly: StyleProperty("-xf-flyout-background", typeof(Shell), nameof(Shell.FlyoutBackgroundColorProperty))]
index 9f31d47..3eee876 100644 (file)
@@ -15,12 +15,19 @@ namespace Xamarin.Forms
 
                public static readonly BindableProperty OnColorProperty = BindableProperty.Create(nameof(OnColor), typeof(Color), typeof(Switch), Color.Default);
 
+               public static readonly BindableProperty ThumbColorProperty = BindableProperty.Create(nameof(ThumbColor), typeof(Color), typeof(Switch), Color.Default);
+
                public Color OnColor
                {
                        get { return (Color)GetValue(OnColorProperty); }
                        set { SetValue(OnColorProperty, value); }
                }
 
+               public Color ThumbColor
+               {
+                       get { return (Color)GetValue(ThumbColorProperty); }
+                       set { SetValue(ThumbColorProperty, value); }
+               }
 
                readonly Lazy<PlatformConfigurationRegistry<Switch>> _platformConfigurationRegistry;
 
index f013a81..c609b42 100644 (file)
@@ -715,7 +715,8 @@ namespace Xamarin.Forms.CustomAttributes
                public enum Switch
                {
                        IsToggled,
-                       OnColor
+                       OnColor,
+                       ThumbColor
                }
 
                public enum CheckBox
index 1d8d64b..b1f089d 100644 (file)
@@ -14,6 +14,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
                bool _disposed;
                Drawable _defaultTrackDrawable;
                string _defaultContentDescription;
+               ColorFilter _defaultThumbColorFilter;
 
                public SwitchRenderer(Context context) : base(context)
                {
@@ -90,6 +91,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
                                        aswitch.SetOnCheckedChangeListener(this);
                                        SetNativeControl(aswitch);
                                        _defaultTrackDrawable = aswitch.TrackDrawable;
+                                       _defaultThumbColorFilter = Control.ThumbDrawable.ColorFilter;
                                }
                                else
                                        UpdateEnabled(); // Normally set by SetNativeControl, but not when the Control is reused.
@@ -97,6 +99,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
                                e.NewElement.Toggled += HandleToggled;
                                Control.Checked = e.NewElement.IsToggled;
                                UpdateOnColor();
+                               UpdateThumbColor();
                        }
                }
 
@@ -106,6 +109,8 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
 
                        if (e.PropertyName == Switch.OnColorProperty.PropertyName)
                                UpdateOnColor();
+                       else if (e.PropertyName == Slider.ThumbColorProperty.PropertyName)
+                               UpdateThumbColor();
                }
 
                void UpdateOnColor()
@@ -130,6 +135,18 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
                        }
                }
 
+               void UpdateThumbColor()
+               {
+                       if (Element == null)
+                               return;
+
+                       Color thumbColor = Element.ThumbColor;
+                       if (thumbColor.IsDefault)
+                               Control.ThumbDrawable.SetColorFilter(_defaultThumbColorFilter);
+                       else
+                               Control.ThumbDrawable.SetColorFilter(thumbColor.ToAndroid(), PorterDuff.Mode.SrcIn);
+               }
+
                void HandleToggled(object sender, EventArgs e)
                {
                        Control.Checked = Element.IsToggled;
index 6ef8100..ba41273 100644 (file)
@@ -12,6 +12,7 @@ namespace Xamarin.Forms.Platform.Android
        public class SwitchRenderer : ViewRenderer<Switch, ASwitch>, CompoundButton.IOnCheckedChangeListener
        {
                Drawable _defaultTrackDrawable;
+               ColorFilter _defaultThumbColorFilter;
 
                public SwitchRenderer(Context context) : base(context)
                {
@@ -83,6 +84,7 @@ namespace Xamarin.Forms.Platform.Android
                                        aswitch.SetOnCheckedChangeListener(this);
                                        SetNativeControl(aswitch);
                                        _defaultTrackDrawable = Control.TrackDrawable;
+                                       _defaultThumbColorFilter = Control.ThumbDrawable.ColorFilter;
                                }
                                else
                                {
@@ -92,6 +94,7 @@ namespace Xamarin.Forms.Platform.Android
                                e.NewElement.Toggled += HandleToggled;
                                Control.Checked = e.NewElement.IsToggled;
                                UpdateOnColor();
+                               UpdateThumbColor();
                        }
                }
 
@@ -101,6 +104,8 @@ namespace Xamarin.Forms.Platform.Android
 
                        if (e.PropertyName == Switch.OnColorProperty.PropertyName)
                                UpdateOnColor();
+                       else if (e.PropertyName == Slider.ThumbColorProperty.PropertyName)
+                               UpdateThumbColor();
                }
 
                void UpdateOnColor()
@@ -128,6 +133,18 @@ namespace Xamarin.Forms.Platform.Android
                        }
                }
 
+               void UpdateThumbColor()
+               {
+                       if (Element == null)
+                               return;
+
+                       Color thumbColor = Element.ThumbColor;
+                       if (thumbColor.IsDefault)
+                               Control.ThumbDrawable.SetColorFilter(_defaultThumbColorFilter);
+                       else
+                               Control.ThumbDrawable.SetColorFilter(thumbColor.ToAndroid(), PorterDuff.Mode.SrcIn);
+               }
+
                void HandleToggled(object sender, EventArgs e)
                {
                        Control.Checked = Element.IsToggled;
index 7aa41d1..297e6a5 100644 (file)
@@ -12,6 +12,7 @@ namespace Xamarin.Forms.Platform.UWP
        {
                Brush _originalOnHoverColor;
                Brush _originalOnColorBrush;
+               Brush _originalThumbOnBrush;
 
                protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
                {
@@ -49,6 +50,8 @@ namespace Xamarin.Forms.Platform.UWP
                        }
                        else if (e.PropertyName == Switch.OnColorProperty.PropertyName)
                                UpdateOnColor();
+                       else if (e.PropertyName == Switch.ThumbColorProperty.PropertyName)
+                               UpdateThumbColor();
                }
 
                protected override bool PreventGestureBubbling { get; set; } = true;
@@ -56,6 +59,7 @@ namespace Xamarin.Forms.Platform.UWP
                void OnControlLoaded(object sender, RoutedEventArgs e)
                {
                        UpdateOnColor();
+                       UpdateThumbColor();
                        Control.Loaded -= OnControlLoaded;
                }
 
@@ -120,5 +124,43 @@ namespace Xamarin.Forms.Platform.UWP
                        else
                                rect.Fill = _originalOnColorBrush;
                }
+
+               void UpdateThumbColor()
+               {
+                       if (Control == null)
+                               return;
+
+                       var grid = Control.GetFirstDescendant<Windows.UI.Xaml.Controls.Grid>();
+                       if (grid == null)
+                               return;
+
+                       ObjectKeyFrame frame = Windows.UI.Xaml.VisualStateManager.GetVisualStateGroups(grid)
+                               .First(g => g.Name == "CommonStates")
+                               .States.First(s => s.Name == "PointerOver")
+                               .Storyboard.Children.OfType<ObjectAnimationUsingKeyFrames>().First(
+                                       t => Storyboard.GetTargetName(t) == "SwitchKnobOn" &&
+                                                Storyboard.GetTargetProperty(t) == "Fill")
+                               .KeyFrames.First();
+
+                       if (_originalThumbOnBrush == null)
+                               _originalThumbOnBrush = (Brush)frame.Value;
+
+                       if (!Element.ThumbColor.IsDefault)
+                               frame.Value = new SolidColorBrush(Element.ThumbColor.ToWindowsColor())
+                               {
+                                       Opacity = _originalThumbOnBrush.Opacity
+                               };
+                       else
+                               frame.Value = _originalThumbOnBrush;
+
+                       var thumb = (Ellipse)grid.FindName("SwitchKnobOn");
+                       if (_originalThumbOnBrush == null)
+                               _originalThumbOnBrush = thumb.Fill;
+
+                       if (!Element.ThumbColor.IsDefault)
+                               thumb.Fill = new SolidColorBrush(Element.ThumbColor.ToWindowsColor());
+                       else
+                               thumb.Fill = _originalThumbOnBrush;
+               }
        }
 }
index 3123ced..92ff1d6 100644 (file)
@@ -8,6 +8,8 @@ namespace Xamarin.Forms.Platform.iOS
        public class SwitchRenderer : ViewRenderer<Switch, UISwitch>
        {
                UIColor _defaultOnColor;
+               UIColor _defaultThumbColor;
+
                protected override void Dispose(bool disposing)
                {
                        if (disposing)
@@ -30,9 +32,11 @@ namespace Xamarin.Forms.Platform.iOS
                                }
 
                                _defaultOnColor = UISwitch.Appearance.OnTintColor;
+                               _defaultThumbColor = UISwitch.Appearance.ThumbTintColor;
                                Control.On = Element.IsToggled;
                                e.NewElement.Toggled += OnElementToggled;
                                UpdateOnColor();
+                               UpdateThumbColor();
                        }
 
                        base.OnElementChanged(e);
@@ -49,6 +53,15 @@ namespace Xamarin.Forms.Platform.iOS
                        }
                }
 
+               void UpdateThumbColor()
+               {
+                       if (Element == null)
+                               return;
+
+                       Color thumbColor = Element.ThumbColor;
+                       Control.ThumbTintColor = thumbColor.IsDefault ? _defaultThumbColor : thumbColor.ToUIColor();
+               }
+
                void OnControlValueChanged(object sender, EventArgs e)
                {
                        ((IElementController)Element).SetValueFromRenderer(Switch.IsToggledProperty, Control.On);
@@ -65,6 +78,8 @@ namespace Xamarin.Forms.Platform.iOS
 
                        if (e.PropertyName == Switch.OnColorProperty.PropertyName)
                                UpdateOnColor();
+                       if (e.PropertyName == Switch.ThumbColorProperty.PropertyName)
+                               UpdateThumbColor();
                }
        }
 }
\ No newline at end of file