ecere/gui/Window;AndroidInterface: Initial multi-touch support
[sdk] / ecere / src / gui / Window.ec
index 6572e81..581e4dc 100644 (file)
@@ -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:
@@ -824,7 +833,9 @@ private:
             x -= rootWindow.clientStart.x;
             y -= rootWindow.clientStart.y - (rootWindow.hasMenuBar ? skinMenuHeight : 0);
          }
+#if !defined(__EMSCRIPTEN__)
          if(!guiApp.fullScreenMode || is3D)
+#endif
          {
             x -= rootWindow.absPosition.x;
             y -= rootWindow.absPosition.y;
@@ -1801,7 +1812,11 @@ private:
                   if(display && !display.flags.memBackBuffer && changeRootWindow)
                      guiApp.interfaceDriver.PositionRootWindow(this, x, y, w, h, windowMoved, windowResized); //realResized);
 
-               if(!guiApp.fullScreenMode && this != guiApp.desktop && (windowResized || windowMoved))
+               if(
+#if !defined(__EMSCRIPTEN__)
+                  !guiApp.fullScreenMode &&
+#endif
+                  this != guiApp.desktop && (windowResized || windowMoved))
                   for(child = parent.children.first; child && child != this; child = child.next)
                      if(child.rootWindow)
                         guiApp.interfaceDriver.UpdateRootWindow(child.rootWindow);
@@ -3787,7 +3802,10 @@ private:
                         if(activateParent && parent && !parent.active /*parent != parent.parent.activeChild*/)
                            parent.ActivateEx(true, true, moveInactive, activateRoot, external, externalSwap);
                      }
-                     else if(!guiApp.fullScreenMode)
+                     else
+#if !defined(__EMSCRIPTEN__)
+                     if(!guiApp.fullScreenMode)
+#endif
                      {
                         Window modalRoot = FindModal();
                         if(!modalRoot) modalRoot = this;
@@ -4051,6 +4069,59 @@ private:
       reEntrancy = false;
    }
 
