MouseApi.hx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import hxd.impl.MouseMode;
  2. import h2d.Graphics;
  3. import h2d.Text;
  4. import hxd.Key;
  5. using hxd.Math;
  6. class MouseApi extends SampleApp {
  7. var state: Text;
  8. var restore: Bool;
  9. var propagate: Bool;
  10. var virtualCursor: Graphics;
  11. var relativePath: Graphics;
  12. var relX: Float;
  13. var relY: Float;
  14. var expectedMode: MouseMode;
  15. override function init() {
  16. super.init();
  17. var window = hxd.Window.getInstance();
  18. addText("Press Escape or right click to restore to Absolute mouse mode");
  19. state = addText("\n");
  20. #if !js // Not supported on JS
  21. // Lock the mouse within the window boundaries.
  22. addCheck("MouseClip", () -> window.mouseClip, (v) -> window.mouseClip = v);
  23. #end
  24. // Use setCursorPos in order to warp the mouse
  25. // JS: Due to browser limitations only useful in relative modes to move the virtual cursor.
  26. addButton("Set position to center", () -> window.setCursorPos(s2d.width>>1, s2d.height>>1));
  27. addText("MouseMode:");
  28. // The default mouse mode behaves like a regular mouse.
  29. addButton("Absolute", () -> window.mouseMode = expectedMode = Absolute);
  30. // Callback will get relative mouse movement.
  31. addButton("Relative", () -> {
  32. window.mouseMode = expectedMode = Relative(onRelativeMove, restore);
  33. relX = 0;
  34. relY = 0;
  35. relativePath.clear();
  36. relativePath.setPosition(s2d.width>>1, s2d.height>>1);
  37. });
  38. // Mouse position would be able to leave the window boundaries, but clipped on exit.
  39. addButton("AbsoluteUnbound", () -> window.mouseMode = expectedMode = AbsoluteUnbound(restore));
  40. // When restoring to Absolute: Either clip mouse position or restore to where it entered relative mode.
  41. addCheck("RestorePos", () -> restore, (v) -> restore = v);
  42. // Would set propagate flag in Relative mode, allowing mouse movement events to pass trough.
  43. addCheck("Propagate", () -> propagate, (v) -> propagate = v);
  44. relativePath = new Graphics();
  45. s2d.addChildAt(relativePath, 0);
  46. virtualCursor = new Graphics(s2d);
  47. virtualCursor.lineStyle(1);
  48. virtualCursor.beginFill(0xffffff);
  49. virtualCursor.moveTo(0, 0);
  50. virtualCursor.lineTo(10, 10);
  51. virtualCursor.lineTo(0, 16);
  52. virtualCursor.endFill();
  53. #if js
  54. // On JS, browser can force-exit the relative mode. In which case switch back to one we want.
  55. window.onMouseModeChange = (from, to) -> to != expectedMode ? from : to;
  56. #end
  57. }
  58. override function update(dt:Float) {
  59. var window = hxd.Window.getInstance();
  60. if (Key.isReleased(Key.ESCAPE) || Key.isReleased(Key.MOUSE_RIGHT)) window.mouseMode = expectedMode = Absolute;
  61. state.text = "Current mode: " + window.mouseMode.getName() + "\nMouse position: " + window.mouseX + ", " + window.mouseY;
  62. virtualCursor.visible = window.mouseMode != Absolute;
  63. virtualCursor.setPosition(window.mouseX, window.mouseY);
  64. }
  65. function onRelativeMove(e: hxd.Event) {
  66. // Draw the movement segment and keep Graphics centered.
  67. relativePath.x -= e.relX;
  68. relativePath.y -= e.relY;
  69. relativePath.lineStyle(1, Std.int(((Math.cos(relX * .05) + 1)) / 2 * 0xff) << 16 | Std.int(((Math.sin(relY * .05) + 1)) / 2 * 0xff) << 8 | 0xff, 1);
  70. relativePath.moveTo(relX, relY);
  71. relX += e.relX;
  72. relY += e.relY;
  73. relativePath.lineTo(relX, relY);
  74. relativePath.lineStyle();
  75. // Since in relative mode mouse position is not updated - update it manually.
  76. var window = hxd.Window.getInstance();
  77. if (propagate) {
  78. window.setCursorPos((window.mouseX + Std.int(e.relX)).iclamp(0, window.width), (window.mouseY + Std.int(e.relY)).iclamp(0, window.height));
  79. e.propagate = true;
  80. }
  81. }
  82. static function main() {
  83. new MouseApi();
  84. }
  85. }