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

Add InputScope Property To NumberBox #3186

Merged
merged 9 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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
28 changes: 27 additions & 1 deletion dev/Generated/NumberBox.properties.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

// DO NOT EDIT! This file was generated by CustomTasks.DependencyPropertyCodeGen
Expand All @@ -17,6 +17,7 @@ GlobalDependencyProperty NumberBoxProperties::s_AcceptsExpressionProperty{ nullp
GlobalDependencyProperty NumberBoxProperties::s_DescriptionProperty{ nullptr };
GlobalDependencyProperty NumberBoxProperties::s_HeaderProperty{ nullptr };
GlobalDependencyProperty NumberBoxProperties::s_HeaderTemplateProperty{ nullptr };
GlobalDependencyProperty NumberBoxProperties::s_InputScopeProperty{ nullptr };
GlobalDependencyProperty NumberBoxProperties::s_IsWrapEnabledProperty{ nullptr };
GlobalDependencyProperty NumberBoxProperties::s_LargeChangeProperty{ nullptr };
GlobalDependencyProperty NumberBoxProperties::s_MaximumProperty{ nullptr };
Expand Down Expand Up @@ -86,6 +87,17 @@ void NumberBoxProperties::EnsureProperties()
ValueHelper<winrt::DataTemplate>::BoxedDefaultValue(),
winrt::PropertyChangedCallback(&OnHeaderTemplatePropertyChanged));
}
if (!s_InputScopeProperty)
{
s_InputScopeProperty =
InitializeDependencyProperty(
L"InputScope",
winrt::name_of<winrt::InputScope>(),
winrt::name_of<winrt::NumberBox>(),
false /* isAttached */,
ValueHelper<winrt::InputScope>::BoxedDefaultValue(),
nullptr);
}
if (!s_IsWrapEnabledProperty)
{
s_IsWrapEnabledProperty =
Expand Down Expand Up @@ -270,6 +282,7 @@ void NumberBoxProperties::ClearProperties()
s_DescriptionProperty = nullptr;
s_HeaderProperty = nullptr;
s_HeaderTemplateProperty = nullptr;
s_InputScopeProperty = nullptr;
s_IsWrapEnabledProperty = nullptr;
s_LargeChangeProperty = nullptr;
s_MaximumProperty = nullptr;
Expand Down Expand Up @@ -438,6 +451,19 @@ winrt::DataTemplate NumberBoxProperties::HeaderTemplate()
return ValueHelper<winrt::DataTemplate>::CastOrUnbox(static_cast<NumberBox*>(this)->GetValue(s_HeaderTemplateProperty));
}

void NumberBoxProperties::InputScope(winrt::InputScope const& value)
{
[[gsl::suppress(con)]]
{
static_cast<NumberBox*>(this)->SetValue(s_InputScopeProperty, ValueHelper<winrt::InputScope>::BoxValueIfNecessary(value));
}
}

winrt::InputScope NumberBoxProperties::InputScope()
{
return ValueHelper<winrt::InputScope>::CastOrUnbox(static_cast<NumberBox*>(this)->GetValue(s_InputScopeProperty));
}

void NumberBoxProperties::IsWrapEnabled(bool value)
{
[[gsl::suppress(con)]]
Expand Down
5 changes: 5 additions & 0 deletions dev/Generated/NumberBox.properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class NumberBoxProperties
void HeaderTemplate(winrt::DataTemplate const& value);
winrt::DataTemplate HeaderTemplate();

void InputScope(winrt::InputScope const& value);
winrt::InputScope InputScope();

void IsWrapEnabled(bool value);
bool IsWrapEnabled();

Expand Down Expand Up @@ -73,6 +76,7 @@ class NumberBoxProperties
static winrt::DependencyProperty DescriptionProperty() { return s_DescriptionProperty; }
static winrt::DependencyProperty HeaderProperty() { return s_HeaderProperty; }
static winrt::DependencyProperty HeaderTemplateProperty() { return s_HeaderTemplateProperty; }
static winrt::DependencyProperty InputScopeProperty() { return s_InputScopeProperty; }
static winrt::DependencyProperty IsWrapEnabledProperty() { return s_IsWrapEnabledProperty; }
static winrt::DependencyProperty LargeChangeProperty() { return s_LargeChangeProperty; }
static winrt::DependencyProperty MaximumProperty() { return s_MaximumProperty; }
Expand All @@ -94,6 +98,7 @@ class NumberBoxProperties
static GlobalDependencyProperty s_DescriptionProperty;
static GlobalDependencyProperty s_HeaderProperty;
static GlobalDependencyProperty s_HeaderTemplateProperty;
static GlobalDependencyProperty s_InputScopeProperty;
static GlobalDependencyProperty s_IsWrapEnabledProperty;
static GlobalDependencyProperty s_LargeChangeProperty;
static GlobalDependencyProperty s_MaximumProperty;
Expand Down
29 changes: 29 additions & 0 deletions dev/NumberBox/APITests/NumberBoxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using MUXControlsTestApp;
using Microsoft.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;

#if USING_TAEF
using WEX.TestExecution;
Expand Down Expand Up @@ -105,6 +106,34 @@ public void VerifyNumberBoxCornerRadius()
});
}

