window.monkey2 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. Namespace mojo.app
  2. #rem monkeydoc Window creation flags.
  3. | WindowFlags | Description
  4. |:--------------|:-----------
  5. | CenterX | Center window horizontally.
  6. | CenterY | Center window vertically.
  7. | Center | Center window.
  8. | Hidden | Window is initally hidden.
  9. | Resizable | Window is resizable.
  10. | Fullscreen | Window is a fullscreen window.
  11. #end
  12. Enum WindowFlags
  13. CenterX=1
  14. CenterY=2
  15. Hidden=4
  16. Resizable=8
  17. Borderless=16
  18. Fullscreen=32
  19. Center=CenterX|CenterY
  20. End
  21. #rem monkeydoc The Window class.
  22. #end
  23. Class Window Extends View
  24. Method New()
  25. Init( "Window",New Recti( 0,0,640,480 ),WindowFlags.Center )
  26. End
  27. Method New( title:String="Window",width:Int=640,height:Int=480,flags:WindowFlags=Null )
  28. Init( title,New Recti( 0,0,width,height ),flags|WindowFlags.Center )
  29. End
  30. Method New( title:String,rect:Recti,flags:WindowFlags=Null )
  31. Init( title,rect,flags )
  32. End
  33. #rem monkeydoc The window title text.
  34. #end
  35. Property Title:String()
  36. Return String.FromUtf8String( SDL_GetWindowTitle( _sdlWindow ) )
  37. Setter( title:String )
  38. SDL_SetWindowTitle( _sdlWindow,title )
  39. End
  40. #rem monkeydoc The window clear color.
  41. #end
  42. Property ClearColor:Color()
  43. Return _clearColor
  44. Setter( clearColor:Color )
  45. _clearColor=clearColor
  46. End
  47. #rem monkeydoc True if window clearing is enabled.
  48. #end
  49. Property ClearEnabled:Bool()
  50. Return _clearEnabled
  51. Setter( clearEnabled:Bool )
  52. _clearEnabled=clearEnabled
  53. End
  54. #rem monkeydoc The window swap interval.
  55. #end
  56. Property SwapInterval:Int()
  57. Return _swapInterval
  58. Setter( swapInterval:Int )
  59. _swapInterval=swapInterval
  60. End
  61. #rem monkeydoc @hidden.
  62. #end
  63. Property Fullscreen:Bool()
  64. Return _fullscreen
  65. Setter( fullscreen:Bool )
  66. If fullscreen=_fullscreen Return
  67. _fullscreen=fullscreen
  68. If _fullscreen
  69. Local mode:SDL_DisplayMode
  70. mode.w=Width
  71. mode.h=Height
  72. SDL_SetWindowDisplayMode( _sdlWindow,Varptr mode )
  73. SDL_SetWindowFullscreen( _sdlWindow,SDL_WINDOW_FULLSCREEN )
  74. Else
  75. SDL_SetWindowFullscreen( _sdlWindow,0 )
  76. Endif
  77. End
  78. Property ContentView:View()
  79. Return _contentView
  80. Setter( contentView:View )
  81. If _contentView RemoveChildView( _contentView )
  82. _contentView=contentView
  83. If _contentView AddChildView( _contentView )
  84. End
  85. Method UpdateWindow( render:Bool )
  86. LayoutWindow()
  87. If render RenderWindow()
  88. End
  89. '***** INTERNAL *****
  90. #rem monkeydoc The internal SDL_Window used by this window.
  91. #end
  92. Property SDLWindow:SDL_Window Ptr()
  93. Return _sdlWindow
  94. End
  95. #rem monkeydoc @hidden The internal SDL_GLContext used by this window.
  96. #end
  97. Property SDLGLContext:SDL_GLContext()
  98. Return _sdlGLContext
  99. End
  100. #rem monkeydoc @hidden
  101. #end
  102. Function AllWindows:Window[]()
  103. Return _allWindows.ToArray()
  104. End
  105. #rem monkeydoc @hidden
  106. #end
  107. Function VisibleWindows:Window[]()
  108. Return _visibleWindows.ToArray()
  109. End
  110. #rem monkeydoc @hidden
  111. #end
  112. Function WindowForID:Window( id:UInt )
  113. Return _windowsByID[id]
  114. End
  115. #rem monkeydoc @hidden
  116. #end
  117. Method SendWindowEvent( event:WindowEvent )
  118. Select event.Type
  119. Case EventType.WindowMoved,EventType.WindowResized
  120. _frame=GetFrame()
  121. Frame=_frame
  122. _weirdHack=true
  123. End
  124. OnWindowEvent( event )
  125. End
  126. Protected
  127. #rem monkeydoc Window event handler.
  128. Called when the window is sent a window event.
  129. #end
  130. Method OnWindowEvent( event:WindowEvent ) Virtual
  131. Select event.Type
  132. Case EventType.WindowClose
  133. App.Terminate()
  134. Case EventType.WindowMoved
  135. Case EventType.WindowResized
  136. App.RequestRender()
  137. Case EventType.WindowGainedFocus
  138. Case EventType.WindowLostFocus
  139. End
  140. End
  141. Protected
  142. Method OnLayout() Override
  143. If _contentView _contentView.Frame=Rect
  144. End
  145. Private
  146. Field _sdlWindow:SDL_Window Ptr
  147. Field _sdlGLContext:SDL_GLContext
  148. Field _flags:WindowFlags
  149. Field _fullscreen:=False
  150. Field _swapInterval:=1
  151. Field _canvas:Canvas
  152. Field _clearColor:=Color.Grey
  153. Field _clearEnabled:=True
  154. Field _contentView:View
  155. Field _minSize:Vec2i
  156. Field _maxSize:Vec2i
  157. Field _frame:Recti
  158. 'Ok, angles glViewport appears To be 'lagging' by one frame, causing weirdness when resizing.
  159. Field _weirdHack:Bool
  160. Global _allWindows:=New Stack<Window>
  161. Global _visibleWindows:=New Stack<Window>
  162. Global _windowsByID:=New Map<UInt,Window>
  163. Method GetMinSize:Vec2i()
  164. Local w:Int,h:Int
  165. SDL_GetWindowMinimumSize( _sdlWindow,Varptr w,Varptr h )
  166. Return New Vec2i( w,h )
  167. End
  168. Method GetMaxSize:Vec2i()
  169. Local w:Int,h:Int
  170. SDL_GetWindowMaximumSize( _sdlWindow,Varptr w,Varptr h )
  171. Return New Vec2i( w,h )
  172. End
  173. Method GetFrame:Recti()
  174. Local x:Int,y:Int,w:Int,h:Int
  175. SDL_GetWindowPosition( _sdlWindow,Varptr x,Varptr y )
  176. SDL_GetWindowSize( _sdlWindow,Varptr w,Varptr h )
  177. Return New Recti( x,y,x+w,y+h )
  178. End
  179. Method LayoutWindow()
  180. 'All this polling is a bit ugly...fixme.
  181. #If __TARGET__="emscripten"
  182. Local w:Int,h:Int,fs:Int
  183. emscripten_get_canvas_size( Varptr w,Varptr h,Varptr fs )
  184. If w<>Frame.Width Or h<>Frame.Height
  185. Frame=New Recti( 0,0,w,h )
  186. Endif
  187. #Else
  188. If MinSize<>_minSize
  189. SDL_SetWindowMinimumSize( _sdlWindow,MinSize.x,MinSize.y )
  190. _minSize=GetMinSize()
  191. MinSize=_minSize
  192. Endif
  193. If MaxSize<>_maxSize
  194. SDL_SetWindowMaximumSize( _sdlWindow,MaxSize.x,MaxSize.y )
  195. _maxSize=GetMaxSize()
  196. MaxSize=_maxSize
  197. Endif
  198. If Frame<>_frame
  199. SDL_SetWindowPosition( _sdlWindow,Frame.X,Frame.Y )
  200. SDL_SetWindowSize( _sdlWindow,Frame.Width,Frame.Height )
  201. _frame=GetFrame()
  202. Frame=_frame
  203. _weirdHack=True
  204. Endif
  205. #Endif
  206. Measure()
  207. UpdateLayout()
  208. End
  209. #rem monkeydoc @hidden
  210. #end
  211. Method RenderWindow()
  212. SDL_GL_MakeCurrent( _sdlWindow,_sdlGLContext )
  213. SDL_GL_SetSwapInterval( _swapInterval )
  214. #If __TARGET__="desktop" And __HOSTOS__="windows"
  215. If _weirdHack
  216. _weirdHack=False
  217. SDL_GL_SwapWindow( _sdlWindow )
  218. Endif
  219. #Endif
  220. Local bounds:=New Recti( 0,0,Frame.Size )
  221. _canvas.Resize( bounds.Size )
  222. _canvas.BeginRender( bounds,New AffineMat3f )
  223. If _clearEnabled _canvas.Clear( _clearColor )
  224. Render( _canvas )
  225. _canvas.EndRender()
  226. SDL_GL_SwapWindow( _sdlWindow )
  227. End
  228. Method Init( title:String,rect:Recti,flags:WindowFlags )
  229. Local x:=(flags & WindowFlags.CenterX) ? SDL_WINDOWPOS_CENTERED Else rect.X
  230. Local y:=(flags & WindowFlags.CenterY) ? SDL_WINDOWPOS_CENTERED Else rect.Y
  231. Local sdlFlags:SDL_WindowFlags=SDL_WINDOW_OPENGL
  232. If flags & WindowFlags.Hidden sdlFlags|=SDL_WINDOW_HIDDEN
  233. If flags & WindowFlags.Resizable sdlFlags|=SDL_WINDOW_RESIZABLE
  234. If flags & WindowFlags.Borderless sdlFlags|=SDL_WINDOW_BORDERLESS
  235. If flags & WindowFlags.Fullscreen _fullscreen=True ; sdlFlags|=SDL_WINDOW_FULLSCREEN
  236. _flags=flags
  237. _sdlWindow=SDL_CreateWindow( title,x,y,rect.Width,rect.Height,sdlFlags )
  238. Assert( _sdlWindow,"FATAL ERROR: SDL_CreateWindow failed" )
  239. _allWindows.Push( Self )
  240. _windowsByID[SDL_GetWindowID( _sdlWindow )]=Self
  241. If Not (flags & WindowFlags.Hidden) _visibleWindows.Push( Self )
  242. _minSize=GetMinSize()
  243. MinSize=_minSize
  244. _maxSize=GetMaxSize()
  245. MaxSize=_maxSize
  246. _frame=GetFrame()
  247. Frame=_frame
  248. 'create GL context
  249. _sdlGLContext=SDL_GL_CreateContext( _sdlWindow )
  250. Assert( _sdlGLContext,"FATAL ERROR: SDL_GL_CreateContext failed" )
  251. SDL_GL_MakeCurrent( _sdlWindow,_sdlGLContext )
  252. _canvas=New Canvas( _frame.Width,_frame.Height )
  253. _clearColor=App.Theme.GetColor( "windowClearColor" )
  254. SetWindow( Self )
  255. UpdateActive()
  256. LayoutWindow()
  257. End
  258. End