+   public bool MultiTouchMessage(TouchPointerEvent event, Array<TouchPointerInfo> 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<TouchPointerInfo> 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;
@@ -4881,8 +4952,12 @@ private:
       Window child;
 
       // Setup relationship with outside world (bb root || !bb)
+#if defined(__EMSCRIPTEN__)
+      if(this == guiApp.desktop)
+#else
       if((!guiApp.fullScreenMode && parent == guiApp.desktop) || this == guiApp.desktop ||
          (_displayDriver && parent.dispDriver && dispDriver != parent.dispDriver))
+#endif
       {
          rootWindow = this;
          if(!tempExtents)
@@ -4914,7 +4989,11 @@ private:
       bool result = false;
       Window child;
 
+#if defined(__EMSCRIPTEN__)
+      if(this == guiApp.desktop)
+#else
       if((!guiApp.fullScreenMode && parent == guiApp.desktop) || (guiApp.fullScreenMode && (this == guiApp.desktop || (_displayDriver && parent.dispDriver && dispDriver != parent.dispDriver))))
+#endif
       {
          subclass(DisplayDriver) dDriver = (dispDriver && !formDesigner) ? dispDriver : GetDisplayDriver(guiApp.defaultDisplayDriver);
          DisplaySystem displaySystem = dDriver ? dDriver.displaySystem : null;
@@ -5020,7 +5099,11 @@ private:
          }
       }
 
-      if(guiApp.fullScreenMode || this != guiApp.desktop)
+      if(
+#if !defined(__EMSCRIPTEN__)
+      guiApp.fullScreenMode ||
+#endif
+         this != guiApp.desktop)
       {
          SetWindowMinimum(&skinMinSize.w, &skinMinSize.h);
          if(display)
@@ -5948,7 +6031,7 @@ private:
    public bool AcquireInput(bool acquired)
    {
       bool result = true;
-      if(acquiredInput != acquired)
+      if((guiApp.acquiredWindow && acquiredInput) != acquired)
       {
          if(active || (!visible && creationActivation == activate))
             result = AcquireInputEx(acquired);
@@ -5981,7 +6064,11 @@ private:
    {
       if(guiApp.driver != null)
       {
+#if !defined(__EMSCRIPTEN__)
          if(guiApp.fullScreenMode && guiApp.desktop.display)
+#else
+         if(true)
+#endif
          {
 #if !defined(__EMSCRIPTEN__)
             guiApp.desktop.mutex.Wait();
@@ -7905,16 +7992,23 @@ public:
 
    bool MenuWindowWindows(MenuItem selection, Modifiers mods)
    {
-      WindowList dialog { master = this };
-      Window document = (Window)(intptr)dialog.Modal();
-      if(document)
+      WindowList
       {
-         if(activeChild.state == maximized)
-            document.SetState(maximized, false, mods);
-         else if(document.state == minimized)
-            document.SetState(normal, false, mods);
-         document.Activate();
-      }
+         master = this; isModal = true;
+
+         void NotifyDestroyed(Window window, DialogResult result)
+         {
+            Window document = (Window)(intptr)result;
+            if(document)
+            {
+               if(activeChild.state == maximized)
+                  document.SetState(maximized, false, 0);
+               else if(document.state == minimized)
+                  document.SetState(normal, false, 0);
+               document.Activate();
+            }
+         }
+      }.Create();
       return true;
    }
 
@@ -7953,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<TouchPointerInfo> 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);
@@ -9780,7 +9875,22 @@ private:
    property subclass(DisplayDriver) _displayDriver  { get { return !formDesigner ? dispDriver : null; } }
 
    WindowController controller;
-   public property WindowController controller { get { return controller; } set { delete controller; controller = value; if(controller) incref controller; } }
+   public property WindowController controller
+   {
+      get { return controller; }
+      set
+      {
+         if(controller)
+            controller.setWindow(null);
+         delete controller;
+         controller = value;
+         if(controller)
+         {
+            incref controller;
+            controller.setWindow(this);
+         }
+      }
+   }
 };
 
 public class CommonControl : Window
@@ -9969,7 +10079,7 @@ class WindowControllerInterface : ControllableWindow
 
    bool OnMouseMove(int x, int y, Modifiers mods)
    {
-      bool result = ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMouseMove)((Window)controller.controlled, controller, x, y, mods);
+      bool result = controller.OnMouseMove ? ((bool(*)(Window, WindowController, int, int, Modifiers))(void *)controller.OnMouseMove)((Window)controller.controlled, controller, x, y, mods) : true;
       if(result)
       {
          bool(* onMouseMove)(Window, int, int, Modifiers) = (void *)controller.windowVTbl[__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove];
@@ -10087,6 +10197,18 @@ class WindowControllerInterface : ControllableWindow
       return result;
    }
 
+   bool OnMultiTouch(TouchPointerEvent event, Array<TouchPointerInfo> infos, Modifiers mods)
+   {
+      bool result = controller.OnMultiTouch ? ((bool(*)(Window, WindowController, TouchPointerEvent event, Array<TouchPointerInfo> infos, Modifiers))(void *)controller.OnMultiTouch)((Window)controller.controlled, controller, event, infos, mods) : true;
+      if(result)
+      {
+         bool(* onMultiTouch)(Window, TouchPointerEvent, Array<TouchPointerInfo>, 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)
@@ -10147,37 +10269,41 @@ class WindowControllerInterface : ControllableWindow
 
 public class WindowController<class V>
 {
-public:
-   property Window window
+   void setWindow(Window value)
    {
-      set
+      uint size = class(Window).vTblSize;
+      if(value)
       {
-         uint size = class(Window).vTblSize;
-         if(value)
+         delete windowVTbl;
+         windowVTbl = new void *[size];
+         memcpy(windowVTbl, value._vTbl, size * sizeof(void *));
+         if(value._vTbl == value._class._vTbl)
          {
-            windowVTbl = new void *[size];
-            memcpy(windowVTbl, value._vTbl, size * sizeof(void *));
-            if(value._vTbl == value._class._vTbl)
-            {
-               value._vTbl = new void *[value._class.vTblSize];
-               memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *));
-            }
+            value._vTbl = new void *[value._class.vTblSize];
+            memcpy(value._vTbl + size, value._class._vTbl + size, (value._class.vTblSize - size) * sizeof(void *));
+         }
+         {
+            int c;
+            for(c = 0; c < size; c++)
             {
-               int c;
-               for(c = 0; c < size; c++)
-               {
-                  void * function = class(WindowControllerInterface)._vTbl[c];
-                  if(function && function != DefaultFunction)
-                     value._vTbl[c] = function;
-                  else
-                     value._vTbl[c] = windowVTbl[c];
-               }
+               void * function = class(WindowControllerInterface)._vTbl[c];
+               if(function && function != DefaultFunction)
+                  value._vTbl[c] = function;
+               else
+                  value._vTbl[c] = windowVTbl[c];
             }
          }
-         else
-            memcpy(value._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *));
-         window = value;
       }
+      else if(window)
+      {
+         memcpy(window._vTbl, windowVTbl, class(Window).vTblSize * sizeof(void *));
+         delete windowVTbl;
+      }
+      window = value;
+   }
+public:
+   property Window window
+   {
       get { return window; }
    }
    property V controlled
@@ -10198,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<TouchPointerInfo> 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);
@@ -10205,7 +10332,7 @@ public:
    virtual void V::OnUnloadGraphics(WindowController controller);
 
 private:
-   int (** windowVTbl)();
+   public int (** windowVTbl)();
    V controlled;
    Window window;