Przeglądaj źródła

Merge branch 'refs/heads/mouselock' into devel

# Conflicts:
#	window/canvas.go
#	window/glfw.go
#	window/window.go
Min 1 rok temu
rodzic
commit
df5f75b0ac
3 zmienionych plików z 66 dodań i 12 usunięć
  1. 51 12
      window/canvas.go
  2. 8 0
      window/glfw.go
  3. 7 0
      window/window.go

+ 51 - 12
window/canvas.go

@@ -328,18 +328,20 @@ type WebGlCanvas struct {
 	cursorEv CursorEvent
 	scrollEv ScrollEvent
 	focusEv  FocusEvent
+	lockEv   LockEvent
 
 	// Callbacks
-	onCtxMenu  js.Func
-	keyDown    js.Func
-	keyUp      js.Func
-	mouseDown  js.Func
-	mouseUp    js.Func
-	mouseMove  js.Func
-	mouseWheel js.Func
-	winResize  js.Func
-	winFocus   js.Func
-	winBlur    js.Func
+	onCtxMenu   js.Func
+	keyDown     js.Func
+	keyUp       js.Func
+	mouseDown   js.Func
+	mouseUp     js.Func
+	mouseMove   js.Func
+	mouseWheel  js.Func
+	winResize   js.Func
+	winFocus    js.Func
+	winBlur     js.Func
+	pointerLock js.Func
 }
 
 // Init initializes the WebGlCanvas singleton.
@@ -386,6 +388,13 @@ func Init(canvasId string) error {
 
 	// TODO scaling/hidpi (device pixel ratio)
 
+	w.pointerLock = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+		w.lockEv.Locked = doc.Get("pointerLockElement").Equal(w.canvas)
+		w.Dispatch(OnLockChange, &w.lockEv)
+		return nil
+	})
+	doc.Call("addEventListener", "pointerlockchange", w.pointerLock)
+
 	// Set up key down callback to dispatch event
 	w.keyDown = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
 		event := args[0]
@@ -435,8 +444,14 @@ func Init(canvasId string) error {
 	// Set up mouse move callback to dispatch event
 	w.mouseMove = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
 		event := args[0]
-		w.cursorEv.Xpos = float32(event.Get("offsetX").Float()) //* float32(w.scaleX) TODO
-		w.cursorEv.Ypos = float32(event.Get("offsetY").Float()) //* float32(w.scaleY)
+		if w.lockEv.Locked {
+			w.cursorEv.Xpos += float32(event.Get("movementX").Float())
+			w.cursorEv.Ypos += float32(event.Get("movementY").Float())
+		} else {
+			w.cursorEv.Xpos = float32(event.Get("offsetX").Float()) //* float32(w.scaleX) TODO
+			w.cursorEv.Ypos = float32(event.Get("offsetY").Float()) //* float32(w.scaleY)
+		}
+
 		w.cursorEv.Mods = getModifiers(event)
 		w.Dispatch(OnCursor, &w.cursorEv)
 		return nil
@@ -556,6 +571,7 @@ func (w *WebGlCanvas) Destroy() {
 	js.Global().Get("window").Call("removeEventListener", "resize", w.winResize)
 	js.Global().Get("window").Call("removeEventListener", "onfocus", w.winFocus)
 	js.Global().Get("window").Call("removeEventListener", "onfocus", w.winBlur)
+	js.Global().Get("document").Call("removeEventListener", "pointerlockchange", w.pointerLock)
 
 	// Release callbacks
 	w.onCtxMenu.Release()
@@ -568,6 +584,7 @@ func (w *WebGlCanvas) Destroy() {
 	w.winResize.Release()
 	w.winFocus.Release()
 	w.winBlur.Release()
+	w.pointerLock.Release()
 }
 
 // GetFramebufferSize returns the framebuffer size.
@@ -610,6 +627,28 @@ func (w *WebGlCanvas) SetCursor(cursor Cursor) {
 	// TODO
 }
 
+// SetCursorMode sets the window's cursor mode.
+// More info: https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API
+func (w *WebGlCanvas) SetCursorMode(mode CursorMode) {
+	switch mode {
+	case CursorNormal:
+		js.Global().Get("document").Call("exitPointerLock")
+	case CursorHidden:
+	case CursorDisabled:
+		promise := w.Canvas().Call("requestPointerLock", map[string]interface{}{"unadjustedMovement": true})
+		if promise.IsUndefined() {
+			w.Canvas().Call("requestPointerLock")
+		} else {
+			promise.Call("catch", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+				if len(args) > 0 && args[0].Get("name").Equal(js.ValueOf("NotSupportedError")) {
+					w.Canvas().Call("requestPointerLock")
+				}
+				return nil
+			}))
+		}
+	}
+}
+
 // DisposeAllCursors deletes all existing custom cursors.
 func (w *WebGlCanvas) DisposeAllCustomCursors() {
 

+ 8 - 0
window/glfw.go

@@ -207,6 +207,7 @@ type GlfwWindow struct {
 	cursorEv CursorEvent
 	scrollEv ScrollEvent
 	focusEv  FocusEvent
+	lockEv   LockEvent
 
 	mods ModifierKey // Current modifier keys
 
@@ -458,6 +459,13 @@ func (w *GlfwWindow) SetCursor(cursor Cursor) {
 	w.Window.SetCursor(cur)
 }
 
+// SetCursorMode sets the window's cursor mode.
+func (w *GlfwWindow) SetCursorMode(mode CursorMode) {
+	w.Window.SetInputMode(glfw.CursorMode, int(mode))
+	w.lockEv.Locked = mode == CursorDisabled
+	w.Dispatch(OnLockChange, &w.lockEv)
+}
+
 // CreateCursor creates a new custom cursor and returns an int handle.
 func (w *GlfwWindow) CreateCursor(imgFile string, xhot, yhot int) (Cursor, error) {
 

+ 7 - 0
window/window.go

@@ -38,6 +38,7 @@ type IWindow interface {
 	GetScale() (x float64, y float64)
 	CreateCursor(imgFile string, xhot, yhot int) (Cursor, error)
 	SetCursor(cursor Cursor)
+	SetCursorMode(mode CursorMode)
 	DisposeAllCustomCursors()
 	Destroy()
 	FullScreen() bool
@@ -88,6 +89,7 @@ const ( //                               Desktop | Browser |
 	OnMouseUp     = "w.OnMouseUp"     //    x    |    x    |
 	OnMouseDown   = "w.OnMouseDown"   //    x    |    x    |
 	OnScroll      = "w.OnScroll"      //    x    |    x    |
+	OnLockChange  = "w.OnLockChange"  //    x    |    x    |
 )
 
 // PosEvent describes a windows position changed event
@@ -140,3 +142,8 @@ type ScrollEvent struct {
 type FocusEvent struct {
 	Focused bool
 }
+
+// LockEvent describes if cursor is locked or not
+type LockEvent struct {
+	Locked bool
+}