Skip to content

Commit

Permalink
Update mappers instead of replacing field values (#13836)
Browse files Browse the repository at this point in the history
* Fix InputTransparent and CascadeInputTransparent

* Adding some tests for the baseline

* This works better

* Fix this

* Also these platforms

* Support compatibility

* Improved the sample for testing

* See what this does

* Revert "See what this does"

This reverts commit 9609697.

* comment out new tests

* Try reverting these

* Revert "Try reverting these"

This reverts commit 31bfb34.

* Revert the bad code hacks

* This should work!

* Use AppendToMapping for Focus commands

* Use new PrependToMapping method

* this

* The entire method is replaced

* Use AppendToMapping for Element and VisualElement

* Skip the failing test for now

* this is no longer needed

* yaml

* this

* Revert "yaml"

This reverts commit 51da889.

* Revert "this"

This reverts commit b7b1b3a.

* this

* Move some controls to use ModifyMapping

* Added a test

* Ensure iOS "text boxes" preserve cursor location

* Fix the Windows tests

* Attach the controls to the UI for focus tests

* undo this

* and this

* obsolete for now

* not Element yet

* Adding some more "text box" tests

* todo

* tests

* Revert "todo"

This reverts commit 328c6ba.

# Conflicts:
#	src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs

* this

* move

* Revert "this"

This reverts commit d62b12a.

* moar tests

* Revert "Revert "todo""

This reverts commit 6065a41.

* all working on windows

* build all again

* Merge the methods

* Ensure iOS "text boxes" preserve cursor location

* Fix the Windows tests

* Attach the controls to the UI for focus tests

* Adding some more "text box" tests

* todo

* tests

* Revert "todo"

This reverts commit 328c6ba.

# Conflicts:
#	src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs

* this

* move

* Revert "this"

This reverts commit d62b12a.

* moar tests

* Revert "Revert "todo""

This reverts commit 6065a41.

* all working on windows

* Merge the methods

* removed as it is not needed

* merge

* Update src/Controls/tests/DeviceTests/ControlsHandlerTestBase.cs

Co-authored-by: Rachel Kang <rachelkang@microsoft.com>

* fix the variable names

* fix

* reset

* Fix things a bit more

* Improve test reports

* fix things

* Update Layout.Standard.cs

* Update Layout.Standard.cs

* not needed

* ReplaceMapping

* updates

* Fix the mappers

* this

* Update AppHostBuilderExtensions.cs

* ws

---------

Co-authored-by: Rachel Kang <rachelkang@microsoft.com>
  • Loading branch information
mattleibow and rachelkang committed Jul 22, 2023
1 parent 484dd78 commit ed7809f
Show file tree
Hide file tree
Showing 39 changed files with 289 additions and 259 deletions.
20 changes: 10 additions & 10 deletions src/Controls/src/Core/Application/Application.Mapper.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#nullable disable
using System;

namespace Microsoft.Maui.Controls
{
public partial class Application
{
[Obsolete("Use ApplicationHandler.Mapper instead.")]
public static IPropertyMapper<IApplication, ApplicationHandler> ControlsApplicationMapper =
new PropertyMapper<Application, ApplicationHandler>(ApplicationHandler.Mapper)
{
#if ANDROID
// There is also a mapper on Window for this property since this property is relevant at the window level for
// Android not the application level
[PlatformConfiguration.AndroidSpecific.Application.WindowSoftInputModeAdjustProperty.PropertyName] = MapWindowSoftInputModeAdjust,
#endif
};
new PropertyMapper<Application, ApplicationHandler>(ApplicationHandler.Mapper);

internal static void RemapForControls()
internal static new void RemapForControls()
{
// Adjust the mappings to preserve Controls.Application legacy behaviors
ApplicationHandler.Mapper = ControlsApplicationMapper;
#if ANDROID
// There is also a mapper on Window for this property since this property is relevant at the window level for
// Android not the application level
ApplicationHandler.Mapper.ReplaceMapping<Application, ApplicationHandler>(PlatformConfiguration.AndroidSpecific.Application.WindowSoftInputModeAdjustProperty.PropertyName, MapWindowSoftInputModeAdjust);
#endif
}
}
}
22 changes: 10 additions & 12 deletions src/Controls/src/Core/Button/Button.Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,22 @@ public partial class Button
/// <summary>
/// The property mapper that maps the abstract properties to the platform-specific methods for further processing.
/// </summary>
public static IPropertyMapper<IButton, ButtonHandler> ControlsButtonMapper = new PropertyMapper<Button, ButtonHandler>(ButtonHandler.Mapper)
[Obsolete("Use ButtonHandler.Mapper instead.")]
public static IPropertyMapper<IButton, ButtonHandler> ControlsButtonMapper = new PropertyMapper<Button, ButtonHandler>(ButtonHandler.Mapper);

internal new static void RemapForControls()
{
[nameof(ContentLayout)] = MapContentLayout,
ButtonHandler.Mapper.ReplaceMapping<Button, IButtonHandler>(nameof(ContentLayout), MapContentLayout);
#if IOS
[nameof(Padding)] = MapPadding,
ButtonHandler.Mapper.ReplaceMapping<Button, IButtonHandler>(nameof(Padding), MapPadding);
#endif
#if WINDOWS
[nameof(IText.Text)] = MapText,
[nameof(ImageSource)] = MapImageSource,
ButtonHandler.Mapper.ReplaceMapping<Button, IButtonHandler>(nameof(ImageSource), MapImageSource);
#endif
[nameof(TextTransform)] = MapText,
[nameof(Text)] = MapText,
[nameof(Button.LineBreakMode)] = MapLineBreakMode,
};
ButtonHandler.Mapper.ReplaceMapping<Button, IButtonHandler>(nameof(Text), MapText);

internal new static void RemapForControls()
{
ButtonHandler.Mapper = ControlsButtonMapper;
ButtonHandler.Mapper.ReplaceMapping<Button, IButtonHandler>(nameof(TextTransform), MapText);
ButtonHandler.Mapper.ReplaceMapping<Button, IButtonHandler>(nameof(Button.LineBreakMode), MapLineBreakMode);
}

/// <summary>
Expand Down
14 changes: 5 additions & 9 deletions src/Controls/src/Core/CheckBox/CheckBox.Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,14 @@ namespace Microsoft.Maui.Controls
{
public partial class CheckBox
{
// TODO Make public for NET8
internal static IPropertyMapper<ICheckBox, CheckBoxHandler> ControlsCheckBoxMapper = new PropertyMapper<CheckBox, CheckBoxHandler>(CheckBoxHandler.Mapper)
internal new static void RemapForControls()
{
[nameof(Color)] = (handler, view) =>
{
handler?.UpdateValue(nameof(ICheckBox.Foreground));
}
};
CheckBoxHandler.Mapper.ReplaceMapping<ICheckBox, ICheckBoxHandler>(nameof(Color), MapColor);
}

internal new static void RemapForControls()
internal static void MapColor(ICheckBoxHandler handler, ICheckBox view)
{
CheckBoxHandler.Mapper = ControlsCheckBoxMapper;
handler?.UpdateValue(nameof(ICheckBox.Foreground));
}
}
}
14 changes: 7 additions & 7 deletions src/Controls/src/Core/DatePicker/DatePicker.Mapper.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#nullable disable
using System;