[TestMethod]
public void VerifyInputScopePropogates()
{
var numberBox = SetupNumberBox();

RunOnUIThread.Execute(() =>
{
Content.UpdateLayout();
var inputTextBox = TestUtilities.FindDescendents<TextBox>(numberBox).Where(e => e.Name == "InputBox").Single();

Verify.AreEqual(1, inputTextBox.InputScope.Names.Count);
Verify.AreEqual(InputScopeNameValue.Number, inputTextBox.InputScope.Names[0].NameValue, "The default InputScope should be 'Number'.");

var scopeName = new InputScopeName();
scopeName.NameValue = InputScopeNameValue.CurrencyAmountAndSymbol;
var scope = new InputScope();
scope.Names.Add(scopeName);

numberBox.InputScope = scope;
Content.UpdateLayout();

Verify.AreEqual(1, inputTextBox.InputScope.Names.Count);
Verify.AreEqual(InputScopeNameValue.CurrencyAmountAndSymbol, inputTextBox.InputScope.Names[0].NameValue, "The InputScope should be 'CurrencyAmountAndSymbol'.");
});

return;
}

[TestMethod]
public void VerifyIsEnabledChangeUpdatesVisualState()
{
Expand Down
14 changes: 14 additions & 0 deletions dev/NumberBox/NumberBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ NumberBox::NumberBox()
LostFocus({ this, &NumberBox::OnNumberBoxLostFocus });

SetDefaultStyleKey(this);
SetDefaultInputScope();
}

