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

Implement HorizontalTextAlignment property in EntryHandlers #524

Merged
merged 2 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ protected virtual void UpdateImeOptions()
EditText.ImeOptions = _currentInputImeFlag;
}

[PortHandler]
void UpdateHorizontalTextAlignment()
{
EditText.UpdateTextAlignment(Element.HorizontalTextAlignment, Element.VerticalTextAlignment);
Expand Down
1 change: 1 addition & 0 deletions src/Compatibility/Core/src/iOS/Renderers/EntryRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ protected virtual bool OnShouldReturn(UITextField view)
return false;
}

[PortHandler]
void UpdateHorizontalTextAlignment()
{
Control.TextAlignment = Element.HorizontalTextAlignment.ToNativeTextAlignment(((IVisualElementController)Element).EffectiveFlowDirection);
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Core/IEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Represents a View that is used for single-line text input.
/// </summary>
public interface IEntry : IView, IText, ITextInput
public interface IEntry : IView, IText, ITextInput, ITextAlignment
{
/// <summary>
/// Gets a value that indicates if the entry should visually obscure typed text.
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Handlers/Entry/EntryHandler.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public static void MapIsPassword(EntryHandler handler, IEntry entry)
handler.TypedNativeView?.UpdateIsPassword(entry);
}

public static void MapHorizontalTextAlignment(EntryHandler handler, IEntry entry)
{
handler.TypedNativeView?.UpdateHorizontalTextAlignment(entry);
}

public static void MapIsTextPredictionEnabled(EntryHandler handler, IEntry entry)
{
handler.TypedNativeView?.UpdateIsTextPredictionEnabled(entry);
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Entry/EntryHandler.Standard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public partial class EntryHandler : AbstractViewHandler<IEntry, object>
public static void MapText(IViewHandler handler, IEntry entry) { }
public static void MapTextColor(IViewHandler handler, IEntry entry) { }
public static void MapIsPassword(IViewHandler handler, IEntry entry) { }
public static void MapHorizontalTextAlignment(IViewHandler handler, IEntry entry) { }
public static void MapIsTextPredictionEnabled(IViewHandler handler, IEntry entry) { }
public static void MapPlaceholder(IViewHandler handler, IEntry entry) { }
public static void MapIsReadOnly(IViewHandler handler, IEntry entry) { }
Expand Down
1 change: 1 addition & 0 deletions src/Core/src/Handlers/Entry/EntryHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public partial class EntryHandler
[nameof(IEntry.Text)] = MapText,
[nameof(IEntry.TextColor)] = MapTextColor,
[nameof(IEntry.IsPassword)] = MapIsPassword,
[nameof(IEntry.HorizontalTextAlignment)] = MapHorizontalTextAlignment,
[nameof(IEntry.IsTextPredictionEnabled)] = MapIsTextPredictionEnabled,
[nameof(IEntry.Placeholder)] = MapPlaceholder,
[nameof(IEntry.IsReadOnly)] = MapIsReadOnly,
Expand Down
5 changes: 5 additions & 0 deletions src/Core/src/Handlers/Entry/EntryHandler.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public static void MapIsPassword(EntryHandler handler, IEntry entry)
handler.TypedNativeView?.UpdateIsPassword(entry);
}

public static void MapHorizontalTextAlignment(EntryHandler handler, IEntry entry)
{
handler.TypedNativeView?.UpdateHorizontalTextAlignment(entry);
}

public static void MapIsTextPredictionEnabled(EntryHandler handler, IEntry entry)
{
handler.TypedNativeView?.UpdateIsTextPredictionEnabled(entry);
Expand Down
6 changes: 2 additions & 4 deletions src/Core/src/Platform/Android/ContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
using Android.Views.InputMethods;
using AndroidX.AppCompat.App;
using AndroidX.Fragment.App;
using Microsoft.Maui;
using AActivity = Android.App.Activity;
using AApplicationInfoFlags = Android.Content.PM.ApplicationInfoFlags;
using AAttribute = Android.Resource.Attribute;
using AColor = Android.Graphics.Color;
using AFragmentManager = AndroidX.Fragment.App.FragmentManager;
using Size = Microsoft.Maui.Size;
using AApplicationInfoFlags = Android.Content.PM.ApplicationInfoFlags;
using AAttribute = Android.Resource.Attribute;

namespace Microsoft.Maui
{
Expand Down
42 changes: 24 additions & 18 deletions src/Core/src/Platform/Android/EntryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ namespace Microsoft.Maui
{
public static class EntryExtensions
{
static readonly int[][] ColorStates = {
new[] { global::Android.Resource.Attribute.StateEnabled },
new[] { -global::Android.Resource.Attribute.StateEnabled }
static readonly int[][] ColorStates =
{
new[] { Android.Resource.Attribute.StateEnabled },
new[] { -Android.Resource.Attribute.StateEnabled }
};

public static void UpdateText(this AppCompatEditText editText, IEntry entry)
Expand Down Expand Up @@ -45,22 +46,9 @@ public static void UpdateIsPassword(this AppCompatEditText editText, IEntry entr
editText.SetInputType(entry);
}

internal static void SetInputType(this AppCompatEditText editText, IEntry entry)
public static void UpdateHorizontalTextAlignment(this AppCompatEditText editText, IEntry entry)
{
editText.InputType = InputTypes.ClassText;
editText.InputType |= InputTypes.TextFlagMultiLine;

if (entry.IsPassword && ((editText.InputType & InputTypes.ClassText) == InputTypes.ClassText))
editText.InputType |= InputTypes.TextVariationPassword;

if (entry.IsPassword && ((editText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber))
editText.InputType |= InputTypes.NumberVariationPassword;

if (!entry.IsTextPredictionEnabled && ((editText.InputType & InputTypes.TextFlagNoSuggestions) != InputTypes.TextFlagNoSuggestions))
editText.InputType |= InputTypes.TextFlagNoSuggestions;

if (entry.IsReadOnly)
editText.InputType = InputTypes.Null;
editText.UpdateHorizontalAlignment(entry.HorizontalTextAlignment, editText.Context != null && editText.Context.HasRtlSupport());
}

public static void UpdateIsTextPredictionEnabled(this AppCompatEditText editText, IEntry entry)
Expand Down Expand Up @@ -96,5 +84,23 @@ public static void UpdateFont(this AppCompatEditText editText, IEntry entry, IFo
var sp = fontManager.GetScaledPixel(font);
editText.SetTextSize(ComplexUnitType.Sp, sp);
}

internal static void SetInputType(this AppCompatEditText editText, IEntry entry)
{
editText.InputType = InputTypes.ClassText;
editText.InputType |= InputTypes.TextFlagMultiLine;

if (entry.IsPassword && ((editText.InputType & InputTypes.ClassText) == InputTypes.ClassText))
editText.InputType |= InputTypes.TextVariationPassword;

if (entry.IsPassword && ((editText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber))
editText.InputType |= InputTypes.NumberVariationPassword;

if (!entry.IsTextPredictionEnabled && ((editText.InputType & InputTypes.TextFlagNoSuggestions) != InputTypes.TextFlagNoSuggestions))
editText.InputType |= InputTypes.TextFlagNoSuggestions;

if (entry.IsReadOnly)
editText.InputType = InputTypes.Null;
}
}
}
34 changes: 34 additions & 0 deletions src/Core/src/Platform/Android/TextAlignmentExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Android.Widget;
using AGravityFlags = Android.Views.GravityFlags;

namespace Microsoft.Maui
{
public static class TextAlignmentExtensions
{
internal static void UpdateHorizontalAlignment(this EditText view, TextAlignment alignment, bool hasRtlSupport, AGravityFlags orMask = AGravityFlags.NoGravity)
{
if (!hasRtlSupport)
view.Gravity = alignment.ToHorizontalGravityFlags() | orMask;
else
view.TextAlignment = alignment.ToTextAlignment();
}

public static void UpdateVerticalAlignment(this EditText view, TextAlignment alignment, AGravityFlags orMask = AGravityFlags.NoGravity)
{
view.Gravity = alignment.ToVerticalGravityFlags() | orMask;
}

public static void UpdateTextAlignment(this EditText view, TextAlignment horizontal, TextAlignment vertical)
{
if (view.Context != null && !view.Context.HasRtlSupport())
{
view.Gravity = vertical.ToVerticalGravityFlags() | horizontal.ToHorizontalGravityFlags();
}
else
{
view.TextAlignment = horizontal.ToTextAlignment();
view.Gravity = vertical.ToVerticalGravityFlags();
}
}
}
}
8 changes: 8 additions & 0 deletions src/Core/src/Platform/iOS/EntryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public static void UpdateIsPassword(this UITextField textField, IEntry entry)
textField.SecureTextEntry = entry.IsPassword;
}

public static void UpdateHorizontalTextAlignment(this UITextField textField, IEntry entry)
{
// We don't have a FlowDirection yet, so there's nothing to pass in here.
// TODO: Update this when FlowDirection is available
// (or update the extension to take an ILabel instead of an alignment and work it out from there)
textField.TextAlignment = entry.HorizontalTextAlignment.ToNative(true);
}

public static void UpdateIsTextPredictionEnabled(this UITextField textField, IEntry entry)
{
if (entry.IsTextPredictionEnabled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@ public async Task FontFamilyInitializesCorrectly(string family)
Assert.NotEqual(fontManager.DefaultTypeface, nativeEntry.Typeface);
}

[Fact(DisplayName = "Horizontal TextAlignment Initializes Correctly")]
public async Task HorizontalTextAlignmentInitializesCorrectly()
{
var xplatHorizontalTextAlignment = TextAlignment.End;

var entry = new EntryStub()
{
Text = "Test",
HorizontalTextAlignment = xplatHorizontalTextAlignment
};

Android.Views.TextAlignment expectedValue = Android.Views.TextAlignment.ViewEnd;

var values = await GetValueAsync(entry, (handler) =>
{
return new
{
ViewValue = entry.HorizontalTextAlignment,
NativeViewValue = GetNativeTextAlignment(handler)
};
});

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

AppCompatEditText GetNativeEntry(EntryHandler entryHandler) =>
(AppCompatEditText)entryHandler.View;

Expand Down Expand Up @@ -84,5 +110,8 @@ bool GetNativeIsBold(EntryHandler entryHandler) =>

bool GetNativeIsItalic(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).Typeface.IsItalic;

Android.Views.TextAlignment GetNativeTextAlignment(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).TextAlignment;
}
}
29 changes: 29 additions & 0 deletions src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ public async Task FontFamilyInitializesCorrectly(string family)
Assert.NotEqual(fontManager.DefaultFont.FamilyName, nativeFont.FamilyName);
}

[Fact(DisplayName = "Horizontal TextAlignment Initializes Correctly")]
public async Task HorizontalTextAlignmentInitializesCorrectly()
{
var xplatHorizontalTextAlignment = TextAlignment.End;

var entry = new EntryStub()
{
Text = "Test",
HorizontalTextAlignment = xplatHorizontalTextAlignment
};

UITextAlignment expectedValue = UITextAlignment.Right;

var values = await GetValueAsync(entry, (handler) =>
{
return new
{
ViewValue = entry.HorizontalTextAlignment,
NativeViewValue = GetNativeTextAlignment(handler)
};
});

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

UITextField GetNativeEntry(EntryHandler entryHandler) =>
(UITextField)entryHandler.View;

Expand Down Expand Up @@ -66,5 +92,8 @@ bool GetNativeIsBold(EntryHandler entryHandler) =>

bool GetNativeIsItalic(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).Font.FontDescriptor.SymbolicTraits.HasFlag(UIFontDescriptorSymbolicTraits.Italic);

UITextAlignment GetNativeTextAlignment(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).TextAlignment;
}
}
6 changes: 4 additions & 2 deletions src/Core/tests/DeviceTests/Stubs/EntryStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ public string Text

public bool IsReadOnly { get; set; }

public Font Font { get; set; }

public TextAlignment HorizontalTextAlignment { get; set; }

public event EventHandler<StubPropertyChangedEventArgs<string>> TextChanged;

void OnTextChanged(string oldValue, string newValue) =>
TextChanged?.Invoke(this, new StubPropertyChangedEventArgs<string>(oldValue, newValue));

public Font Font { get; set; }
}
}