window.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. package ebiten
  15. import (
  16. "image"
  17. "sync/atomic"
  18. )
  19. const (
  20. maxInt = int(^uint(0) >> 1)
  21. minInt = -maxInt - 1
  22. invalidPos = minInt
  23. )
  24. // IsWindowDecorated reports whether the window is decorated.
  25. //
  26. // IsWindowDecorated is concurrent-safe.
  27. func IsWindowDecorated() bool {
  28. if w := uiDriver().Window(); w != nil {
  29. return w.IsDecorated()
  30. }
  31. return false
  32. }
  33. // SetWindowDecorated sets the state if the window is decorated.
  34. //
  35. // The window is decorated by default.
  36. //
  37. // SetWindowDecorated works only on desktops.
  38. // SetWindowDecorated does nothing on other platforms.
  39. //
  40. // SetWindowDecorated does nothing on macOS when the window is fullscreened natively by the macOS desktop
  41. // instead of SetFullscreen(true).
  42. //
  43. // SetWindowDecorated is concurrent-safe.
  44. func SetWindowDecorated(decorated bool) {
  45. if w := uiDriver().Window(); w != nil {
  46. w.SetDecorated(decorated)
  47. }
  48. }
  49. // IsWindowResizable reports whether the window is resizable by the user's dragging on desktops.
  50. // On the other environments, IsWindowResizable always returns false.
  51. //
  52. // IsWindowResizable is concurrent-safe.
  53. func IsWindowResizable() bool {
  54. if w := uiDriver().Window(); w != nil {
  55. return w.IsResizable()
  56. }
  57. return false
  58. }
  59. // SetWindowResizable sets whether the window is resizable by the user's dragging on desktops.
  60. // On the other environments, SetWindowResizable does nothing.
  61. //
  62. // The window is not resizable by default.
  63. //
  64. // If SetWindowResizable is called with true and Run is used, SetWindowResizable panics. Use RunGame instead.
  65. //
  66. // SetWindowResizable does nothing on macOS when the window is fullscreened natively by the macOS desktop
  67. // instead of SetFullscreen(true).
  68. //
  69. // SetWindowResizable is concurrent-safe.
  70. func SetWindowResizable(resizable bool) {
  71. theUIContext.setWindowResizable(resizable)
  72. }
  73. // SetWindowTitle sets the title of the window.
  74. //
  75. // SetWindowTitle does nothing on browsers or mobiles.
  76. //
  77. // SetWindowTitle is concurrent-safe.
  78. func SetWindowTitle(title string) {
  79. if w := uiDriver().Window(); w != nil {
  80. w.SetTitle(title)
  81. }
  82. }
  83. // SetWindowIcon sets the icon of the game window.
  84. //
  85. // If len(iconImages) is 0, SetWindowIcon reverts the icon to the default one.
  86. //
  87. // For desktops, see the document of glfwSetWindowIcon of GLFW 3.2:
  88. //
  89. // This function sets the icon of the specified window.
  90. // If passed an array of candidate images, those of or closest to the sizes
  91. // desired by the system are selected.
  92. // If no images are specified, the window reverts to its default icon.
  93. //
  94. // The desired image sizes varies depending on platform and system settings.
  95. // The selected images will be rescaled as needed.
  96. // Good sizes include 16x16, 32x32 and 48x48.
  97. //
  98. // As macOS windows don't have icons, SetWindowIcon doesn't work on macOS.
  99. //
  100. // SetWindowIcon doesn't work on browsers or mobiles.
  101. //
  102. // SetWindowIcon is concurrent-safe.
  103. func SetWindowIcon(iconImages []image.Image) {
  104. if w := uiDriver().Window(); w != nil {
  105. w.SetIcon(iconImages)
  106. }
  107. }
  108. // WindowPosition returns the window position.
  109. // The origin position is the left-upper corner of the current monitor.
  110. // The unit is device-independent pixels.
  111. //
  112. // WindowPosition panics if the main loop does not start yet.
  113. //
  114. // WindowPosition returns the last window position in fullscreen mode.
  115. //
  116. // WindowPosition returns (0, 0) on browsers and mobiles.
  117. //
  118. // WindowPosition is concurrent-safe.
  119. func WindowPosition() (x, y int) {
  120. if w := uiDriver().Window(); w != nil {
  121. return w.Position()
  122. }
  123. return 0, 0
  124. }
  125. // SetWindowPosition sets the window position.
  126. // The origin position is the left-upper corner of the current monitor.
  127. // The unit is device-independent pixels.
  128. //
  129. // SetWindowPosition does nothing in fullscreen mode.
  130. //
  131. // SetWindowPosition does nothing on browsers and mobiles.
  132. //
  133. // SetWindowPosition is concurrent-safe.
  134. func SetWindowPosition(x, y int) {
  135. atomic.StoreUint32(&windowPositionSetExplicitly, 1)
  136. if w := uiDriver().Window(); w != nil {
  137. w.SetPosition(x, y)
  138. }
  139. }
  140. var (
  141. windowPositionSetExplicitly uint32
  142. )
  143. func initializeWindowPositionIfNeeded(width, height int) {
  144. w := uiDriver().Window()
  145. if w == nil {
  146. return
  147. }
  148. if atomic.LoadUint32(&windowPositionSetExplicitly) == 0 {
  149. sw, sh := uiDriver().ScreenSizeInFullscreen()
  150. x := (sw - width) / 2
  151. y := (sh - height) / 3
  152. w.SetPosition(x, y)
  153. }
  154. }
  155. // WindowSize returns the window size on desktops.
  156. // WindowSize returns (0, 0) on other environments.
  157. //
  158. // In fullscreen mode, WindowSize returns the original window size.
  159. //
  160. // WindowSize is concurrent-safe.
  161. func WindowSize() (int, int) {
  162. if w := uiDriver().Window(); w != nil {
  163. return w.Size()
  164. }
  165. return 0, 0
  166. }
  167. // SetWindowSize sets the window size on desktops.
  168. // SetWindowSize does nothing on other environments.
  169. //
  170. // In fullscreen mode, SetWindowSize sets the original window size.
  171. //
  172. // SetWindowSize panics if width or height is not a positive number.
  173. //
  174. // SetWindowSize is concurrent-safe.
  175. func SetWindowSize(width, height int) {
  176. if width <= 0 || height <= 0 {
  177. panic("ebiten: width and height must be positive")
  178. }
  179. if w := uiDriver().Window(); w != nil {
  180. w.SetSize(width, height)
  181. }
  182. }
  183. // WindowSizeLimist returns the limitation of the window size on desktops.
  184. // A negative value indicates the size is not limited.
  185. //
  186. // WindowMaxSize is concurrent-safe.
  187. func WindowSizeLimits() (minw, minh, maxw, maxh int) {
  188. if w := uiDriver().Window(); w != nil {
  189. return w.SizeLimits()
  190. }
  191. return -1, -1, -1, -1
  192. }
  193. // SetWindowSizeLimits sets the limitation of the window size on desktops.
  194. // A negative value indicates the size is not limited.
  195. //
  196. // SetWindowMaxSize is concurrent-safe.
  197. func SetWindowSizeLimits(minw, minh, maxw, maxh int) {
  198. if w := uiDriver().Window(); w != nil {
  199. w.SetSizeLimits(minw, minh, maxw, maxh)
  200. }
  201. }
  202. // IsWindowFloating reports whether the window is always shown above all the other windows.
  203. //
  204. // IsWindowFloating returns false on browsers and mobiles.
  205. //
  206. // IsWindowFloating is concurrent-safe.
  207. func IsWindowFloating() bool {
  208. if w := uiDriver().Window(); w != nil {
  209. return w.IsFloating()
  210. }
  211. return false
  212. }
  213. // SetWindowFloating sets the state whether the window is always shown above all the other windows.
  214. //
  215. // SetWindowFloating does nothing on browsers or mobiles.
  216. //
  217. // SetWindowFloating does nothing on macOS when the window is fullscreened natively by the macOS desktop
  218. // instead of SetFullscreen(true).
  219. //
  220. // SetWindowFloating is concurrent-safe.
  221. func SetWindowFloating(float bool) {
  222. if w := uiDriver().Window(); w != nil {
  223. w.SetFloating(float)
  224. }
  225. }
  226. // MaximizeWindow maximizes the window.
  227. //
  228. // MaximizeWindow panics when the window is not resizable.
  229. //
  230. // MaximizeWindow does nothing on browsers or mobiles.
  231. //
  232. // MaximizeWindow is concurrent-safe.
  233. func MaximizeWindow() {
  234. if !IsWindowResizable() {
  235. panic("ebiten: a window to maximize must be resizable")
  236. }
  237. if w := uiDriver().Window(); w != nil {
  238. w.Maximize()
  239. }
  240. }
  241. // IsWindowMaximized reports whether the window is maximized or not.
  242. //
  243. // IsWindowMaximized returns false when the window is not resizable.
  244. //
  245. // IsWindowMaximized always returns false on browsers and mobiles.
  246. //
  247. // IsWindowMaximized is concurrent-safe.
  248. func IsWindowMaximized() bool {
  249. if !IsWindowResizable() {
  250. return false
  251. }
  252. if w := uiDriver().Window(); w != nil {
  253. return w.IsMaximized()
  254. }
  255. return false
  256. }
  257. // MinimizeWindow minimizes the window.
  258. //
  259. // If the main loop does not start yet, MinimizeWindow does nothing.
  260. //
  261. // MinimizeWindow does nothing on browsers or mobiles.
  262. //
  263. // MinimizeWindow is concurrent-safe.
  264. func MinimizeWindow() {
  265. if w := uiDriver().Window(); w != nil {
  266. w.Minimize()
  267. }
  268. }
  269. // IsWindowMinimized reports whether the window is minimized or not.
  270. //
  271. // IsWindowMinimized always returns false on browsers and mobiles.
  272. //
  273. // IsWindowMinimized is concurrent-safe.
  274. func IsWindowMinimized() bool {
  275. if w := uiDriver().Window(); w != nil {
  276. return w.IsMinimized()
  277. }
  278. return false
  279. }
  280. // RestoreWindow restores the window from its maximized or minimized state.
  281. //
  282. // RestoreWindow panics when the window is not maximized nor minimized.
  283. //
  284. // RestoreWindow is concurrent-safe.
  285. func RestoreWindow() {
  286. if !IsWindowMaximized() && !IsWindowMinimized() {
  287. panic("ebiten: RestoreWindow must be called on a maximized or a minimized window")
  288. }
  289. if w := uiDriver().Window(); w != nil {
  290. w.Restore()
  291. }
  292. }