void NumberBox::SetDefaultInputScope()
{
// Sets the default value of the InputScope property.
// Note that InputScope is a class that cannot be set to a default value within the IDL.
winrt::InputScopeName inputScopeName = winrt::InputScopeName(winrt::InputScopeNameValue::Number);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we prefer using auto and const for the local variable types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a problem, should I pursue this now though or wait for potential work-arounds setting in the default style?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just did it now so hopefully we can close this. There is no response on work-arounds for the XAML bugs.

winrt::InputScope inputScope = winrt::InputScope();
inputScope.Names().Append(inputScopeName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Names [](start = 15, length = 5)

I'm not that familiar with inputScope, does this mean that you can apply multiple input scopes? like you can have number and currency at the same time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mean that you can apply multiple input scopes?
Yes, you can apply multiple name values to the same input scope.

It's certainly an interesting design decision, one which I've never understood myself. However, my assumption has always been it's for the cases where the user can switch the keyboard. It simply limits what keyboards you are allowed to switch between. You might have to reach out to the Windows team to understand the thinking here though. I don't recall ever seeing documented reasons why this is a collection.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MikeHillberg do you happen to know?


static_cast<NumberBox*>(this)->SetValue(s_InputScopeProperty, ValueHelper<winrt::InputScope>::BoxValueIfNecessary(inputScope));

return;
}

// This was largely copied from Calculator's GetRegionalSettingsAwareDecimalFormatter()
Expand Down
2 changes: 2 additions & 0 deletions dev/NumberBox/NumberBox.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class NumberBox :

void MoveCaretToTextEnd();

void SetDefaultInputScope();

bool m_valueUpdating{ false };
bool m_textUpdating{ false };

Expand Down
12 changes: 12 additions & 0 deletions dev/NumberBox/NumberBox.idl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ unsealed runtimeclass NumberBox : Windows.UI.Xaml.Controls.Control
// TextBox properties
Object Header;
Windows.UI.Xaml.DataTemplate HeaderTemplate;

[WUXC_VERSION_PREVIEW]
{
Windows.UI.Xaml.Input.InputScope InputScope;
}

String PlaceholderText;
Windows.UI.Xaml.Controls.Primitives.FlyoutBase SelectionFlyout;
Windows.UI.Xaml.Media.SolidColorBrush SelectionHighlightColor;
Expand Down Expand Up @@ -102,6 +108,12 @@ unsealed runtimeclass NumberBox : Windows.UI.Xaml.Controls.Control
static Windows.UI.Xaml.DependencyProperty HeaderProperty{ get; };
[MUX_PROPERTY_CHANGED_CALLBACK(TRUE)]
static Windows.UI.Xaml.DependencyProperty HeaderTemplateProperty{ get; };

[WUXC_VERSION_PREVIEW]
{
static Windows.UI.Xaml.DependencyProperty InputScopeProperty{ get; };
}

static Windows.UI.Xaml.DependencyProperty PlaceholderTextProperty{ get; };
static Windows.UI.Xaml.DependencyProperty SelectionFlyoutProperty{ get; };
static Windows.UI.Xaml.DependencyProperty SelectionHighlightColorProperty{ get; };
Expand Down
2 changes: 1 addition & 1 deletion dev/NumberBox/NumberBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@

<TextBox x:Name="InputBox"
Grid.Row="1"
InputScope="Number"
InputScope="{TemplateBinding InputScope}"
PlaceholderText="{TemplateBinding PlaceholderText}"
contract7Present:SelectionFlyout="{TemplateBinding SelectionFlyout}"
SelectionHighlightColor="{TemplateBinding SelectionHighlightColor}"
Expand Down
8 changes: 8 additions & 0 deletions dev/NumberBox/TestUI/NumberBoxPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@
<ComboBoxItem Content="Right" />
</ComboBox>

<ComboBox x:Name="InputScopeComboBox" AutomationProperties.Name="InputScopeComboBox" Header="InputScope" SelectedIndex="0" SelectionChanged="InputScope_Changed">
<ComboBoxItem Content="Number" />
<ComboBoxItem Content="Default" />
<ComboBoxItem Content="CurrencyAmountAndSymbol" />
<ComboBoxItem Content="TelephoneNumber" />
<ComboBoxItem Content="Formula" />
</ComboBox>

<CheckBox x:Name="EnabledCheckBox" AutomationProperties.Name="EnabledCheckBox" IsChecked="True" Content="Enabled"/>

<CheckBox x:Name="ExpressionCheckBox" AutomationProperties.Name="ExpressionCheckBox" IsChecked="False" Content="Accepts Expression"/>
Expand Down
20 changes: 20 additions & 0 deletions dev/NumberBox/TestUI/NumberBoxPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Automation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Markup;

namespace MUXControlsTestApp
Expand All @@ -27,6 +28,25 @@ public NumberBoxPage()
TestNumberBox.RegisterPropertyChangedCallback(NumberBox.TextProperty, new DependencyPropertyChangedCallback(TextPropertyChanged));
}

private void InputScope_Changed(object sender, RoutedEventArgs e)
{
if (TestNumberBox != null &&
sender is ComboBox comboBox &&
comboBox.SelectedItem is ComboBoxItem item)
{
var scopeName = new InputScopeName();
scopeName.NameValue = (InputScopeNameValue)Enum.Parse(typeof(InputScopeNameValue), item.Content?.ToString() ?? string.Empty, true);

var scope = new InputScope();
scope.Names.Add(scopeName);

TestNumberBox.InputScope = scope;

// Help testing by returning focus to the NumberBox to see the keyboard change
TestNumberBox.Focus(FocusState.Keyboard);
}
}

private void SpinMode_Changed(object sender, RoutedEventArgs e)
{
if (TestNumberBox != null)
Expand Down