namespace Microsoft.Maui.Controls
{
public partial class DatePicker
{
public static IPropertyMapper<IDatePicker, DatePickerHandler> ControlsDatePickerMapper = new PropertyMapper<DatePicker, DatePickerHandler>(DatePickerHandler.Mapper)
{
#if IOS
[PlatformConfiguration.iOSSpecific.DatePicker.UpdateModeProperty.PropertyName] = MapUpdateMode,
#endif
};
[Obsolete("Use DatePickerHandler.Mapper instead.")]
public static IPropertyMapper<IDatePicker, DatePickerHandler> ControlsDatePickerMapper = new PropertyMapper<DatePicker, DatePickerHandler>(DatePickerHandler.Mapper);

internal static new void RemapForControls()
{
// Adjust the mappings to preserve Controls.DatePicker legacy behaviors
DatePickerHandler.Mapper = ControlsDatePickerMapper;
#if IOS
DatePickerHandler.Mapper.ReplaceMapping<DatePicker, IDatePickerHandler>(PlatformConfiguration.iOSSpecific.DatePicker.UpdateModeProperty.PropertyName, MapUpdateMode);
#endif
}
}
}
12 changes: 5 additions & 7 deletions src/Controls/src/Core/Editor/Editor.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ namespace Microsoft.Maui.Controls
{
public partial class Editor
{
public static void MapText(EditorHandler handler, Editor editor)
public static void MapText(EditorHandler handler, Editor editor) =>
MapText((IEditorHandler)handler, editor);

public static void MapText(IEditorHandler handler, Editor editor)
{
if (handler.DataFlowDirection == DataFlowDirection.FromPlatform)
if (handler is ViewHandler viewHandler && viewHandler.DataFlowDirection == DataFlowDirection.FromPlatform)
{
Platform.EditTextExtensions.UpdateTextFromPlatform(handler.PlatformView, editor);
return;
}

MapText((IEditorHandler)handler, editor);
}

public static void MapText(IEditorHandler handler, Editor editor)
{
Platform.EditTextExtensions.UpdateText(handler.PlatformView, editor);
}

Expand Down
18 changes: 9 additions & 9 deletions src/Controls/src/Core/Editor/Editor.Mapper.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#nullable disable
using System;

namespace Microsoft.Maui.Controls
{
public partial class Editor
{
[Obsolete("Use EditorHandler.Mapper instead.")]
public static IPropertyMapper<IEditor, EditorHandler> ControlsEditorMapper =
new PropertyMapper<Editor, EditorHandler>(EditorHandler.Mapper)
{
#if WINDOWS
[PlatformConfiguration.WindowsSpecific.InputView.DetectReadingOrderFromContentProperty.PropertyName] = MapDetectReadingOrderFromContent,
#endif
[nameof(Text)] = MapText,
[nameof(TextTransform)] = MapText,
};
new PropertyMapper<Editor, EditorHandler>(EditorHandler.Mapper);

internal static new void RemapForControls()
{
// Adjust the mappings to preserve Controls.Editor legacy behaviors
EditorHandler.Mapper = ControlsEditorMapper;
#if WINDOWS
EditorHandler.Mapper.ReplaceMapping<Editor, IEditorHandler>(PlatformConfiguration.WindowsSpecific.InputView.DetectReadingOrderFromContentProperty.PropertyName, MapDetectReadingOrderFromContent);
#endif
EditorHandler.Mapper.ReplaceMapping<Editor, IEditorHandler>(nameof(Text), MapText);
EditorHandler.Mapper.ReplaceMapping<Editor, IEditorHandler>(nameof(TextTransform), MapText);

#if ANDROID
EditorHandler.CommandMapper.PrependToMapping(nameof(IEditor.Focus), MapFocus);
Expand Down
11 changes: 7 additions & 4 deletions src/Controls/src/Core/Element/Element.Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ namespace Microsoft.Maui.Controls
/// <include file="../../../docs/Microsoft.Maui.Controls/Element.xml" path="Type[@FullName='Microsoft.Maui.Controls.Element']/Docs/*" />
public partial class Element
{
public static IPropertyMapper<Maui.IElement, IElementHandler> ControlsElementMapper = new PropertyMapper<IElement, IElementHandler>(ViewHandler.ViewMapper)
[Obsolete("Use ViewHandler.ViewMapper instead.")]
public static IPropertyMapper<Maui.IElement, IElementHandler> ControlsElementMapper = new PropertyMapper<IElement, IElementHandler>(ViewHandler.ViewMapper);

internal static void RemapForControls()
{
[AutomationProperties.IsInAccessibleTreeProperty.PropertyName] = MapAutomationPropertiesIsInAccessibleTree,
[AutomationProperties.ExcludedWithChildrenProperty.PropertyName] = MapAutomationPropertiesExcludedWithChildren,
};
ViewHandler.ViewMapper.ReplaceMapping<Maui.IElement, IElementHandler>(AutomationProperties.IsInAccessibleTreeProperty.PropertyName, MapAutomationPropertiesIsInAccessibleTree);
ViewHandler.ViewMapper.ReplaceMapping<Maui.IElement, IElementHandler>(AutomationProperties.ExcludedWithChildrenProperty.PropertyName, MapAutomationPropertiesExcludedWithChildren);
}
}
}
16 changes: 7 additions & 9 deletions src/Controls/src/Core/Entry/Entry.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,8 @@ public partial class Entry
public static void MapImeOptions(EntryHandler handler, Entry entry) =>
MapImeOptions((IEntryHandler)handler, entry);

public static void MapText(EntryHandler handler, Entry entry)
{
if (handler.DataFlowDirection == DataFlowDirection.FromPlatform)
{
Platform.EditTextExtensions.UpdateTextFromPlatform(handler.PlatformView, entry);
return;
}

public static void MapText(EntryHandler handler, Entry entry) =>
MapText((IEntryHandler)handler, entry);
}

public static void MapImeOptions(IEntryHandler handler, Entry entry)
{
Expand All @@ -29,6 +21,12 @@ public static void MapImeOptions(IEntryHandler handler, Entry entry)

public static void MapText(IEntryHandler handler, Entry entry)
{
if (handler is ViewHandler viewHandler && viewHandler.DataFlowDirection == DataFlowDirection.FromPlatform)
{
Platform.EditTextExtensions.UpdateTextFromPlatform(handler.PlatformView, entry);
return;
}

Platform.EditTextExtensions.UpdateText(handler.PlatformView, entry);
}

Expand Down
28 changes: 14 additions & 14 deletions src/Controls/src/Core/Entry/Entry.Mapper.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
#nullable disable
using System;

namespace Microsoft.Maui.Controls
{
public partial class Entry
{
[Obsolete("Use EntryHandler.Mapper instead.")]
public static IPropertyMapper<IEntry, EntryHandler> ControlsEntryMapper =
new PropertyMapper<Entry, EntryHandler>(EntryHandler.Mapper)
{
#if ANDROID
[PlatformConfiguration.AndroidSpecific.Entry.ImeOptionsProperty.PropertyName] = MapImeOptions,
#elif WINDOWS
[PlatformConfiguration.WindowsSpecific.InputView.DetectReadingOrderFromContentProperty.PropertyName] = MapDetectReadingOrderFromContent,
#elif IOS
[PlatformConfiguration.iOSSpecific.Entry.CursorColorProperty.PropertyName] = MapCursorColor,
[PlatformConfiguration.iOSSpecific.Entry.AdjustsFontSizeToFitWidthProperty.PropertyName] = MapAdjustsFontSizeToFitWidth,
#endif
[nameof(Text)] = MapText,
[nameof(TextTransform)] = MapText,
};
new PropertyMapper<Entry, EntryHandler>(EntryHandler.Mapper);

internal static new void RemapForControls()
{
// Adjust the mappings to preserve Controls.Entry legacy behaviors
EntryHandler.Mapper = ControlsEntryMapper;
#if ANDROID
EntryHandler.Mapper.ReplaceMapping<Entry, IEntryHandler>(PlatformConfiguration.AndroidSpecific.Entry.ImeOptionsProperty.PropertyName, MapImeOptions);
#elif WINDOWS
EntryHandler.Mapper.ReplaceMapping<Entry, IEntryHandler>(PlatformConfiguration.WindowsSpecific.InputView.DetectReadingOrderFromContentProperty.PropertyName, MapDetectReadingOrderFromContent);
#elif IOS
EntryHandler.Mapper.ReplaceMapping<Entry, IEntryHandler>(PlatformConfiguration.iOSSpecific.Entry.CursorColorProperty.PropertyName, MapCursorColor);
EntryHandler.Mapper.ReplaceMapping<Entry, IEntryHandler>(PlatformConfiguration.iOSSpecific.Entry.AdjustsFontSizeToFitWidthProperty.PropertyName, MapAdjustsFontSizeToFitWidth);
#endif
EntryHandler.Mapper.ReplaceMapping<Entry, IEntryHandler>(nameof(Text), MapText);
EntryHandler.Mapper.ReplaceMapping<Entry, IEntryHandler>(nameof(TextTransform), MapText);

#if ANDROID
EntryHandler.CommandMapper.PrependToMapping(nameof(IEntry.Focus), MapFocus);
Expand Down
15 changes: 10 additions & 5 deletions src/Controls/src/Core/FlyoutPage/FlyoutPage.Mapper.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
using System;

namespace Microsoft.Maui.Controls
{
/// <include file="../../../docs/Microsoft.Maui.Controls/FlyoutPage.xml" path="Type[@FullName='Microsoft.Maui.Controls.FlyoutPage']/Docs/*" />
public partial class FlyoutPage
{
public static IPropertyMapper<IFlyoutView, FlyoutViewHandler> ControlsFlyoutPageMapper = new PropertyMapper<IFlyoutView, FlyoutViewHandler>(FlyoutViewHandler.Mapper)
{
[nameof(FlyoutLayoutBehavior)] = (handler, __) => handler.UpdateValue(nameof(IFlyoutView.FlyoutBehavior)),
};
[Obsolete("Use FlyoutViewHandler.Mapper instead.")]
public static IPropertyMapper<IFlyoutView, FlyoutViewHandler> ControlsFlyoutPageMapper = new PropertyMapper<IFlyoutView, FlyoutViewHandler>(FlyoutViewHandler.Mapper);

internal new static void RemapForControls()
{
FlyoutViewHandler.Mapper = ControlsFlyoutPageMapper;
FlyoutViewHandler.Mapper.ReplaceMapping<IFlyoutView, IFlyoutViewHandler>(nameof(FlyoutLayoutBehavior), MapFlyoutLayoutBehavior);
}

internal static void MapFlyoutLayoutBehavior(IFlyoutViewHandler handler, IFlyoutView view)
{
handler.UpdateValue(nameof(IFlyoutView.FlyoutBehavior));
}
}
}
39 changes: 19 additions & 20 deletions src/Controls/src/Core/Label/Label.Mapper.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
#nullable disable
using System;
using Microsoft.Maui.Handlers;

namespace Microsoft.Maui.Controls
{
/// <include file="../../../docs/Microsoft.Maui.Controls/Label.xml" path="Type[@FullName='Microsoft.Maui.Controls.Label']/Docs/*" />
public partial class Label
{
public static IPropertyMapper<ILabel, LabelHandler> ControlsLabelMapper = new PropertyMapper<Label, LabelHandler>(LabelHandler.Mapper)
{
[nameof(TextType)] = MapTextType,
[nameof(Text)] = MapText,
[nameof(FormattedText)] = MapText,
[nameof(TextTransform)] = MapText,
#if WINDOWS
[PlatformConfiguration.WindowsSpecific.InputView.DetectReadingOrderFromContentProperty.PropertyName] = MapDetectReadingOrderFromContent,
#endif
#if IOS
[nameof(TextDecorations)] = MapTextDecorations,
[nameof(CharacterSpacing)] = MapCharacterSpacing,
[nameof(LineHeight)] = MapLineHeight,
[nameof(ILabel.Font)] = MapFont,
[nameof(TextColor)] = MapTextColor,
#endif
[nameof(Label.LineBreakMode)] = MapLineBreakMode,
[nameof(Label.MaxLines)] = MapMaxLines,
};
[Obsolete("Use LabelHandler.Mapper instead.")]
public static IPropertyMapper<ILabel, LabelHandler> ControlsLabelMapper = new PropertyMapper<Label, LabelHandler>(LabelHandler.Mapper);

internal static new void RemapForControls()
{
// Adjust the mappings to preserve Controls.Label legacy behaviors
// ILabel does not include the TextType property, so we map it here to handle HTML text
// And we map some of the other property handlers to Controls-specific versions that avoid stepping on HTML text settings

LabelHandler.Mapper = ControlsLabelMapper;
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(nameof(TextType), MapTextType);
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(nameof(Text), MapText);
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(nameof(FormattedText), MapText);
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(nameof(TextTransform), MapText);
#if WINDOWS
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(PlatformConfiguration.WindowsSpecific.InputView.DetectReadingOrderFromContentProperty.PropertyName, MapDetectReadingOrderFromContent);
#endif
#if IOS
LabelHandler.Mapper.ModifyMapping<Label, ILabelHandler>(nameof(TextDecorations), MapTextDecorations);
LabelHandler.Mapper.ModifyMapping<Label, ILabelHandler>(nameof(CharacterSpacing), MapCharacterSpacing);
LabelHandler.Mapper.ModifyMapping<Label, ILabelHandler>(nameof(LineHeight), MapLineHeight);
LabelHandler.Mapper.ModifyMapping<Label, ILabelHandler>(nameof(ILabel.Font), MapFont);
LabelHandler.Mapper.ModifyMapping<Label, ILabelHandler>(nameof(TextColor), MapTextColor);
#endif
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(nameof(Label.LineBreakMode), MapLineBreakMode);
LabelHandler.Mapper.ReplaceMapping<Label, ILabelHandler>(nameof(Label.MaxLines), MapMaxLines);
}
}
}
Loading

0 comments on commit ed7809f

Please sign in to comment.