Merge branch 'Dreamescaper-editor'

This commit is contained in:
Eilon Lipton 2022-06-07 16:29:28 -07:00
Родитель 7847ac9278 c336c79ba5
Коммит c83aa5775e
11 изменённых файлов: 247 добавлений и 21 удалений

Просмотреть файл

@ -0,0 +1,19 @@
@page "/editorplayground"
<ContentPage>
<StackLayout Margin="20">
<Editor @bind-Text="_text" OnCompleted="OnCompleted" AutoSize="EditorAutoSizeOption.TextChanges" />
<Label Text=@($"Edits count: {_editsNumber}. Text entered: {_text}")/>
</StackLayout>
</ContentPage>
@code
{
string _text;
int _editsNumber;
void OnCompleted()
{
_editsNumber++;
}
}

Просмотреть файл

@ -11,6 +11,7 @@
<Button Text="Skia Playground" OnClick="@(async () => await NavigationManager.NavigateToAsync("/skia"))"></Button>
<Button Text="Picker Playground" OnClick="@(async () => await NavigationManager.NavigateToAsync("/pickerplayground"))"></Button>
<Button Text="CollectionView Playground" OnClick="@(async () => await NavigationManager.NavigateToAsync("/collectionviewplayground"))"></Button>
<Button Text="Editor Playground" OnClick="@(async () => await NavigationManager.NavigateToAsync("/editorplayground"))"></Button>
</StackLayout>
</ScrollView>
</ContentPage>

Просмотреть файл

@ -10,6 +10,7 @@ CheckBox
ContentPage
ContentView
DatePicker
Editor
#Element // Element is special so we don't generate it
Entry
FlyoutItem

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
namespace Microsoft.MobileBlazorBindings.Elements
{
public partial class Editor
{
[Parameter] public EventCallback OnCompleted { get; set; }
partial void RenderAdditionalAttributes(AttributesBuilder builder)
{
builder.AddAttribute("oncompleted", OnCompleted);
}
}
}

Просмотреть файл

@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
using Microsoft.MobileBlazorBindings.Elements.Handlers;
using System.Threading.Tasks;
using XF = Xamarin.Forms;
namespace Microsoft.MobileBlazorBindings.Elements
{
public partial class Editor : InputView
{
static Editor()
{
ElementHandlerRegistry.RegisterElementHandler<Editor>(
renderer => new EditorHandler(renderer, new XF.Editor()));
}
/// <summary>
/// Gets or sets a value that controls whether the editor will change size to accommodate input as the user enters it.
/// </summary>
/// <value>
/// Whether the editor will change size to accommodate input as the user enters it.
/// </value>
[Parameter] public XF.EditorAutoSizeOption? AutoSize { get; set; }
/// <summary>
/// Gets a value that indicates whether the font for the editor is bold, italic, or neither.
/// </summary>
[Parameter] public XF.FontAttributes? FontAttributes { get; set; }
/// <summary>
/// Gets the font family to which the font for the editor belongs.
/// </summary>
[Parameter] public string FontFamily { get; set; }
/// <summary>
/// Gets the size of the font for the editor.
/// </summary>
[Parameter] public double? FontSize { get; set; }
[Parameter] public bool? IsTextPredictionEnabled { get; set; }
public new XF.Editor NativeControl => ((EditorHandler)ElementHandler).EditorControl;
protected override void RenderAttributes(AttributesBuilder builder)
{
base.RenderAttributes(builder);
if (AutoSize != null)
{
builder.AddAttribute(nameof(AutoSize), (int)AutoSize.Value);
}
if (FontAttributes != null)
{
builder.AddAttribute(nameof(FontAttributes), (int)FontAttributes.Value);
}
if (FontFamily != null)
{
builder.AddAttribute(nameof(FontFamily), FontFamily);
}
if (FontSize != null)
{
builder.AddAttribute(nameof(FontSize), AttributeHelper.DoubleToString(FontSize.Value));
}
if (IsTextPredictionEnabled != null)
{
builder.AddAttribute(nameof(IsTextPredictionEnabled), IsTextPredictionEnabled.Value);
}
RenderAdditionalAttributes(builder);
}
partial void RenderAdditionalAttributes(AttributesBuilder builder);
}
}

Просмотреть файл

