Skip to content

Commit

Permalink
fix(android): various issues with readonly textblock
Browse files Browse the repository at this point in the history
- IsReadOnly=True breaks AcceptsReturn=True (multi-line)
- IsReadOnly=True can still bring up keyboard on click
  • Loading branch information
Xiaoy312 committed Apr 22, 2020
1 parent 15d2b92 commit 2dd4bc8
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -447,5 +447,76 @@ public void Focus_Programmatic()

_app.WaitForText("TargetTextBox", "orangutan");
}

[Test]
[AutoRetry]
[ActivePlatforms(Platform.Android)]
public void TextBox_Readonly_ShouldNotBringUpKeyboard()
{
Run("Uno.UI.Samples.UITests.TextBoxControl.TextBox_IsReadOnly");

var target = _app.Marked("txt");
var readonlyToggle = _app.Marked("tglReadonly"); // default: checked

// initial state
_app.WaitForElement(target);
var screenshot1 = TakeScreenshot("textbox readonly", ignoreInSnapshotCompare: true);

// remove readonly and focus textbox
readonlyToggle.Tap(); // now: unchecked
target.Tap();
_app.Wait(seconds: 1); // allow keyboard to fully open
var screenshot2 = TakeScreenshot("textbox focused with keyboard", ignoreInSnapshotCompare: true);

// reapply readonly and try focus textbox
readonlyToggle.Tap(); // now: checked
target.Tap();
_app.Wait(seconds: 1); // allow keyboard to fully open (if ever possible)
_app.WaitForElement(target);
var screenshot3 = TakeScreenshot("textbox readonly again", ignoreInSnapshotCompare: true);

// the bottom half should only contains the keyboard and some blank space,
// but not the textbox nor the toggle buttons that needs to be excluded.
var screen = _app.GetScreenDimensions();
var bottomHalfRect = new Rectangle(
0, (int)screen.Height / 2,
(int)screen.Width, (int)screen.Height / 2
);

ImageAssert.AreNotEqual(screenshot1, screenshot2, bottomHalfRect); // no keyboard != keyboard
ImageAssert.AreEqual(screenshot1, screenshot3, bottomHalfRect); // no keyboard == no keyboard
}

[Test]
[AutoRetry]
[ActivePlatforms(Platform.Android)]
public void TextBox_IsReadOnly_AcceptsReturn_Test()
{
/* test disabled for ios and wasm, due to #
*-ios: when setting AcceptsReturn to false, the TextBox doesn't resize appropriately
* -wasm: AcceptsReturn is not implemented or does nothing */

Run("UITests.Shared.Windows_UI_Xaml_Controls.TextBoxTests.TextBox_IsReadOnly_AcceptsReturn");
// for context, IsReadOnly=True used to break AcceptsReturn=True on android

var target = _app.Marked("TargetTextBox");
var readonlyCheckBox = _app.Marked("IsReadOnlyCheckBox"); // default: checked
var multilineCheckBox = _app.Marked("AcceptsReturnCheckBox"); // default: checked

// initial state
_app.WaitForElement(target);
var multilineReadonlyTextRect = target.FirstResult().Rect;

// remove readonly
readonlyCheckBox.Tap(); // now: unchecked
var multilineTextRect = target.FirstResult().Rect;

// remove multiline
multilineCheckBox.Tap(); // now: unchecked
var normalTextRect = target.FirstResult().Rect;

multilineTextRect.Height.Should().Be(multilineReadonlyTextRect.Height, because: "toggling IsReadOnly should not affect AcceptsReturn=True(multiline) TextBox.Height");
normalTextRect.Height.Should().NotBe(multilineTextRect.Height, because: "toggling AcceptsReturn should not affect TextBox.Height");
}
}
}
7 changes: 7 additions & 0 deletions src/SamplesApp/UITests.Shared/UITests.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\TextBox\TextBox_IsReadOnly_AcceptsReturn.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\TextBox\TextBox_MaxLength.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -3701,6 +3705,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\TextBox\TextBox_Margin.xaml.cs">
<DependentUpon>TextBox_Margin.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\TextBox\TextBox_IsReadOnly_AcceptsReturn.xaml.cs">
<DependentUpon>TextBox_IsReadOnly_AcceptsReturn.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml_Controls\TextBox\TextBox_MaxLength.xaml.cs">
<DependentUpon>TextBox_MaxLength.xaml</DependentUpon>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<UserControl
x:Class="UITests.Shared.Windows_UI_Xaml_Controls.TextBoxTests.TextBox_IsReadOnly_AcceptsReturn"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.Windows_UI_Xaml_Controls.TextBox"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="IsReadOnly:" />
<CheckBox x:Name="IsReadOnlyCheckBox" IsChecked="{Binding ElementName=TargetTextBox, Path=IsReadOnly, Mode=TwoWay}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="AcceptsReturn:" />
<CheckBox x:Name="AcceptsReturnCheckBox" IsChecked="{Binding ElementName=TargetTextBox, Path=AcceptsReturn, Mode=TwoWay}" />
</StackPanel>

<TextBox x:Name="TargetTextBox"
Text="lorem&#x0a;ipsum&#x0a;asd&#x0a;asd&#x0a;asd"
AcceptsReturn="True"
IsReadOnly="True" />
</StackPanel>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Uno.UI.Samples.Controls;
using Windows.UI.Xaml.Controls;

// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236

namespace UITests.Shared.Windows_UI_Xaml_Controls.TextBoxTests
{
[SampleControlInfo("TextBox", description: "#2700: Setting IsReadOnly=True breaks AcceptReturns=True on android")]
public sealed partial class TextBox_IsReadOnly_AcceptsReturn : UserControl
{
public TextBox_IsReadOnly_AcceptsReturn()
{
this.InitializeComponent();
}
}
}
40 changes: 21 additions & 19 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/TextBox.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -322,24 +322,7 @@ private void UpdateInputScope(InputScope inputScope)
inputType |= InputTypes.TextFlagMultiLine;
}

if (IsReadOnly)
{
_textBoxView.InputType = InputTypes.Null;

// Clear the listener so the inputs have no effect.
// Setting the input type to InputTypes.Null is not enough.
_listener = _textBoxView.KeyListener;
_textBoxView.KeyListener = null;
}
else
{
if (_listener != null)
{
_textBoxView.KeyListener = _listener;
}

_textBoxView.InputType = inputType;
}
_textBoxView.InputType = inputType;
}
}

Expand Down Expand Up @@ -407,7 +390,26 @@ partial void OnIsReadonlyChangedPartial(DependencyPropertyChangedEventArgs e)
{
if (_textBoxView != null)
{
UpdateInputScope(InputScope);
var isReadOnly = IsReadOnly;

_textBoxView.Focusable = !isReadOnly;
_textBoxView.FocusableInTouchMode = !isReadOnly;
_textBoxView.Clickable = !isReadOnly;
_textBoxView.LongClickable = !isReadOnly;
_textBoxView.SetCursorVisible(!isReadOnly);

if (isReadOnly)
{
_listener = _textBoxView.KeyListener;
_textBoxView.KeyListener = null;
}
else
{
if (_listener != null)
{
_textBoxView.KeyListener = _listener;
}
}
}
}

Expand Down

0 comments on commit 2dd4bc8

Please sign in to comment.