Added transitions and net pipe to SampleApp, updated gyp files
http://codereview.appspot.com/4839047/
http://codereview.appspot.com/4801080/


git-svn-id: http://skia.googlecode.com/svn/trunk@2059 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/TransitionView.cpp b/samplecode/TransitionView.cpp
new file mode 100644
index 0000000..8cf3227
--- /dev/null
+++ b/samplecode/TransitionView.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "SampleCode.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "SkTime.h"
+#include "SkInterpolator.h"
+
+static const char gIsTransitionQuery[] = "is-transition";
+static const char gReplaceTransitionEvt[] = "replace-transition-view";
+static bool isTransition(SkView* view) {
+    SkEvent isTransition(gIsTransitionQuery);
+    return view->doQuery(&isTransition);
+}
+
+class TransitionView : public SampleView {
+public:
+    TransitionView(SkView* prev, SkView* next, int direction) : fInterp(4, 2){
+        fAnimationDirection = (Direction)(1 << (direction % 8));
+        
+        fPrev = prev;
+        fPrev->setClipToBounds(false);
+        fPrev->setVisibleP(true);
+        (void)SampleView::SetUsePipe(fPrev, false);
+        //Not calling unref because fPrev is assumed to have been created, so 
+        //this will result in a transfer of ownership
+        this->attachChildToBack(fPrev);
+        
+        fNext = next;
+        fNext->setClipToBounds(true);
+        fNext->setVisibleP(true);
+        (void)SampleView::SetUsePipe(fNext, false);
+        //Calling unref because next is a newly created view and TransitionView
+        //is now the sole owner of fNext
+        this->attachChildToFront(fNext)->unref();
+    }
+    
+    ~TransitionView(){
+        //SkDebugf("deleted transition\n");
+    }
+    
+    virtual void requestMenu(SkOSMenu* menu) {
+        if (SampleView::IsSampleView(fNext))
+            ((SampleView*)fNext)->requestMenu(menu);
+    }
+    
+protected:
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SkString title;
+            if (SampleCode::RequestTitle(fNext, &title)) {
+                SampleCode::TitleR(evt, title.c_str());
+                return true;
+            }
+            return false;
+        }
+        if (evt->isType(gIsTransitionQuery)) {
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+    virtual bool onEvent(const SkEvent& evt) {
+        if (evt.isType(gReplaceTransitionEvt)) {
+            fPrev->detachFromParent();
+            fPrev = (SkView*)SkEventSink::FindSink(evt.getFast32());
+            (void)SampleView::SetUsePipe(fPrev, false);
+            //attach the new fPrev and call unref to balance the ref in onDraw
+            this->attachChildToBack(fPrev)->unref();
+            this->inval(NULL);
+            return true;
+        } 
+        return this->INHERITED::onEvent(evt);
+    }
+    virtual void onDrawBackground(SkCanvas* canvas) {}
+    virtual void onDrawContent(SkCanvas* canvas) {
+        SkScalar values[4];
+        SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(), values);
+        //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe);
+        //SkDebugf("%f %f %f %f %d\n", values[0], values[1], values[2], values[3], result);
+        if (SkInterpolator::kNormal_Result == result) {
+            fPrev->setLocX(values[kPrevX]);
+            fPrev->setLocY(values[kPrevY]);
+            fNext->setLocX(values[kNextX]);
+            fNext->setLocY(values[kNextY]);
+            this->inval(NULL);
+        }
+        else {
+            fNext->setLocX(0);
+            fNext->setLocY(0);
+            fNext->setClipToBounds(false);
+            
+            SkView* parent = this->getParent();
+            int id = this->getParent()->getSinkID();
+            
+            SkEvent* evt;
+            if (isTransition(parent)) {
+                evt = new SkEvent(gReplaceTransitionEvt, id);
+                evt->setFast32(fNext->getSinkID());
+                //increate ref count of fNext so it survives detachAllChildren
+                fNext->ref();
+            }
+            else {
+                parent->attachChildToFront(fNext);
+                (void)SampleView::SetUsePipe(fNext, fUsePipe);
+                evt = new SkEvent("unref-transition-view", id);
+                evt->setFast32(this->getSinkID());
+                fUsePipe = false;
+                //keep this(TransitionView) alive so it can be deleted by its 
+                //parent through the unref-transition-view event
+                this->ref();
+                this->detachFromParent();
+            }
+            this->detachAllChildren();
+            evt->post();
+        }
+        this->inval(NULL);
+    }
+    
+    virtual void onSizeChange() {
+        this->INHERITED::onSizeChange();
+        
+        fNext->setSize(this->width(), this->height());
+        fPrev->setSize(this->width(), this->height());
+        
+        SkScalar lr = 0, ud = 0;
+        if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection))
+            lr = this->width();
+        if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection))
+            lr = -this->width();
+        if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection))
+            ud = this->height();
+        if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection))
+            ud = -this->height();
+        
+        fBegin[kPrevX] = fBegin[kPrevY] = 0;
+        fBegin[kNextX] = lr;
+        fBegin[kNextY] = ud;
+        fNext->setLocX(lr);
+        fNext->setLocY(ud);
+        
+        if (isTransition(fPrev))
+            lr = ud = 0;
+        fEnd[kPrevX] = -lr;
+        fEnd[kPrevY] = -ud;
+        fEnd[kNextX] = fEnd[kNextY] = 0;
+        SkScalar blend[] = {0.8, 0.0, 0.0, 1.0};
+        fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend);
+        fInterp.setKeyFrame(1, SkTime::GetMSecs()+500, fEnd, blend);
+    }
+    
+private:
+    enum {
+        kPrevX = 0,
+        kPrevY = 1,
+        kNextX = 2,
+        kNextY = 3
+    };
+    SkView* fPrev;
+    SkView* fNext;
+    SkInterpolator fInterp;
+    
+    enum Direction{
+        kUpDirection    = 1,
+        kURDirection    = 1 << 1,
+        kRightDirection = 1 << 2,
+        kDRDirection    = 1 << 3,
+        kDownDirection  = 1 << 4,
+        kDLDirection    = 1 << 5,
+        kLeftDirection  = 1 << 6,
+        kULDirection    = 1 << 7
+    };
+    
+    Direction fAnimationDirection;
+    SkScalar fBegin[4];
+    SkScalar fEnd[4];
+    
+    typedef SampleView INHERITED;
+};
+
+SkView* create_transition(SkView* prev, SkView* next, int direction) {
+    return SkNEW_ARGS(TransitionView, (prev, next, direction));
+};
\ No newline at end of file