Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Mouse.cs
浏览该文件的文档.
1#if ANDROID
2using System.Collections.Concurrent;
3using Android.App;
4using Android.OS;
5using Android.Views;
6#pragma warning disable CA1416
7#elif BROWSER
9#elif !IOS
10using Silk.NET.Input;
11#endif
12
13namespace Engine.Input {
14 public static class Mouse {
15#if ANDROID
16 public struct MouseButtonInfo {
17 public MouseButton Button;
18 public bool Press;//true:按下,false: 抬起
19 public Point2 Position;
20
21 public MouseButtonInfo(MouseButton button, bool press, Point2 position) {
22 Button = button;
23 Press = press;
24 Position = position;
25 }
26 }
27
28 public static ConcurrentQueue<MouseButtonInfo> m_cachedMouseButtonEvents = [];
29
30 static Vector2 m_queuedMouseMovement;
31
32 static float m_queuedMouseWheelMovement;
33
34 static bool m_pointerCaptureRequested;
35#elif BROWSER
36 internal static Point2 m_currentMousePosition;
37 internal static Vector2 m_queuedMouseMovement;
38 internal static float m_queuedMouseWheelMovement;
39 static bool m_pointerCaptureRequested;
40#elif !IOS
41 public static IMouse m_mouse;
42#endif
44
46
48
50
52
54
55 public static Point2 MouseMovement { get; private set; }
56
57 public static int MouseWheelMovement { get; private set; }
58
59 public static Point2? MousePosition { get; private set; }
60
61 public static bool IsMouseVisible { get; set; }
62
63 public static event Action<MouseEvent> MouseMove;
64
65 public static event Action<MouseButtonEvent> MouseDown;
66
67 public static event Action<MouseButtonEvent> MouseUp;
68
69 public static void SetMousePosition(int x, int y) {
70#if !MOBILE && !BROWSER
71 m_mouse.Position = new System.Numerics.Vector2(x, y);
72#endif
73 }
74
75 internal static void Initialize() {
76#if ANDROID
77 if (Build.VERSION.SdkInt >= (BuildVersionCodes)26) {
78 Window.m_surface.SetOnCapturedPointerListener(new OnCapturedPointerListener());
79 }
80#elif !IOS && !BROWSER
82 m_mouse.MouseDown += MouseDownHandler;
83 m_mouse.MouseUp += MouseUpHandler;
84 //m_mouse.MouseMove += MouseMoveHandler;
85 m_mouse.Scroll += MouseWheelHandler;
86#endif
87 }
88
89 internal static void Dispose() { }
90
91 internal static void BeforeFrame() {
92#if ANDROID
93 if (IsMouseVisible) {
94 if (m_pointerCaptureRequested) {
95 m_pointerCaptureRequested = false;
96 if (Build.VERSION.SdkInt >= (BuildVersionCodes)26) {
97 Window.m_surface?.ReleasePointerCapture();
98 }
99 Clear();
100 }
102 m_lastMousePosition = null;
103 }
104 else {
105 if (!m_pointerCaptureRequested) {
106 m_pointerCaptureRequested = true;
107 if (Build.VERSION.SdkInt >= (BuildVersionCodes)26) {
108 Window.m_surface?.RequestPointerCapture();
109 }
110 }
111 if (m_lastMousePosition.HasValue) {
112 MouseMovement = Point2.Round(m_queuedMouseMovement.X, m_queuedMouseMovement.Y);
113 }
114 //安卓端m_lastMousePosition只用来表示是不是鼠标不可见后的第一帧
116 m_queuedMouseMovement = Vector2.Zero;
117 }
118 MouseWheelMovement = (int)MathUtils.Round(m_queuedMouseWheelMovement) * 120;
119 m_queuedMouseWheelMovement = 0f;
120 while (!m_cachedMouseButtonEvents.IsEmpty) {
121 if (m_cachedMouseButtonEvents.TryDequeue(out MouseButtonInfo buttonInfo)) {
122 if (buttonInfo.Press) {
123 ProcessMouseDown(buttonInfo.Button, buttonInfo.Position);
124 }
125 else {
126 ProcessMouseUp(buttonInfo.Button, buttonInfo.Position);
127 }
128 }
129 else {
130 Thread.Yield();
131 }
132 }
133#elif BROWSER
134 if (Window.IsActive) {
135 ProcessMouseMove(m_currentMousePosition);
136 if (IsMouseVisible) {
137 if (m_pointerCaptureRequested) {
138 m_pointerCaptureRequested = false;
140 }
142 m_lastMousePosition = null;
143 }
144 else {
145 if (!m_pointerCaptureRequested) {
146 m_pointerCaptureRequested = true;
148 }
149 if (m_lastMousePosition.HasValue) {
150 MouseMovement = Point2.Round(m_queuedMouseMovement.X, m_queuedMouseMovement.Y);
151 }
152 m_lastMousePosition = m_currentMousePosition;
153 m_queuedMouseMovement = Vector2.Zero;
154 }
155 }
156 else {
157 m_lastMousePosition = null;
158 }
159 MouseWheelMovement = (int)MathUtils.Round(m_queuedMouseWheelMovement) * 120;
160 m_queuedMouseWheelMovement = 0f;
161#elif !IOS
162 if (Window.IsActive) {
163 Point2 position = new((int)m_mouse.Position.X, (int)m_mouse.Position.Y);
164 ProcessMouseMove(position);
165 if (IsMouseVisible) {
166 m_mouse.Cursor.CursorMode = CursorMode.Normal;
168 m_lastMousePosition = null;
169 }
170 else {
171 m_mouse.Cursor.CursorMode = CursorMode.Raw;
172 if (m_lastMousePosition.HasValue) {
173 MouseMovement = new Point2(position.X - m_lastMousePosition.Value.X, position.Y - m_lastMousePosition.Value.Y);
174 }
175 Point2 windowSize = Window.Size;
176 if (position.X < 0
177 || position.X >= windowSize.X
178 || position.Y < 0
179 || position.Y >= windowSize.Y) {
180 position = new Point2(windowSize.X / 2, windowSize.Y / 2);
181 SetMousePosition(position.X, position.Y);
182 }
183 m_lastMousePosition = position;
184 }
185 }
186 else {
187 m_lastMousePosition = null;
188 }
189#endif
190 }
191#if ANDROID
192 public static void EnqueueMouseButtonEvent(MouseButton button, bool press, Point2 position) => m_cachedMouseButtonEvents.Enqueue(new MouseButtonInfo(button, press, position));
193#endif
194#if ANDROID
195 internal static void HandleMotionEvent(MotionEvent e) {
196 switch (e.Action) {
197 case MotionEventActions.Move: {
198 for (int num = e.HistorySize - 1; num >= 0; num--) {
199 m_queuedMouseMovement += new Vector2(e.GetHistoricalX(num), e.GetHistoricalY(num));
200 }
201 MousePosition = Point2.Round(e.GetX(), e.GetY());
202 break;
203 }
204 case MotionEventActions.HoverMove: MousePosition = Point2.Round(e.GetX(), e.GetY()); break;
205 case MotionEventActions.ButtonPress:
206 EnqueueMouseButtonEvent(TranslateMouseButton(e.ActionButton), true, Point2.Round(e.GetX(), e.GetY())); break;
207 case MotionEventActions.ButtonRelease:
208 EnqueueMouseButtonEvent(TranslateMouseButton(e.ActionButton), false, Point2.Round(e.GetX(), e.GetY())); break;
209 case MotionEventActions.PointerIdShift: {
210 for (int num2 = e.HistorySize - 1; num2 >= 0; num2--) {
211 m_queuedMouseWheelMovement += MathUtils.Sign(e.GetHistoricalAxisValue(Axis.Vscroll, num2));
212 }
213 m_queuedMouseWheelMovement += MathUtils.Sign(e.GetAxisValue(Axis.Vscroll));
214 break;
215 }
216 }
217 }
218
219 public static MouseButton TranslateMouseButton(MotionEventButtonState state) => state switch {
220 MotionEventButtonState.Primary => MouseButton.Left,
221 MotionEventButtonState.Secondary => MouseButton.Right,
222 MotionEventButtonState.Tertiary => MouseButton.Middle,
223 MotionEventButtonState.Back => MouseButton.Ext1,
224 MotionEventButtonState.Forward => MouseButton.Ext2,
225 _ => MouseButton.Left
226 };
227
228 public static PointerIconType TranslateCursorType(CursorType cursorType) => cursorType switch {
229 CursorType.Arrow => PointerIconType.Arrow,
230 CursorType.IBeam => PointerIconType.Text,
231 CursorType.Crosshair => PointerIconType.Crosshair,
232 CursorType.Hand => PointerIconType.Hand,
233 CursorType.HResize => PointerIconType.HorizontalDoubleArrow,
234 CursorType.VResize => PointerIconType.VerticalDoubleArrow,
235 CursorType.NwseResize => PointerIconType.TopLeftDiagonalDoubleArrow,
236 CursorType.NeswResize => PointerIconType.TopRightDiagonalDoubleArrow,
237 CursorType.ResizeAll => PointerIconType.AllScroll,
238 CursorType.NotAllowed => PointerIconType.NoDrop,
239 CursorType.Grab => PointerIconType.Grab,
240 CursorType.Grabbing => PointerIconType.Grabbing,
241 _ => PointerIconType.Default
242 };
243
244 public class OnCapturedPointerListener : Java.Lang.Object, View.IOnCapturedPointerListener {
245 public bool OnCapturedPointer(View view, MotionEvent e) {
246 if (e == null) {
247 return true;
248 }
249 if ((e.Source & InputSourceType.MouseRelative) == InputSourceType.MouseRelative) {
250 HandleMotionEvent(e);
251 }
252 return true;
253 }
254 }
255#elif !IOS && !BROWSER
256 static void MouseDownHandler(IMouse mouse, Silk.NET.Input.MouseButton button) {
257 MouseButton mouseButton = TranslateMouseButton(button);
258 if (mouseButton != (MouseButton)(-1)) {
259 System.Numerics.Vector2 position = mouse.Position;
260 ProcessMouseDown(mouseButton, new Point2((int)position.X, (int)position.Y));
261 }
262 }
263
264 static void MouseUpHandler(IMouse mouse, Silk.NET.Input.MouseButton button) {
265 MouseButton mouseButton = TranslateMouseButton(button);
266 if (mouseButton != (MouseButton)(-1)) {
267 System.Numerics.Vector2 position = mouse.Position;
268 ProcessMouseUp(mouseButton, new Point2((int)position.X, (int)position.Y));
269 }
270 }
271
272 // ReSharper disable UnusedParameter.Local
273 // ReSharper disable UnusedMember.Local
274 static void MouseMoveHandler(IMouse mouse, System.Numerics.Vector2 position)
275 // ReSharper restore UnusedMember.Local
276 // ReSharper restore UnusedParameter.Local
277 {
278 ProcessMouseMove(new Point2((int)position.X, (int)position.Y));
279 }
280
281 static void MouseWheelHandler(IMouse mouse, ScrollWheel scrollWheel) => ProcessMouseWheel(scrollWheel.Y);
282
283 public static MouseButton TranslateMouseButton(Silk.NET.Input.MouseButton mouseButton) => mouseButton switch {
284 Silk.NET.Input.MouseButton.Left => MouseButton.Left,
285 Silk.NET.Input.MouseButton.Right => MouseButton.Right,
286 Silk.NET.Input.MouseButton.Middle => MouseButton.Middle,
287 Silk.NET.Input.MouseButton.Button4 => MouseButton.Ext1,
288 Silk.NET.Input.MouseButton.Button5 => MouseButton.Ext2,
289 _ => (MouseButton)(-1)
290 };
291
292 public static StandardCursor TranslateCursorType(CursorType cursorType) => cursorType switch {
293 CursorType.Arrow => StandardCursor.Arrow,
294 CursorType.IBeam => StandardCursor.IBeam,
295 CursorType.Crosshair => StandardCursor.Crosshair,
296 CursorType.Hand or CursorType.Grab or CursorType.Grabbing => StandardCursor.Hand,
297 CursorType.HResize => StandardCursor.HResize,
298 CursorType.VResize => StandardCursor.VResize,
299 CursorType.NwseResize => StandardCursor.NwseResize,
300 CursorType.NeswResize => StandardCursor.NeswResize,
301 CursorType.ResizeAll => StandardCursor.ResizeAll,
302 CursorType.NotAllowed => StandardCursor.NotAllowed,
303 CursorType.Wait => StandardCursor.Wait,
304 CursorType.WaitArrow => StandardCursor.WaitArrow,
305 _ => StandardCursor.Default
306 };
307#endif
308
309 static Mouse() {
310 m_mouseButtonsDownArray = new bool[Enum.GetValues<MouseButton>().Length];
311 m_mouseButtonsDownFrameArray = new int[Enum.GetValues<MouseButton>().Length];
312 m_mouseButtonsDelayedUpArray = new bool[Enum.GetValues<MouseButton>().Length];
313 m_mouseButtonsDownOnceArray = new bool[Enum.GetValues<MouseButton>().Length];
314 m_mouseButtonsUpOnceArray = new bool[Enum.GetValues<MouseButton>().Length];
315 IsMouseVisible = true;
316 }
317
318 public static bool IsMouseButtonDown(MouseButton mouseButton) => m_mouseButtonsDownArray[(int)mouseButton];
319
320 public static bool IsMouseButtonDownOnce(MouseButton mouseButton) => m_mouseButtonsDownOnceArray[(int)mouseButton];
321
322 public static bool IsMouseButtonUpOnce(MouseButton mouseButton) => m_mouseButtonsUpOnceArray[(int)mouseButton];
323
324 public static void Clear() {
325 for (int i = 0; i < m_mouseButtonsDownArray.Length; i++) {
326 m_mouseButtonsDownArray[i] = false;
330 m_mouseButtonsUpOnceArray[i] = false;
331 }
332 }
333
334 internal static void AfterFrame() {
335 for (int i = 0; i < m_mouseButtonsDownArray.Length; i++) {
339 m_mouseButtonsDownArray[i] = false;
341 }
342 else {
343 m_mouseButtonsUpOnceArray[i] = false;
344 }
345 }
346 if (!IsMouseVisible) {
347 MousePosition = null;
348#if !MOBILE && !BROWSER
349 m_mouse.Cursor.CursorMode = Window.IsActive ? CursorMode.Raw : CursorMode.Normal;
350 }
351 else {
352 m_mouse.Cursor.CursorMode = CursorMode.Normal;
353#endif
354 }
356 }
357
358 public static void ProcessMouseDown(MouseButton mouseButton, Point2 position) {
359 if (Window.IsActive
361 if (!MousePosition.HasValue) {
362 ProcessMouseMove(position);
363 }
364 m_mouseButtonsDownArray[(int)mouseButton] = true;
365 m_mouseButtonsDownFrameArray[(int)mouseButton] = Time.FrameIndex;
366 m_mouseButtonsDownOnceArray[(int)mouseButton] = true;
367 if (IsMouseVisible && MouseDown != null) {
368 MouseDown(new MouseButtonEvent { Button = mouseButton, Position = position });
369 }
370 }
371 }
372
373 public static void ProcessMouseUp(MouseButton mouseButton, Point2 position) {
374 if (Window.IsActive
376 if (!MousePosition.HasValue) {
377 ProcessMouseMove(position);
378 }
379 if (m_mouseButtonsDownArray[(int)mouseButton]
380 && Time.FrameIndex == m_mouseButtonsDownFrameArray[(int)mouseButton]) {
381 m_mouseButtonsDelayedUpArray[(int)mouseButton] = true;
382 }
383 else {
384 m_mouseButtonsDownArray[(int)mouseButton] = false;
385 m_mouseButtonsUpOnceArray[(int)mouseButton] = true;
386 }
387 if (IsMouseVisible && MouseUp != null) {
388 MouseUp(new MouseButtonEvent { Button = mouseButton, Position = position });
389 }
390 }
391 }
392
393 public static void ProcessMouseMove(Point2 position) {
394 if (Window.IsActive
396 && IsMouseVisible) {
397 MousePosition = position;
398 MouseMove?.Invoke(new MouseEvent { Position = position });
399 }
400 }
401
402 public static void ProcessMouseWheel(float value) {
403 if (Window.IsActive
405 MouseWheelMovement += (int)(120 * value);
406 }
407 }
408
409 public static void SetCursorType(CursorType cursorType) {
410#if ANDROID
411 //不知道为什么安卓上无效
412 if (Build.VERSION.SdkInt >= (BuildVersionCodes)24) {
413 Window.m_surface?.PointerIcon = PointerIcon.GetSystemIcon(Application.Context, TranslateCursorType(cursorType));
414 }
415#elif !IOS && !BROWSER
416 m_mouse.Cursor.StandardCursor = TranslateCursorType(cursorType);
417#endif
418 }
419 }
420}
static partial void SetNeedPointerLock(bool need)
static bool IsKeyboardVisible
static void MouseUpHandler(IMouse mouse, Silk.NET.Input.MouseButton button)
static bool IsMouseButtonUpOnce(MouseButton mouseButton)
static void MouseDownHandler(IMouse mouse, Silk.NET.Input.MouseButton button)
static void BeforeFrame()
static bool[] m_mouseButtonsDownOnceArray
static Action< MouseButtonEvent > MouseDown
static void Initialize()
static void Clear()
static ? Point2 MousePosition
static void MouseMoveHandler(IMouse mouse, System.Numerics.Vector2 position)
static void ProcessMouseDown(MouseButton mouseButton, Point2 position)
static void ProcessMouseWheel(float value)
static bool IsMouseButtonDownOnce(MouseButton mouseButton)
static int MouseWheelMovement
static void ProcessMouseMove(Point2 position)
static Action< MouseButtonEvent > MouseUp
static int[] m_mouseButtonsDownFrameArray
static void MouseWheelHandler(IMouse mouse, ScrollWheel scrollWheel)
static bool[] m_mouseButtonsDownArray
static void ProcessMouseUp(MouseButton mouseButton, Point2 position)
static void SetCursorType(CursorType cursorType)
static bool[] m_mouseButtonsUpOnceArray
static IMouse m_mouse
static bool IsMouseButtonDown(MouseButton mouseButton)
static Point2 MouseMovement
static ? Point2 m_lastMousePosition
static Action< MouseEvent > MouseMove
static void AfterFrame()
static bool IsMouseVisible
static bool[] m_mouseButtonsDelayedUpArray
static void SetMousePosition(int x, int y)
static StandardCursor TranslateCursorType(CursorType cursorType)
static void Dispose()
static MouseButton TranslateMouseButton(Silk.NET.Input.MouseButton mouseButton)
static float Round(float x)
static int Sign(int x)
static int FrameIndex
定义 Time.cs:26
static bool IsActive
static Point2 Size
static IInputContext m_inputContext
@ Crosshair
Crosshair cursor.
@ Arrow
Regular arrow cursor.
@ Wait
Hourglass/waiting cursor.
@ WaitArrow
Regular arrow but with an hourglass/waiting icon cursor.
@ IBeam
Text input I-beam cursor.
@ ResizeAll
Omni-directional resize/move cursor.
@ VResize
Vertical resize arrow cursor.
@ HResize
Horizontal resize arrow cursor.
@ NeswResize
Top-right to bottom-left diagonal resize/move arrow cursor.
@ NwseResize
Top-left to bottom-right diagonal resize/move arrow cursor.
@ NotAllowed
Operation not allowed cursor.
static readonly Point2 Zero
static Point2 Round(Vector2 v)
static readonly Vector2 Zero