internal/ui: return a null Window on Xbox

Updates #2084
This commit is contained in:
Hajime Hoshi 2022-06-01 01:26:28 +09:00
parent ff868ba39f
commit 9c15bda275
6 changed files with 155 additions and 129 deletions

View File

@ -31,6 +31,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/glfw" "github.com/hajimehoshi/ebiten/v2/internal/glfw"
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver"
"github.com/hajimehoshi/ebiten/v2/internal/hooks" "github.com/hajimehoshi/ebiten/v2/internal/hooks"
"github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk"
"github.com/hajimehoshi/ebiten/v2/internal/thread" "github.com/hajimehoshi/ebiten/v2/internal/thread"
) )
@ -104,7 +105,7 @@ type userInterfaceImpl struct {
fpsModeInited bool fpsModeInited bool
input Input input Input
iwindow Window iwindow glfwWindow
sizeCallback glfw.SizeCallback sizeCallback glfw.SizeCallback
closeCallback glfw.CloseCallback closeCallback glfw.CloseCallback
@ -1403,7 +1404,10 @@ func (u *userInterfaceImpl) Input() *Input {
return &u.input return &u.input
} }
func (u *userInterfaceImpl) Window() *Window { func (u *userInterfaceImpl) Window() Window {
if microsoftgdk.IsXbox() {
return &nullWindow{}
}
return &u.iwindow return &u.iwindow
} }

View File

@ -666,6 +666,6 @@ func (u *userInterfaceImpl) Input() *Input {
return &u.input return &u.input
} }
func (u *userInterfaceImpl) Window() *Window { func (u *userInterfaceImpl) Window() Window {
return &Window{} return &nullWindow{}
} }

View File

