ui: Add IsCursorVisible (#377)

This commit is contained in:
Hajime Hoshi 2017-08-12 15:39:41 +09:00
parent 2c7cfba863
commit b186bc1e94
5 changed files with 85 additions and 16 deletions

View File

@ -43,6 +43,7 @@ var (
ebiten.KeyS: 0, ebiten.KeyS: 0,
ebiten.KeyF: 0, ebiten.KeyF: 0,
ebiten.KeyB: 0, ebiten.KeyB: 0,
ebiten.KeyC: 0,
} }
count = 0 count = 0
) )
@ -60,6 +61,7 @@ func update(screen *ebiten.Image) error {
screenWidth, screenHeight := screen.Size() screenWidth, screenHeight := screen.Size()
fullscreen := ebiten.IsFullscreen() fullscreen := ebiten.IsFullscreen()
runnableInBackground := ebiten.IsRunnableInBackground() runnableInBackground := ebiten.IsRunnableInBackground()
cursorVisible := ebiten.IsCursorVisible()
if keyStates[ebiten.KeyUp] == 1 { if keyStates[ebiten.KeyUp] == 1 {
screenHeight += d screenHeight += d
@ -86,7 +88,7 @@ func update(screen *ebiten.Image) error {
case 2: case 2:
screenScale = 1 screenScale = 1
default: default:
panic("not reach") panic("not reached")
} }
} }
if keyStates[ebiten.KeyF] == 1 { if keyStates[ebiten.KeyF] == 1 {
@ -95,10 +97,14 @@ func update(screen *ebiten.Image) error {
if keyStates[ebiten.KeyB] == 1 { if keyStates[ebiten.KeyB] == 1 {
runnableInBackground = !runnableInBackground runnableInBackground = !runnableInBackground
} }
if keyStates[ebiten.KeyC] == 1 {
cursorVisible = !cursorVisible
}
ebiten.SetScreenSize(screenWidth, screenHeight) ebiten.SetScreenSize(screenWidth, screenHeight)
ebiten.SetScreenScale(screenScale) ebiten.SetScreenScale(screenScale)
ebiten.SetFullscreen(fullscreen) ebiten.SetFullscreen(fullscreen)
ebiten.SetRunnableInBackground(runnableInBackground) ebiten.SetRunnableInBackground(runnableInBackground)
ebiten.SetCursorVisibility(cursorVisible)
count++ count++
@ -119,8 +125,9 @@ func update(screen *ebiten.Image) error {
x, y := ebiten.CursorPosition() x, y := ebiten.CursorPosition()
msg := fmt.Sprintf(`Press arrow keys to change the window size msg := fmt.Sprintf(`Press arrow keys to change the window size
Press S key to change the window scale Press S key to change the window scale
Press F key to change the fullscreen state Press F key to switch the fullscreen state
Press B key to change the run-in-background state Press B key to switch the run-in-background state
Press C key to switch the cursor visibility
Cursor: (%d, %d) Cursor: (%d, %d)
FPS: %0.2f`, x, y, ebiten.CurrentFPS()) FPS: %0.2f`, x, y, ebiten.CurrentFPS())
ebitenutil.DebugPrint(screen, msg) ebitenutil.DebugPrint(screen, msg)

View File

@ -45,6 +45,7 @@ type userInterface struct {
origPosX int origPosX int
origPosY int origPosY int
initFullscreen bool initFullscreen bool
initCursorVisible bool
runnableInBackground bool runnableInBackground bool
m sync.Mutex m sync.Mutex
} }
@ -81,6 +82,13 @@ func initialize() error {
currentUI.funcs = make(chan func()) currentUI.funcs = make(chan func())
currentUI.window.MakeContextCurrent() currentUI.window.MakeContextCurrent()
mode := glfw.CursorNormal
if !currentUI.isInitCursorVisible() {
mode = glfw.CursorHidden
}
currentUI.window.SetInputMode(glfw.CursorMode, mode)
return nil return nil
} }
@ -134,6 +142,19 @@ func (u *userInterface) setInitFullscreen(initFullscreen bool) {
u.m.Unlock() u.m.Unlock()
} }
func (u *userInterface) isInitCursorVisible() bool {
u.m.Lock()
v := u.initCursorVisible
u.m.Unlock()
return v
}
func (u *userInterface) setInitCursorVisible(visible bool) {
u.m.Lock()
u.initCursorVisible = visible
u.m.Unlock()
}
func (u *userInterface) isRunnableInBackground() bool { func (u *userInterface) isRunnableInBackground() bool {
u.m.Lock() u.m.Lock()
v := u.runnableInBackground v := u.runnableInBackground
@ -269,18 +290,33 @@ func adjustCursorPosition(x, y int) (int, int) {
return x - int(ox/s), y - int(oy/s) return x - int(ox/s), y - int(oy/s)
} }
func IsCursorVisible() bool {
u := currentUI
if !u.isRunning() {
return u.isInitCursorVisible()
}
v := false
_ = currentUI.runOnMainThread(func() error {
v = currentUI.window.GetInputMode(glfw.CursorMode) == glfw.CursorNormal
return nil
})
return v
}
func SetCursorVisibility(visible bool) { func SetCursorVisibility(visible bool) {
// This can be called before Run: change the state asyncly. u := currentUI
go func() { if !u.isRunning() {
_ = currentUI.runOnMainThread(func() error { u.setInitCursorVisible(visible)
c := glfw.CursorNormal return
if !visible { }
c = glfw.CursorHidden _ = currentUI.runOnMainThread(func() error {
} c := glfw.CursorNormal
currentUI.window.SetInputMode(glfw.CursorMode, c) if !visible {
return nil c = glfw.CursorHidden
}) }
}() currentUI.window.SetInputMode(glfw.CursorMode, c)
return nil
})
} }
func Run(width, height int, scale float64, title string, g GraphicsContext) error { func Run(width, height int, scale float64, title string, g GraphicsContext) error {
@ -502,7 +538,12 @@ func (u *userInterface) setScreenSize(width, height int, scale float64, fullscre
// SwapInterval is affected by the current monitor of the window. // SwapInterval is affected by the current monitor of the window.
// This needs to be called at least after SetMonitor. // This needs to be called at least after SetMonitor.
// Without SwapInterval after SetMonitor, vsynch doesn't work (#375). // Without SwapInterval after SetMonitor, vsynch doesn't work (#375).
//
// TODO: (#405) If triple buffering is needed, SwapInterval(0) should be called,
// but is this correct? If glfw.SwapInterval(0) and the driver doesn't support triple
// buffering, what will happen?
glfw.SwapInterval(1) glfw.SwapInterval(1)
// TODO: Rename this variable? // TODO: Rename this variable?
u.sizeChanged = true u.sizeChanged = true
return true return true

View File

@ -84,6 +84,11 @@ func adjustCursorPosition(x, y int) (int, int) {
return x, y return x, y
} }
func IsCursorVisible() bool {
// The initial value is an empty string, so don't compare with "auto" here.
return canvas.Get("style").Get("cursor").String() != "none"
}
func SetCursorVisibility(visibility bool) { func SetCursorVisibility(visibility bool) {
if visibility { if visibility {
canvas.Get("style").Set("cursor", "auto") canvas.Get("style").Set("cursor", "auto")

View File

@ -114,6 +114,10 @@ func adjustCursorPosition(x, y int) (int, int) {
return x, y return x, y
} }
func IsCursorVisible() bool {
return false
}
func SetCursorVisibility(visibility bool) { func SetCursorVisibility(visibility bool) {
// Do nothing // Do nothing
} }

16
run.go
View File

@ -179,8 +179,20 @@ func ScreenScale() float64 {
return ui.ScreenScale() return ui.ScreenScale()
} }
// IsCursorVisible returns a boolean value indicating whether
// the cursor is visible or not.
//
// IsCursorVisible always returns false on mobiles.
//
// This function is concurrent-safe.
func IsCursorVisible() bool {
return ui.IsCursorVisible()
}
// SetCursorVisibility changes the state of cursor visiblity. // SetCursorVisibility changes the state of cursor visiblity.
// //
// SetCursorVisibility does nothing on mobiles.
//
// This function is concurrent-safe. // This function is concurrent-safe.
func SetCursorVisibility(visible bool) { func SetCursorVisibility(visible bool) {
ui.SetCursorVisibility(visible) ui.SetCursorVisibility(visible)
@ -205,7 +217,7 @@ func IsFullscreen() bool {
// On browsers, the game screen is resized to fit with the body element (client) size. // On browsers, the game screen is resized to fit with the body element (client) size.
// Additionally, the game screen is automatically resized when the body element is resized. // Additionally, the game screen is automatically resized when the body element is resized.
// //
// SetFullscreen doesn't work on mobiles. // SetFullscreen does nothing on mobiles.
// //
// This function is concurrent-safe. // This function is concurrent-safe.
func SetFullscreen(fullscreen bool) { func SetFullscreen(fullscreen bool) {
@ -227,7 +239,7 @@ func IsRunnableInBackground() bool {
// Known issue: On browsers, even if the state is on, the game doesn't run in background tabs. // Known issue: On browsers, even if the state is on, the game doesn't run in background tabs.
// This is because browsers throttles background tabs not to often update. // This is because browsers throttles background tabs not to often update.
// //
// SetRunnableInBackground doesn't work on mobiles so far. // SetRunnableInBackground does nothing on mobiles so far.
// //
// This function is concurrent-safe. // This function is concurrent-safe.
func SetRunnableInBackground(runnableInBackground bool) { func SetRunnableInBackground(runnableInBackground bool) {