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 IsReadOnly in IEntry Handlers #437

Merged
merged 12 commits into from
Mar 10, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ void SetSelectionLengthFromRenderer(int selectionLength)
}
}

[PortHandler]
protected virtual void UpdateIsReadOnly()
{
bool isReadOnly = !Element.IsReadOnly;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ void SetSelectionLengthFromRenderer(int selectionLength)
}
}

[PortHandler]
void UpdateIsReadOnly()
{
Control.UserInteractionEnabled = !Element.IsReadOnly;
Expand Down
1 change: 1 addition & 0 deletions src/Controls/samples/Controls.Sample/Pages/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void SetupMauiLayout()
verticalStack.Add(new Entry { Text = "Entry", TextColor = Color.DarkRed });
verticalStack.Add(new Entry { IsPassword = true, TextColor = Color.Black });
verticalStack.Add(new Entry { IsTextPredictionEnabled = false });
verticalStack.Add(new Entry { Text = "This should be read only property", IsReadOnly = true });

verticalStack.Add(new Slider());

Expand Down
2 changes: 2 additions & 0 deletions src/Core/src/Core/ITextInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ public interface ITextInput : IText
/// Gets the maximum allowed length of input.
/// </summary>
new string Text { get; set; }

bool IsReadOnly { get; }
}
}
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 @@ -53,6 +53,11 @@ public static void MapIsTextPredictionEnabled(EntryHandler handler, IEntry entry
handler.TypedNativeView?.UpdateIsTextPredictionEnabled(entry);
}

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

void OnTextChanged(string? text)
{
if (VirtualView == null || TypedNativeView == null)
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 @@ -10,5 +10,6 @@ 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 MapIsTextPredictionEnabled(IViewHandler handler, IEntry entry) { }
public static void MapIsReadOnly(IViewHandler handler, IEntry entry) { }
}
}
3 changes: 2 additions & 1 deletion src/Core/src/Handlers/Entry/EntryHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public partial class EntryHandler
[nameof(IEntry.Text)] = MapText,
[nameof(IEntry.TextColor)] = MapTextColor,
[nameof(IEntry.IsPassword)] = MapIsPassword,
[nameof(IEntry.IsTextPredictionEnabled)] = MapIsTextPredictionEnabled
[nameof(IEntry.IsTextPredictionEnabled)] = MapIsTextPredictionEnabled,
[nameof(IEntry.IsReadOnly)] = MapIsReadOnly
};

public EntryHandler() : base(EntryMapper)
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 @@ -61,6 +61,11 @@ public static void MapIsTextPredictionEnabled(EntryHandler handler, IEntry entry
handler.TypedNativeView?.UpdateIsTextPredictionEnabled(entry);
}

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

void OnEditingChanged(object? sender, EventArgs e) => OnTextChanged();

void OnEditingEnded(object? sender, EventArgs e) => OnTextChanged();
Expand Down
13 changes: 13 additions & 0 deletions src/Core/src/Platform/Android/EntryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,24 @@ internal static void SetInputType(this EditText editText, IEntry entry)

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

if (entry.IsReadOnly)
editText.InputType = InputTypes.Null;
}

public static void UpdateIsTextPredictionEnabled(this EditText editText, IEntry entry)
{
editText.SetInputType(entry);
}

public static void UpdateIsReadOnly(this EditText editText, IEntry entry)
{
bool isEditable = !entry.IsReadOnly;

editText.SetInputType(entry);

editText.FocusableInTouchMode = isEditable;
editText.Focusable = isEditable;
}
}
}
5 changes: 5 additions & 0 deletions src/Core/src/Platform/iOS/EntryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,10 @@ public static void UpdateIsTextPredictionEnabled(this UITextField textField, IEn
else
textField.AutocorrectionType = UITextAutocorrectionType.No;
}

public static void UpdateIsReadOnly(this UITextField textField, IEntry entry)
{
textField.UserInteractionEnabled = !entry.IsReadOnly;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,12 @@ bool GetNativeIsPassword(EntryHandler entryHandler)

bool GetNativeIsTextPredictionEnabled(EntryHandler entryHandler) =>
!GetNativeEntry(entryHandler).InputType.HasFlag(InputTypes.TextFlagNoSuggestions);

bool GetNativeIsReadOnly(EntryHandler entryHandler)
{
var editText = GetNativeEntry(entryHandler);

return !editText.Focusable && !editText.FocusableInTouchMode;
}
}
}
17 changes: 17 additions & 0 deletions src/Core/tests/DeviceTests/Handlers/Entry/EntryHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,23 @@ await ValidatePropertyUpdatesValue(
unsetValue);
}

[Theory(DisplayName = "IsReadOnly Updates Correctly")]
[InlineData(true, true)]
jsuarezruiz marked this conversation as resolved.
Show resolved Hide resolved
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(false, false)]
public async Task IsReadOnlyUpdatesCorrectly(bool setValue, bool unsetValue)
{
var entry = new EntryStub();

await ValidatePropertyUpdatesValue(
entry,
nameof(IEntry.IsReadOnly),
GetNativeIsReadOnly,
setValue,
unsetValue);
}

[Theory(DisplayName = "Text Changed Events Fire Correctly")]
// null/empty
[InlineData(null, null, false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@ bool GetNativeIsPassword(EntryHandler entryHandler) =>

bool GetNativeIsTextPredictionEnabled(EntryHandler entryHandler) =>
GetNativeEntry(entryHandler).AutocorrectionType == UITextAutocorrectionType.Yes;

bool GetNativeIsReadOnly(EntryHandler entryHandler) =>
!GetNativeEntry(entryHandler).UserInteractionEnabled;
}
}
2 changes: 2 additions & 0 deletions src/Core/tests/DeviceTests/Stubs/EntryStub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public string Text

public bool IsTextPredictionEnabled { get; set; }

public bool IsReadOnly { get; set; }

public event EventHandler<StubPropertyChangedEventArgs<string>> TextChanged;

void OnTextChanged(string oldValue, string newValue) =>
Expand Down