@ -436,8 +436,8 @@ func (u *userInterfaceImpl) Input() *Input {
return &u.input return &u.input
} }
func (u *userInterfaceImpl) Window() *Window { func (u *userInterfaceImpl) Window() Window {
return &Window{} return &nullWindow{}
} }
type Touch struct { type Touch struct {

122
internal/ui/window.go Normal file
View File

@ -0,0 +1,122 @@
// Copyright 2022 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ui
import (
"image"
)
type Window interface {
IsDecorated() bool
SetDecorated(decorated bool)
ResizingMode() WindowResizingMode
SetResizingMode(mode WindowResizingMode)
Position() (int, int)
SetPosition(x, y int)
Size() (int, int)
SetSize(width, height int)
SizeLimits() (minw, minh, maxw, maxh int)
SetSizeLimits(minw, minh, maxw, maxh int)
IsFloating() bool
SetFloating(floating bool)
Maximize()
IsMaximized() bool
Minimize()
IsMinimized() bool
SetIcon(iconImages []image.Image)
SetTitle(title string)
Restore()
IsBeingClosed() bool
SetClosingHandled(handled bool)
IsClosingHandled() bool
}
type nullWindow struct{}
func (*nullWindow) IsDecorated() bool {
return false
}
func (*nullWindow) SetDecorated(decorated bool) {
}
func (*nullWindow) ResizingMode() WindowResizingMode {
return WindowResizingModeDisabled
}
func (*nullWindow) SetResizingMode(mode WindowResizingMode) {
}
func (*nullWindow) Position() (int, int) {
return 0, 0
}
func (*nullWindow) SetPosition(x, y int) {
}
func (*nullWindow) Size() (int, int) {
return 0, 0
}
func (*nullWindow) SetSize(width, height int) {
}
func (*nullWindow) SizeLimits() (minw, minh, maxw, maxh int) {
return -1, -1, -1, -1
}
func (*nullWindow) SetSizeLimits(minw, minh, maxw, maxh int) {
}
func (*nullWindow) IsFloating() bool {
return false
}
func (*nullWindow) SetFloating(floating bool) {
}
func (*nullWindow) Maximize() {
}
func (*nullWindow) IsMaximized() bool {
return false
}
func (*nullWindow) Minimize() {
}
func (*nullWindow) IsMinimized() bool {
return false
}
func (*nullWindow) SetIcon(iconImages []image.Image) {
}
func (*nullWindow) SetTitle(title string) {
}
func (*nullWindow) Restore() {
}
func (*nullWindow) IsBeingClosed() bool {
return false
}
func (*nullWindow) SetClosingHandled(handled bool) {
}
func (*nullWindow) IsClosingHandled() bool {
return false
}

View File

@ -23,11 +23,11 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/glfw" "github.com/hajimehoshi/ebiten/v2/internal/glfw"
) )
type Window struct { type glfwWindow struct {
ui *userInterfaceImpl ui *userInterfaceImpl
} }
func (w *Window) IsDecorated() bool { func (w *glfwWindow) IsDecorated() bool {
if !w.ui.isRunning() { if !w.ui.isRunning() {
return w.ui.isInitWindowDecorated() return w.ui.isInitWindowDecorated()
} }
@ -38,7 +38,7 @@ func (w *Window) IsDecorated() bool {
return v return v
} }
func (w *Window) SetDecorated(decorated bool) { func (w *glfwWindow) SetDecorated(decorated bool) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.setInitWindowDecorated(decorated) w.ui.setInitWindowDecorated(decorated)
return return
@ -53,7 +53,7 @@ func (w *Window) SetDecorated(decorated bool) {
}) })
} }
func (w *Window) ResizingMode() WindowResizingMode { func (w *glfwWindow) ResizingMode() WindowResizingMode {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.m.Lock() w.ui.m.Lock()
mode := w.ui.windowResizingMode mode := w.ui.windowResizingMode
@ -67,7 +67,7 @@ func (w *Window) ResizingMode() WindowResizingMode {
return mode return mode
} }
func (w *Window) SetResizingMode(mode WindowResizingMode) { func (w *glfwWindow) SetResizingMode(mode WindowResizingMode) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.m.Lock() w.ui.m.Lock()
w.ui.windowResizingMode = mode w.ui.windowResizingMode = mode
@ -82,7 +82,7 @@ func (w *Window) SetResizingMode(mode WindowResizingMode) {
}) })
} }
func (w *Window) IsFloating() bool { func (w *glfwWindow) IsFloating() bool {
if !w.ui.isRunning() { if !w.ui.isRunning() {
return w.ui.isInitWindowFloating() return w.ui.isInitWindowFloating()
} }
@ -93,7 +93,7 @@ func (w *Window) IsFloating() bool {
return v return v
} }
func (w *Window) SetFloating(floating bool) { func (w *glfwWindow) SetFloating(floating bool) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.setInitWindowFloating(floating) w.ui.setInitWindowFloating(floating)
return return
@ -106,7 +106,7 @@ func (w *Window) SetFloating(floating bool) {
}) })
} }
func (w *Window) IsMaximized() bool { func (w *glfwWindow) IsMaximized() bool {
if !w.ui.isRunning() { if !w.ui.isRunning() {
return w.ui.isInitWindowMaximized() return w.ui.isInitWindowMaximized()
} }
@ -120,7 +120,7 @@ func (w *Window) IsMaximized() bool {
return v return v
} }
func (w *Window) Maximize() { func (w *glfwWindow) Maximize() {
// Do not allow maximizing the window when the window is not resizable. // Do not allow maximizing the window when the window is not resizable.
// On Windows, it is possible to restore the window from being maximized by mouse-dragging, // On Windows, it is possible to restore the window from being maximized by mouse-dragging,
// and this can be an unexpected behavior. // and this can be an unexpected behavior.
@ -134,7 +134,7 @@ func (w *Window) Maximize() {
w.ui.t.Call(w.ui.maximizeWindow) w.ui.t.Call(w.ui.maximizeWindow)
} }
func (w *Window) IsMinimized() bool { func (w *glfwWindow) IsMinimized() bool {
if !w.ui.isRunning() { if !w.ui.isRunning() {
return false return false
} }
@ -145,7 +145,7 @@ func (w *Window) IsMinimized() bool {
return v return v
} }
func (w *Window) Minimize() { func (w *glfwWindow) Minimize() {
if !w.ui.isRunning() { if !w.ui.isRunning() {
// Do nothing // Do nothing
return return
@ -153,7 +153,7 @@ func (w *Window) Minimize() {
w.ui.t.Call(w.ui.iconifyWindow) w.ui.t.Call(w.ui.iconifyWindow)
} }
func (w *Window) Restore() { func (w *glfwWindow) Restore() {
if !w.ui.isRunning() { if !w.ui.isRunning() {
// Do nothing // Do nothing
return return
@ -161,7 +161,7 @@ func (w *Window) Restore() {
w.ui.t.Call(w.ui.restoreWindow) w.ui.t.Call(w.ui.restoreWindow)
} }
func (w *Window) Position() (int, int) { func (w *glfwWindow) Position() (int, int) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
panic("ui: WindowPosition can't be called before the main loop starts") panic("ui: WindowPosition can't be called before the main loop starts")
} }
@ -184,7 +184,7 @@ func (w *Window) Position() (int, int) {
return x, y return x, y
} }
func (w *Window) SetPosition(x, y int) { func (w *glfwWindow) SetPosition(x, y int) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.setInitWindowPositionInDIP(x, y) w.ui.setInitWindowPositionInDIP(x, y)
return return
@ -194,7 +194,7 @@ func (w *Window) SetPosition(x, y int) {
}) })
} }
func (w *Window) Size() (int, int) { func (w *glfwWindow) Size() (int, int) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
ww, wh := w.ui.getInitWindowSizeInDIP() ww, wh := w.ui.getInitWindowSizeInDIP()
return w.ui.adjustWindowSizeBasedOnSizeLimitsInDIP(ww, wh) return w.ui.adjustWindowSizeBasedOnSizeLimitsInDIP(ww, wh)
@ -208,7 +208,7 @@ func (w *Window) Size() (int, int) {
return ww, wh return ww, wh
} }
func (w *Window) SetSize(width, height int) { func (w *glfwWindow) SetSize(width, height int) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.setInitWindowSizeInDIP(width, height) w.ui.setInitWindowSizeInDIP(width, height)
return return
@ -225,11 +225,11 @@ func (w *Window) SetSize(width, height int) {
}) })
} }
func (w *Window) SizeLimits() (minw, minh, maxw, maxh int) { func (w *glfwWindow) SizeLimits() (minw, minh, maxw, maxh int) {
return w.ui.getWindowSizeLimitsInDIP() return w.ui.getWindowSizeLimitsInDIP()
} }
func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) { func (w *glfwWindow) SetSizeLimits(minw, minh, maxw, maxh int) {
if !w.ui.setWindowSizeLimitsInDIP(minw, minh, maxw, maxh) { if !w.ui.setWindowSizeLimitsInDIP(minw, minh, maxw, maxh) {
return return
} }
@ -240,12 +240,12 @@ func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) {
w.ui.t.Call(w.ui.updateWindowSizeLimits) w.ui.t.Call(w.ui.updateWindowSizeLimits)
} }
func (w *Window) SetIcon(iconImages []image.Image) { func (w *glfwWindow) SetIcon(iconImages []image.Image) {
// The icons are actually set at (*UserInterface).loop. // The icons are actually set at (*UserInterface).loop.
w.ui.setIconImages(iconImages) w.ui.setIconImages(iconImages)
} }
func (w *Window) SetTitle(title string) { func (w *glfwWindow) SetTitle(title string) {
if !w.ui.isRunning() { if !w.ui.isRunning() {
w.ui.m.Lock() w.ui.m.Lock()
w.ui.title = title w.ui.title = title
@ -258,14 +258,14 @@ func (w *Window) SetTitle(title string) {
}) })
} }
func (w *Window) IsBeingClosed() bool { func (w *glfwWindow) IsBeingClosed() bool {
return w.ui.isWindowBeingClosed() return w.ui.isWindowBeingClosed()
} }
func (w *Window) SetClosingHandled(handled bool) { func (w *glfwWindow) SetClosingHandled(handled bool) {
w.ui.setWindowClosingHandled(handled) w.ui.setWindowClosingHandled(handled)
} }
func (w *Window) IsClosingHandled() bool { func (w *glfwWindow) IsClosingHandled() bool {
return w.ui.isWindowClosingHandled() return w.ui.isWindowClosingHandled()
} }

