1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using Antmicro.Renode.Peripherals.Input; 10 using Xwt; 11 12 namespace Antmicro.Renode.Extensions.Analyzers.Video.Handlers 13 { 14 internal class AbsolutePointerHandler : PointerHandler 15 { AbsolutePointerHandler(IAbsolutePositionPointerInput tablet, FrameBufferDisplayWidget widget)16 public AbsolutePointerHandler(IAbsolutePositionPointerInput tablet, FrameBufferDisplayWidget widget) : base(tablet) 17 { 18 this.widget = widget; 19 previousCursorType = widget.Cursor; 20 // it looks strange, but without it handling cursor for the first time causes glitches 21 ShowCursor(); 22 } 23 Init()24 public override void Init() 25 { 26 // this will hide cursor and draw cross if needed 27 PointerMoved(lastX, lastY, 0, 0); 28 } 29 ButtonReleased(int button)30 public override void ButtonReleased(int button) 31 { 32 base.ButtonReleased(button); 33 if(isCursorOverImageRectangle) 34 { 35 HideCursor(); 36 } 37 } 38 PointerMoved(int x, int y, int dx, int dy)39 public override void PointerMoved(int x, int y, int dx, int dy) 40 { 41 lastX = x; 42 lastY = y; 43 44 var image = widget.Image; 45 if(image == null) 46 { 47 return; 48 } 49 50 var ainput = (IAbsolutePositionPointerInput)input; 51 var imgRect = widget.ActualImageArea; 52 53 // if cursor doesn't touch actual image, return 54 if(!imgRect.IntersectsWith(new Rectangle(x, y, 1, 1))) 55 { 56 ShowCursor(); 57 isCursorOverImageRectangle = false; 58 return; 59 } 60 if(!isCursorOverImageRectangle) 61 { 62 widget.CanGetFocus = true; 63 widget.SetFocus(); 64 isCursorOverImageRectangle = true; 65 HideCursor(); 66 } 67 68 // this fragment converts click-point coordinates: 69 // from 70 // FrameBufferAnalyzer coordinates system (i.e., XWT coordinates of canvas on which the buffer was drawn) 71 // through 72 // Buffer coordinates system (i.e., resolution set on emulated graphic card) 73 // to 74 // Touchscreen coordinates system 75 var maxX = (int)image.Width; 76 var maxY = (int)image.Height; 77 78 var imageX = ((x - imgRect.X) / imgRect.Width) * maxX; 79 var imageY = ((y - imgRect.Y) / imgRect.Height) * maxY; 80 81 X = (int)imageX; 82 Y = (int)imageY; 83 84 var touchscreenX = (int)Math.Round(imageX * ainput.MaxX / maxX); 85 var touchscreenY = (int)Math.Round(imageY * ainput.MaxY / maxY); 86 87 ainput.MoveTo(touchscreenX, touchscreenY); 88 89 var opm = OnPointerMoved; 90 if(opm != null) 91 { 92 opm(X, Y); 93 } 94 } 95 96 public int X { get; protected set; } 97 public int Y { get; protected set; } 98 99 public event Action<int, int> OnPointerMoved; 100 HideCursor()101 private void HideCursor() 102 { 103 if(widget.Cursor == CursorType.Invisible) 104 { 105 return; 106 } 107 previousCursorType = widget.Cursor; 108 widget.Cursor = CursorType.Invisible; 109 } 110 ShowCursor()111 private void ShowCursor() 112 { 113 widget.Cursor = previousCursorType; 114 } 115 116 private int lastX, lastY; 117 private CursorType previousCursorType; 118 private readonly FrameBufferDisplayWidget widget; 119 private bool isCursorOverImageRectangle; 120 } 121 } 122 123