Skip to content

Commit

Permalink
Implement TitleColor property in PickerHandlers
Browse files Browse the repository at this point in the history
  • Loading branch information
jsuarezruiz committed Apr 13, 2021
1 parent fc90bf6 commit 471c785
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 11 deletions.
4 changes: 1 addition & 3 deletions src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ void SetupMauiLayout()
verticalStack.Add(new Editor { Text = "Lorem ipsum dolor sit amet", FontSize = 10, FontFamily = "dokdo_regular" });
verticalStack.Add(new Editor { Text = "ReadOnly Editor", IsReadOnly = true });


var entry = new Entry();
entry.TextChanged += (sender, e) =>
{
Expand Down Expand Up @@ -161,7 +160,6 @@ void SetupMauiLayout()
placeholderSearchBar.Placeholder = "Placeholder";
verticalStack.Add(placeholderSearchBar);


var monkeyList = new List<string>
{
"Baboon",
Expand All @@ -173,7 +171,7 @@ void SetupMauiLayout()
"Japanese Macaque"
};

var picker = new Picker { Title = "Select a monkey", FontFamily = "Dokdo" };
var picker = new Picker { Title = "Select a monkey", TitleColor = Color.Red, FontFamily = "Dokdo" };

picker.ItemsSource = monkeyList;
verticalStack.Add(picker);
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Core/IPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public interface IPicker : IView, ITextStyle
/// </summary>
string Title { get; }

/// <summary>
/// Gets the color for the Picker title.
/// </summary>
Color TitleColor { get; }

/// <summary>
/// Gets or sets the internal list of items to template and display.
/// </summary>
Expand Down
34 changes: 30 additions & 4 deletions src/Core/src/Handlers/Picker/PickerHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Collections.Specialized;
using System.Linq;
using Android.App;
using Microsoft.Extensions.DependencyInjection;
using Android.Content.Res;
using Android.Text;
using Android.Text.Style;
using AResource = Android.Resource;

namespace Microsoft.Maui.Handlers
Expand All @@ -11,6 +13,8 @@ public partial class PickerHandler : ViewHandler<IPicker, MauiPicker>
{
AlertDialog? _dialog;

static ColorStateList? DefaultTitleColors { get; set; }

protected override MauiPicker CreateNativeView() =>
new MauiPicker(Context);

Expand All @@ -35,11 +39,24 @@ protected override void DisconnectHandler(MauiPicker nativeView)

base.DisconnectHandler(nativeView);
}

protected override void SetupDefaults(MauiPicker nativeView)
{
base.SetupDefaults(nativeView);

DefaultTitleColors = nativeView.HintTextColors;
}

public static void MapTitle(PickerHandler handler, IPicker picker)
{
handler.NativeView?.UpdateTitle(picker);
}

public static void MapTitleColor(PickerHandler handler, IPicker picker)
{
handler.NativeView?.UpdateTitleColor(picker, DefaultTitleColors);
}

public static void MapSelectedIndex(PickerHandler handler, IPicker picker)
{
handler.NativeView?.UpdateSelectedIndex(picker);
Expand Down Expand Up @@ -86,16 +103,25 @@ void OnClick(object? sender, EventArgs e)
{
using (var builder = new AlertDialog.Builder(Context))
{
builder.SetTitle(VirtualView.Title ?? string.Empty);
if (VirtualView.TitleColor == Color.Default)
{
builder.SetTitle(VirtualView.Title ?? string.Empty);
}
else
{
var title = new SpannableString(VirtualView.Title ?? string.Empty);
title.SetSpan(new ForegroundColorSpan(VirtualView.TitleColor.ToNative()), 0, title.Length(), SpanTypes.ExclusiveExclusive);
builder.SetTitle(title);
}

string[] items = VirtualView.Items.ToArray();

builder.SetItems(items, (EventHandler<Android.Content.DialogClickEventArgs>)((s, e) =>
builder.SetItems(items, (s, e) =>
{
var selectedIndex = e.Which;
VirtualView.SelectedIndex = selectedIndex;
base.NativeView?.UpdatePicker(VirtualView);
}));
});

builder.SetNegativeButton(AResource.String.Cancel, (o, args) => { });

Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Picker/PickerHandler.Standard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public partial class PickerHandler : ViewHandler<IPicker, object>
protected override object CreateNativeView() => throw new NotImplementedException();

public static void MapTitle(PickerHandler handler, IPicker view) { }
public static void MapTitleColor(PickerHandler handler, IPicker view) { }
public static void MapSelectedIndex(PickerHandler handler, IPicker view) { }
public static void MapCharacterSpacing(PickerHandler handler, IPicker view) { }
public static void MapFont(PickerHandler handler, IPicker view) { }
Expand Down
3 changes: 3 additions & 0 deletions src/Core/src/Handlers/Picker/PickerHandler.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public partial class PickerHandler : ViewHandler<IPicker, ComboBox>
[MissingMapper]
public static void MapTitle(PickerHandler handler, IPicker view) { }

[MissingMapper]
public static void MapTitleColor(PickerHandler handler, IPicker view) { }

[MissingMapper]
public static void MapSelectedIndex(PickerHandler handler, IPicker view) { }

Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Picker/PickerHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public partial class PickerHandler
[nameof(IPicker.SelectedIndex)] = MapSelectedIndex,
[nameof(IPicker.TextColor)] = MapTextColor,
[nameof(IPicker.Title)] = MapTitle,
[nameof(IPicker.TitleColor)] = MapTitleColor
};

public PickerHandler() : base(PickerMapper)
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Handlers/Picker/PickerHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ public static void MapTitle(PickerHandler handler, IPicker picker)
handler.NativeView?.UpdateTitle(picker);
}

public static void MapTitleColor(PickerHandler handler, IPicker picker)
{
handler.NativeView?.UpdateTitleColor(picker);
}

public static void MapSelectedIndex(PickerHandler handler, IPicker picker)
{
handler.NativeView?.UpdateSelectedIndex(picker);
Expand Down
30 changes: 29 additions & 1 deletion src/Core/src/Platform/Android/PickerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
namespace Microsoft.Maui
using Android.Content.Res;

namespace Microsoft.Maui
{
public static class PickerExtensions
{
static readonly int[][] ColorStates =
{
new[] { Android.Resource.Attribute.StateEnabled },
new[] { -Android.Resource.Attribute.StateEnabled }
};

public static void UpdateTitle(this MauiPicker nativePicker, IPicker picker) =>
UpdatePicker(nativePicker, picker);

public static void UpdateTitleColor(this MauiPicker nativePicker, IPicker picker, ColorStateList? defaultColor)
{
var titleColor = picker.TitleColor;

if (titleColor.IsDefault)
{
nativePicker.SetHintTextColor(defaultColor);
}
else
{
var androidColor = titleColor.ToNative();

if (!nativePicker.TextColors.IsOneColor(ColorStates, androidColor))
{
var acolor = androidColor.ToArgb();
nativePicker.SetHintTextColor(new ColorStateList(ColorStates, new[] { acolor, acolor }));
}
}
}

public static void UpdateSelectedIndex(this MauiPicker nativePicker, IPicker picker) =>
UpdatePicker(nativePicker, picker);

Expand Down
21 changes: 21 additions & 0 deletions src/Core/src/Platform/iOS/PickerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Foundation;
using Microsoft.Maui.Handlers;

namespace Microsoft.Maui
Expand All @@ -8,9 +9,29 @@ public static class PickerExtensions
public static void UpdateTitle(this MauiPicker nativePicker, IPicker picker) =>
nativePicker.UpdatePicker(picker);

public static void UpdateTitleColor(this MauiPicker nativePicker, IPicker picker) =>
nativePicker.SetTitleColor(picker);

public static void UpdateSelectedIndex(this MauiPicker nativePicker, IPicker picker) =>
nativePicker.SetSelectedIndex(picker, picker.SelectedIndex);

internal static void SetTitleColor(this MauiPicker nativePicker, IPicker picker)
{
var title = picker.Title;

if (string.IsNullOrEmpty(title))
return;

var titleColor = picker.TitleColor;

nativePicker.UpdateAttributedPlaceholder(new NSAttributedString(title, null, titleColor.ToNative()));
}

internal static void UpdateAttributedPlaceholder(this MauiPicker nativePicker, NSAttributedString nsAttributedString)
{
nativePicker.AttributedPlaceholder = nsAttributedString;
}

internal static void UpdatePicker(this MauiPicker nativePicker, IPicker picker)
{
var selectedIndex = picker.SelectedIndex;
Expand Down
19 changes: 18 additions & 1 deletion src/Core/tests/DeviceTests/AssertionExtensions.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Threading.Tasks;
using CoreGraphics;
using Foundation;
using Microsoft.Maui.Essentials;
using UIKit;
using Xunit;
using Xunit.Sdk;
Expand Down Expand Up @@ -224,5 +223,23 @@ public static void AssertHasUnderline(this NSAttributedString attributedString)
throw new XunitException("Label does not have the UnderlineStyle attribute");
}
}

public static UIColor GetForegroundColor(this NSAttributedString text)
{
if (text == null)
return UIColor.Clear;

var value = text.GetAttribute(UIStringAttributeKey.ForegroundColor, 0, out var range);

if (value == null)
return UIColor.Clear;

Assert.Equal(0, range.Location);
Assert.Equal(text.Length, range.Length);

var kerning = Assert.IsType<UIColor>(value);

return kerning;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using Xunit;
using AColor = Android.Graphics.Color;

namespace Microsoft.Maui.DeviceTests
{
Expand All @@ -19,6 +20,18 @@ public async Task TitleInitializesCorrectly()
await ValidatePropertyInitValue(picker, () => picker.Title, GetNativeTitle, picker.Title);
}

[Fact(DisplayName = "Title Color Initializes Correctly")]
public async Task TitleColorInitializesCorrectly()
{
var picker = new PickerStub
{
Title = "Select an Item",
TitleColor = Color.CadetBlue
};

await ValidatePropertyInitValue(picker, () => picker.TitleColor, GetNativeTitleColor, picker.TitleColor);
}

[Fact(DisplayName = "CharacterSpacing Initializes Correctly")]
public async Task CharacterSpacingInitializesCorrectly()
{
Expand Down Expand Up @@ -56,7 +69,7 @@ public async Task CharacterSpacingInitializesCorrectly()
}

MauiPicker GetNativePicker(PickerHandler pickerHandler) =>
(MauiPicker)pickerHandler.NativeView;
pickerHandler.NativeView;

string GetNativeTitle(PickerHandler pickerHandler) =>
GetNativePicker(pickerHandler).Hint;
Expand Down Expand Up @@ -84,5 +97,12 @@ bool GetNativeIsBold(PickerHandler pickerHandler) =>

bool GetNativeIsItalic(PickerHandler pickerHandler) =>
GetNativePicker(pickerHandler).Typeface.IsItalic;

Color GetNativeTitleColor(PickerHandler pickerHandler)
{
var currentTextColorInt = GetNativePicker(pickerHandler).CurrentTextColor;
var currentTextColor = new AColor(currentTextColorInt);
return currentTextColor.ToColor();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Handlers;
using UIKit;
using Xunit;
Expand All @@ -7,8 +8,34 @@ namespace Microsoft.Maui.DeviceTests
{
public partial class PickerHandlerTests
{
[Fact(DisplayName = "Title Color Initializes Correctly")]
public async Task TitleColorInitializesCorrectly()
{
var xplatTitleColor = Color.CadetBlue;

var picker = new PickerStub
{
Title = "Select an Item",
TitleColor = xplatTitleColor
};

var expectedValue = xplatTitleColor.ToNative();

var values = await GetValueAsync(picker, (handler) =>
{
return new
{
ViewValue = picker.TitleColor,
NativeViewValue = GetNativeTitleColor(handler)
};
});

Assert.Equal(xplatTitleColor, values.ViewValue);
Assert.Equal(expectedValue, values.NativeViewValue);
}

MauiPicker GetNativePicker(PickerHandler pickerHandler) =>
(MauiPicker)pickerHandler.NativeView;
pickerHandler.NativeView;

string GetNativeTitle(PickerHandler pickerHandler) =>
GetNativePicker(pickerHandler).Text;
Expand Down Expand Up @@ -46,5 +73,11 @@ bool GetNativeIsBold(PickerHandler pickerHandler) =>

bool GetNativeIsItalic(PickerHandler pickerHandler) =>
GetNativePicker(pickerHandler).Font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic);

UIColor GetNativeTitleColor(PickerHandler pickerHandler)
{
var mauiPicker = GetNativePicker(pickerHandler);
return mauiPicker.AttributedPlaceholder.GetForegroundColor();
}
}
}
2 changes: 2 additions & 0 deletions src/Core/tests/DeviceTests/Stubs/PickerStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public partial class PickerStub : StubBase, IPicker
{
public string Title { get; set; }

public Color TitleColor { get; set; }

public IList<string> Items { get; set; } = new List<string>();

public IList ItemsSource { get; set; }
Expand Down

0 comments on commit 471c785

Please sign in to comment.