View File

@ -1,100 +0,0 @@
// Copyright 2022 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build android || ios || js || ebitencbackend
// +build android ios js ebitencbackend
package ui
import (
"image"
)
type Window struct{}
func (*Window) IsDecorated() bool {
return false
}
func (*Window) SetDecorated(decorated bool) {
}
func (*Window) ResizingMode() WindowResizingMode {
return WindowResizingModeDisabled
}
func (*Window) SetResizingMode(mode WindowResizingMode) {
}
func (*Window) Position() (int, int) {
return 0, 0
}
func (*Window) SetPosition(x, y int) {
}
func (*Window) Size() (int, int) {
return 0, 0
}
func (*Window) SetSize(width, height int) {
}
func (*Window) SizeLimits() (minw, minh, maxw, maxh int) {
return -1, -1, -1, -1
}
func (*Window) SetSizeLimits(minw, minh, maxw, maxh int) {
}
func (*Window) IsFloating() bool {
return false
}
func (*Window) SetFloating(floating bool) {
}
func (*Window) Maximize() {
}
func (*Window) IsMaximized() bool {
return false
}
func (*Window) Minimize() {
}
func (*Window) IsMinimized() bool {
return false
}
func (*Window) SetIcon(iconImages []image.Image) {
}
func (*Window) SetTitle(title string) {
}
func (*Window) Restore() {
}
func (*Window) IsBeingClosed() bool {
return false
}
func (*Window) SetClosingHandled(handled bool) {
}
func (*Window) IsClosingHandled() bool {
return false
}