using System; using System.Collections.Generic; using Avalonia.Controls.Platform.Surfaces; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.iOS.Specific; using Avalonia.Platform; using Avalonia.Rendering; using CoreGraphics; using Foundation; using ObjCRuntime; using UIKit; namespace Avalonia.iOS { [Adopts("UIKeyInput")] class TopLevelImpl : UIView, ITopLevelImpl, IFramebufferPlatformSurface { private readonly KeyboardEventsHelper _keyboardHelper; private IInputRoot _inputRoot; public TopLevelImpl() { _keyboardHelper = new KeyboardEventsHelper(this); AutoresizingMask = UIViewAutoresizing.All; _keyboardHelper.ActivateAutoShowKeyboard(); Surfaces = new object[] { this }; } [Export("hasText")] public bool HasText => _keyboardHelper.HasText(); [Export("insertText:")] public void InsertText(string text) => _keyboardHelper.InsertText(text); [Export("deleteBackward")] public void DeleteBackward() => _keyboardHelper.DeleteBackward(); public override bool CanBecomeFirstResponder => _keyboardHelper.CanBecomeFirstResponder(); public Action Closed { get; set; } public Action Input { get; set; } public Action Paint { get; set; } public Action Resized { get; set; } public Action ScalingChanged { get; set; } public new IPlatformHandle Handle => null; public double RenderScaling => UIScreen.MainScreen.Scale; public override void LayoutSubviews() => Resized?.Invoke(ClientSize); public Size ClientSize => Bounds.Size.ToAvalonia(); public IMouseDevice MouseDevice => iOSPlatform.MouseDevice; public IRenderer CreateRenderer(IRenderRoot root) { return new ImmediateRenderer(root); } public override void Draw(CGRect rect) { Paint?.Invoke(new Rect(rect.X, rect.Y, rect.Width, rect.Height)); } public void Invalidate(Rect rect) => SetNeedsDisplay(); public void SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot; public Point PointToClient(PixelPoint point) => point.ToPoint(1); public PixelPoint PointToScreen(Point point) => PixelPoint.FromPoint(point, 1); public void SetCursor(IPlatformHandle cursor) { //Not supported } public IEnumerable Surfaces { get; } public override void TouchesEnded(NSSet touches, UIEvent evt) { var touch = touches.AnyObject as UITouch; if (touch != null) { var location = touch.LocationInView(this).ToAvalonia(); Input?.Invoke(new RawPointerEventArgs( iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot, RawPointerEventType.LeftButtonUp, location, RawInputModifiers.None)); } } Point _touchLastPoint; public override void TouchesBegan(NSSet touches, UIEvent evt) { var touch = touches.AnyObject as UITouch; if (touch != null) { var location = touch.LocationInView(this).ToAvalonia(); _touchLastPoint = location; Input?.Invoke(new RawPointerEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot, RawPointerEventType.Move, location, RawInputModifiers.None)); Input?.Invoke(new RawPointerEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot, RawPointerEventType.LeftButtonDown, location, RawInputModifiers.None)); } } public override void TouchesMoved(NSSet touches, UIEvent evt) { var touch = touches.AnyObject as UITouch; if (touch != null) { var location = touch.LocationInView(this).ToAvalonia(); if (iOSPlatform.MouseDevice.Captured != null) Input?.Invoke(new RawPointerEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot, RawPointerEventType.Move, location, RawInputModifiers.LeftMouseButton)); else { //magic number based on test - correction of 0.02 is working perfect double correction = 0.02; Input?.Invoke(new RawMouseWheelEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot, location, (location - _touchLastPoint) * correction, RawInputModifiers.LeftMouseButton)); } _touchLastPoint = location; } } public ILockedFramebuffer Lock() => new EmulatedFramebuffer(this); public IPopupImpl CreatePopup() => null; public Action LostFocus { get; set; } } }