diff --git a/lime/app/Application.hx b/lime/app/Application.hx index 98ce663b0..075ee7aeb 100644 --- a/lime/app/Application.hx +++ b/lime/app/Application.hx @@ -4,16 +4,19 @@ package lime.app; import lime.ui.IKeyEventListener; import lime.ui.IMouseEventListener; import lime.ui.ITouchEventListener; +import lime.ui.IWindowEventListener; import lime.ui.KeyEventManager; import lime.ui.KeyEvent; import lime.ui.MouseEventManager; import lime.ui.MouseEvent; import lime.ui.TouchEventManager; import lime.ui.TouchEvent; +import lime.ui.WindowEventManager; +import lime.ui.WindowEvent; import lime.system.System; -class Application implements IKeyEventListener implements IMouseEventListener implements ITouchEventListener { +class Application implements IKeyEventListener implements IMouseEventListener implements ITouchEventListener implements IWindowEventListener { public var handle:Dynamic; @@ -35,10 +38,12 @@ class Application implements IKeyEventListener implements IMouseEventListener im new KeyEventManager (); new MouseEventManager (); new TouchEventManager (); + new WindowEventManager (); KeyEventManager.addEventListener (this); MouseEventManager.addEventListener (this); TouchEventManager.addEventListener (this); + WindowEventManager.addEventListener (this); var window = new Window (this); var renderer = new Renderer (window); @@ -63,6 +68,8 @@ class Application implements IKeyEventListener implements IMouseEventListener im public function onTouchEnd (event:TouchEvent):Void {} public function onTouchMove (event:TouchEvent):Void {} public function onTouchStart (event:TouchEvent):Void {} + public function onWindowActivate (event:WindowEvent):Void {} + public function onWindowDeactivate (event:WindowEvent):Void {} diff --git a/lime/ui/IWindowEventListener.hx b/lime/ui/IWindowEventListener.hx new file mode 100644 index 000000000..55488b12c --- /dev/null +++ b/lime/ui/IWindowEventListener.hx @@ -0,0 +1,11 @@ +package lime.ui; + + +interface IWindowEventListener { + + + function onWindowActivate (event:WindowEvent):Void; + function onWindowDeactivate (event:WindowEvent):Void; + + +} \ No newline at end of file diff --git a/lime/ui/WindowEvent.hx b/lime/ui/WindowEvent.hx new file mode 100644 index 000000000..c5146e406 --- /dev/null +++ b/lime/ui/WindowEvent.hx @@ -0,0 +1,32 @@ +package lime.ui; + + +class WindowEvent { + + + public var type:WindowEventType; + + + public function new (type:WindowEventType = null) { + + this.type = type; + + } + + + public function clone ():WindowEvent { + + return new WindowEvent (type); + + } + + +} + + +@:enum abstract WindowEventType(Int) { + + var WINDOW_ACTIVATE = 0; + var WINDOW_DEACTIVATE = 1; + +} \ No newline at end of file diff --git a/lime/ui/WindowEventManager.hx b/lime/ui/WindowEventManager.hx new file mode 100644 index 000000000..36270a7c7 --- /dev/null +++ b/lime/ui/WindowEventManager.hx @@ -0,0 +1,70 @@ +package lime.ui; + + +import lime.system.System; + + +class WindowEventManager { + + + private static var instance:WindowEventManager; + + private var listeners:Array; + + + public function new () { + + listeners = new Array (); + instance = this; + + #if (cpp || neko) + lime_window_event_manager_register (handleEvent, new WindowEvent ()); + #end + + } + + + public static function addEventListener (listener:IWindowEventListener):Void { + + if (instance != null) { + + instance.listeners.push (listener); + + } + + } + + + private function handleEvent (event:WindowEvent):Void { + + var event = event.clone (); + + switch (event.type) { + + case WINDOW_ACTIVATE: + + for (listener in listeners) { + + listener.onWindowActivate (event); + + } + + case WINDOW_DEACTIVATE: + + for (listener in listeners) { + + listener.onWindowDeactivate (event); + + } + + } + + } + + + #if (cpp || neko) + private static var lime_window_event_manager_register = System.load ("lime", "lime_window_event_manager_register", 2); + #end + + +} \ No newline at end of file diff --git a/project/Build.xml b/project/Build.xml index f9e7866f3..7b72eb652 100644 --- a/project/Build.xml +++ b/project/Build.xml @@ -51,6 +51,7 @@ + diff --git a/project/include/ui/WindowEvent.h b/project/include/ui/WindowEvent.h new file mode 100644 index 000000000..a05cb810a --- /dev/null +++ b/project/include/ui/WindowEvent.h @@ -0,0 +1,38 @@ +#ifndef LIME_UI_WINDOW_EVENT_H +#define LIME_UI_WINDOW_EVENT_H + + +#include + + +namespace lime { + + + enum WindowEventType { + + WINDOW_ACTIVATE, + WINDOW_DEACTIVATE + + }; + + + class WindowEvent { + + public: + + static AutoGCRoot* callback; + static AutoGCRoot* eventObject; + + WindowEvent (); + + static void Dispatch (WindowEvent* event); + + WindowEventType type; + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 977065131..992d480b7 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace lime { @@ -104,6 +105,15 @@ namespace lime { } + value lime_window_event_manager_register (value callback, value eventObject) { + + WindowEvent::callback = new AutoGCRoot (callback); + WindowEvent::eventObject = new AutoGCRoot (eventObject); + return alloc_null (); + + } + + DEFINE_PRIM (lime_application_create, 0); DEFINE_PRIM (lime_application_exec, 1); DEFINE_PRIM (lime_key_event_manager_register, 2); @@ -113,6 +123,7 @@ namespace lime { DEFINE_PRIM (lime_renderer_create, 1); DEFINE_PRIM (lime_touch_event_manager_register, 2); DEFINE_PRIM (lime_window_create, 1); + DEFINE_PRIM (lime_window_event_manager_register, 2); } diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index aab17442c..18974bec2 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -43,6 +43,9 @@ namespace lime { } + windowEvent.type = WINDOW_DEACTIVATE; + WindowEvent::Dispatch (&windowEvent); + SDL_Quit (); return 0; @@ -54,71 +57,6 @@ namespace lime { switch (event->type) { - case SDL_QUIT: - - //quit - active = false; - break; - - case SDL_WINDOWEVENT: - - switch (event->window.event) { - - case SDL_WINDOWEVENT_SHOWN: - - //activate - break; - - case SDL_WINDOWEVENT_HIDDEN: - - //deactivate - break; - - case SDL_WINDOWEVENT_EXPOSED: - - //poll - break; - - case SDL_WINDOWEVENT_SIZE_CHANGED: - - //resize - break; - - case SDL_WINDOWEVENT_FOCUS_GAINED: - - //focus in - break; - - case SDL_WINDOWEVENT_FOCUS_LOST: - - //focus out - break; - - case SDL_WINDOWEVENT_CLOSE: - - active = false; - break; - - default: - - break; - - } - - case SDL_MOUSEMOTION: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEWHEEL: - - ProcessMouseEvent (event); - break; - - case SDL_KEYDOWN: - case SDL_KEYUP: - - ProcessKeyEvent (event); - break; - case SDL_JOYAXISMOTION: case SDL_JOYBALLMOTION: case SDL_JOYBUTTONDOWN: @@ -130,6 +68,49 @@ namespace lime { //joy break; + case SDL_KEYDOWN: + case SDL_KEYUP: + + ProcessKeyEvent (event); + break; + + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEWHEEL: + + ProcessMouseEvent (event); + break; + + case SDL_WINDOWEVENT: + + switch (event->window.event) { + + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_HIDDEN: + + ProcessWindowEvent (event); + break; + + case SDL_WINDOWEVENT_EXPOSED: /*poll*/ break; + case SDL_WINDOWEVENT_SIZE_CHANGED: /*resize*/ break; + case SDL_WINDOWEVENT_FOCUS_GAINED: /*focus in*/ break; + case SDL_WINDOWEVENT_FOCUS_LOST: /*focus out*/ break; + case SDL_WINDOWEVENT_CLOSE: + + active = false; + break; + + } + + break; + + case SDL_QUIT: + + //quit + active = false; + break; + } } @@ -186,6 +167,24 @@ namespace lime { } + void SDLApplication::ProcessWindowEvent (SDL_Event* event) { + + if (WindowEvent::callback) { + + switch (event->window.event) { + + case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_ACTIVATE; break; + case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_DEACTIVATE; break; + + } + + WindowEvent::Dispatch (&windowEvent); + + } + + } + + Application* CreateApplication () { return new SDLApplication (); diff --git a/project/src/backend/sdl/SDLApplication.h b/project/src/backend/sdl/SDLApplication.h index 8bad05232..8e140fc89 100644 --- a/project/src/backend/sdl/SDLApplication.h +++ b/project/src/backend/sdl/SDLApplication.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace lime { @@ -27,11 +28,13 @@ namespace lime { void ProcessKeyEvent (SDL_Event* event); void ProcessMouseEvent (SDL_Event* event); void ProcessTouchEvent (SDL_Event* event); + void ProcessWindowEvent (SDL_Event* event); bool active; KeyEvent keyEvent; MouseEvent mouseEvent; TouchEvent touchEvent; + WindowEvent windowEvent; }; diff --git a/project/src/ui/WindowEvent.cpp b/project/src/ui/WindowEvent.cpp new file mode 100644 index 000000000..11f56886f --- /dev/null +++ b/project/src/ui/WindowEvent.cpp @@ -0,0 +1,43 @@ +#include +#include + + +namespace lime { + + + AutoGCRoot* WindowEvent::callback = 0; + AutoGCRoot* WindowEvent::eventObject = 0; + + static int id_type; + static bool init = false; + + + WindowEvent::WindowEvent () { + + type = WINDOW_ACTIVATE; + + } + + + void WindowEvent::Dispatch (WindowEvent* event) { + + if (WindowEvent::callback) { + + if (!init) { + + id_type = val_id ("type"); + + } + + value object = (WindowEvent::eventObject ? WindowEvent::eventObject->get () : alloc_empty_object ()); + + alloc_field (object, id_type, alloc_int (event->type)); + + val_call1 (WindowEvent::callback->get (), object); + + } + + } + + +} \ No newline at end of file