window.monkey2 8.0 KB

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