Unify handleTouch and handleClick in SampleApp.

Allow each sample to handle clicks in Android SampleApp.

Remove SampleWindow::handleTouch.

Allow an SkWindow to have multiple clicks.

Add an owner pointer to SkView::Click.

Reviewed at http://codereview.appspot.com/4643052/


git-svn-id: http://skia.googlecode.com/svn/trunk@1673 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/android_sample/SampleApp/jni/sample-jni.cpp b/android_sample/SampleApp/jni/sample-jni.cpp
index ffda03d..d602c07 100644
--- a/android_sample/SampleApp/jni/sample-jni.cpp
+++ b/android_sample/SampleApp/jni/sample-jni.cpp
@@ -210,7 +210,7 @@
             SkDebugf("motion event ignored\n");
             return;
     }
-    gWindow->handleTouch(owner, x, y, state);
+    gWindow->handleClick(x, y, state, (void*) owner);
 }
 
 JNIEXPORT void JNICALL Java_com_skia_sampleapp_SampleApp_updateSize(JNIEnv* env,
diff --git a/include/views/SkView.h b/include/views/SkView.h
index d3633db..9cefb33 100644
--- a/include/views/SkView.h
+++ b/include/views/SkView.h
@@ -142,6 +142,7 @@
         SkPoint     fOrig, fPrev, fCurr;
         SkIPoint    fIOrig, fIPrev, fICurr;
         State       fState;
+        void*       fOwner;
     private:
         SkEventSinkID   fTargetID;
         char*           fType;
diff --git a/include/views/SkWindow.h b/include/views/SkWindow.h
index 1477ec6..3de2a82 100644
--- a/include/views/SkWindow.h
+++ b/include/views/SkWindow.h
@@ -54,7 +54,7 @@
     // return the bounds of the dirty/inval rgn, or [0,0,0,0] if none
     const SkIRect& getDirtyBounds() const { return fDirtyRgn.getBounds(); }
 
-    bool    handleClick(int x, int y, Click::State);
+    bool    handleClick(int x, int y, Click::State, void* owner = NULL);
     bool    handleChar(SkUnichar);
     bool    handleKey(SkKey);
     bool    handleKeyUp(SkKey);
@@ -74,7 +74,7 @@
         const char path[]) {}
 protected:
     virtual bool onEvent(const SkEvent&);
-    virtual bool onDispatchClick(int x, int y, Click::State);
+    virtual bool onDispatchClick(int x, int y, Click::State, void* owner);
     // called if part of our bitmap is invalidated
     virtual void onHandleInval(const SkIRect&);
     virtual bool onHandleChar(SkUnichar);
@@ -92,7 +92,8 @@
     SkBitmap::Config    fConfig;
     SkBitmap    fBitmap;
     SkRegion    fDirtyRgn;
-    Click*      fClick; // to track clicks
+
+    SkTDArray<Click*>       fClicks; // to track clicks
 
     SkTDArray<SkOSMenu*>    fMenus;
 
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index 9c2b7d1..8a8ac9c 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -1206,7 +1206,8 @@
 
 static const char gGestureClickType[] = "GestureClickType";
 
-bool SampleWindow::onDispatchClick(int x, int y, Click::State state) {
+bool SampleWindow::onDispatchClick(int x, int y, Click::State state,
+        void* owner) {
     if (Click::kMoved_State == state) {
         updatePointer(x, y);
     }
@@ -1217,7 +1218,7 @@
     if (w - x < 16 && h - y < 16) {
         return false;   // let the OS handle the click
     } else {
-        return this->INHERITED::onDispatchClick(x, y, state);
+        return this->INHERITED::onDispatchClick(x, y, state, owner);
     }
 }
 
@@ -1236,51 +1237,20 @@
     return new GestureClick(this);
 }
 
