Browse Source

[WASM] Cursors

pull/7295/head
Sergey Mikolaitis 4 years ago
parent
commit
d8c89df26b
  1. 1
      src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs
  2. 92
      src/Web/Avalonia.Web.Blazor/Cursor.cs
  3. 9
      src/Web/Avalonia.Web.Blazor/RazorViewTopLevelImpl.cs
  4. 21
      src/Web/Avalonia.Web.Blazor/WinStubs.cs
  5. 2
      src/Web/Avalonia.Web.Blazor/WindowingPlatform.cs

1
src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs

@ -257,6 +257,7 @@ namespace Avalonia.Web.Blazor
_inputHelper.Hide();
_inputHelper.SetCursor("default");
_topLevelImpl.SetCssCursor = _inputHelper.SetCursor;
Console.WriteLine("starting html canvas setup");
_interop = await SKHtmlCanvasInterop.ImportAsync(Js, _htmlCanvas, OnRenderFrame);

92
src/Web/Avalonia.Web.Blazor/Cursor.cs

@ -0,0 +1,92 @@
using Avalonia.Input;
using Avalonia.Platform;
namespace Avalonia.Web.Blazor
{
public class CssCursor : ICursorImpl
{
public string? Value { get; set; }
public CssCursor(StandardCursorType type)
{
Value = ToKeyword(type);
}
/// <summary>
/// Create a cursor from base64 image
/// </summary>
public CssCursor(string base64, string format, PixelPoint hotspot, StandardCursorType fallback)
{
Value = $"url(data:image/{format},{base64}) {hotspot.X} {hotspot.Y}, {ToKeyword(fallback)}";
}
/// <summary>
/// Create a cursor from url to *.cur file.
/// </summary>
public CssCursor(string url, StandardCursorType fallback)
{
Value = $"url('{url}'), {ToKeyword(fallback)}";
}
/// <summary>
/// Create a cursor from png/svg and hotspot position
/// </summary>
public CssCursor(string url, PixelPoint hotSpot, StandardCursorType fallback)
{
Value = $"url('{url}') {hotSpot.X} {hotSpot.Y}, {ToKeyword(fallback)}";
}
private static string ToKeyword(StandardCursorType type) => type switch
{
StandardCursorType.Hand => "pointer",
StandardCursorType.Cross => "crosshair",
StandardCursorType.Help => "help",
StandardCursorType.Ibeam => "text",
StandardCursorType.No => "not-allowed",
StandardCursorType.None => "none",
StandardCursorType.Wait => "progress",
StandardCursorType.AppStarting => "wait",
StandardCursorType.DragMove => "move",
StandardCursorType.DragCopy => "copy",
StandardCursorType.DragLink => "alias",
StandardCursorType.UpArrow => "default",/*not found matching one*/
StandardCursorType.SizeWestEast => "ew-resize",
StandardCursorType.SizeNorthSouth => "ns-resize",
StandardCursorType.SizeAll => "move",
StandardCursorType.TopSide => "n-resize",
StandardCursorType.BottomSide => "s-resize",
StandardCursorType.LeftSide => "w-resize",
StandardCursorType.RightSide => "e-resize",
StandardCursorType.TopLeftCorner => "nw-resize",
StandardCursorType.TopRightCorner => "ne-resize",
StandardCursorType.BottomLeftCorner => "sw-resize",
StandardCursorType.BottomRightCorner => "se-resize",
_ => "default",
};
public void Dispose() {}
}
internal class CssCursorFactory : ICursorFactory
{
public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot)
{
using var imageStream = new MemoryStream();
cursor.Save(imageStream);
//not memory optimized because CryptoStream with ToBase64Transform is not supported in the browser.
var base64String = Convert.ToBase64String(imageStream.ToArray());
return new CssCursor(base64String, "png", hotSpot, StandardCursorType.Arrow);
}
ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType)
{
return new CssCursor(cursorType);
}
}
}

9
src/Web/Avalonia.Web.Blazor/RazorViewTopLevelImpl.cs

@ -126,8 +126,12 @@ namespace Avalonia.Web.Blazor
public void SetCursor(ICursorImpl cursor)
{
// nop
var cur = cursor as CssCursor;
if (cur == null || cur.Value == null)
{
throw new NotSupportedException();
}
SetCssCursor?.Invoke(cur.Value);
}
public IPopupImpl? CreatePopup()
@ -146,6 +150,7 @@ namespace Avalonia.Web.Blazor
public IEnumerable<object> Surfaces => new object[] { _currentSurface! };
public Action<string>? SetCssCursor { get; set; }
public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; }
public Action<Size, PlatformResizeReason>? Resized { get; set; }

21
src/Web/Avalonia.Web.Blazor/WinStubs.cs

@ -23,27 +23,6 @@ namespace Avalonia.Web.Blazor
public Task<object> GetDataAsync(string format) => Task.FromResult<object>(new ());
}
internal class CursorStub : ICursorImpl
{
public void Dispose()
{
}
}
internal class CursorFactoryStub : ICursorFactory
{
public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot)
{
return new CursorStub();
}
ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType)
{
return new CursorStub();
}
}
internal class IconLoaderStub : IPlatformIconLoader
{
private class IconStub : IWindowIconImpl

2
src/Web/Avalonia.Web.Blazor/WindowingPlatform.cs

@ -35,7 +35,7 @@ namespace Avalonia.Web.Blazor
s_keyboard = new KeyboardDevice();
AvaloniaLocator.CurrentMutable
.Bind<IClipboard>().ToSingleton<ClipboardStub>()
.Bind<ICursorFactory>().ToSingleton<CursorFactoryStub>()
.Bind<ICursorFactory>().ToSingleton<CssCursorFactory>()
.Bind<IKeyboardDevice>().ToConstant(s_keyboard)
.Bind<IPlatformSettings>().ToConstant(instance)
.Bind<IPlatformThreadingInterface>().ToConstant(instance)

Loading…
Cancel
Save