Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions window/canvas.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ type WebGlCanvas struct {
cursorEv CursorEvent
scrollEv ScrollEvent
focusEv FocusEvent
lockEv LockEvent

// Callbacks
onCtxMenu js.Func
Expand All @@ -340,6 +341,7 @@ type WebGlCanvas struct {
winResize js.Func
winFocus js.Func
winBlur js.Func
mouseLock js.Func
}

// Init initializes the WebGlCanvas singleton.
Expand Down Expand Up @@ -386,6 +388,13 @@ func Init(canvasId string) error {

// TODO scaling/hidpi (device pixel ratio)

w.mouseLock = 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.mouseLock)

// Set up key down callback to dispatch event
w.keyDown = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
event := args[0]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.mouseLock)

// Release callbacks
w.onCtxMenu.Release()
Expand All @@ -568,6 +584,7 @@ func (w *WebGlCanvas) Destroy() {
w.winResize.Release()
w.winFocus.Release()
w.winBlur.Release()
w.mouseLock.Release()
}

// GetFramebufferSize returns the framebuffer size.
Expand Down Expand Up @@ -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() {

Expand Down
8 changes: 8 additions & 0 deletions window/glfw.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ type GlfwWindow struct {
cursorEv CursorEvent
scrollEv ScrollEvent
focusEv FocusEvent
lockEv LockEvent

mods ModifierKey // Current modifier keys

Expand Down Expand Up @@ -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) {

Expand Down
7 changes: 7 additions & 0 deletions window/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -136,6 +138,11 @@ type ScrollEvent struct {
Mods ModifierKey
}

// LockEvent describes if cursor is locked or not
type LockEvent struct {
Locked bool
}

// FocusEvent describes a focus event
type FocusEvent struct {
Focused bool
Expand Down