Browse Source

implement previewer interactions for mouse and keyboard.

Dan Walmsley 7 years ago
parent
commit
1eda1edc04

+ 141 - 1
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs

@@ -4,11 +4,15 @@ using System.Runtime.InteropServices;
 using Avalonia.Controls.Embedding.Offscreen;
 using Avalonia.Controls.Platform.Surfaces;
 using Avalonia.Input;
+using Avalonia.Input.Raw;
 using Avalonia.Layout;
 using Avalonia.Platform;
 using Avalonia.Remote.Protocol;
+using Avalonia.Remote.Protocol.Input;
 using Avalonia.Remote.Protocol.Viewport;
 using Avalonia.Threading;
+using InputModifiers = Avalonia.Input.InputModifiers;
+using Key = Avalonia.Input.Key;
 using PixelFormat = Avalonia.Platform.PixelFormat;
 using ProtocolPixelFormat = Avalonia.Remote.Protocol.Viewport.PixelFormat;
 
@@ -33,6 +37,65 @@ namespace Avalonia.Controls.Remote.Server
             _transport.OnMessage += OnMessage;
         }
 
+        private static RawMouseEventType GetAvaloniaEventType (Avalonia.Remote.Protocol.Input.MouseButton button, bool pressed)
+        {
+            switch (button)
+            {
+                case Avalonia.Remote.Protocol.Input.MouseButton.Left:
+                    return pressed ? RawMouseEventType.LeftButtonDown : RawMouseEventType.LeftButtonUp;
+
+                case Avalonia.Remote.Protocol.Input.MouseButton.Middle:
+                    return pressed ? RawMouseEventType.MiddleButtonDown : RawMouseEventType.MiddleButtonUp;
+
+                case Avalonia.Remote.Protocol.Input.MouseButton.Right:
+                    return pressed ? RawMouseEventType.RightButtonDown : RawMouseEventType.RightButtonUp;
+
+                default:
+                    return RawMouseEventType.Move;
+            }
+        }
+
+        private static InputModifiers GetAvaloniaInputModifiers (Avalonia.Remote.Protocol.Input.InputModifiers[] modifiers)
+        {
+            var result = InputModifiers.None;
+
+            foreach(var modifier in modifiers)
+            {
+                switch (modifier)
+                {
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.Control:
+                        result |= InputModifiers.Control;
+                        break;
+
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.Alt:
+                        result |= InputModifiers.Alt;
+                        break;
+
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.Shift:
+                        result |= InputModifiers.Shift;
+                        break;
+
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.Windows:
+                        result |= InputModifiers.Windows;
+                        break;
+
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.LeftMouseButton:
+                        result |= InputModifiers.LeftMouseButton;
+                        break;
+
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.MiddleMouseButton:
+                        result |= InputModifiers.MiddleMouseButton;
+                        break;
+
+                    case Avalonia.Remote.Protocol.Input.InputModifiers.RightMouseButton:
+                        result |= InputModifiers.RightMouseButton;
+                        break;
+                }
+            }
+
+            return result;
+        }
+
         protected virtual void OnMessage(IAvaloniaRemoteTransportConnection transport, object obj)
         {
             lock (_lock)
@@ -51,8 +114,9 @@ namespace Avalonia.Controls.Remote.Server
                     {
                         _dpi = new Vector(renderInfo.DpiX, renderInfo.DpiY);
                         _invalidated = true;
-                        RenderIfNeeded();
                     }
+                    
+                    Dispatcher.UIThread.Post(RenderIfNeeded);
                 }
                 if (obj is ClientSupportedPixelFormatsMessage supportedFormats)
                 {
@@ -91,6 +155,80 @@ namespace Avalonia.Controls.Remote.Server
                         _pendingAllocation = allocated;
                     }
                 }
+                if(obj is PointerMovedEventMessage pointer)
+                {
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        Input?.Invoke(new RawMouseEventArgs(
+                            MouseDevice, 
+                            0, 
+                            InputRoot, 
+                            RawMouseEventType.Move, 
+                            new Point(pointer.X, pointer.Y), 
+                            GetAvaloniaInputModifiers(pointer.Modifiers)));
+                    }, DispatcherPriority.Input);
+                }
+                if(obj is PointerPressedEventMessage pressed)
+                {
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        Input?.Invoke(new RawMouseEventArgs(
+                            MouseDevice,
+                            0,
+                            InputRoot,
+                            GetAvaloniaEventType(pressed.Button, true),
+                            new Point(pressed.X, pressed.Y),
+                            GetAvaloniaInputModifiers(pressed.Modifiers)));
+                    }, DispatcherPriority.Input);
+                }
+                if (obj is PointerPressedEventMessage released)
+                {
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        Input?.Invoke(new RawMouseEventArgs(
+                            MouseDevice,
+                            0,
+                            InputRoot,
+                            GetAvaloniaEventType(released.Button, false),
+                            new Point(released.X, released.Y),
+                            GetAvaloniaInputModifiers(released.Modifiers)));
+                    }, DispatcherPriority.Input);
+                }
+                if(obj is ScrollEventMessage scroll)
+                {
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        Input?.Invoke(new RawMouseWheelEventArgs(
+                            MouseDevice,
+                            0,
+                            InputRoot,
+                            new Point(scroll.X, scroll.Y),
+                            new Vector(scroll.DeltaX, scroll.DeltaY),
+                            GetAvaloniaInputModifiers(scroll.Modifiers)));
+                    }, DispatcherPriority.Input);
+                }
+                if(obj is KeyEventMessage key)
+                {
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        Input?.Invoke(new RawKeyEventArgs(
+                            KeyboardDevice,
+                            0,
+                            key.IsDown ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp,
+                            (Key)key.Key,
+                            GetAvaloniaInputModifiers(key.Modifiers)));
+                    }, DispatcherPriority.Input);
+                }
+                if(obj is TextInputEventMessage text)
+                {
+                    Dispatcher.UIThread.Post(() =>
+                    {
+                        Input?.Invoke(new RawTextInputEventArgs(
+                            KeyboardDevice,
+                            0,
+                            text.Text));
+                    }, DispatcherPriority.Input);
+                }
             }
         }
 
@@ -184,5 +322,7 @@ namespace Avalonia.Controls.Remote.Server
         }
 
         public override IMouseDevice MouseDevice { get; } = new MouseDevice();
+
+        public IKeyboardDevice KeyboardDevice { get; } = new KeyboardDevice();
     }
 }

+ 2 - 2
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Reactive.Disposables;
@@ -20,7 +20,7 @@ namespace Avalonia.DesignerSupport.Remote
         public IPlatformHandle Handle { get; }
         public Size MaxClientSize { get; }
         public Size ClientSize { get; }
-        public double Scaling { get; }
+        public double Scaling { get; } = 1.0;
         public IEnumerable<object> Surfaces { get; }
         public Action<RawInputEventArgs> Input { get; set; }
         public Action<Rect> Paint { get; set; }

+ 6 - 0
src/Avalonia.Remote.Protocol/InputMessages.cs

@@ -75,4 +75,10 @@ namespace Avalonia.Remote.Protocol.Input
         public Key Key { get; set; }
     }
 
+    [AvaloniaRemoteMessageGuid("C174102E-7405-4594-916F-B10B8248A17D")]
+    public class TextInputEventMessage : InputEventMessageBase
+    {
+        public string Text { get; set; }
+    }
+
 }