window.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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. "github.com/hajimehoshi/ebiten/v2/internal/ui"
  19. )
  20. // WindowResizingModeType represents a mode in which a user resizes the window.
  21. //
  22. // Regardless of the resizing mode, an Ebitengine application can still change the window size or make
  23. // the window fullscreen by calling Ebitengine functions.
  24. type WindowResizingModeType int
  25. // WindowResizingModeTypes
  26. const (
  27. // WindowResizingModeDisabled indicates the mode to disallow resizing the window by a user.
  28. WindowResizingModeDisabled WindowResizingModeType = WindowResizingModeType(ui.WindowResizingModeDisabled)
  29. // WindowResizingModeOnlyFullscreenEnabled indicates the mode to disallow resizing the window,
  30. // but allow to make the window fullscreen by a user.
  31. // This works only on macOS so far.
  32. // On the other platforms, this is the same as WindowResizingModeDisabled.
  33. WindowResizingModeOnlyFullscreenEnabled WindowResizingModeType = WindowResizingModeType(ui.WindowResizingModeOnlyFullscreenEnabled)
  34. // WindowResizingModeEnabled indicates the mode to allow resizing the window by a user.
  35. WindowResizingModeEnabled WindowResizingModeType = WindowResizingModeType(ui.WindowResizingModeEnabled)
  36. )
  37. // IsWindowDecorated reports whether the window is decorated.
  38. //
  39. // IsWindowDecorated is concurrent-safe.
  40. func IsWindowDecorated() bool {
  41. return ui.Get().Window().IsDecorated()
  42. }
  43. // SetWindowDecorated sets the state if the window is decorated.
  44. //
  45. // The window is decorated by default.
  46. //
  47. // SetWindowDecorated works only on desktops.
  48. // SetWindowDecorated does nothing if the platform is not a desktop.
  49. //
  50. // SetWindowDecorated is concurrent-safe.
  51. func SetWindowDecorated(decorated bool) {
  52. ui.Get().Window().SetDecorated(decorated)
  53. }
  54. // WindowResizingMode returns the current mode in which a user resizes the window.
  55. //
  56. // The default mode is WindowResizingModeDisabled.
  57. //
  58. // WindowResizingMode is concurrent-safe.
  59. func WindowResizingMode() WindowResizingModeType {
  60. return WindowResizingModeType(ui.Get().Window().ResizingMode())
  61. }
  62. // SetWindowResizingMode sets the mode in which a user resizes the window.
  63. //
  64. // SetWindowResizingMode is concurrent-safe.
  65. func SetWindowResizingMode(mode WindowResizingModeType) {
  66. ui.Get().Window().SetResizingMode(ui.WindowResizingMode(mode))
  67. }
  68. // IsWindowResizable reports whether the window is resizable by the user's dragging on desktops.
  69. // On the other environments, IsWindowResizable always returns false.
  70. //
  71. // Deprecated: as of v2.3. Use WindowResizingMode instead.
  72. func IsWindowResizable() bool {
  73. return ui.Get().Window().ResizingMode() == ui.WindowResizingModeEnabled
  74. }
  75. // SetWindowResizable sets whether the window is resizable by the user's dragging on desktops.
  76. // On the other environments, SetWindowResizable does nothing.
  77. //
  78. // Deprecated: as of v2.3, Use SetWindowResizingMode instead.
  79. func SetWindowResizable(resizable bool) {
  80. mode := ui.WindowResizingModeDisabled
  81. if resizable {
  82. mode = ui.WindowResizingModeEnabled
  83. }
  84. ui.Get().Window().SetResizingMode(mode)
  85. }
  86. // SetWindowTitle sets the title of the window.
  87. //
  88. // SetWindowTitle does nothing if the platform is not a desktop.
  89. //
  90. // SetWindowTitle is concurrent-safe.
  91. func SetWindowTitle(title string) {
  92. ui.Get().Window().SetTitle(title)
  93. }
  94. // SetWindowIcon sets the icon of the game window.
  95. //
  96. // If len(iconImages) is 0, SetWindowIcon reverts the icon to the default one.
  97. //
  98. // For desktops, see the document of glfwSetWindowIcon of GLFW 3.2:
  99. //
  100. // This function sets the icon of the specified window.
  101. // If passed an array of candidate images, those of or closest to the sizes
  102. // desired by the system are selected.
  103. // If no images are specified, the window reverts to its default icon.
  104. //
  105. // The desired image sizes varies depending on platform and system settings.
  106. // The selected images will be rescaled as needed.
  107. // Good sizes include 16x16, 32x32 and 48x48.
  108. //
  109. // As macOS windows don't have icons, SetWindowIcon doesn't work on macOS.
  110. //
  111. // SetWindowIcon doesn't work if the platform is not a desktop.
  112. //
  113. // SetWindowIcon is concurrent-safe.
  114. func SetWindowIcon(iconImages []image.Image) {
  115. ui.Get().Window().SetIcon(iconImages)
  116. }
  117. // WindowPosition returns the window position.
  118. // The origin position is the upper-left corner of the current monitor.
  119. // The unit is device-independent pixels.
  120. //
  121. // WindowPosition panics if the main loop does not start yet.
  122. //
  123. // WindowPosition returns the original window position in fullscreen mode.
  124. //
  125. // WindowPosition returns (0, 0) if the platform is not a desktop.
  126. //
  127. // WindowPosition is concurrent-safe.
  128. func WindowPosition() (x, y int) {
  129. return ui.Get().Window().Position()
  130. }
  131. // SetWindowPosition sets the window position.
  132. // The origin position is the upper-left corner of the current monitor.
  133. // The unit is device-independent pixels.
  134. //
  135. // SetWindowPosition sets the original window position in fullscreen mode.
  136. //
  137. // SetWindowPosition does nothing if the platform is not a desktop.
  138. //
  139. // SetWindowPosition is concurrent-safe.
  140. func SetWindowPosition(x, y int) {
  141. windowPositionSetExplicitly.Store(true)
  142. ui.Get().Window().SetPosition(x, y)
  143. }
  144. var (
  145. windowPositionSetExplicitly atomic.Bool
  146. )
  147. func initializeWindowPositionIfNeeded(width, height int) {
  148. if !windowPositionSetExplicitly.Load() {
  149. sw, sh := ui.Get().Monitor().Size()
  150. x, y := ui.InitialWindowPosition(sw, sh, width, height)
  151. ui.Get().Window().SetPosition(x, y)
  152. }
  153. }
  154. // WindowSize returns the window size on desktops.
  155. // WindowSize returns (0, 0) on other environments.
  156. //
  157. // Even if the application is in fullscreen mode, WindowSize returns the original window size
  158. // If you need the fullscreen dimensions, see Monitor().Size() instead.
  159. //
  160. // WindowSize is concurrent-safe.
  161. func WindowSize() (int, int) {
  162. return ui.Get().Window().Size()
  163. }
  164. // SetWindowSize sets the window size on desktops.
  165. // SetWindowSize does nothing on other environments.
  166. //
  167. // Even if the application is in fullscreen mode, SetWindowSize sets the original window size.
  168. //
  169. // SetWindowSize panics if width or height is not a positive number.
  170. //
  171. // SetWindowSize is concurrent-safe.
  172. func SetWindowSize(width, height int) {
  173. if width <= 0 || height <= 0 {
  174. panic("ebiten: width and height must be positive")
  175. }
  176. ui.Get().Window().SetSize(width, height)
  177. }
  178. // WindowSizeLimits returns the limitation of the window size on desktops.
  179. // A negative value indicates the size is not limited.
  180. //
  181. // WindowSizeLimits is concurrent-safe.
  182. func WindowSizeLimits() (minw, minh, maxw, maxh int) {
  183. return ui.Get().Window().SizeLimits()
  184. }
  185. // SetWindowSizeLimits sets the limitation of the window size on desktops.
  186. // A negative value indicates the size is not limited.
  187. //
  188. // SetWindowSizeLimits is concurrent-safe.
  189. func SetWindowSizeLimits(minw, minh, maxw, maxh int) {
  190. ui.Get().Window().SetSizeLimits(minw, minh, maxw, maxh)
  191. }
  192. // IsWindowFloating reports whether the window is always shown above all the other windows.
  193. //
  194. // IsWindowFloating returns false if the platform is not a desktop.
  195. //
  196. // IsWindowFloating is concurrent-safe.
  197. func IsWindowFloating() bool {
  198. return ui.Get().Window().IsFloating()
  199. }
  200. // SetWindowFloating sets the state whether the window is always shown above all the other windows.
  201. //
  202. // SetWindowFloating does nothing if the platform is not a desktop.
  203. //
  204. // SetWindowFloating is concurrent-safe.
  205. func SetWindowFloating(float bool) {
  206. ui.Get().Window().SetFloating(float)
  207. }
  208. // MaximizeWindow maximizes the window.
  209. //
  210. // MaximizeWindow does nothing when the window is not resizable (WindowResizingModeEnabled).
  211. //
  212. // MaximizeWindow does nothing if the platform is not a desktop.
  213. //
  214. // MaximizeWindow is concurrent-safe.
  215. func MaximizeWindow() {
  216. ui.Get().Window().Maximize()
  217. }
  218. // IsWindowMaximized reports whether the window is maximized or not.
  219. //
  220. // IsWindowMaximized returns false when the window is not resizable (WindowResizingModeEnabled).
  221. //
  222. // IsWindowMaximized always returns false if the platform is not a desktop.
  223. //
  224. // IsWindowMaximized is concurrent-safe.
  225. func IsWindowMaximized() bool {
  226. return ui.Get().Window().IsMaximized()
  227. }
  228. // MinimizeWindow minimizes the window.
  229. //
  230. // If the main loop does not start yet, MinimizeWindow does nothing.
  231. //
  232. // MinimizeWindow does nothing if the platform is not a desktop.
  233. //
  234. // MinimizeWindow is concurrent-safe.
  235. func MinimizeWindow() {
  236. ui.Get().Window().Minimize()
  237. }
  238. // IsWindowMinimized reports whether the window is minimized or not.
  239. //
  240. // IsWindowMinimized always returns false if the platform is not a desktop.
  241. //
  242. // IsWindowMinimized is concurrent-safe.
  243. func IsWindowMinimized() bool {
  244. return ui.Get().Window().IsMinimized()
  245. }
  246. // RestoreWindow restores the window from its maximized or minimized state.
  247. //
  248. // RestoreWindow panics when the window is not maximized nor minimized.
  249. //
  250. // RestoreWindow is concurrent-safe.
  251. func RestoreWindow() {
  252. if !IsWindowMaximized() && !IsWindowMinimized() {
  253. panic("ebiten: RestoreWindow must be called on a maximized or a minimized window")
  254. }
  255. ui.Get().Window().Restore()
  256. }
  257. // IsWindowBeingClosed returns true when the user is trying to close the window on desktops.
  258. // As the window is closed immediately by default,
  259. // you might want to call SetWindowClosingHandled(true) to prevent the window is automatically closed.
  260. //
  261. // IsWindowBeingClosed always returns false if the platform is not a desktop.
  262. //
  263. // IsWindowBeingClosed is concurrent-safe.
  264. func IsWindowBeingClosed() bool {
  265. return theInputState.windowBeingClosed()
  266. }
  267. // SetWindowClosingHandled sets whether the window closing is handled or not on desktops. The default state is false.
  268. //
  269. // If the window closing is handled, the window is not closed immediately and
  270. // the game can know whether the window is being closed or not by IsWindowBeingClosed.
  271. // In this case, the window is not closed automatically.
  272. // To end the game, you have to return an error value at the Game's Update function.
  273. //
  274. // SetWindowClosingHandled works only on desktops.
  275. // SetWindowClosingHandled does nothing if the platform is not a desktop.
  276. //
  277. // SetWindowClosingHandled is concurrent-safe.
  278. func SetWindowClosingHandled(handled bool) {
  279. ui.Get().Window().SetClosingHandled(handled)
  280. }
  281. // IsWindowClosingHandled reports whether the window closing is handled or not on desktops by SetWindowClosingHandled.
  282. //
  283. // IsWindowClosingHandled always returns false if the platform is not a desktop.
  284. //
  285. // IsWindowClosingHandled is concurrent-safe.
  286. func IsWindowClosingHandled() bool {
  287. return ui.Get().Window().IsClosingHandled()
  288. }
  289. // SetWindowMousePassthrough sets whether a mouse cursor passthroughs the window or not on desktops. The default state is false.
  290. //
  291. // Even if this is set true, some platforms might require a window to be undecorated
  292. // in order to make the mouse cursor passthrough the window.
  293. //
  294. // SetWindowMousePassthrough works only on desktops.
  295. // SetWindowMousePassthrough does nothing if the platform is not a desktop.
  296. //
  297. // SetWindowMousePassthrough is concurrent-safe.
  298. func SetWindowMousePassthrough(enabled bool) {
  299. ui.Get().Window().SetMousePassthrough(enabled)
  300. }
  301. // IsWindowMousePassthrough reports whether a mouse cursor passthroughs the window or not on desktops.
  302. //
  303. // IsWindowMousePassthrough always returns false if the platform is not a desktop.
  304. //
  305. // IsWindowMousePassthrough is concurrent-safe.
  306. func IsWindowMousePassthrough() bool {
  307. return ui.Get().Window().IsMousePassthrough()
  308. }
  309. // RequestAttention requests user attention to the current window and/or the current application.
  310. //
  311. // RequestAttention works only on desktops.
  312. // RequestAttention does nothing if the platform is not a desktop.
  313. //
  314. // RequestAttention is concurrent-safe.
  315. func RequestAttention() {
  316. ui.Get().Window().RequestAttention()
  317. }