mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
ebiten: add (*Monitor).Size() to replace ScreenSizeInFullscreen()
Also, this change fixes redundant checks the case when a monitor does not exist. Now Ebitengine checks a monitor existence at the initialization. Closes #2145 Closes #2795
This commit is contained in:
parent
230619a036
commit
f4029aaa77
@ -85,7 +85,7 @@ func (g *Game) Draw(screen *ebiten.Image) {
|
||||
op.Filter = ebiten.FilterLinear
|
||||
screen.DrawImage(gophersImage, op)
|
||||
|
||||
fw, fh := ebiten.ScreenSizeInFullscreen()
|
||||
fw, fh := ebiten.Monitor().Size()
|
||||
msg := "This is an example of the finest fullscreen.\n"
|
||||
if runtime.GOOS == "js" {
|
||||
msg += "Press F or touch the screen to enter fullscreen (again).\n"
|
||||
|
@ -80,7 +80,7 @@ func (m *mascot) Layout(outsideWidth, outsideHeight int) (int, int) {
|
||||
func (m *mascot) Update() error {
|
||||
m.count++
|
||||
|
||||
sw, sh := ebiten.ScreenSizeInFullscreen()
|
||||
sw, sh := ebiten.Monitor().Size()
|
||||
ebiten.SetWindowPosition(m.x16/16, m.y16/16+sh-height)
|
||||
|
||||
if m.vx16 == 0 {
|
||||
|
@ -401,7 +401,7 @@ func parseWindowPosition() (int, int, bool) {
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Device scale factor: %0.2f\n", ebiten.Monitor().DeviceScaleFactor())
|
||||
w, h := ebiten.ScreenSizeInFullscreen()
|
||||
w, h := ebiten.Monitor().Size()
|
||||
fmt.Printf("Screen size in fullscreen: %d, %d\n", w, h)
|
||||
|
||||
// Decode an image from the image file's byte slice.
|
||||
|
@ -42,14 +42,15 @@ func (m *Monitor) Name() string {
|
||||
|
||||
// DeviceScaleFactor is concurrent-safe as contentScale is immutable.
|
||||
func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
// It is rare, but monitor can be nil when glfw.GetPrimaryMonitor returns nil.
|
||||
// In this case, return 1 as a tentative scale (#1878).
|
||||
if m == nil {
|
||||
return 1
|
||||
}
|
||||
return m.contentScale
|
||||
}
|
||||
|
||||
// Size returns the size of the monitor in device-independent pixels.
|
||||
func (m *Monitor) Size() (int, int) {
|
||||
w, h := m.sizeInDIP()
|
||||
return int(w), int(h)
|
||||
}
|
||||
|
||||
func (m *Monitor) sizeInDIP() (float64, float64) {
|
||||
w, h := m.boundsInGLFWPixels.Dx(), m.boundsInGLFWPixels.Dy()
|
||||
s := m.DeviceScaleFactor()
|
||||
@ -88,6 +89,11 @@ func (m *monitors) primaryMonitor() *Monitor {
|
||||
m.m.Lock()
|
||||
defer m.m.Unlock()
|
||||
|
||||
// GetMonitors might return nil in theory (#1878, #1887).
|
||||
// primaryMonitor can be called at the initialization, so monitors can be nil.
|
||||
if len(m.monitors) == 0 {
|
||||
return nil
|
||||
}
|
||||
return m.monitors[0]
|
||||
}
|
||||
|
||||
|
20
internal/ui/screensizeinfullscreen_js.go
Normal file
20
internal/ui/screensizeinfullscreen_js.go
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2024 The Ebitengine 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
|
||||
|
||||
func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
// On browsers, ScreenSizeInFullscreen returns the 'window' (global object) size, not 'screen' size for backward compatibility (#2145).
|
||||
return window.Get("width").Int(), window.Get("height").Int()
|
||||
}
|
21
internal/ui/screensizeinfullscreen_notjs.go
Normal file
21
internal/ui/screensizeinfullscreen_notjs.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2024 The Ebitengine 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 !js
|
||||
|
||||
package ui
|
||||
|
||||
func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
return u.Monitor().Size()
|
||||
}
|
@ -178,9 +178,9 @@ func (u *UserInterface) initializeGLFW() error {
|
||||
m = theMonitors.primaryMonitor()
|
||||
}
|
||||
|
||||
// GetPrimaryMonitor might return nil in theory (#1887).
|
||||
// GetMonitors might return nil in theory (#1878, #1887).
|
||||
if m == nil {
|
||||
return errors.New("ui: no monitor was found at initialize")
|
||||
return errors.New("ui: no monitor was found at initializeGLFW")
|
||||
}
|
||||
|
||||
u.setInitMonitor(m)
|
||||
@ -265,7 +265,7 @@ func (u *UserInterface) AppendMonitors(monitors []*Monitor) []*Monitor {
|
||||
// Monitor returns the window's current monitor. Returns nil if there is no current monitor yet.
|
||||
func (u *UserInterface) Monitor() *Monitor {
|
||||
if !u.isRunning() {
|
||||
return nil
|
||||
return u.getInitMonitor()
|
||||
}
|
||||
var monitor *Monitor
|
||||
u.mainThread.Call(func() {
|
||||
@ -571,36 +571,6 @@ func (u *UserInterface) setWindowClosingHandled(handled bool) {
|
||||
u.m.Unlock()
|
||||
}
|
||||
|
||||
func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
if u.isTerminated() {
|
||||
return 0, 0
|
||||
}
|
||||
if !u.isRunning() {
|
||||
m := u.getInitMonitor()
|
||||
w, h := m.sizeInDIP()
|
||||
return int(w), int(h)
|
||||
}
|
||||
|
||||
var w, h int
|
||||
u.mainThread.Call(func() {
|
||||
if u.isTerminated() {
|
||||
return
|
||||
}
|
||||
m, err := u.currentMonitor()
|
||||
if err != nil {
|
||||
u.setError(err)
|
||||
return
|
||||
}
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
wf, hf := m.sizeInDIP()
|
||||
w = int(wf)
|
||||
h = int(hf)
|
||||
})
|
||||
return w, h
|
||||
}
|
||||
|
||||
// isFullscreen must be called from the main thread.
|
||||
func (u *UserInterface) isFullscreen() (bool, error) {
|
||||
if !u.isRunning() {
|
||||
|
@ -121,6 +121,7 @@ type userInterfaceImpl struct {
|
||||
var (
|
||||
window = js.Global().Get("window")
|
||||
document = js.Global().Get("document")
|
||||
screen = js.Global().Get("screen")
|
||||
canvas js.Value
|
||||
requestAnimationFrame = js.Global().Get("requestAnimationFrame")
|
||||
setTimeout = js.Global().Get("setTimeout")
|
||||
@ -131,10 +132,6 @@ var (
|
||||
documentHidden = js.Global().Get("Object").Call("getOwnPropertyDescriptor", js.Global().Get("Document").Get("prototype"), "hidden").Get("get").Call("bind", document)
|
||||
)
|
||||
|
||||
func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
return window.Get("innerWidth").Int(), window.Get("innerHeight").Int()
|
||||
}
|
||||
|
||||
func (u *UserInterface) SetFullscreen(fullscreen bool) {
|
||||
if !canvas.Truthy() {
|
||||
return
|
||||
@ -796,6 +793,10 @@ func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
return m.deviceScaleFactor
|
||||
}
|
||||
|
||||
func (m *Monitor) Size() (int, int) {
|
||||
return screen.Get("width").Int(), screen.Get("height").Int()
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func glfwMonitorSizeInGLFWPixels(m *glfw.Monitor) (int, int, error) {
|
||||
|
||||
// Note: GLFW currently returns physical pixel sizes,
|
||||
// but we need to predict the window system-side size of the fullscreen window
|
||||
// for Ebitengine's `ScreenSizeInFullscreen` public API.
|
||||
// for Ebitengine's `(*Monitor).Size()` public API.
|
||||
// Also at the moment we need this prior to switching to fullscreen, but that might be replaceable.
|
||||
// So this function computes the ratio of physical per logical pixels.
|
||||
xconn, err := xgb.NewConn()
|
||||
|
@ -183,12 +183,6 @@ func (u *UserInterface) update() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
// TODO: This function should return gbuildWidthPx, gbuildHeightPx,
|
||||
// but these values are not initialized until the main loop starts.
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// SetOutsideSize is called from mobile/ebitenmobileview.
|
||||
//
|
||||
// SetOutsideSize is concurrent safe.
|
||||
@ -289,6 +283,11 @@ func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
return m.deviceScaleFactor
|
||||
}
|
||||
|
||||
func (m *Monitor) Size() (int, int) {
|
||||
// TODO: Return a valid value.
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -102,10 +102,6 @@ func (*UserInterface) IsFocused() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (*UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (u *UserInterface) readInputState(inputState *InputState) {
|
||||
u.m.Lock()
|
||||
defer u.m.Unlock()
|
||||
@ -170,6 +166,10 @@ func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (m *Monitor) Size() (int, int) {
|
||||
return int(C.kScreenWidth), int(C.kScreenHeight)
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
@ -92,10 +92,6 @@ func (*UserInterface) IsFocused() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (*UserInterface) ScreenSizeInFullscreen() (int, int) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
func (u *UserInterface) readInputState(inputState *InputState) {
|
||||
// TODO: Implement this.
|
||||
}
|
||||
@ -163,6 +159,10 @@ func (m *Monitor) DeviceScaleFactor() float64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (m *Monitor) Size() (int, int) {
|
||||
return screenWidth, screenHeight
|
||||
}
|
||||
|
||||
func (u *UserInterface) AppendMonitors(mons []*Monitor) []*Monitor {
|
||||
return append(mons, theMonitor)
|
||||
}
|
||||
|
16
monitor.go
16
monitor.go
@ -34,13 +34,23 @@ func (m *MonitorType) Name() string {
|
||||
//
|
||||
// DeviceScaleFactor might panic on init function on some devices like Android.
|
||||
// Then, it is not recommended to call DeviceScaleFactor from init functions.
|
||||
//
|
||||
// DeviceScaleFactor must be called on the main thread before the main loop,
|
||||
// and is concurrent-safe after the main loop.
|
||||
func (m *MonitorType) DeviceScaleFactor() float64 {
|
||||
return (*ui.Monitor)(m).DeviceScaleFactor()
|
||||
}
|
||||
|
||||
// Size returns the size of the monitor in device-independent pixels.
|
||||
// This is the same as the screen size in fullscreen mode.
|
||||
// The returned value can be given to SetSize function if the perfectly fit fullscreen is needed.
|
||||
//
|
||||
// On mobiles, Size returns (0, 0) so far.
|
||||
//
|
||||
// Size's use cases are limited. If you are making a fullscreen application, you can use RunGame and
|
||||
// the Game interface's Layout function instead. If you are making a not-fullscreen application but the application's
|
||||
// behavior depends on the monitor size, Size is useful.
|
||||
func (m *MonitorType) Size() (int, int) {
|
||||
return (*ui.Monitor)(m).Size()
|
||||
}
|
||||
|
||||
// Monitor returns the current monitor.
|
||||
func Monitor() *MonitorType {
|
||||
m := ui.Get().Monitor()
|
||||
|
2
run.go
2
run.go
@ -352,6 +352,8 @@ func isRunGameEnded() bool {
|
||||
//
|
||||
// ScreenSizeInFullscreen must be called on the main thread before ebiten.RunGame, and is concurrent-safe after
|
||||
// ebiten.RunGame.
|
||||
//
|
||||
// Deprecated: as of v2.6. Use Monitor().Size() instead.
|
||||
func ScreenSizeInFullscreen() (int, int) {
|
||||
return ui.Get().ScreenSizeInFullscreen()
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ var (
|
||||
|
||||
func initializeWindowPositionIfNeeded(width, height int) {
|
||||
if atomic.LoadUint32(&windowPositionSetExplicitly) == 0 {
|
||||
sw, sh := ui.Get().ScreenSizeInFullscreen()
|
||||
sw, sh := ui.Get().Monitor().Size()
|
||||
x, y := ui.InitialWindowPosition(sw, sh, width, height)
|
||||
ui.Get().Window().SetPosition(x, y)
|
||||
}
|
||||
@ -175,7 +175,7 @@ func initializeWindowPositionIfNeeded(width, height int) {
|
||||
// WindowSize returns (0, 0) on other environments.
|
||||
//
|
||||
// Even if the application is in fullscreen mode, WindowSize returns the original window size
|
||||
// If you need the fullscreen dimensions, see ScreenSizeInFullscreen instead.
|
||||
// If you need the fullscreen dimensions, see Monitor().Size() instead.
|
||||
//
|
||||
// WindowSize is concurrent-safe.
|
||||
func WindowSize() (int, int) {
|
||||
|
Loading…
Reference in New Issue
Block a user