-union IntPtr {
-    int     fInt;
-    void*   fPtr;
-};
-
-static void* int2ptr(int n) {
-    IntPtr data;
-    data.fInt = n;
-    return data.fPtr;
-}
-
-bool SampleWindow::handleTouch(int ownerId, float x, float y, SkView::Click::State state) {
-    void* click = int2ptr(ownerId);
-    switch(state) {
-        case SkView::Click::kDown_State:
-            fGesture.touchBegin(click, x, y);
-            break;
-        case SkView::Click::kMoved_State:
-            fGesture.touchMoved(click, x, y);
-            this->inval(NULL);
-            break;
-        case SkView::Click::kUp_State:
-            fGesture.touchEnd(click);
-            this->inval(NULL);
-            break;
-        default:
-            return false;
-    }
-    return true;
-}
-
 bool SampleWindow::onClick(Click* click) {
     if (GestureClick::IsGesture(click)) {
         float x = SkScalarToFloat(click->fCurr.fX);
         float y = SkScalarToFloat(click->fCurr.fY);
         switch (click->fState) {
             case SkView::Click::kDown_State:
-                fGesture.touchBegin(click, x, y);
+                fGesture.touchBegin(click->fOwner, x, y);
                 break;
             case SkView::Click::kMoved_State:
-                fGesture.touchMoved(click, x, y);
+                fGesture.touchMoved(click->fOwner, x, y);
                 this->inval(NULL);
                 break;
             case SkView::Click::kUp_State:
-                fGesture.touchEnd(click);
+                fGesture.touchEnd(click->fOwner);
                 this->inval(NULL);
                 break;
         }
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index 4d16121..35a2bb4 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -77,7 +77,7 @@
     virtual bool onEvent(const SkEvent& evt);
     virtual bool onQuery(SkEvent* evt);
 
-    virtual bool onDispatchClick(int x, int y, Click::State);
+    virtual bool onDispatchClick(int x, int y, Click::State, void* owner);
     virtual bool onClick(Click* click);
     virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
 
diff --git a/src/views/SkView.cpp b/src/views/SkView.cpp
index 1cd6339..4b99987 100644
--- a/src/views/SkView.cpp
+++ b/src/views/SkView.cpp
@@ -296,10 +296,11 @@
 
 SkView::Click::Click(SkView* target)
 {
-	SkASSERT(target);
-	fTargetID = target->getSinkID();
-	fType = NULL;
-	fWeOwnTheType = false;
+    SkASSERT(target);
+    fTargetID = target->getSinkID();
+    fType = NULL;
+    fWeOwnTheType = false;
+    fOwner = NULL;
 }
 
 SkView::Click::~Click()
diff --git a/src/views/SkWindow.cpp b/src/views/SkWindow.cpp
index dc833ec..b35f6f2 100644
--- a/src/views/SkWindow.cpp
+++ b/src/views/SkWindow.cpp
@@ -41,13 +41,13 @@
 
 SkWindow::SkWindow() : fFocusView(NULL)
 {
-	fClick = NULL;
-	fWaitingOnInval = false;
+    fClicks.reset();
+    fWaitingOnInval = false;
 
 #ifdef SK_BUILD_FOR_WINCE
-	fConfig = SkBitmap::kRGB_565_Config;
+    fConfig = SkBitmap::kRGB_565_Config;
 #else
-	fConfig = SkBitmap::kARGB_8888_Config;
+    fConfig = SkBitmap::kARGB_8888_Config;
 #endif
 
     fMatrix.reset();
@@ -55,9 +55,8 @@
 
 SkWindow::~SkWindow()
 {
-	delete fClick;
-
-	fMenus.deleteAll();
+    fClicks.deleteAll();
+    fMenus.deleteAll();
 }
 
 void SkWindow::setMatrix(const SkMatrix& matrix) {
@@ -369,40 +368,57 @@
     return false;
 }
 
-bool SkWindow::handleClick(int x, int y, Click::State state) {
-    return this->onDispatchClick(x, y, state);
+bool SkWindow::handleClick(int x, int y, Click::State state, void *owner) {
+    return this->onDispatchClick(x, y, state, owner);
 }
 
-bool SkWindow::onDispatchClick(int x, int y, Click::State state) {
+bool SkWindow::onDispatchClick(int x, int y, Click::State state,
+        void* owner) {
 	bool handled = false;
 
+    // First, attempt to find an existing click with this owner.
+    int index = -1;
+    for (int i = 0; i < fClicks.count(); i++) {
+        if (owner == fClicks[i]->fOwner) {
+            index = i;
+            break;
+        }
+    }
+
 	switch (state) {
-	case Click::kDown_State:
-		if (fClick)
-			delete fClick;
-		fClick = this->findClickHandler(SkIntToScalar(x), SkIntToScalar(y));
-		if (fClick)
-		{
-			SkView::DoClickDown(fClick, x, y);
-			handled = true;
-		}
-		break;
-	case Click::kMoved_State:
-		if (fClick)
-		{
-			SkView::DoClickMoved(fClick, x, y);
-			handled = true;
-		}
-		break;
-	case Click::kUp_State:
-		if (fClick)
-		{
-			SkView::DoClickUp(fClick, x, y);
-			delete fClick;
-			fClick = NULL;
-			handled = true;
-		}
-		break;
+        case Click::kDown_State: {
+            if (index != -1) {
+                delete fClicks[index];
+                fClicks.remove(index);
+            }
+            Click* click = this->findClickHandler(SkIntToScalar(x),
+                    SkIntToScalar(y));
+
+            if (click) {
+                click->fOwner = owner;
+                *fClicks.append() = click;
+                SkView::DoClickDown(click, x, y);
+                handled = true;
+            }
+            break;
+        }
+        case Click::kMoved_State:
+            if (index != -1) {
+                SkView::DoClickMoved(fClicks[index], x, y);
+                handled = true;
+            }
+            break;
+        case Click::kUp_State:
+            if (index != -1) {
+                SkView::DoClickUp(fClicks[index], x, y);
+                delete fClicks[index];
+                fClicks.remove(index);
+                handled = true;
+            }
+            break;
+        default:
+            // Do nothing
+            break;
 	}
 	return handled;
 }