From: Jerome St-Louis Date: Wed, 15 Jul 2015 16:06:38 +0000 (-0400) Subject: ecere/gui/Window;AndroidInterface: Initial multi-touch support X-Git-Url: https://ecere.com/cgi-bin/gitweb.cgi?p=sdk;a=commitdiff_plain;h=22b9a16bb1dbe8b3243bba143f21966b2adbd677 ecere/gui/Window;AndroidInterface: Initial multi-touch support --- diff --git a/ecere/src/gui/Window.ec b/ecere/src/gui/Window.ec index 85dcdaa..581e4dc 100644 --- a/ecere/src/gui/Window.ec +++ b/ecere/src/gui/Window.ec @@ -491,6 +491,15 @@ private class HotKeySlot : struct Key key; }; +public struct TouchPointerInfo +{ + int id; + int x, y; + float size, pressure; +}; + +public enum TouchPointerEvent { move, up, down, pointerUp, pointerDown }; + public class Window { private: @@ -4060,6 +4069,59 @@ private: reEntrancy = false; } + public bool MultiTouchMessage(TouchPointerEvent event, Array infos, Modifiers * mods, bool consequential, bool activate) + { + bool result = true; + if(infos.count) + { + Window w = null; + while(result && w != this) + { + // TODO: How to handle this? + int x = infos[0].x; + int y = infos[0].y; + Window msgWindow = GetAtPosition(x,y, false, true, w); + Window window; + delete w; + w = msgWindow; + if(w) incref w; + window = (w && !w.disabled) ? w : null; + + if(consequential) mods->isSideEffect = true; + if(!result || (window && window.destroyed)) window = null; + + if(window) + { + if(window.OnMultiTouch && !window.disabled) + { + Array in { size = infos.size }; + memcpy(in.array, infos.array, sizeof(TouchPointerInfo) * infos.size); + + for(i : in) + { + i.x -= (window.absPosition.x + window.clientStart.x); + i.y -= (window.absPosition.y + window.clientStart.y); + + i.x = Max(Min(i.x, 32767),-32768); + i.y = Max(Min(i.y, 32767),-32768); + } + + incref window; + if(!window.OnMultiTouch(event, in, *mods)) + result = false; + + delete in; + delete window; + } + } + if(!result || !w || !w.clickThrough) + break; + } + delete w; + } + return result; + } + public bool MouseMessage(uint method, int x, int y, Modifiers * mods, bool consequential, bool activate) { bool result = true; @@ -7985,6 +8047,7 @@ public: virtual bool OnMiddleButtonDown(int x, int y, Modifiers mods); virtual bool OnMiddleButtonUp(int x, int y, Modifiers mods); virtual bool OnMiddleDoubleClick(int x, int y, Modifiers mods); + virtual bool OnMultiTouch(TouchPointerEvent event, Array infos, Modifiers mods); virtual void OnMouseCaptureLost(void); virtual void OnHScroll(ScrollBarAction action, int position, Key key); virtual void OnVScroll(ScrollBarAction action, int position, Key key); @@ -10134,6 +10197,18 @@ class WindowControllerInterface : ControllableWindow return result; } + bool OnMultiTouch(TouchPointerEvent event, Array infos, Modifiers mods) + { + bool result = controller.OnMultiTouch ? ((bool(*)(Window, WindowController, TouchPointerEvent event, Array infos, Modifiers))(void *)controller.OnMultiTouch)((Window)controller.controlled, controller, event, infos, mods) : true; + if(result) + { + bool(* onMultiTouch)(Window, TouchPointerEvent, Array, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMultiTouch]; + if(onMultiTouch) + onMultiTouch(controller.window, event, infos, mods); + } + return result; + } + void OnResize(int width, int height) { if(controller.OnResize) @@ -10249,6 +10324,7 @@ public: virtual bool V::OnMiddleButtonDown(WindowController controller, int x, int y, Modifiers mods); virtual bool V::OnMiddleButtonUp(WindowController controller, int x, int y, Modifiers mods); virtual bool V::OnMiddleDoubleClick(WindowController controller, int x, int y, Modifiers mods); + virtual bool V::OnMultiTouch(WindowController controller, TouchPointerEvent event, Array infos, Modifiers mods); virtual void V::OnResize(WindowController controller, int width, int height); virtual void V::OnRedraw(WindowController controller, Surface surface); virtual bool V::OnCreate(WindowController controller); diff --git a/ecere/src/gui/drivers/AndroidInterface.ec b/ecere/src/gui/drivers/AndroidInterface.ec index bfa009d..c623415 100644 --- a/ecere/src/gui/drivers/AndroidInterface.ec +++ b/ecere/src/gui/drivers/AndroidInterface.ec @@ -440,6 +440,7 @@ static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* wi { AndroidAppGlue app = (AndroidAppGlue)activity->instance; LOGI("NativeWindowDestroyed: %p -- %p\n", activity, window); + app.window = null; app.set_window(null); } @@ -512,7 +513,7 @@ default dllexport void ANativeActivity_onCreate(ANativeActivity* activity, void* ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_FULLSCREEN|AWINDOW_FLAG_KEEP_SCREEN_ON, 0 ); app = AndroidActivity { activity = activity, moduleName = moduleName }; incref app; - app.setSavedState(savedState, savedStateSize); + app.setSavedState(savedState, (uint)savedStateSize); activity->callbacks->onDestroy = onDestroy; activity->callbacks->onStart = onStart; activity->callbacks->onResume = onResume; @@ -1060,6 +1061,22 @@ static Key keyCodeTable[] = // Why don't we have this in the NDK :( // default int32_t AKeyEvent_getUnichar(const AInputEvent* key_event); +static Array buildPointerInfo(AInputEvent * event) +{ + uint count = (uint)AMotionEvent_getPointerCount(event); + Array infos { size = count }; + int i; + for(i = 0; i < count; i++) + { + infos[i].x = (int)AMotionEvent_getX(event, i); + infos[i].y = (int)AMotionEvent_getY(event, i); + infos[i].id = (int)AMotionEvent_getPointerId(event, i); + infos[i].pressure = AMotionEvent_getPressure(event, i); + infos[i].size = AMotionEvent_getSize(event, i); + } + return infos; +} + class AndroidActivity : AndroidAppGlue { AndroidPollSource source; @@ -1124,20 +1141,48 @@ class AndroidActivity : AndroidAppGlue mouseX = x, mouseY = y; if(result) window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown, x, y, &keyFlags, false, true); + if(result) + { + Array infos = buildPointerInfo(event); + window.MultiTouchMessage(down, infos, &keyFlags, false, true); + delete infos; + } break; } case AMOTION_EVENT_ACTION_UP: mouseX = x, mouseY = y; - window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp, x, y, &keyFlags, false, true); + if(window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp, x, y, &keyFlags, false, true)) + { + Array infos = buildPointerInfo(event); + window.MultiTouchMessage(up, infos, &keyFlags, false, true); + delete infos; + } break; case AMOTION_EVENT_ACTION_MOVE: mouseX = x, mouseY = y; - window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x, y, &keyFlags, false, true); + if(window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove, x, y, &keyFlags, false, true)) + { + Array infos = buildPointerInfo(event); + window.MultiTouchMessage(move, infos, &keyFlags, false, true); + delete infos; + } break; case AMOTION_EVENT_ACTION_CANCEL: break; case AMOTION_EVENT_ACTION_OUTSIDE: break; - case AMOTION_EVENT_ACTION_POINTER_DOWN: break; - case AMOTION_EVENT_ACTION_POINTER_UP: break; + case AMOTION_EVENT_ACTION_POINTER_DOWN: + { + Array infos = buildPointerInfo(event); + window.MultiTouchMessage(pointerDown, infos, &keyFlags, false, true); + delete infos; + break; + } + case AMOTION_EVENT_ACTION_POINTER_UP: + { + Array infos = buildPointerInfo(event); + window.MultiTouchMessage(pointerUp, infos, &keyFlags, false, true); + delete infos; + break; + } } return 1; }