diff --git a/internal/ui/ui_glfw.go b/internal/ui/ui_glfw.go index b157bc0e3..7078e3cce 100644 --- a/internal/ui/ui_glfw.go +++ b/internal/ui/ui_glfw.go @@ -31,6 +31,7 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/glfw" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" "github.com/hajimehoshi/ebiten/v2/internal/hooks" + "github.com/hajimehoshi/ebiten/v2/internal/microsoftgdk" "github.com/hajimehoshi/ebiten/v2/internal/thread" ) @@ -104,7 +105,7 @@ type userInterfaceImpl struct { fpsModeInited bool input Input - iwindow Window + iwindow glfwWindow sizeCallback glfw.SizeCallback closeCallback glfw.CloseCallback @@ -1403,7 +1404,10 @@ func (u *userInterfaceImpl) Input() *Input { return &u.input } -func (u *userInterfaceImpl) Window() *Window { +func (u *userInterfaceImpl) Window() Window { + if microsoftgdk.IsXbox() { + return &nullWindow{} + } return &u.iwindow } diff --git a/internal/ui/ui_js.go b/internal/ui/ui_js.go index 97951a9ec..8a270e9cb 100644 --- a/internal/ui/ui_js.go +++ b/internal/ui/ui_js.go @@ -666,6 +666,6 @@ func (u *userInterfaceImpl) Input() *Input { return &u.input } -func (u *userInterfaceImpl) Window() *Window { - return &Window{} +func (u *userInterfaceImpl) Window() Window { + return &nullWindow{} } diff --git a/internal/ui/ui_mobile.go b/internal/ui/ui_mobile.go index 4d066fdd5..7df1adce6 100644 --- a/internal/ui/ui_mobile.go +++ b/internal/ui/ui_mobile.go @@ -436,8 +436,8 @@ func (u *userInterfaceImpl) Input() *Input { return &u.input } -func (u *userInterfaceImpl) Window() *Window { - return &Window{} +func (u *userInterfaceImpl) Window() Window { + return &nullWindow{} } type Touch struct { diff --git a/internal/ui/window.go b/internal/ui/window.go new file mode 100644 index 000000000..9e6e86c85 --- /dev/null +++ b/internal/ui/window.go @@ -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 +} diff --git a/internal/ui/window_glfw.go b/internal/ui/window_glfw.go index 1fb6d0cdd..383d6acf9 100644 --- a/internal/ui/window_glfw.go +++ b/internal/ui/window_glfw.go @@ -23,11 +23,11 @@ import ( "github.com/hajimehoshi/ebiten/v2/internal/glfw" ) -type Window struct { +type glfwWindow struct { ui *userInterfaceImpl } -func (w *Window) IsDecorated() bool { +func (w *glfwWindow) IsDecorated() bool { if !w.ui.isRunning() { return w.ui.isInitWindowDecorated() } @@ -38,7 +38,7 @@ func (w *Window) IsDecorated() bool { return v } -func (w *Window) SetDecorated(decorated bool) { +func (w *glfwWindow) SetDecorated(decorated bool) { if !w.ui.isRunning() { w.ui.setInitWindowDecorated(decorated) 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() { w.ui.m.Lock() mode := w.ui.windowResizingMode @@ -67,7 +67,7 @@ func (w *Window) ResizingMode() WindowResizingMode { return mode } -func (w *Window) SetResizingMode(mode WindowResizingMode) { +func (w *glfwWindow) SetResizingMode(mode WindowResizingMode) { if !w.ui.isRunning() { w.ui.m.Lock() 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() { return w.ui.isInitWindowFloating() } @@ -93,7 +93,7 @@ func (w *Window) IsFloating() bool { return v } -func (w *Window) SetFloating(floating bool) { +func (w *glfwWindow) SetFloating(floating bool) { if !w.ui.isRunning() { w.ui.setInitWindowFloating(floating) 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() { return w.ui.isInitWindowMaximized() } @@ -120,7 +120,7 @@ func (w *Window) IsMaximized() bool { return v } -func (w *Window) Maximize() { +func (w *glfwWindow) Maximize() { // 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, // and this can be an unexpected behavior. @@ -134,7 +134,7 @@ func (w *Window) Maximize() { w.ui.t.Call(w.ui.maximizeWindow) } -func (w *Window) IsMinimized() bool { +func (w *glfwWindow) IsMinimized() bool { if !w.ui.isRunning() { return false } @@ -145,7 +145,7 @@ func (w *Window) IsMinimized() bool { return v } -func (w *Window) Minimize() { +func (w *glfwWindow) Minimize() { if !w.ui.isRunning() { // Do nothing return @@ -153,7 +153,7 @@ func (w *Window) Minimize() { w.ui.t.Call(w.ui.iconifyWindow) } -func (w *Window) Restore() { +func (w *glfwWindow) Restore() { if !w.ui.isRunning() { // Do nothing return @@ -161,7 +161,7 @@ func (w *Window) Restore() { w.ui.t.Call(w.ui.restoreWindow) } -func (w *Window) Position() (int, int) { +func (w *glfwWindow) Position() (int, int) { if !w.ui.isRunning() { 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 } -func (w *Window) SetPosition(x, y int) { +func (w *glfwWindow) SetPosition(x, y int) { if !w.ui.isRunning() { w.ui.setInitWindowPositionInDIP(x, y) 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() { ww, wh := w.ui.getInitWindowSizeInDIP() return w.ui.adjustWindowSizeBasedOnSizeLimitsInDIP(ww, wh) @@ -208,7 +208,7 @@ func (w *Window) Size() (int, int) { return ww, wh } -func (w *Window) SetSize(width, height int) { +func (w *glfwWindow) SetSize(width, height int) { if !w.ui.isRunning() { w.ui.setInitWindowSizeInDIP(width, height) 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() } -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) { return } @@ -240,12 +240,12 @@ func (w *Window) SetSizeLimits(minw, minh, maxw, maxh int) { 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. w.ui.setIconImages(iconImages) } -func (w *Window) SetTitle(title string) { +func (w *glfwWindow) SetTitle(title string) { if !w.ui.isRunning() { w.ui.m.Lock() 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() } -func (w *Window) SetClosingHandled(handled bool) { +func (w *glfwWindow) SetClosingHandled(handled bool) { w.ui.setWindowClosingHandled(handled) } -func (w *Window) IsClosingHandled() bool { +func (w *glfwWindow) IsClosingHandled() bool { return w.ui.isWindowClosingHandled() } diff --git a/internal/ui/window_null.go b/internal/ui/window_null.go deleted file mode 100644 index ac428f089..000000000 --- a/internal/ui/window_null.go +++ /dev/null @@ -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 -}