@ -3,24 +3,16 @@
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
using System.Threading.Tasks;
namespace Microsoft.MobileBlazorBindings.Elements
{
public partial class Entry : InputView
{
[Parameter] public EventCallback OnCompleted { get; set; }
[Parameter] public EventCallback<string> TextChanged { get; set; }
partial void RenderAdditionalAttributes(AttributesBuilder builder)
{
builder.AddAttribute("oncompleted", OnCompleted);
builder.AddAttribute("ontextchanged", EventCallback.Factory.Create<ChangeEventArgs>(this, HandleTextChanged));
}
private Task HandleTextChanged(ChangeEventArgs evt)
{
return TextChanged.InvokeAsync((string)evt.Value);
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.MobileBlazorBindings.Core;
namespace Microsoft.MobileBlazorBindings.Elements.Handlers
{
public partial class EditorHandler : InputViewHandler
{
partial void Initialize(NativeComponentRenderer renderer)
{
ConfigureEvent(
eventName: "oncompleted",
setId: id => CompletedEventHandlerId = id,
clearId: id => { if (CompletedEventHandlerId == id) { CompletedEventHandlerId = 0; } });
EditorControl.Completed += (s, e) =>
{
if (CompletedEventHandlerId != default)
{
renderer.Dispatcher.InvokeAsync(() => renderer.DispatchEventAsync(CompletedEventHandlerId, null, e));
}
};
}
public ulong CompletedEventHandlerId { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.MobileBlazorBindings.Core;
using System;
using XF = Xamarin.Forms;
namespace Microsoft.MobileBlazorBindings.Elements.Handlers
{
public partial class EditorHandler : InputViewHandler
{
private static readonly XF.EditorAutoSizeOption AutoSizeDefaultValue = XF.Editor.AutoSizeProperty.DefaultValue is XF.EditorAutoSizeOption value ? value : default;
private static readonly XF.FontAttributes FontAttributesDefaultValue = XF.Editor.FontAttributesProperty.DefaultValue is XF.FontAttributes value ? value : default;
private static readonly string FontFamilyDefaultValue = XF.Editor.FontFamilyProperty.DefaultValue is string value ? value : default;
private static readonly double FontSizeDefaultValue = XF.Editor.FontSizeProperty.DefaultValue is double value ? value : default;
private static readonly bool IsTextPredictionEnabledDefaultValue = XF.Editor.IsTextPredictionEnabledProperty.DefaultValue is bool value ? value : default;
public EditorHandler(NativeComponentRenderer renderer, XF.Editor editorControl) : base(renderer, editorControl)
{
EditorControl = editorControl ?? throw new ArgumentNullException(nameof(editorControl));
Initialize(renderer);
}
partial void Initialize(NativeComponentRenderer renderer);
public XF.Editor EditorControl { get; }
public override void ApplyAttribute(ulong attributeEventHandlerId, string attributeName, object attributeValue, string attributeEventUpdatesAttributeName)
{
switch (attributeName)
{
case nameof(XF.Editor.AutoSize):
EditorControl.AutoSize = (XF.EditorAutoSizeOption)AttributeHelper.GetInt(attributeValue, (int)AutoSizeDefaultValue);
break;
case nameof(XF.Editor.FontAttributes):
EditorControl.FontAttributes = (XF.FontAttributes)AttributeHelper.GetInt(attributeValue, (int)FontAttributesDefaultValue);
break;
case nameof(XF.Editor.FontFamily):
EditorControl.FontFamily = (string)attributeValue ?? FontFamilyDefaultValue;
break;
case nameof(XF.Editor.FontSize):
EditorControl.FontSize = AttributeHelper.StringToDouble((string)attributeValue, FontSizeDefaultValue);
break;
case nameof(XF.Editor.IsTextPredictionEnabled):
EditorControl.IsTextPredictionEnabled = AttributeHelper.GetBool(attributeValue, IsTextPredictionEnabledDefaultValue);
break;
default:
base.ApplyAttribute(attributeEventHandlerId, attributeName, attributeValue, attributeEventUpdatesAttributeName);
break;
}
}
}
}

Просмотреть файл

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
namespace Microsoft.MobileBlazorBindings.Elements.Handlers
@ -21,20 +20,8 @@ namespace Microsoft.MobileBlazorBindings.Elements.Handlers
renderer.Dispatcher.InvokeAsync(() => renderer.DispatchEventAsync(CompletedEventHandlerId, null, e));
}
};
ConfigureEvent(
eventName: "ontextchanged",
setId: id => TextChangedEventHandlerId = id,
clearId: id => { if (TextChangedEventHandlerId == id) { TextChangedEventHandlerId = 0; } });
EntryControl.TextChanged += (s, e) =>
{
if (TextChangedEventHandlerId != default)
{
renderer.Dispatcher.InvokeAsync(() => renderer.DispatchEventAsync(TextChangedEventHandlerId, null, new ChangeEventArgs { Value = EntryControl.Text }));
}
};
}
public ulong CompletedEventHandlerId { get; set; }
public ulong TextChangedEventHandlerId { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
namespace Microsoft.MobileBlazorBindings.Elements.Handlers
{
public partial class InputViewHandler
{
partial void Initialize(NativeComponentRenderer renderer)
{
ConfigureEvent(
eventName: "ontextchanged",
setId: id => TextChangedEventHandlerId = id,
clearId: id => { if (TextChangedEventHandlerId == id) { TextChangedEventHandlerId = 0; } });
InputViewControl.TextChanged += (s, e) =>
{
if (TextChangedEventHandlerId != default)
{
// InputViewControl.Text is used here instead of TextChangedEventArgs.NewTextValue to prevent infinite loops.
// See https://github.com/dotnet/MobileBlazorBindings/issues/430.
renderer.Dispatcher.InvokeAsync(() => renderer.DispatchEventAsync(TextChangedEventHandlerId, null, new ChangeEventArgs { Value = InputViewControl.Text }));
}
};
}
public ulong TextChangedEventHandlerId { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
using Microsoft.AspNetCore.Components;
using Microsoft.MobileBlazorBindings.Core;
using System.Threading.Tasks;
namespace Microsoft.MobileBlazorBindings.Elements
{
public partial class InputView : View
{
[Parameter] public EventCallback<string> TextChanged { get; set; }
partial void RenderAdditionalAttributes(AttributesBuilder builder)
{
builder.AddAttribute("ontextchanged", EventCallback.Factory.Create<ChangeEventArgs>(this, HandleTextChanged));
}
private Task HandleTextChanged(ChangeEventArgs evt)
{
return TextChanged.InvokeAsync((string)evt.Value);
}
}
}