window.go (5948B)
1 // Copyright 2019 The Ebiten Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build (darwin || freebsd || linux || windows) && !android && !ios 16 // +build darwin freebsd linux windows 17 // +build !android 18 // +build !ios 19 20 package glfw 21 22 import ( 23 "image" 24 25 "github.com/hajimehoshi/ebiten/v2/internal/glfw" 26 ) 27 28 type window struct { 29 ui *UserInterface 30 } 31 32 func (w *window) IsDecorated() bool { 33 if !w.ui.isRunning() { 34 return w.ui.isInitWindowDecorated() 35 } 36 v := false 37 _ = w.ui.t.Call(func() error { 38 v = w.ui.window.GetAttrib(glfw.Decorated) == glfw.True 39 return nil 40 }) 41 return v 42 } 43 44 func (w *window) SetDecorated(decorated bool) { 45 if !w.ui.isRunning() { 46 w.ui.setInitWindowDecorated(decorated) 47 return 48 } 49 50 _ = w.ui.t.Call(func() error { 51 if w.ui.isNativeFullscreen() { 52 return nil 53 } 54 55 w.ui.setWindowDecorated(decorated) 56 return nil 57 }) 58 } 59 60 func (w *window) IsResizable() bool { 61 if !w.ui.isRunning() { 62 return w.ui.isInitWindowResizable() 63 } 64 v := false 65 _ = w.ui.t.Call(func() error { 66 v = w.ui.window.GetAttrib(glfw.Resizable) == glfw.True 67 return nil 68 }) 69 return v 70 } 71 72 func (w *window) SetResizable(resizable bool) { 73 if !w.ui.isRunning() { 74 w.ui.setInitWindowResizable(resizable) 75 return 76 } 77 _ = w.ui.t.Call(func() error { 78 if w.ui.isNativeFullscreen() { 79 return nil 80 } 81 w.ui.setWindowResizable(resizable) 82 return nil 83 }) 84 } 85 86 func (w *window) IsFloating() bool { 87 if !w.ui.isRunning() { 88 return w.ui.isInitWindowFloating() 89 } 90 var v bool 91 _ = w.ui.t.Call(func() error { 92 v = w.ui.window.GetAttrib(glfw.Floating) == glfw.True 93 return nil 94 }) 95 return v 96 } 97 98 func (w *window) SetFloating(floating bool) { 99 if !w.ui.isRunning() { 100 w.ui.setInitWindowFloating(floating) 101 return 102 } 103 _ = w.ui.t.Call(func() error { 104 if w.ui.isNativeFullscreen() { 105 return nil 106 } 107 w.ui.setWindowFloating(floating) 108 return nil 109 }) 110 } 111 112 func (w *window) IsMaximized() bool { 113 if !w.ui.isRunning() { 114 return w.ui.isInitWindowMaximized() 115 } 116 var v bool 117 _ = w.ui.t.Call(func() error { 118 v = w.ui.window.GetAttrib(glfw.Maximized) == glfw.True 119 return nil 120 }) 121 return v 122 } 123 124 func (w *window) Maximize() { 125 if !w.IsResizable() { 126 panic("glfw: a window to maximize must be resizable") 127 } 128 if !w.ui.isRunning() { 129 w.ui.setInitWindowMaximized(true) 130 return 131 } 132 _ = w.ui.t.Call(func() error { 133 w.ui.maximizeWindow() 134 return nil 135 }) 136 } 137 138 func (w *window) IsMinimized() bool { 139 if !w.ui.isRunning() { 140 return false 141 } 142 var v bool 143 _ = w.ui.t.Call(func() error { 144 v = w.ui.window.GetAttrib(glfw.Iconified) == glfw.True 145 return nil 146 }) 147 return v 148 } 149 150 func (w *window) Minimize() { 151 if !w.ui.isRunning() { 152 // Do nothing 153 return 154 } 155 _ = w.ui.t.Call(func() error { 156 w.ui.iconifyWindow() 157 return nil 158 }) 159 } 160 161 func (w *window) Restore() { 162 if !w.ui.isRunning() { 163 // Do nothing 164 return 165 } 166 _ = w.ui.t.Call(func() error { 167 w.ui.restoreWindow() 168 return nil 169 }) 170 } 171 172 func (w *window) Position() (int, int) { 173 if !w.ui.isRunning() { 174 panic("glfw: WindowPosition can't be called before the main loop starts") 175 } 176 x, y := 0, 0 177 _ = w.ui.t.Call(func() error { 178 var wx, wy int 179 if w.ui.isFullscreen() && !w.ui.isNativeFullscreenAvailable() { 180 wx, wy = w.ui.origPos() 181 } else { 182 wx, wy = w.ui.window.GetPos() 183 } 184 mx, my := currentMonitor(w.ui.window).GetPos() 185 wx -= mx 186 wy -= my 187 xf := w.ui.fromGLFWPixel(float64(wx)) 188 yf := w.ui.fromGLFWPixel(float64(wy)) 189 x, y = int(xf), int(yf) 190 return nil 191 }) 192 return x, y 193 } 194 195 func (w *window) SetPosition(x, y int) { 196 if !w.ui.isRunning() { 197 w.ui.setInitWindowPosition(x, y) 198 return 199 } 200 _ = w.ui.t.Call(func() error { 201 w.ui.setWindowPosition(x, y) 202 return nil 203 }) 204 } 205 206 func (w *window) Size() (int, int) { 207 if !w.ui.isRunning() { 208 ww, wh := w.ui.getInitWindowSize() 209 return w.ui.adjustWindowSizeBasedOnSizeLimitsInDP(ww, wh) 210 } 211 ww, wh := 0, 0 212 _ = w.ui.t.Call(func() error { 213 ww = int(w.ui.fromGLFWPixel(float64(w.ui.windowWidth))) 214 wh = int(w.ui.fromGLFWPixel(float64(w.ui.windowHeight))) 215 return nil 216 }) 217 return ww, wh 218 } 219 220 func (w *window) SetSize(width, height int) { 221 if !w.ui.isRunning() { 222 w.ui.setInitWindowSize(width, height) 223 return 224 } 225 _ = w.ui.t.Call(func() error { 226 // When a window is a native fullscreen, forcing to resize the window might leave unexpected image lags. 227 // Forbid this. 228 if w.ui.isNativeFullscreen() { 229 return nil 230 } 231 232 ww := int(w.ui.toGLFWPixel(float64(width))) 233 wh := int(w.ui.toGLFWPixel(float64(height))) 234 w.ui.setWindowSize(ww, wh, w.ui.isFullscreen()) 235 return nil 236 }) 237 } 238 239 func (w *window) SizeLimits() (minw, minh, maxw, maxh int) { 240 return w.ui.getWindowSizeLimitsInDP() 241 } 242 243 func (w *window) SetSizeLimits(minw, minh, maxw, maxh int) { 244 if !w.ui.setWindowSizeLimitsInDP(minw, minh, maxw, maxh) { 245 return 246 } 247 if !w.ui.isRunning() { 248 return 249 } 250 251 _ = w.ui.t.Call(func() error { 252 w.ui.updateWindowSizeLimits() 253 return nil 254 }) 255 } 256 257 func (w *window) SetIcon(iconImages []image.Image) { 258 // The icons are actually set at (*UserInterface).loop. 259 w.ui.setIconImages(iconImages) 260 } 261 262 func (w *window) SetTitle(title string) { 263 if !w.ui.isRunning() { 264 w.ui.setInitTitle(title) 265 return 266 } 267 w.ui.title = title 268 _ = w.ui.t.Call(func() error { 269 w.ui.setWindowTitle(title) 270 return nil 271 }) 272 } 273 274 func (w *window) IsBeingClosed() bool { 275 return w.ui.isWindowBeingClosed() 276 } 277 278 func (w *window) SetClosingHandled(handled bool) { 279 w.ui.setWindowClosingHandled(handled) 280 } 281 282 func (w *window) IsClosingHandled() bool { 283 return w.ui.isWindowClosingHandled() 284 }