1db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com/* 2db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com * Copyright 2011 Google Inc. 3db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com * 4db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com * Use of this source code is governed by a BSD-style license that can be 5db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com * found in the LICENSE file. 6db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com */ 76a12178fb32146232912fc20abb463b430f9025depoger@google.com#include "TransitionView.h" 86a12178fb32146232912fc20abb463b430f9025depoger@google.com 9b1b7f707907b8c63b955cd2aef1cc454623e3656tfarina@chromium.org#include "OverView.h" 10db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SampleCode.h" 11db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SkView.h" 12db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SkCanvas.h" 13db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SkTime.h" 14db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com#include "SkInterpolator.h" 15db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com 16db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic const char gIsTransitionQuery[] = "is-transition"; 17db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comstatic const char gReplaceTransitionEvt[] = "replace-transition-view"; 18ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com 19b1b7f707907b8c63b955cd2aef1cc454623e3656tfarina@chromium.orgbool is_transition(SkView* view) { 20db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkEvent isTransition(gIsTransitionQuery); 21db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return view->doQuery(&isTransition); 22db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com} 23db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com 24db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comclass TransitionView : public SampleView { 258d8847521e9a077d1c317c622dd76d7e8087d3bdreed@google.com enum { 26b1b7f707907b8c63b955cd2aef1cc454623e3656tfarina@chromium.org // kDurationMS = 500 278d8847521e9a077d1c317c622dd76d7e8087d3bdreed@google.com kDurationMS = 1 288d8847521e9a077d1c317c622dd76d7e8087d3bdreed@google.com }; 29b1b7f707907b8c63b955cd2aef1cc454623e3656tfarina@chromium.org 30db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.compublic: 31db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com TransitionView(SkView* prev, SkView* next, int direction) : fInterp(4, 2){ 32db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fAnimationDirection = (Direction)(1 << (direction % 8)); 33ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 34db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev = prev; 35db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev->setClipToBounds(false); 36db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev->setVisibleP(true); 37b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState); 38ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com //Not calling unref because fPrev is assumed to have been created, so 39db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com //this will result in a transfer of ownership 40db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com this->attachChildToBack(fPrev); 41ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 42db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext = next; 43db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setClipToBounds(true); 44db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setVisibleP(true); 45b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com (void)SampleView::SetUsePipe(fNext, SkOSMenu::kOffState); 46db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com //Calling unref because next is a newly created view and TransitionView 47db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com //is now the sole owner of fNext 48db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com this->attachChildToFront(fNext)->unref(); 49ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 50ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fDone = false; 51ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com //SkDebugf("--created transition\n"); 52db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 53ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 54db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com ~TransitionView(){ 55ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com //SkDebugf("--deleted transition\n"); 56db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 57ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 58db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com virtual void requestMenu(SkOSMenu* menu) { 59db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (SampleView::IsSampleView(fNext)) 60db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com ((SampleView*)fNext)->requestMenu(menu); 61db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 62ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 63db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comprotected: 64db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com virtual bool onQuery(SkEvent* evt) { 65db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (SampleCode::TitleQ(*evt)) { 66db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkString title; 67db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (SampleCode::RequestTitle(fNext, &title)) { 68db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SampleCode::TitleR(evt, title.c_str()); 69db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return true; 70db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 71db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return false; 72db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 73db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (evt->isType(gIsTransitionQuery)) { 74db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return true; 75db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 76db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return this->INHERITED::onQuery(evt); 77db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 78db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com virtual bool onEvent(const SkEvent& evt) { 79db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (evt.isType(gReplaceTransitionEvt)) { 80079813e2da59f35e2744af7a785d01d9f490e280reed@google.com SkView* prev = fPrev; 81079813e2da59f35e2744af7a785d01d9f490e280reed@google.com prev->ref(); 82079813e2da59f35e2744af7a785d01d9f490e280reed@google.com 83db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev->detachFromParent(); 84db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev = (SkView*)SkEventSink::FindSink(evt.getFast32()); 85b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState); 86db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com //attach the new fPrev and call unref to balance the ref in onDraw 87db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com this->attachChildToBack(fPrev)->unref(); 88db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com this->inval(NULL); 89f85693d53a487b00360e77de69556b13bda0e602skia.committer@gmail.com 90079813e2da59f35e2744af7a785d01d9f490e280reed@google.com SkASSERT(1 == prev->getRefCnt()); 91079813e2da59f35e2744af7a785d01d9f490e280reed@google.com prev->unref(); 92db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return true; 93ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } 94ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (evt.isType("transition-done")) { 95ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fNext->setLoc(0, 0); 96ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fNext->setClipToBounds(false); 97ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com SkEvent* evt = new SkEvent(gReplaceTransitionEvt, 98ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com this->getParent()->getSinkID()); 99ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com evt->setFast32(fNext->getSinkID()); 100ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com //increate ref count of fNext so it survives detachAllChildren 101ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fNext->ref(); 102ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com this->detachAllChildren(); 103ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com evt->post(); 104ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com return true; 105ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } 106db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return this->INHERITED::onEvent(evt); 107db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 108db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com virtual void onDrawBackground(SkCanvas* canvas) {} 109db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com virtual void onDrawContent(SkCanvas* canvas) { 110ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (fDone) 111ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com return; 112ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com 113ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (is_overview(fNext) || is_overview(fPrev)) { 114b073d920c90bc95f6c216327acd321a4fc809bfascroggo@google.com fPipeState = SkOSMenu::kOffState; 115ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com } 116ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 117db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkScalar values[4]; 118db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(), values); 119db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe); 120db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com //SkDebugf("%f %f %f %f %d\n", values[0], values[1], values[2], values[3], result); 121db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (SkInterpolator::kNormal_Result == result) { 122db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev->setLocX(values[kPrevX]); 123db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev->setLocY(values[kPrevY]); 124db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setLocX(values[kNextX]); 125db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setLocY(values[kNextY]); 126db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com this->inval(NULL); 127db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 128db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com else { 129ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com (new SkEvent("transition-done", this->getSinkID()))->post(); 130ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com fDone = true; 131db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 132db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 133ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 134db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com virtual void onSizeChange() { 135db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com this->INHERITED::onSizeChange(); 136ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 137db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setSize(this->width(), this->height()); 138db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fPrev->setSize(this->width(), this->height()); 139ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 140db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkScalar lr = 0, ud = 0; 141db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection)) 142db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com lr = this->width(); 143db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection)) 144db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com lr = -this->width(); 145db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection)) 146db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com ud = this->height(); 147db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection)) 148db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com ud = -this->height(); 149ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 150db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fBegin[kPrevX] = fBegin[kPrevY] = 0; 151db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fBegin[kNextX] = lr; 152db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fBegin[kNextY] = ud; 153db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setLocX(lr); 154db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fNext->setLocY(ud); 155ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 156ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com if (is_transition(fPrev)) 157db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com lr = ud = 0; 158db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fEnd[kPrevX] = -lr; 159db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fEnd[kPrevY] = -ud; 160db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fEnd[kNextX] = fEnd[kNextY] = 0; 1614b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org SkScalar blend[] = { 0.8f, 0.0f, 1624b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org 0.0f, SK_Scalar1 }; 163db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend); 1648d8847521e9a077d1c317c622dd76d7e8087d3bdreed@google.com fInterp.setKeyFrame(1, SkTime::GetMSecs()+kDurationMS, fEnd, blend); 165db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com } 166ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 167db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comprivate: 168db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com enum { 169db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kPrevX = 0, 170db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kPrevY = 1, 171db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kNextX = 2, 172db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kNextY = 3 173db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com }; 174db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkView* fPrev; 175db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkView* fNext; 176ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com bool fDone; 177db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkInterpolator fInterp; 178ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 179db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com enum Direction{ 180db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kUpDirection = 1, 181db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kURDirection = 1 << 1, 182db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kRightDirection = 1 << 2, 183db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kDRDirection = 1 << 3, 184db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kDownDirection = 1 << 4, 185db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kDLDirection = 1 << 5, 186db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kLeftDirection = 1 << 6, 187db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com kULDirection = 1 << 7 188db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com }; 189ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 190db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com Direction fAnimationDirection; 191db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkScalar fBegin[4]; 192db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com SkScalar fEnd[4]; 193ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 194db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com typedef SampleView INHERITED; 195db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com}; 196db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com 197db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.comSkView* create_transition(SkView* prev, SkView* next, int direction) { 1986293820c96ac1cf6f33377fb510549bf6a4f9ed6djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 199fc84359aa920567e72742877a1249f52d076ad35skia.committer@gmail.com // Disable transitions for Android 200fc84359aa920567e72742877a1249f52d076ad35skia.committer@gmail.com return next; 2016293820c96ac1cf6f33377fb510549bf6a4f9ed6djsollen@google.com#else 202db03eaa37111a63835ab7f61cb550971e609a621yangsu@google.com return SkNEW_ARGS(TransitionView, (prev, next, direction)); 2036293820c96ac1cf6f33377fb510549bf6a4f9ed6djsollen@google.com#endif 2046a12178fb32146232912fc20abb463b430f9025depoger@google.com} 205