app.monkey2 20 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. #Import "native/app.cpp"
  2. #Import "native/app.h"
  3. Namespace mojo.app
  4. Extern Private
  5. Function AppInit()="bbApp::init"
  6. Public
  7. '#Import "assets/Roboto-Regular.ttf@/mojo"
  8. '#Import "assets/RobotoMono-Regular.ttf@/mojo"
  9. #rem monkeydoc The global AppInstance instance.
  10. #end
  11. Global App:AppInstance
  12. #rem monkeydoc @hidden
  13. #end
  14. Struct DisplayMode
  15. Field width:Int
  16. Field height:Int
  17. Field hertz:Int
  18. End
  19. #rem monkeydoc The AppInstance class.
  20. The AppInstance class is mainly reponsible for running the app 'event loop', but also provides several utility functions for managing the application.
  21. A global instance of the AppInstance class is stored in the [[App]] global variable, so you can use any member of the AppInstance simply by prefixing it with 'App.', eg: App.MilliSecs
  22. #end
  23. Class AppInstance
  24. #rem monkeydoc Invoked when the app becomes idle.
  25. #end
  26. Field Idle:Void()
  27. #rem monkeydoc Invoked when app is activated.
  28. #end
  29. Field Activated:Void()
  30. #rem monkeydoc Invoked when app is deactivated.
  31. #end
  32. Field Deactivated:Void()
  33. #rem monkeydoc @hidden
  34. #end
  35. Field ThemeChanged:Void()
  36. #rem monkeydoc Invoked when a file is dropped on an app window.
  37. #end
  38. Field FileDropped:Void( path:String )
  39. #rem monkeydoc Key event filter.
  40. To prevent the event from being sent to a view, a filter can eat the event using [[Event.Eat]].
  41. Filter functions should check if the event has already been 'eaten' by checking the event's [[Event.Eaten]] property before processing the event.
  42. #end
  43. Field KeyEventFilter:Void( event:KeyEvent )
  44. #rem monkeydoc MouseEvent filter.
  45. To prevent the event from being sent to a view, a filter can eat the event using [[Event.Eat]].
  46. Filter functions should check if the event has already been 'eaten' by checking the event's [[Event.Eaten]] property before processing the event.
  47. #end
  48. Field MouseEventFilter:Void( event:MouseEvent )
  49. #rem monkeydoc Create a new app instance.
  50. #end
  51. Method New( config:StringMap<String> =Null )
  52. App=Self
  53. If Not config config=New StringMap<String>
  54. _config=config
  55. SDL_Init( SDL_INIT_VIDEO|SDL_INIT_JOYSTICK )
  56. 'possible fix for linux crashing at exit (can't reproduce myself).
  57. '
  58. libc.atexit( SDL_Quit )
  59. AppInit()
  60. Keyboard.Init()
  61. Mouse.Init()
  62. Audio.Init()
  63. SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER,1 )
  64. #If __TARGET__="windows" Or __TARGET__="macos" Or __TARGET__="emscripten"
  65. _captureMouse=True
  66. #Endif
  67. #if __MOBILE_TARGET__
  68. _touchMouse=True
  69. SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_ES )
  70. SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION,2 )
  71. #Else If __TARGET__="emscripten"
  72. #Else If __TARGET__="raspbian"
  73. #Else If __DESKTOP_TARGET__
  74. #if __TARGET__="windows"
  75. Local gl_profile:Int
  76. Select GetConfig( "GL_context_profile","es" )
  77. Case "core"
  78. gl_profile=SDL_GL_CONTEXT_PROFILE_CORE
  79. Case "compatibility"
  80. gl_profile=SDL_GL_CONTEXT_PROFILE_COMPATIBILITY
  81. Default
  82. gl_profile=SDL_GL_CONTEXT_PROFILE_ES
  83. End
  84. Local gl_major:=Int( GetConfig( "GL_context_major_version",2 ) )
  85. Local gl_minor:=Int( GetConfig( "GL_context_minor_version",0 ) )
  86. SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK,gl_profile )
  87. SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION,gl_major )
  88. SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION,gl_minor )
  89. #Endif
  90. SDL_GL_SetAttribute( SDL_GL_SHARE_WITH_CURRENT_CONTEXT,1 )
  91. SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE,Int( GetConfig( "GL_depth_buffer_enabled",0 ) ) )
  92. SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE,Int( GetConfig( "GL_stencil_buffer_enabled",0 ) ) )
  93. 'create dummy window/context
  94. Local _sdlWindow:=SDL_CreateWindow( "<dummy>",0,0,0,0,SDL_WINDOW_HIDDEN|SDL_WINDOW_OPENGL )
  95. Assert( _sdlWindow,"FATAL ERROR: SDL_CreateWindow failed" )
  96. Local _sdlGLContext:=SDL_GL_CreateContext( _sdlWindow )
  97. Assert( _sdlGLContext,"FATAL ERROR: SDL_GL_CreateContext failed" )
  98. SDL_GL_MakeCurrent( _sdlWindow,_sdlGLContext )
  99. #Endif
  100. _defaultFont=_res.OpenFont( "DejaVuSans",16 )
  101. _theme=New Theme
  102. Local themePath:=GetConfig( "initialTheme","default" )
  103. Local themeScale:=Float( GetConfig( "initialThemeScale",1 ) )
  104. _theme.Load( themePath,New Vec2f( themeScale ) )
  105. _theme.ThemeChanged+=Lambda()
  106. ThemeChanged()
  107. RequestRender()
  108. UpdateWindows()
  109. End
  110. End
  111. #rem monkeydoc Fallback font.
  112. #end
  113. Property DefaultFont:Font()
  114. Return _defaultFont
  115. End
  116. #rem monkeydoc The current theme.
  117. #end
  118. Property Theme:Theme()
  119. Return _theme
  120. End
  121. #rem monkeydoc True if clipboard text is empty.
  122. This is faster than checking whether [[ClipboardText]] returns an empty string.
  123. #end
  124. Property ClipboardTextEmpty:Bool()
  125. Return SDL_HasClipboardText()=SDL_FALSE
  126. End
  127. #rem monkeydoc Clipboard text.
  128. #end
  129. Property ClipboardText:String()
  130. If SDL_HasClipboardText()=SDL_FALSE Return ""
  131. Local p:=SDL_GetClipboardText()
  132. Local str:=String.FromCString( p )
  133. 'fix windows eols
  134. str=str.Replace( "~r~n","~n" )
  135. str=str.Replace( "~r","~n" )
  136. SDL_free( p )
  137. Return str
  138. Setter( text:String )
  139. SDL_SetClipboardText( text )
  140. End
  141. #rem monkeydoc The current key view.
  142. The key view is the view key events are sent to.
  143. #end
  144. Property KeyView:View()
  145. If Not _active Return Null
  146. If IsActive( _keyView ) Return _keyView
  147. If _modalView Return _modalView
  148. Return _activeWindow
  149. Setter( keyView:View )
  150. _keyView=keyView
  151. End
  152. #rem monkeydoc The current mouse view.
  153. The mouse view is the view that the mouse is currently 'dragging'.
  154. #end
  155. Property MouseView:View()
  156. Return _mouseView
  157. End
  158. #rem monkeydoc The current hover view.
  159. The hover view is the view that the mouse is currently 'hovering' over.
  160. #end
  161. Property HoverView:View()
  162. Return _hoverView
  163. End
  164. #rem monkeydoc The desktop size
  165. #end
  166. Property DesktopSize:Vec2i()
  167. #If __TARGET__="emscripten"
  168. Return New Vec2i( 1280,960 )
  169. #Else
  170. Local dm:SDL_DisplayMode
  171. If SDL_GetDesktopDisplayMode( 0,Varptr dm ) Return New Vec2i
  172. Return New Vec2i( dm.w,dm.h )
  173. #Endif
  174. End
  175. #rem monkeydoc True if app is active.
  176. An app is active if any of its windows has system input focus.
  177. #end
  178. Property Active:Bool()
  179. Return _active
  180. End
  181. #rem monkeydoc The currently active window.
  182. The active window is the window that has system input focus.
  183. #end
  184. Property ActiveWindow:Window()
  185. If Not _activeWindow
  186. Local windows:=Window.VisibleWindows()
  187. If windows _activeWindow=windows[0]
  188. Endif
  189. Return _activeWindow
  190. End
  191. #rem monkeydoc Mouse location relative to the active window.
  192. @see [[ActiveWindow]], [[MouseX]], [[MouseY]]
  193. #end
  194. Property MouseLocation:Vec2i()
  195. Return _mouseLocation
  196. End
  197. #rem monkeydoc @hidden
  198. #end
  199. Property ModalView:View()
  200. Return _modalView
  201. End
  202. #rem monkeydoc Approximate frames per second rendering rate.
  203. #end
  204. Property FPS:Float()
  205. Return _fps
  206. End
  207. #rem monkeydoc Number of milliseconds app has been running.
  208. Deprecated! Just use std.time.Millisecs()
  209. #end
  210. Property Millisecs:Int()
  211. Return std.time.Millisecs()
  212. End
  213. #rem monkeydoc Puts the app to sleep.
  214. Note: Use of this method is not recommended, as the app will be unresponsive while sleeping!
  215. #end
  216. Method Sleep( seconds:Double )
  217. Local timeout:=Now()+seconds
  218. Repeat
  219. Local sleep:=timeout-Now()
  220. If sleep>10
  221. time.Sleep( sleep )
  222. UpdateWindows()
  223. Else If sleep>0
  224. time.Sleep( sleep )
  225. Else
  226. Return
  227. Endif
  228. Forever
  229. End
  230. #If __DESKTOP_TARGET__
  231. #rem monkeydoc @hidden
  232. #end
  233. Method WaitIdle()
  234. Local future:=New Future<Bool>
  235. Idle+=Lambda()
  236. future.Set( True )
  237. End
  238. future.Get()
  239. End
  240. #Endif
  241. #rem monkeydoc @hidden
  242. #end
  243. Method GetConfig:String( name:String,defValue:String )
  244. If _config.Contains( name ) Return _config[name]
  245. Return defValue
  246. End
  247. #rem monkeydoc @hidden
  248. #end
  249. Method GetDisplayModes:DisplayMode[]()
  250. Local n:=SDL_GetNumDisplayModes( 0 )
  251. Local modes:=New DisplayMode[n]
  252. For Local i:=0 Until n
  253. Local mode:SDL_DisplayMode
  254. SDL_GetDisplayMode( 0,i,Varptr mode )
  255. modes[i].width=mode.w
  256. modes[i].height=mode.h
  257. modes[i].hertz=mode.refresh_rate
  258. Next
  259. Return modes
  260. End
  261. #rem monkeydoc @hidden
  262. #end
  263. Method BeginModal( view:View )
  264. _modalStack.Push( _modalView )
  265. _modalView=view
  266. RequestRender()
  267. End
  268. #rem monkeydoc @hidden
  269. #end
  270. Method EndModal()
  271. _modalView=_modalStack.Pop()
  272. RequestRender()
  273. End
  274. #rem monkeydoc Terminate the app.
  275. #end
  276. Method Terminate()
  277. libc.exit_( 0 )
  278. End
  279. #rem monkeydoc Request that the app render itself.
  280. #end
  281. Method RequestRender()
  282. _requestRender=True
  283. End
  284. #rem monkeydoc @hidden
  285. #end
  286. Method MainLoop()
  287. If Not _requestRender
  288. SDL_WaitEvent( Null )
  289. Endif
  290. UpdateEvents()
  291. UpdateWindows()
  292. End
  293. #rem monkeydoc @hidden
  294. #end
  295. Method IsActive:Bool( view:View )
  296. Return view And view.Active And (Not _modalView Or view.IsChildOf( _modalView ))
  297. End
  298. #rem monkeydoc @hidden
  299. #end
  300. Method ActiveViewAtMouseLocation:View()
  301. If Not _window Return Null
  302. Local view:=_window.FindViewAtWindowPoint( _mouseLocation )
  303. If IsActive( view ) Return view
  304. Return Null
  305. End
  306. #rem monkeydoc @hidden
  307. #end
  308. Method UpdateWindows()
  309. Local render:=_requestRender
  310. _requestRender=False
  311. If render UpdateFPS()
  312. For Local window:=Eachin Window.VisibleWindows()
  313. window.UpdateWindow( render )
  314. End
  315. If _mouseView And Not IsActive( _mouseView )
  316. SendMouseEvent( EventType.MouseUp,_mouseView )
  317. _mouseView=Null
  318. Endif
  319. If _hoverView And Not IsActive( _hoverView )
  320. SendMouseEvent( EventType.MouseLeave,_hoverView )
  321. _hoverView=Null
  322. Endif
  323. If Not _hoverView And Not _touchMouse
  324. _hoverView=ActiveViewAtMouseLocation()
  325. If _mouseView And _hoverView<>_mouseView _hoverView=Null
  326. If _hoverView SendMouseEvent( EventType.MouseEnter,_hoverView )
  327. Endif
  328. End
  329. #rem monkeydoc @hidden
  330. #end
  331. Function EmscriptenMainLoop()
  332. App._requestRender=True
  333. App.MainLoop()
  334. End
  335. #rem monkeydoc Run the app.
  336. #end
  337. Method Run()
  338. #if __DESKTOP_TARGET__
  339. SDL_AddEventWatch( _EventFilter,Null )
  340. #endif
  341. RequestRender()
  342. #If __TARGET__="emscripten"
  343. emscripten_set_main_loop( EmscriptenMainLoop,0,1 )
  344. #Else
  345. Repeat
  346. MainLoop()
  347. Forever
  348. #Endif
  349. End
  350. Private
  351. Field _config:StringMap<String>
  352. Field _touchMouse:Bool=False 'Whether mouse is really touch
  353. Field _captureMouse:Bool=False 'Whether to use SDL_CaptureMouse
  354. Field _res:=New ResourceManager
  355. Field _defaultFont:Font
  356. Field _theme:Theme
  357. Field _active:Bool
  358. Field _activeWindow:Window
  359. Field _keyView:View
  360. Field _hoverView:View
  361. Field _mouseView:View
  362. Field _requestRender:Bool
  363. Field _fps:Float
  364. Field _fpsFrames:Int
  365. Field _fpsMillis:Int
  366. Field _window:Window
  367. Field _key:Key
  368. Field _rawKey:Key
  369. Field _keyChar:String
  370. Field _modifiers:Modifier
  371. Field _mouseButton:MouseButton
  372. Field _mouseLocation:Vec2i
  373. Field _mouseWheel:Vec2i
  374. Field _mouseClicks:Int=0
  375. Field _modalView:View
  376. Field _modalStack:=New Stack<View>
  377. Field _polling:Bool
  378. Method UpdateFPS()
  379. _fpsFrames+=1
  380. Local elapsed:=App.Millisecs-_fpsMillis
  381. If elapsed>=250
  382. _fps=Round( _fpsFrames/(elapsed/1000.0) )
  383. _fpsMillis+=elapsed
  384. _fpsFrames=0
  385. Endif
  386. End
  387. Method UpdateEvents()
  388. Local event:SDL_Event
  389. _polling=True
  390. Mouse.Update()
  391. Keyboard.Update()
  392. While SDL_PollEvent( Varptr event )
  393. Keyboard.SendEvent( Varptr event )
  394. DispatchEvent( Varptr event )
  395. Wend
  396. _polling=False
  397. Local idle:=Idle
  398. Idle=Null
  399. idle()
  400. End
  401. Method SendKeyEvent( type:EventType )
  402. Local view:=KeyView
  403. Local event:=New KeyEvent( type,view,_key,_rawKey,_modifiers,_keyChar )
  404. KeyEventFilter( event )
  405. If event.Eaten Return
  406. If view view.SendKeyEvent( event )
  407. End
  408. Method SendMouseEvent( type:EventType,view:View )
  409. Local location:=view.TransformWindowPointToView( _mouseLocation )
  410. Local event:=New MouseEvent( type,view,location,_mouseButton,_mouseWheel,_modifiers,_mouseClicks )
  411. MouseEventFilter( event )
  412. If event.Eaten Return
  413. view.SendMouseEvent( event )
  414. If event.Eaten Return
  415. Select type
  416. Case EventType.MouseDown
  417. Select _mouseButton
  418. Case MouseButton.Left
  419. SendMouseEvent( EventType.MouseClick,view )
  420. If _mouseClicks And Not (_mouseClicks & 1)
  421. SendMouseEvent( EventType.MouseDoubleClick,view )
  422. End
  423. Case MouseButton.Right
  424. SendMouseEvent( EventType.MouseRightClick,view )
  425. End
  426. End
  427. End
  428. Method SendWindowEvent( type:EventType )
  429. Local event:=New WindowEvent( type,_window )
  430. _window.SendWindowEvent( event )
  431. End
  432. Method DispatchEvent( event:SDL_Event Ptr )
  433. Select event->type
  434. #If __TARGET__="macos"
  435. Case SDL_QUIT
  436. If _activeWindow _activeWindow.SendWindowEvent( New WindowEvent( EventType.WindowClose,_activeWindow ) )
  437. #Endif
  438. Case SDL_KEYDOWN
  439. Local kevent:=Cast<SDL_KeyboardEvent Ptr>( event )
  440. _window=Window.WindowForID( kevent->windowID )
  441. If Not _window Return
  442. _key=Keyboard.KeyCodeToKey( Int( kevent->keysym.sym ) )
  443. _rawKey=Keyboard.ScanCodeToRawKey( Int( kevent->keysym.scancode ) )
  444. _keyChar=Keyboard.KeyName( _key )
  445. If kevent->repeat_
  446. SendKeyEvent( EventType.KeyRepeat )
  447. Else
  448. SendKeyEvent( EventType.KeyDown )
  449. Endif
  450. _modifiers=Keyboard.Modifiers
  451. Case SDL_KEYUP
  452. Local kevent:=Cast<SDL_KeyboardEvent Ptr>( event )
  453. _window=Window.WindowForID( kevent->windowID )
  454. If Not _window Return
  455. _key=Keyboard.KeyCodeToKey( Int( kevent->keysym.sym ) )
  456. _rawKey=Keyboard.ScanCodeToRawKey( Int( kevent->keysym.scancode ) )
  457. _keyChar=Keyboard.KeyName( _key )
  458. SendKeyEvent( EventType.KeyUp )
  459. _modifiers=Keyboard.Modifiers
  460. Case SDL_TEXTINPUT
  461. Local tevent:=Cast<SDL_TextInputEvent Ptr>( event )
  462. _window=Window.WindowForID( tevent->windowID )
  463. If Not _window Return
  464. _keyChar=String.FromCString( tevent->text )
  465. SendKeyEvent( EventType.KeyChar )
  466. Case SDL_MOUSEBUTTONDOWN
  467. Local mevent:=Cast<SDL_MouseButtonEvent Ptr>( event )
  468. _window=Window.WindowForID( mevent->windowID )
  469. If Not _window Return
  470. _mouseLocation=_window.MouseScale * New Vec2i( mevent->x,mevent->y )
  471. _mouseButton=Cast<MouseButton>( mevent->button )
  472. If Not _mouseView
  473. Local mouseView:=ActiveViewAtMouseLocation()
  474. If mouseView
  475. If _touchMouse
  476. _hoverView=mouseView
  477. SendMouseEvent( EventType.MouseEnter,_hoverView )
  478. Endif
  479. If _captureMouse SDL_CaptureMouse( SDL_TRUE )
  480. _mouseView=mouseView
  481. _mouseClicks=mevent->clicks
  482. SendMouseEvent( EventType.MouseDown,_mouseView )
  483. _mouseClicks=0
  484. Endif
  485. Endif
  486. Case SDL_MOUSEBUTTONUP
  487. Local mevent:=Cast<SDL_MouseButtonEvent Ptr>( event )
  488. _window=Window.WindowForID( mevent->windowID )
  489. If Not _window Return
  490. _mouseLocation=_window.MouseScale * New Vec2i( mevent->x,mevent->y )
  491. _mouseButton=Cast<MouseButton>( mevent->button )
  492. If _mouseView
  493. If _captureMouse SDL_CaptureMouse( SDL_FALSE )
  494. SendMouseEvent( EventType.MouseUp,_mouseView )
  495. _mouseButton=Null
  496. _mouseView=Null
  497. If _touchMouse
  498. SendMouseEvent( EventType.MouseLeave,_hoverView )
  499. _hoverView=Null
  500. Endif
  501. Endif
  502. Case SDL_MOUSEMOTION
  503. Local mevent:=Cast<SDL_MouseMotionEvent Ptr>( event )
  504. _window=Window.WindowForID( mevent->windowID )
  505. If Not _window Return
  506. _mouseLocation=_window.MouseScale * New Vec2i( mevent->x,mevent->y )
  507. If Not _touchMouse
  508. Local hoverView:=ActiveViewAtMouseLocation()
  509. If _mouseView And hoverView<>_mouseView hoverView=Null
  510. If hoverView<>_hoverView
  511. If _hoverView SendMouseEvent( EventType.MouseLeave,_hoverView )
  512. _hoverView=hoverView
  513. If _hoverView SendMouseEvent( EventType.MouseEnter,_hoverView )
  514. Endif
  515. Endif
  516. If _mouseView
  517. SendMouseEvent( EventType.MouseMove,_mouseView )
  518. Else If _hoverView
  519. SendMouseEvent( EventType.MouseMove,_hoverView )
  520. Endif
  521. Case SDL_MOUSEWHEEL
  522. Local mevent:=Cast<SDL_MouseWheelEvent Ptr>( event )
  523. _window=Window.WindowForID( mevent->windowID )
  524. If Not _window Return
  525. _mouseWheel=New Vec2i( mevent->x,mevent->y )
  526. If _mouseView
  527. SendMouseEvent( EventType.MouseWheel,_mouseView )
  528. Else If _hoverView
  529. SendMouseEvent( EventType.MouseWheel,_hoverView )
  530. Endif
  531. Case SDL_WINDOWEVENT
  532. Local wevent:=Cast<SDL_WindowEvent Ptr>( event )
  533. _window=Window.WindowForID( wevent->windowID )
  534. If Not _window Return
  535. Select wevent->event
  536. Case SDL_WINDOWEVENT_CLOSE
  537. SendWindowEvent( EventType.WindowClose )
  538. Case SDL_WINDOWEVENT_MOVED
  539. Case SDL_WINDOWEVENT_RESIZED
  540. Case SDL_WINDOWEVENT_SIZE_CHANGED
  541. Case SDL_WINDOWEVENT_FOCUS_GAINED
  542. Print "SDL_WINDOWEVENT_FOCUS_GAINED"
  543. Local active:=_active
  544. _activeWindow=_window
  545. _active=True
  546. SendWindowEvent( EventType.WindowGainedFocus )
  547. If active<>_active Activated()
  548. Case SDL_WINDOWEVENT_FOCUS_LOST
  549. Print "SDL_WINDOWEVENT_FOCUS_LOST"
  550. Local active:=_active
  551. ' _activeWindow=Null 'Not a great idea!
  552. _active=False
  553. If _mouseView And Not _captureMouse 'should probably do this anyway?
  554. SendMouseEvent( EventType.MouseUp,_mouseView )
  555. _mouseView=Null
  556. Endif
  557. If _hoverView
  558. SendMouseEvent( EventType.MouseLeave,_hoverView )
  559. _hoverView=Null
  560. Endif
  561. SendWindowEvent( EventType.WindowLostFocus )
  562. If active<>_active Deactivated()
  563. Case SDL_WINDOWEVENT_LEAVE
  564. If _mouseView And Not _captureMouse
  565. SendMouseEvent( EventType.MouseUp,_mouseView )
  566. _mouseView=Null
  567. Endif
  568. If _hoverView
  569. SendMouseEvent( EventType.MouseLeave,_hoverView )
  570. _hoverView=Null
  571. Endif
  572. End
  573. Case SDL_USEREVENT
  574. Local uevent:=Cast<SDL_UserEvent Ptr>( event )
  575. Local event:=Cast<AsyncEvent Ptr>( uevent->data1 )
  576. event->Dispatch()
  577. Case SDL_RENDER_TARGETS_RESET
  578. Print "SDL_RENDER_TARGETS_RESET"
  579. RequestRender()
  580. Case SDL_RENDER_DEVICE_RESET
  581. Print "SDL_RENDER_DEVICE_RESET"
  582. mojo.graphics.glutil.glGraphicsSeq+=1
  583. Case SDL_WINDOWEVENT_MOVED
  584. SendWindowEvent( EventType.WindowMoved )
  585. Case SDL_WINDOWEVENT_RESIZED
  586. SendWindowEvent( EventType.WindowResized )
  587. UpdateWindows()
  588. Case SDL_WINDOWEVENT_EXPOSED
  589. RequestRender()
  590. Case SDL_DROPFILE
  591. Local devent:=Cast<SDL_DropEvent Ptr>( event )
  592. Local path:=String.FromCString( devent->file ).Replace( "\","/" )
  593. SDL_free( devent->file )
  594. FileDropped( path )
  595. End
  596. End
  597. Function _EventFilter:Int( userData:Void Ptr,event:SDL_Event Ptr )
  598. Return App.EventFilter( userData,event )
  599. End
  600. Method EventFilter:Int( userData:Void Ptr,event:SDL_Event Ptr )
  601. Select event[0].type
  602. Case SDL_WINDOWEVENT
  603. Local wevent:=Cast<SDL_WindowEvent Ptr>( event )
  604. _window=Window.WindowForID( wevent->windowID )
  605. If Not _window Return 1
  606. Select wevent->event
  607. Case SDL_WINDOWEVENT_MOVED
  608. SendWindowEvent( EventType.WindowMoved )
  609. Return 0
  610. Case SDL_WINDOWEVENT_RESIZED
  611. SendWindowEvent( EventType.WindowResized )
  612. UpdateWindows()
  613. Return 0
  614. End
  615. #if __TARGET__="ios"
  616. Case SDL_APP_TERMINATING
  617. 'Terminate the app.
  618. 'Shut everything down before returning from this function.
  619. return 0
  620. Case SDL_APP_LOWMEMORY
  621. 'You will get this when your app is paused and iOS wants more memory.
  622. 'Release as much memory as possible.
  623. return 0
  624. Case SDL_APP_WILLENTERBACKGROUND
  625. 'Prepare your app to go into the background. Stop loops, etc.
  626. 'This gets called when the user hits the home button, or gets a call.
  627. return 0
  628. Case SDL_APP_DIDENTERBACKGROUND
  629. 'This will get called if the user accepted whatever sent your app to the background.
  630. 'If the user got a phone call and canceled it, you'll instead get an SDL_APP_DIDENTERFOREGROUND event and restart your loops.
  631. 'When you get this, you have 5 seconds to save all your state or the app will be terminated.
  632. 'Your app is NOT active at this point.
  633. return 0
  634. Case SDL_APP_WILLENTERFOREGROUND
  635. 'This call happens when your app is coming back to the foreground.
  636. 'Restore all your state here.
  637. return 0
  638. Case SDL_APP_DIDENTERFOREGROUND
  639. 'Restart your loops here.
  640. 'Your app is interactive and getting CPU again.
  641. return 0
  642. #Endif
  643. End
  644. Return 1
  645. End
  646. End